Author SHA1 Message Date
Thomas StoddardandKyle Schwarz 5ee450353b Bindings: Python: Add T1S members 2026-01-07 23:32:20 -05:00
Thomas StoddardandKyle Schwarz 516bca682c EthernetMessage: Add T1S symbol support 2026-01-07 16:34:34 -05:00
Jonathan SchwartzandKyle Schwarz 3f5150bef3 FirmIO: Fix instability and memory leak issues 2026-01-07 13:35:23 -05:00
Thomas StoddardandKyle Schwarz 2a2d55f20d Bindings: Python : Add baudrate and LIN mode methods 2026-01-07 10:51:25 -05:00
Thomas StoddardandKyle Schwarz 977677e3af Bindings: Add LiveData and LiveDataMessage support in Python bindings 2026-01-05 10:40:14 -05:00
Kyle Schwarz 000036f745 Driver: DXX: Update
Fixes D2XX HANDLE leak.
2025-12-19 22:30:14 -05:00
Kyle Schwarz be6a15c017 Device: Galaxy2: Update supported networks 2025-12-18 12:22:12 -05:00
Nicholas ZamoraandKyle Schwarz 5288385495 Driver: DXX: Update libredxx for FT260 support 2025-12-16 11:05:11 -05:00
Max Brombach d6d9fc16ef Device: Update chips for ValueCAN4_2EL bootloader 2025-12-10 19:47:23 +00:00
Kyle Schwarz dbab92b25c Bindings: Python: Migrate to smart_holder 2025-12-09 14:24:40 -05:00
Max Brombach 579160f6d4 Device: Fix Epsilon-XL bootloader pipeline and chip info 2025-12-08 21:16:14 +00:00
Emily Brooks 737d5ceb3b TransmitMessage: Mark timestamp as extended when using CAN FD 2025-12-05 13:53:26 -05:00
Emily Brooks 95521a5548 TransmitMessage: Add TX support for neoVI network 2025-12-05 10:53:53 -05:00
Emily BrooksandKyle Schwarz 16cd476c01 Network: neoVI: Add TX support 2025-12-03 14:43:35 -05:00
Thomas StoddardandKyle Schwarz d328d314b6 Bindings: Python: Update pybind11
Updates to 3.0.1 and switches to smart_holder & native_enum.
2025-11-24 11:56:09 -05:00
Bryant JonesandKyle Schwarz 7b5b94d980 Docs: Python: Add SPI example 2025-11-20 17:08:30 -05:00
Kyle Schwarz fedb4b88f3 Build: Update icspb 2025-11-10 11:29:42 -05:00
Kyle Schwarz 5cac3a4600 Examples: Remove commented example 2025-11-05 12:01:58 -05:00
Yasser YassineandKyle Schwarz 9ff4bf7d0d MACsec: Refactor API 2025-11-05 12:00:07 -05:00
Kyle Schwarz 30c009fe8f Device: Refactor online keep alive 2025-11-04 16:24:49 -05:00
Max BrombachandKyle Schwarz 51e4fdc6d9 Device: Update tree structs and add size checks to non-deprecated devices 2025-11-04 14:29:37 -05:00
Yasser YassineandKyle Schwarz 39b54d8c4e Device: Fix bootloader phases 2025-11-04 12:37:19 -05:00
Kyle Schwarz 615b7d8d56 Bindings: Python: Document 3.14 support 2025-11-04 11:51:55 -05:00
Kyle Schwarz e3f4bbdc73 Device: sendEthPhyMsg(): Drop online requirement 2025-11-04 11:06:51 -05:00
Nicholas ZamoraandKyle Schwarz 563c444def Device: Add RAD-Gemini 2025-11-03 09:37:50 -05:00
Kyle Schwarz 3f3300d677 Communication: EthernetStatusMessage: Handle BASE-T invalid case 2025-10-31 12:31:03 -04:00
Max BrombachandKyle Schwarz b9e3542bcf Device: Use variant Core chip and fix ZChip flash for FIRE2 2025-10-31 12:02:02 -04:00
Kyle Schwarz 7f192a0cea Network: Use Type::AutomotiveEthernet 2025-10-30 23:40:30 -04:00
Kyle Schwarz 3b60bfc986 CI: Add Fedora 43 & drop 41 2025-10-30 21:21:07 -04:00
Kyle Schwarz d51f88d023 Communication: EthernetStatusMessage: Add BASE-T support 2025-10-30 21:13:20 -04:00
Kyle Schwarz f3cb41d60b Communication: Network: Add Type::AutomotiveEthernet
Also condense switch statements
2025-10-30 21:11:23 -04:00
Yasser YassineandKyle Schwarz 1b00c6a05b Gigastar(2): Fix bootloaders steps 2025-10-30 14:37:12 -04:00
Kyle Schwarz ebf9409c18 Device: Guard mutex usage 2025-10-30 11:18:12 -04:00
Kyle Schwarz 83ab65b062 Device: Fix NeoVI message guard 2025-10-29 15:37:58 -04:00
Kyle Schwarz 7f1668a55b Device: Move network mutex to goOnline 2025-10-29 15:24:03 -04:00
Max Brombach 10ffd756a1 Device: Remove erroneous API error in VSA buffer overlap check 2025-10-29 12:56:46 -04:00
Jonathan SchwartzandKyle Schwarz c2f1022858 Device: Add network mutex support 2025-10-24 12:12:36 -04:00
Kyle Schwarz bf311ebe30 Communication: Add NeoVI timestamps 2025-10-21 15:18:26 -04:00
Max BrombachandKyle Schwarz 5cdaeb1edc Communication: Remove CoreMiniExtendedMsgHdr from HardwareLINPacket struct 2025-10-16 13:31:20 -04:00
Kyle Schwarz deabc2cff4 Linux: Update udev rules
Always unbind ftdi_sio for ICS devices
2025-10-13 09:28:04 -04:00
Yasser YassineandKyle Schwarz b48160286b Device: Add reconnect() 2025-10-11 16:33:22 -04:00
Kyle Schwarz 5d672d48d4 Bindings: Python: Add get_chip_versions 2025-10-09 22:51:18 -04:00
Kyle Schwarz 495632ddb7 Driver: DXX: Add PLASMA 2025-10-09 21:56:48 -04:00
Kyle Schwarz 3668b86f37 Linux: Update udev rules
libredxx doesn't use ftdi_sio
2025-10-09 21:54:57 -04:00
Yasser YassineandKyle Schwarz 0bd733bc5d Device: Add bootloader information & getChipVersions() 2025-10-09 21:21:45 -04:00
Emily BrooksandKyle Schwarz 99a2ca4f0d Device: WiVI: Add VIN support 2025-10-08 15:49:03 -04:00
Kyle Schwarz ec350b522a DeviceSettings: Remove checksum validation 2025-10-06 15:36:55 -04:00
Thomas StoddardandKyle Schwarz 895cd0792c Communication: I2C: Fix invalid packet logic 2025-10-02 10:12:15 -04:00
Max BrombachandKyle Schwarz a5ec9a2d20 VSA: Fix incorrect bytesRead value for end of overlapped buffer 2025-09-30 14:03:21 -04:00
Max BrombachandKyle Schwarz b9d3dde8d5 VSA: Remove packet truncation mechanism 2025-09-30 11:41:40 -04:00
Kyle Schwarz 11643e2281 Bindings: Python: Add EthPhyMessage
Also fixes PhyMessages for RADEpsilon(XL)
2025-09-29 17:17:26 -04:00
Max BrombachandKyle Schwarz f22d666f94 VSA: Discard timestamp top bit 2025-09-24 14:13:29 -04:00
Bryant JonesandKyle Schwarz 58b22da09b Device: Add neoVI FIRE3 T1S/LIN 2025-09-18 17:18:27 -04:00
Yasser YassineandKyle Schwarz 88d32128c9 Communication: Add SPI support 2025-09-17 13:30:12 -04:00
Kyle Schwarz 6d82289864 Driver: DXX: Update libredxx 2025-09-16 11:42:13 -04:00
Kyle Schwarz 674e905340 Driver: CDCACM: Add missing Darwin frameworks 2025-09-15 15:57:16 -04:00
Kyle Schwarz 8b7e2556a0 Driver: DXX: Fix ION, FIRE, ValueCAN3, & VividCAN 2025-09-10 10:11:08 -04:00
Max BrombachandKyle Schwarz fbdab1e998 Communication: Fix MultiChannelCommunication race 2025-09-09 15:52:54 -04:00
Max Brombach f53bc2e920 Fix FlexRay extension bugs and implement FlexRay example 2025-09-04 14:27:32 +00:00
Bryant JonesandKyle Schwarz a9e1f24f67 Device: Comet: Fix networks 2025-09-02 10:26:50 -04:00
Kyle Schwarz b10e29b8f5 Driver: DXX: Update libredxx 2025-08-28 23:24:04 -04:00
Thomas StoddardandKyle Schwarz 3c0c0dd44c Docs: Refactor icsneopy examples 2025-08-28 11:40:57 -04:00
Kyle Schwarz cf2cf3e28b CMake: Disable libredxx install 2025-08-28 10:09:30 -04:00
Kyle Schwarz 6926ca8199 CI: Update Linux images 2025-08-25 11:29:46 -04:00
Kyle Schwarz 29dc7b345f Driver: Switch to libredxx
- no more libFTDI
- no more libusb on Linux and macOS
- no more FTDI repack
- no more binary libs
- faster D2XX on Windows (no longer uses COM)
2025-08-25 11:24:03 -04:00
Kyle Schwarz 17285389e3 Tests: Switch to FetchContent 2025-08-21 20:19:22 -04:00
Bryant JonesandKyle Schwarz 328563b7e6 Docs: Add TC10 .py example 2025-08-12 12:36:16 -04:00
Kyle Schwarz 6b60804174 Device: Add com keepalive 2025-08-06 17:17:36 -04:00
Jonathan SchwartzandKyle Schwarz c5bce795c6 Device: Add MessageFilter to enableMessagePolling() 2025-07-29 13:15:18 -04:00
Yasser YassineandKyle Schwarz 1e5e714f5b Device: Add disk formatting 2025-07-22 20:02:06 +00:00
Kyle Schwarz d70defbf8a All: Address compiler warnings 2025-07-17 15:47:23 -04:00
Thomas StoddardandKyle Schwarz 10efacf91e Communication: EthernetMessage: Switch to TX_WRAP 2025-07-17 01:49:31 +00:00
Kyle Schwarz 6d985ca873 Communication: Fix neotc10sleepstatus_t 2025-07-16 11:54:27 -04:00
Nicholas Zamora 19df557b4a DeviceAppVersion: Add operator== 2025-07-09 20:48:22 +00:00
Kyle Schwarz 7afa41bf2a API: C: Add TC10 2025-07-03 09:30:29 -04:00
Kyle Schwarz c056e8dc2e Driver: Servd: Toggle closing when done 2025-07-02 14:28:59 -04:00
Yasser YassineandKyle Schwarz d5ae1cdb03 Device: RED2: Update settings 2025-07-02 18:10:51 +00:00
Kyle Schwarz 5795791eac Driver: Servd: Fix Address creation 2025-06-19 16:48:15 -04:00
Ben KleinhekselandKyle Schwarz c91db6355c Device: Add setValueLiveData()
* Adds the ability to set a CoreMini signal value via the live data interface
* Adds definition for the Manual Trigger and DAQ Enable signals
2025-06-18 21:51:32 +00:00
Kyle Schwarz f37b88d616 Communication: Fix ScriptStatus sizes 2025-06-12 11:17:59 -04:00
Yasser YassineandKyle Schwarz 33dea748f7 Device: Add supportsCoreminiScript() 2025-06-06 19:29:42 +00:00
Kyle Schwarz 245073f9d5 1.0.0 2025-06-05 21:10:54 -04:00
Kyle Schwarz c4e858d346 Driver: Prefer Npcap
Prefer Npcap over WinPcap and TCP
2025-06-04 22:14:09 -04:00
Keith NashandKyle Schwarz b3d47f2ae5 Communication: Add LogDataMessage 2025-05-16 19:36:27 +00:00
Kyle Schwarz b94ade1ef6 FIRE3: Add Ethernet Activation Lines 2025-05-15 11:11:26 -04:00
Bryant Jones d9ea5e085e Device: Gigastar2: Update networks 2025-05-09 11:51:26 -04:00
Bryant JonesandKyle Schwarz 5125520e76 Device: Gigastar2: Update networks 2025-05-09 15:30:20 +00:00
Kyle Schwarz 4dcb944d35 Driver: Add Servd 2025-05-08 11:22:42 -04:00
Yasser YassineandKyle Schwarz 7eeb1b6c38 Device: Refactor ComponentVersions
Also:
- Add setGenericData()
- Add ExtendedResponseFilter
2025-04-30 18:49:35 +00:00
Kyle Schwarz b1e875980c Communication: Rename Ethernet to Ethernet 01 2025-04-18 09:39:40 -04:00
Kyle Schwarz 8b680f2b64 All: Update network names
Updates all network names, the new format is <id>_<%02d>.
2025-04-17 20:57:46 +00:00
Kyle Schwarz e88cd244c8 Driver: D3XX: Refactor pipe logic 2025-04-15 17:44:58 -04:00
Jonathan SchwartzandKyle Schwarz 70733b3d96 Epsilon: Add PHY settings 2025-04-09 14:08:55 +00:00
Jonathan SchwartzandKyle Schwarz f743f32e63 Bindings: Python: Add FlexRay
Only RX at this time.
2025-04-08 20:47:51 +00:00
Kyle Schwarz 830fe1af59 Build: Add CMake 4.0.0 support 2025-03-31 15:56:14 -04:00
Jonathan SchwartzandKyle Schwarz 2209e348a3 CI: Add warnings & error on warnings 2025-03-28 17:35:26 +00:00
Jonathan SchwartzandKyle Schwarz 52e98af9fd Device: Add RAD-EpsilonXL 2025-03-25 20:43:18 +00:00
Jonathan SchwartzandKyle Schwarz e1a0ca056a Communication: Ignore empty LIN frames for checksum 2025-03-21 18:04:45 +00:00
Kyle Schwarz 538d6ec0c8 Communication: Remove unused parameter 2025-03-17 23:12:25 -04:00
Kyle Schwarz 1ba3eded09 Device: Gracefully handle old firmware without ComponentVersions 2025-03-14 15:38:34 -04:00
Kyle Schwarz 89047447a6 Bindings: Python: Add DoIP Ethernet Activation 2025-03-10 10:50:25 -04:00
Kyle Schwarz f97fd75b8d Docs: icsneopy: Add TC10 example 2025-03-03 17:06:22 -05:00
Yasser YassineandKyle Schwarz ea5f11268c RADMoon2: Enable communication for MDIO 2025-02-26 02:40:01 +00:00
Yasser YassineandKyle Schwarz 759cb2436d Device: RM2 & RM3: Update settings 2025-02-25 22:45:08 +00:00
Kyle Schwarz 771d82826f CI: Delay GitHub push 2025-02-20 15:31:45 -05:00
Yaroslav StetsykandKyle Schwarz b7330a2cea RADMoon3: Add TC10 2025-02-20 19:24:33 +00:00
Kyle Schwarz fb3778f91b Bindings: Python: Rework disk bindings 2025-02-20 12:04:16 -05:00
Kyle Schwarz a0c8cc62df Bindings: Python: Add coremini functions 2025-02-19 17:38:07 +00:00
Kyle Schwarz 77b3564677 Communication: Add missing short format commands 2025-02-19 00:20:49 -05:00
Kyle Schwarz 051063e684 RADGigastar: Add disk support 2025-02-19 00:18:41 -05:00
Kyle Schwarz 7c1cfde6a0 CI: Remove duplicate DOCKER_HOST 2025-02-19 00:16:36 -05:00
Yasser YassineandKyle Schwarz d4995fa2a9 Device: Fix heartbeat thread join location 2025-02-19 05:15:23 +00:00
Kyle Schwarz fb5c4babce CI: Remove hardware tests 2025-02-19 05:12:51 +00:00
Kurt Wachowski 4ba1a1e1dd Resolve "Add MACsec support" 2025-02-17 20:44:58 +00:00
Kyle Schwarz 6b9a687ff9 Bindings: Python: Use static MSVC runtime library 2025-02-11 16:43:00 -05:00
Kyle Schwarz 02b5dafca9 Bindings: Python: Simplify debug process 2025-02-11 12:43:30 -05:00
David RebbeandKyle Schwarz f04cd16bee Platform: Improve Windows wstring support 2025-02-06 18:43:51 +00:00
Jonathan SchwartzandKyle Schwarz c5ba2d8d32 Communication: Add missing CAN error types 2025-02-04 15:15:44 +00:00
Kyle Schwarz a22791c9e0 CI: Move Windows jobs 2025-02-03 17:16:30 -05:00
Kyle Schwarz dc2a364afb Bindings: Python: Fix API docs since adding stubs 2025-01-29 14:53:18 -05:00
Kyle Schwarz 114b664d78 All: Welcome to 2025 2025-01-15 16:46:07 -05:00
Kyle Schwarz 2acf248583 Bindings: Python: Add stubs 2025-01-09 00:14:46 -05:00
Kyle Schwarz f18aa00322 Communication: Add EthernetStatusMessage 2025-01-06 14:12:19 -05:00
Jonathan SchwartzandKyle Schwarz 87baa97c3f Device: Fix ComponentVersion retrieval 2025-01-06 19:06:11 +00:00
Jonathan SchwartzandKyle Schwarz 8dcbbe0d72 NeoVIConnect: Add ComponentVersions support 2025-01-06 14:51:42 +00:00
Kyle Schwarz b624d06ca0 Driver: FTD3XX: Fix close() 2024-12-30 14:14:23 -05:00
Kyle Schwarz c249df8756 Bindings: Python: Add CANErrorCountMessage 2024-12-23 10:28:19 -05:00
Kyle Schwarz b2161211c5 Bindings: Python: Add Message::Type MessageFilter 2024-12-20 18:28:41 -05:00
Kyle Schwarz 0ee8a990a7 Bindings: Python: Fix get_gptp_status default arg 2024-12-20 18:28:22 -05:00
Yasser YassineandKyle Schwarz dc0f16b1d2 Communication: Add GPTPStatus 2024-12-20 23:22:25 +00:00
Kyle Schwarz c4ce803d62 LINMessage: Fix timestamp scaling 2024-12-19 15:54:27 -05:00
Kyle Schwarz 34cacf4cf2 EthernetMessage: Fix TX receipts
Fixes
- HardwareEthernetPacket packing
- EthernetMessage::fcs
2024-12-13 12:55:57 -05:00
Kyle Schwarz 4157558e84 Bindings: Python: Drop GIL for Device calls
Avoids an ABBA deadlock with the GIL and messageCallbacksLock
2024-12-12 11:12:55 -05:00
Kyle Schwarz 40b85488dc TCP: Add LIBICSNEO_DISABLE_TCP env option 2024-12-11 17:25:36 -05:00
Kyle Schwarz 7584563002 Bindings: Python: Add default MessageFilter constructor 2024-12-11 17:22:09 -05:00
Kyle Schwarz 4f83614037 Bindings: Python: Fix Device RTC functions 2024-12-04 12:31:06 -05:00
Kyle Schwarz 38a4af8062 Device: Fix getRTC response size
Some devices pad to 16-bit.
2024-12-04 12:11:01 -05:00
Kyle Schwarz 3b95b41be4 Bindings: Python: Add LINMessage 2024-12-03 23:41:51 -05:00
Kyle Schwarz 3da31a29b4 Bindings: Python: Add more Network members 2024-12-03 22:35:40 -05:00
Kyle Schwarz d0f3e593df Device: Add RAD-Galaxy 2 2024-12-02 20:02:06 -05:00
Kyle Schwarz 90268a4f04 CI: Update DOCKER_HOST 2024-12-02 19:44:21 -05:00
Kyle Schwarz dbe19a5616 Bindings: Python: Add MDIOMessage 2024-11-08 15:06:45 -05:00
Kyle Schwarz e5d7a38160 CI: Fix push command 2024-11-05 16:00:30 -05:00
Kyle Schwarz d714b620c4 CI: Add GitHub auto-push 2024-11-05 14:58:54 -05:00
Kyle Schwarz 10d2625cb6 Bindings: Python: Add get_tc10_status 2024-11-05 14:30:53 -05:00
Kyle Schwarz b9cfa85009 Docs: Add GitHub link 2024-11-05 12:56:27 -05:00
Kyle Schwarz 776d14bb3e Docs: Fix RTD requirements path 2024-11-04 18:05:24 -05:00
713 changed files with 14612 additions and 151445 deletions
+1
View File
@@ -15,3 +15,4 @@ third-party/concurrentqueue/tests
examples/csharp/bin examples/csharp/bin
examples/csharp/obj examples/csharp/obj
test/system test/system
.env
+96 -217
View File
@@ -1,10 +1,10 @@
variables: variables:
DEBIAN_FRONTEND: noninteractive DEBIAN_FRONTEND: noninteractive
LIBICSNEO_ICSPB_REPO: https://gitlab-ci-token:${CI_JOB_TOKEN}@${LIBICSNEO_ICSPB_GIT}
stages: stages:
- build - build
- unit_test - unit_test
- hardware_test
- deploy - deploy
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@@ -14,14 +14,14 @@ stages:
build windows/x64: build windows/x64:
stage: build stage: build
script: script:
- CMD.EXE /C ci\build-windows64.bat - cmd /C ci\build-windows64.bat
artifacts: artifacts:
when: always when: always
paths: paths:
- build - build
expire_in: 3 days expire_in: 3 days
tags: tags:
- icsneo-windows - libicsneo-win-x64
unit_test windows/x64: unit_test windows/x64:
stage: unit_test stage: unit_test
@@ -32,20 +32,20 @@ unit_test windows/x64:
needs: needs:
- build windows/x64 - build windows/x64
tags: tags:
- icsneo-windows - libicsneo-win-x64
timeout: 5m timeout: 5m
build windows/x86: build windows/x86:
stage: build stage: build
script: script:
- CMD.EXE /C ci\build-windows32.bat - cmd /C ci\build-windows32.bat
artifacts: artifacts:
when: always when: always
paths: paths:
- build - build
expire_in: 3 days expire_in: 3 days
tags: tags:
- icsneo-windows - libicsneo-win-x64
unit_test windows/x86: unit_test windows/x86:
stage: unit_test stage: unit_test
@@ -56,7 +56,7 @@ unit_test windows/x86:
needs: needs:
- build windows/x86 - build windows/x86
tags: tags:
- icsneo-windows - libicsneo-win-x64
timeout: 5m timeout: 5m
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@@ -68,7 +68,9 @@ unit_test windows/x86:
script: script:
- apt update -y - apt update -y
- apt upgrade -y - apt upgrade -y
- apt install -y g++ ninja-build cmake libusb-1.0-0-dev libpcap-dev git - apt install -y g++ ninja-build cmake libpcap-dev git ca-certificates
- echo "$ICS_IPA_CA_CRT" >/usr/local/share/ca-certificates/ica-ipa-ca.crt
- update-ca-certificates --fresh
- sh ci/build-posix.sh - sh ci/build-posix.sh
artifacts: artifacts:
when: always when: always
@@ -83,7 +85,7 @@ unit_test windows/x86:
script: script:
- apt update -y - apt update -y
- apt upgrade -y - apt upgrade -y
- apt install -y libusb-1.0-0-dev libpcap-dev - apt install -y libpcap-dev
- build/libicsneo-unit-tests - build/libicsneo-unit-tests
tags: tags:
- linux-build - linux-build
@@ -94,7 +96,9 @@ unit_test windows/x86:
script: script:
- apt update -y - apt update -y
- apt upgrade -y - apt upgrade -y
- apt install -y clang lld ninja-build cmake libusb-1.0-0-dev libpcap-dev git - apt install -y clang lld ninja-build cmake libpcap-dev git ca-certificates
- echo "$ICS_IPA_CA_CRT" >/usr/local/share/ca-certificates/ica-ipa-ca.crt
- update-ca-certificates --fresh
- CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh - CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh
artifacts: artifacts:
when: always when: always
@@ -109,36 +113,12 @@ unit_test windows/x86:
script: script:
- apt update -y - apt update -y
- apt upgrade -y - apt upgrade -y
- apt install -y libusb-1.0-0-dev libpcap-dev - apt install -y libpcap-dev
- build/libicsneo-unit-tests - build/libicsneo-unit-tests
tags: tags:
- linux-build - linux-build
timeout: 5m timeout: 5m
build linux/ubuntu/2004/amd64/gcc:
<<: *build_linux_ubuntu_gcc
image: ubuntu:20.04
unit_test linux/ubuntu/2004/amd64/gcc:
<<: *test_linux_ubuntu_gcc
image: ubuntu:20.04
dependencies:
- build linux/ubuntu/2004/amd64/gcc
needs:
- build linux/ubuntu/2004/amd64/gcc
build linux/ubuntu/2004/amd64/clang:
<<: *build_linux_ubuntu_clang
image: ubuntu:20.04
unit_test linux/ubuntu/2004/amd64/clang:
<<: *test_linux_ubuntu_clang
image: ubuntu:20.04
dependencies:
- build linux/ubuntu/2004/amd64/clang
needs:
- build linux/ubuntu/2004/amd64/clang
build linux/ubuntu/2204/amd64/gcc: build linux/ubuntu/2204/amd64/gcc:
<<: *build_linux_ubuntu_gcc <<: *build_linux_ubuntu_gcc
image: ubuntu:22.04 image: ubuntu:22.04
@@ -163,6 +143,30 @@ unit_test linux/ubuntu/2204/amd64/clang:
needs: needs:
- build linux/ubuntu/2204/amd64/clang - build linux/ubuntu/2204/amd64/clang
build linux/ubuntu/2404/amd64/gcc:
<<: *build_linux_ubuntu_gcc
image: ubuntu:24.04
unit_test linux/ubuntu/2404/amd64/gcc:
<<: *test_linux_ubuntu_gcc
image: ubuntu:24.04
dependencies:
- build linux/ubuntu/2404/amd64/gcc
needs:
- build linux/ubuntu/2404/amd64/gcc
build linux/ubuntu/2404/amd64/clang:
<<: *build_linux_ubuntu_clang
image: ubuntu:24.04
unit_test linux/ubuntu/2404/amd64/clang:
<<: *test_linux_ubuntu_clang
image: ubuntu:24.04
dependencies:
- build linux/ubuntu/2404/amd64/clang
needs:
- build linux/ubuntu/2404/amd64/clang
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Fedora # Fedora
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
@@ -176,7 +180,9 @@ unit_test linux/ubuntu/2204/amd64/clang:
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
- echo fastestmirror=True >>/etc/dnf/dnf.conf - echo fastestmirror=True >>/etc/dnf/dnf.conf
- dnf upgrade -y - dnf upgrade -y
- dnf install -y g++ libpcap-devel cmake ninja-build libusb1-devel git - dnf install -y g++ libpcap-devel cmake ninja-build git ca-certificates
- echo "$ICS_IPA_CA_CRT" >/etc/pki/ca-trust/source/anchors/ica-ipa-ca.crt
- update-ca-trust
- sh ci/build-posix.sh - sh ci/build-posix.sh
artifacts: artifacts:
when: always when: always
@@ -195,7 +201,7 @@ unit_test linux/ubuntu/2204/amd64/clang:
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
- echo fastestmirror=True >>/etc/dnf/dnf.conf - echo fastestmirror=True >>/etc/dnf/dnf.conf
- dnf upgrade -y - dnf upgrade -y
- dnf install -y libpcap-devel libusb1-devel - dnf install -y libpcap-devel
- build/libicsneo-unit-tests - build/libicsneo-unit-tests
tags: tags:
- linux-build - linux-build
@@ -210,7 +216,9 @@ unit_test linux/ubuntu/2204/amd64/clang:
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
- echo fastestmirror=True >>/etc/dnf/dnf.conf - echo fastestmirror=True >>/etc/dnf/dnf.conf
- dnf upgrade -y - dnf upgrade -y
- dnf install -y clang lld libpcap-devel cmake ninja-build libusb1-devel git - dnf install -y clang lld libpcap-devel cmake ninja-build git ca-certificates
- echo "$ICS_IPA_CA_CRT" >/etc/pki/ca-trust/source/anchors/ica-ipa-ca.crt
- update-ca-trust
- CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh - CC=clang CXX=clang++ LDFLAGS=-fuse-ld=lld sh ci/build-posix.sh
artifacts: artifacts:
when: always when: always
@@ -229,196 +237,59 @@ unit_test linux/ubuntu/2204/amd64/clang:
- echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf - echo max_parallel_downloads=10 >>/etc/dnf/dnf.conf
- echo fastestmirror=True >>/etc/dnf/dnf.conf - echo fastestmirror=True >>/etc/dnf/dnf.conf
- dnf upgrade -y - dnf upgrade -y
- dnf install -y libpcap-devel libusb1-devel - dnf install -y libpcap-devel
- build/libicsneo-unit-tests - build/libicsneo-unit-tests
tags: tags:
- linux-build - linux-build
timeout: 5m timeout: 5m
build linux/fedora/37/amd64/gcc: build linux/fedora/42/amd64/gcc:
<<: *build_linux_fedora_gcc <<: *build_linux_fedora_gcc
image: fedora:37 image: fedora:42
unit_test linux/fedora/37/amd64/gcc: unit_test linux/fedora/42/amd64/gcc:
<<: *test_linux_fedora_gcc <<: *test_linux_fedora_gcc
image: fedora:37 image: fedora:42
dependencies: dependencies:
- build linux/fedora/37/amd64/gcc - build linux/fedora/42/amd64/gcc
needs: needs:
- build linux/fedora/37/amd64/gcc - build linux/fedora/42/amd64/gcc
build linux/fedora/37/amd64/clang: build linux/fedora/42/amd64/clang:
<<: *build_linux_fedora_clang <<: *build_linux_fedora_clang
image: fedora:37 image: fedora:42
unit_test linux/fedora/37/amd64/clang: unit_test linux/fedora/42/amd64/clang:
<<: *test_linux_fedora_clang <<: *test_linux_fedora_clang
image: fedora:37 image: fedora:42
dependencies: dependencies:
- build linux/fedora/37/amd64/clang - build linux/fedora/42/amd64/clang
needs: needs:
- build linux/fedora/37/amd64/clang - build linux/fedora/42/amd64/clang
build linux/fedora/38/amd64/gcc: build linux/fedora/43/amd64/gcc:
<<: *build_linux_fedora_gcc <<: *build_linux_fedora_gcc
image: fedora:38 image: fedora:43
unit_test linux/fedora/38/amd64/gcc: unit_test linux/fedora/43/amd64/gcc:
<<: *test_linux_fedora_gcc <<: *test_linux_fedora_gcc
image: fedora:38 image: fedora:43
dependencies: dependencies:
- build linux/fedora/38/amd64/gcc - build linux/fedora/43/amd64/gcc
needs: needs:
- build linux/fedora/38/amd64/gcc - build linux/fedora/43/amd64/gcc
build linux/fedora/38/amd64/clang: build linux/fedora/43/amd64/clang:
<<: *build_linux_fedora_clang <<: *build_linux_fedora_clang
image: fedora:38 image: fedora:43
unit_test linux/fedora/38/amd64/clang: unit_test linux/fedora/43/amd64/clang:
<<: *test_linux_fedora_clang <<: *test_linux_fedora_clang
image: fedora:38 image: fedora:43
dependencies: dependencies:
- build linux/fedora/38/amd64/clang - build linux/fedora/43/amd64/clang
needs: needs:
- build linux/fedora/38/amd64/clang - build linux/fedora/43/amd64/clang
build linux/fedora/39/amd64/gcc:
<<: *build_linux_fedora_gcc
image: fedora:39
unit_test linux/fedora/39/amd64/gcc:
<<: *test_linux_fedora_gcc
image: fedora:39
dependencies:
- build linux/fedora/39/amd64/gcc
needs:
- build linux/fedora/39/amd64/gcc
build linux/fedora/39/amd64/clang:
<<: *build_linux_fedora_clang
image: fedora:39
unit_test linux/fedora/39/amd64/clang:
<<: *test_linux_fedora_clang
image: fedora:39
dependencies:
- build linux/fedora/39/amd64/clang
needs:
- build linux/fedora/39/amd64/clang
.hw_test: &hw_test
stage: hardware_test
tags:
- libicsneo_hil
timeout: 5m
script:
- echo $GUEST_OS_TAG
- echo $DEVICE_PORT
- /opt/libvirt-driver/prepare.sh
- /opt/libvirt-driver/run.sh
after_script:
- /opt/libvirt-driver/cleanup.sh
allow_failure: true
.fedora38_needs: &fedora38_needs
needs:
- job: build linux/fedora/38/amd64/clang
artifacts: true
hardware_test fedora38-red2:
<<: *hw_test
<<: *fedora38_needs
variables:
GUEST_OS_TAG: fedora38
DEVICE_PORT: ETH_A
hardware_test fedora38-vcan42:
<<: *hw_test
<<: *fedora38_needs
variables:
GUEST_OS_TAG: fedora38
DEVICE_PORT: USB_D
hardware_test fedora38-fire3:
<<: *hw_test
<<: *fedora38_needs
variables:
GUEST_OS_TAG: fedora38
DEVICE_PORT: ETH_B
hardware_test fedora38-vcan42-EL:
<<: *hw_test
<<: *fedora38_needs
variables:
GUEST_OS_TAG: fedora38
DEVICE_PORT: USB_C
.ubuntu2204_needs: &ubuntu2204_needs
needs:
- job: build linux/ubuntu/2204/amd64/clang
artifacts: true
hardware_test ubuntu2204-red2:
<<: *hw_test
<<: *ubuntu2204_needs
variables:
GUEST_OS_TAG: ubuntu22.04
DEVICE_PORT: ETH_A
hardware_test ubuntu2204-vcan42:
<<: *hw_test
<<: *ubuntu2204_needs
variables:
GUEST_OS_TAG: ubuntu22.04
DEVICE_PORT: USB_D
hardware_test ubuntu2204-fire3:
<<: *hw_test
<<: *ubuntu2204_needs
variables:
GUEST_OS_TAG: ubuntu22.04
DEVICE_PORT: ETH_B
hardware_test ubuntu2204-vcan42-EL:
<<: *hw_test
<<: *ubuntu2204_needs
variables:
GUEST_OS_TAG: ubuntu22.04
DEVICE_PORT: USB_C
.win10_needs: &win10_needs
needs:
- job: build windows/x64
artifacts: true
hardware_test win10-red2:
<<: *hw_test
<<: *win10_needs
variables:
GUEST_OS_TAG: win10
DEVICE_PORT: ETH_A
hardware_test win10-vcan42:
<<: *hw_test
<<: *win10_needs
variables:
GUEST_OS_TAG: win10
DEVICE_PORT: USB_D
hardware_test win10-fire3:
<<: *hw_test
<<: *win10_needs
variables:
GUEST_OS_TAG: win10
DEVICE_PORT: ETH_B
hardware_test win10-vcan42-EL:
<<: *hw_test
<<: *win10_needs
variables:
GUEST_OS_TAG: win10
DEVICE_PORT: USB_C
#------------------------------------------------------------------------------- #-------------------------------------------------------------------------------
# Python Module # Python Module
@@ -427,22 +298,13 @@ hardware_test win10-vcan42-EL:
build python/linux/amd64: build python/linux/amd64:
stage: build stage: build
tags: tags:
- linux-build - linux-native-amd64
image: python:3.12
services:
- name: docker:dind
entrypoint: ["env", "-u", "DOCKER_HOST"]
command: ["dockerd-entrypoint.sh"]
variables: variables:
CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh CIBW_BEFORE_ALL: sh ci/bootstrap-cibuildwheel.sh && sh ci/bootstrap-libpcap.sh
CIBW_BUILD: "*manylinux*" # no musl CIBW_BUILD: "*manylinux*" # no musl
CIBW_ARCHS: x86_64 CIBW_ARCHS: x86_64
DOCKER_HOST: tcp://docker:2375/ CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install
DOCKER_DRIVER: overlay2
DOCKER_TLS_CERTDIR: ""
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install
script: script:
- curl -sSL https://get.docker.com/ | sh
- sh ci/build-wheel-posix.sh - sh ci/build-wheel-posix.sh
artifacts: artifacts:
paths: paths:
@@ -453,10 +315,10 @@ build python/linux/arm64:
tags: tags:
- arm64-linux-build - arm64-linux-build
variables: variables:
CIBW_BEFORE_ALL: yum install -y flex && sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh CIBW_BEFORE_ALL: sh ci/bootstrap-cibuildwheel.sh && sh ci/bootstrap-libpcap.sh
CIBW_BUILD: "*manylinux*" # no musl CIBW_BUILD: "*manylinux*" # no musl
CIBW_ARCHS: aarch64 CIBW_ARCHS: aarch64
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install:/project/libusb/install CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=/project/libpcap/install
script: script:
- sh ci/build-wheel-posix.sh - sh ci/build-wheel-posix.sh
artifacts: artifacts:
@@ -468,9 +330,9 @@ build python/macos:
tags: tags:
- macos-arm64 - macos-arm64
variables: variables:
CIBW_BEFORE_ALL: sh ci/bootstrap-libpcap.sh && sh ci/bootstrap-libusb.sh CIBW_BEFORE_ALL: sh ci/bootstrap-libpcap.sh
CIBW_ARCHS: arm64 CIBW_ARCHS: arm64
CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/install:$CI_PROJECT_DIR/libusb/install CIBW_ENVIRONMENT: CMAKE_PREFIX_PATH=$CI_PROJECT_DIR/libpcap/install
MACOSX_DEPLOYMENT_TARGET: 10.14 MACOSX_DEPLOYMENT_TARGET: 10.14
script: script:
- sh ci/build-wheel-posix.sh - sh ci/build-wheel-posix.sh
@@ -498,7 +360,7 @@ deploy python/pypi:
TWINE_PASSWORD: $PYPI_TOKEN TWINE_PASSWORD: $PYPI_TOKEN
tags: tags:
- linux-build - linux-build
image: python:3.12 image: python:3.13
rules: rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH - if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
script: script:
@@ -514,3 +376,20 @@ deploy python/pypi:
- build python/linux/arm64 - build python/linux/arm64
- build python/macos - build python/macos
- build python/windows - build python/windows
push github:
stage: deploy
tags:
- linux-build
image: alpine:latest
rules:
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH
when: delayed
start_in: 10 minutes
dependencies:
- deploy python/pypi
needs:
- deploy python/pypi
script:
- apk add git
- git push https://$LIBICSNEO_GITHUB_USERNAME:$LIBICSNEO_GITHUB_TOKEN@github.com/intrepidcs/libicsneo.git HEAD:master
+1 -1
View File
@@ -9,7 +9,7 @@ build:
python: python:
install: install:
- requirements: docs/icsneopy/requirements.txt - requirements: docs/requirements.txt
sphinx: sphinx:
configuration: docs/conf.py configuration: docs/conf.py
+5 -21
View File
@@ -3,24 +3,8 @@ SUBSYSTEM=="usb", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666"
KERNEL=="ttyUSB?", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666" KERNEL=="ttyUSB?", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666"
KERNEL=="ttyACM?", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666" KERNEL=="ttyACM?", ATTRS{idVendor}=="093c", GROUP="users", MODE="0666"
# neoVI ION/PLASMA PIDs are not in the latest ftdi_sio driver so lets make a ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="093c", KERNEL=="ttyUSB*", \
# rule to add it when we see a new unclaimed device. RUN+="/bin/sh -c 'echo $id:1.0>/sys/bus/usb/drivers/ftdi_sio/unbind'"
# PLASMA = 0x0801, ION = 0x0901
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \ ACTION=="add", SUBSYSTEMS=="usb", ATTRS{idVendor}=="093c", DRIVER=="usbhid", \
ATTRS{idVendor}=="093c", ATTRS{idProduct}=="0801", \ RUN+="/bin/sh -c 'echo $id:1.0>/sys/bus/usb/drivers/usbhid/unbind'"
DRIVER=="", \
RUN+="/sbin/modprobe -b ftdi_sio"
ACTION=="add", SUBSYSTEM=="drivers", \
ENV{DEVPATH}=="/bus/usb-serial/drivers/ftdi_sio", \
ATTR{new_id}="093c 0801"
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
ATTRS{idVendor}=="093c", ATTRS{idProduct}=="0901", \
DRIVER=="", \
RUN+="/sbin/modprobe -b ftdi_sio"
ACTION=="add", SUBSYSTEM=="usb", ENV{DEVTYPE}=="usb_interface", \
ATTRS{idVendor}=="093c", ATTRS{idProduct}=="1000", \
DRIVER=="", \
RUN+="/sbin/modprobe -b ftdi_sio"
ACTION=="add", SUBSYSTEM=="drivers", \
ENV{DEVPATH}=="/bus/usb-serial/drivers/ftdi_sio", \
ATTR{new_id}="093c 0901"
+75 -123
View File
@@ -1,5 +1,5 @@
cmake_minimum_required(VERSION 3.12) cmake_minimum_required(VERSION 3.16)
project(libicsneo VERSION 0.3.0) project(libicsneo VERSION 1.0.0)
cmake_policy(SET CMP0074 NEW) cmake_policy(SET CMP0074 NEW)
if(POLICY CMP0135) if(POLICY CMP0135)
@@ -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)
@@ -23,15 +22,13 @@ set(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to
option(LIBICSNEO_ENABLE_FIRMIO "Enable communication between Linux and CoreMini within the same device" OFF) option(LIBICSNEO_ENABLE_FIRMIO "Enable communication between Linux and CoreMini within the same device" OFF)
option(LIBICSNEO_ENABLE_RAW_ETHERNET "Enable devices which communicate over raw ethernet" ON) option(LIBICSNEO_ENABLE_RAW_ETHERNET "Enable devices which communicate over raw ethernet" ON)
option(LIBICSNEO_ENABLE_CDCACM "Enable devices which communicate over USB CDC ACM" ON) option(LIBICSNEO_ENABLE_CDCACM "Enable devices which communicate over USB CDC ACM" ON)
option(LIBICSNEO_ENABLE_FTDI "Enable devices which communicate over USB FTDI2XX" ON)
option(LIBICSNEO_ENABLE_TCP "Enable devices which communicate over TCP" OFF) option(LIBICSNEO_ENABLE_TCP "Enable devices which communicate over TCP" OFF)
option(LIBICSNEO_ENABLE_FTD3XX "Enable devices which communicate over USB FTD3XX" ON) option(LIBICSNEO_ENABLE_DXX "Enable devices which communicate over D2XX/D3XX via libredxx" ON)
option(LIBICSNEO_ENABLE_BINDINGS_PYTHON "Enable Python library" OFF) option(LIBICSNEO_ENABLE_BINDINGS_PYTHON "Enable Python library" OFF)
if(NOT CMAKE_CXX_STANDARD) set(CMAKE_CXX_STANDARD 17)
set(CMAKE_CXX_STANDARD 17) set(CMAKE_MSVC_RUNTIME_LIBRARY "MultiThreaded")
endif()
include(GNUInstallDirs) include(GNUInstallDirs)
@@ -39,17 +36,13 @@ set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
# Enable Warnings # Enable Warnings
if(MSVC) if(MSVC)
# Force to always compile with W4 set(LIBICSNEO_COMPILER_WARNINGS /W4)
if(CMAKE_CXX_FLAGS MATCHES "/W[0-4]")
string(REGEX REPLACE "/W[0-4]" "/W4" CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS}")
else()
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
endif()
# http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html # http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2017/p0618r0.html
# Still supported until a suitable replacement is standardized # Still supported until a suitable replacement is standardized
add_definitions(-D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING) add_definitions(-D_SILENCE_CXX17_CODECVT_HEADER_DEPRECATION_WARNING)
add_definitions(-D_ITERATOR_DEBUG_LEVEL=0)
else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX) else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-switch -Wno-unknown-pragmas") set(LIBICSNEO_COMPILER_WARNINGS -Wall -Wno-switch -Wno-unknown-pragmas)
endif() endif()
find_package(Threads REQUIRED) find_package(Threads REQUIRED)
@@ -111,6 +104,7 @@ endif()
if(WIN32) if(WIN32)
set(PLATFORM_SRC set(PLATFORM_SRC
platform/windows/strings.cpp
platform/windows/registry.cpp platform/windows/registry.cpp
) )
@@ -121,9 +115,9 @@ if(WIN32)
) )
endif() endif()
if(LIBICSNEO_ENABLE_CDCACM OR LIBICSNEO_ENABLE_FTDI) if(LIBICSNEO_ENABLE_CDCACM)
list(APPEND PLATFORM_SRC list(APPEND PLATFORM_SRC
platform/windows/vcp.cpp platform/windows/cdcacm.cpp
) )
endif() endif()
else() # Darwin or Linux else() # Darwin or Linux
@@ -141,12 +135,6 @@ else() # Darwin or Linux
) )
endif() endif()
if(LIBICSNEO_ENABLE_FTDI)
list(APPEND PLATFORM_SRC
platform/posix/ftdi.cpp
)
endif()
if(LIBICSNEO_ENABLE_CDCACM) if(LIBICSNEO_ENABLE_CDCACM)
list(APPEND PLATFORM_SRC list(APPEND PLATFORM_SRC
platform/posix/cdcacm.cpp platform/posix/cdcacm.cpp
@@ -170,51 +158,9 @@ else() # Darwin or Linux
endif() endif()
endif() endif()
if(LIBICSNEO_ENABLE_FTD3XX) if(LIBICSNEO_ENABLE_DXX)
if(NOT FTD3XX_ROOT) # allow system override
include(FetchContent)
if(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.3.0.10-win-x64.zip")
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=459e635496ab47d6069c9d3515fdd6d82cba3d95e7ae34f794d66ffdf336e9d1")
elseif(WIN32 AND CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.3.0.10-win-i686.zip")
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=ce4259ae11772d6ede7d217172156fa392f329b29d9455131f4126a2fb89dad1")
elseif(APPLE AND CMAKE_SIZEOF_VOID_P EQUAL 8)
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-macos-universal2.zip")
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=0904ac5eda8e1dc4b5aac3714383bcc7792b42dfeb585dce6cbfb8b67b8c0c51")
elseif(UNIX)
if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|amd64|AMD64")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-x64.zip")
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=cf66bf299fc722f050cdd3c36998a670f1df69f7c0df18afa73707277067114b")
endif()
elseif(CMAKE_SYSTEM_PROCESSOR MATCHES "arm.*|aarch64")
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-aarch64.zip")
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=66341b5112b9841e959e81400b51711be96fec91894477c5cbfc29b10a0c00a6")
elseif(CMAKE_SIZEOF_VOID_P EQUAL 4)
set(LIBICSNEO_FTD3XX_URL "https://github.com/intrepidcs/libftd3xx-repack/releases/download/24.34.0/libftd3xx-1.0.16-linux-armhf.zip")
set(LIBICSNEO_FTD3XX_URL_HASH "SHA256=cec1f959b48a11eb6b829ed43c81b6ba1c0bcf3e797bafcc84a6376e5ffc3c47")
endif()
endif()
endif()
if(NOT LIBICSNEO_FTD3XX_URL)
message(FATAL_ERROR "Unsupported platform for FTD3XX driver")
endif()
FetchContent_Declare(
ftdi3xx
URL ${LIBICSNEO_FTD3XX_URL}
URL_HASH ${LIBICSNEO_FTD3XX_URL_HASH}
)
FetchContent_GetProperties(ftdi3xx)
if(NOT ftdi3xx_POPULATED)
FetchContent_Populate(ftdi3xx)
endif()
set(FTD3XX_ROOT "${ftdi3xx_SOURCE_DIR}")
endif()
find_package(FTD3XX REQUIRED)
list(APPEND PLATFORM_SRC list(APPEND PLATFORM_SRC
platform/ftd3xx.cpp platform/dxx.cpp
) )
endif() endif()
@@ -245,10 +191,17 @@ set(SRC_FILES
communication/message/ethphymessage.cpp communication/message/ethphymessage.cpp
communication/message/linmessage.cpp communication/message/linmessage.cpp
communication/message/livedatamessage.cpp communication/message/livedatamessage.cpp
communication/message/logdatamessage.cpp
communication/message/tc10statusmessage.cpp communication/message/tc10statusmessage.cpp
communication/message/gptpstatusmessage.cpp
communication/message/ethernetstatusmessage.cpp
communication/message/networkmutexmessage.cpp
communication/message/clientidmessage.cpp
communication/message/transmitmessage.cpp
communication/packet/flexraypacket.cpp communication/packet/flexraypacket.cpp
communication/packet/canpacket.cpp communication/packet/canpacket.cpp
communication/packet/a2bpacket.cpp communication/packet/a2bpacket.cpp
communication/packet/spipacket.cpp
communication/packet/ethernetpacket.cpp communication/packet/ethernetpacket.cpp
communication/packet/versionpacket.cpp communication/packet/versionpacket.cpp
communication/packet/iso9141packet.cpp communication/packet/iso9141packet.cpp
@@ -272,7 +225,9 @@ set(SRC_FILES
communication/communication.cpp communication/communication.cpp
communication/driver.cpp communication/driver.cpp
communication/livedata.cpp communication/livedata.cpp
communication/ringbuffer.cpp core/ringbuffer.cpp
core/crc32.cpp
core/macseccfg.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
@@ -286,6 +241,7 @@ set(SRC_FILES
disk/plasiondiskreaddriver.cpp disk/plasiondiskreaddriver.cpp
disk/extextractordiskreaddriver.cpp disk/extextractordiskreaddriver.cpp
disk/fat.cpp disk/fat.cpp
disk/diskdetails.cpp
disk/vsa/vsa.cpp disk/vsa/vsa.cpp
disk/vsa/vsa02.cpp disk/vsa/vsa02.cpp
disk/vsa/vsa03.cpp disk/vsa/vsa03.cpp
@@ -302,6 +258,7 @@ set(SRC_FILES
disk/vsa/vsa0f.cpp disk/vsa/vsa0f.cpp
disk/vsa/vsa6a.cpp disk/vsa/vsa6a.cpp
disk/vsa/vsaparser.cpp disk/vsa/vsaparser.cpp
platform/servd.cpp
${PLATFORM_SRC} ${PLATFORM_SRC}
) )
@@ -362,9 +319,10 @@ target_include_directories(icsneocpp
${CMAKE_CURRENT_SOURCE_DIR}/include ${CMAKE_CURRENT_SOURCE_DIR}/include
${LIBICSNEO_EXTENSION_INCLUDE_PATHS} ${LIBICSNEO_EXTENSION_INCLUDE_PATHS}
) )
target_link_libraries(icsneocpp PUBLIC Threads::Threads) target_link_libraries(icsneocpp PUBLIC Threads::Threads $<$<BOOL:${WIN32}>:ws2_32 iphlpapi>)
set_property(TARGET icsneocpp PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET icsneocpp PROPERTY POSITION_INDEPENDENT_CODE ON)
target_compile_features(icsneocpp PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_features(icsneocpp PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
target_compile_options(icsneocpp PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
message("Loaded extensions: " ${LIBICSNEO_EXTENSION_TARGETS}) message("Loaded extensions: " ${LIBICSNEO_EXTENSION_TARGETS})
target_link_libraries(icsneocpp PUBLIC ${LIBICSNEO_EXTENSION_TARGETS}) target_link_libraries(icsneocpp PUBLIC ${LIBICSNEO_EXTENSION_TARGETS})
if(LIBICSNEO_ENABLE_FIRMIO) if(LIBICSNEO_ENABLE_FIRMIO)
@@ -375,13 +333,15 @@ if(LIBICSNEO_ENABLE_RAW_ETHERNET)
endif() endif()
if(LIBICSNEO_ENABLE_CDCACM) if(LIBICSNEO_ENABLE_CDCACM)
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_CDCACM) target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_CDCACM)
if(APPLE)
find_library(CORE_FOUNDATION_FRAMEWORK CoreFoundation REQUIRED)
find_library(IO_KIT_FRAMEWORK IOKit REQUIRED)
target_link_libraries(icsneocpp PRIVATE ${CORE_FOUNDATION_FRAMEWORK} ${IO_KIT_FRAMEWORK})
endif()
endif() endif()
if(LIBICSNEO_ENABLE_FTDI) if(LIBICSNEO_ENABLE_DXX)
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_FTDI) target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_DXX)
endif() target_link_libraries(icsneocpp PRIVATE libredxx::libredxx)
if(LIBICSNEO_ENABLE_FTD3XX)
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_FTD3XX)
target_link_libraries(icsneocpp PRIVATE FTD3XX::FTD3XX)
endif() endif()
if(LIBICSNEO_ENABLE_TCP) if(LIBICSNEO_ENABLE_TCP)
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_TCP) target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_TCP)
@@ -395,35 +355,25 @@ add_subdirectory(third-party/fatfs)
set_property(TARGET fatfs PROPERTY POSITION_INDEPENDENT_CODE ON) set_property(TARGET fatfs PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(icsneocpp PRIVATE fatfs) target_link_libraries(icsneocpp PRIVATE fatfs)
# libftdi # dxx
if(LIBICSNEO_ENABLE_FTDI) if(LIBICSNEO_ENABLE_DXX)
if(NOT WIN32) include(FetchContent)
target_include_directories(icsneocpp PUBLIC third-party/libftdi/src) FetchContent_Declare(libredxx
set(LIBFTDI_DOCUMENTATION OFF CACHE INTERNAL "") GIT_REPOSITORY https://github.com/Zeranoe/libredxx.git
set(LIBFTDI_BUILD_TESTS OFF CACHE INTERNAL "") GIT_TAG c28c3f4e1c46f0e0fc119843eb73edd81d5bbb3d
set(LIBFTDI_INSTALL OFF CACHE INTERNAL "") )
set(LIBFTDI_PYTHON_BINDINGS OFF CACHE INTERNAL "") set(LIBREDXX_DISABLE_INSTALL ON)
set(LIBFTDI_LINK_PYTHON_LIBRARY OFF CACHE INTERNAL "") FetchContent_MakeAvailable(libredxx)
set(FTDIPP OFF CACHE INTERNAL "") endif()
set(FTDI_EEPROM OFF CACHE INTERNAL "")
add_subdirectory(third-party/libftdi)
target_include_directories(icsneocpp PRIVATE ${LIBUSB_INCLUDE_DIR})
set_property(TARGET ftdi1-static PROPERTY POSITION_INDEPENDENT_CODE ON)
target_link_libraries(icsneocpp PUBLIC ftdi1-static)
target_link_libraries(icsneocpp PUBLIC ${CMAKE_THREAD_LIBS_INIT})
endif(NOT WIN32)
endif(LIBICSNEO_ENABLE_FTDI)
# pcap # pcap
if(LIBICSNEO_ENABLE_RAW_ETHERNET) if(LIBICSNEO_ENABLE_RAW_ETHERNET)
if(WIN32) if(WIN32)
if(LIBICSNEO_NPCAP_INCLUDE_DIR STREQUAL "") if(LIBICSNEO_NPCAP_INCLUDE_DIR STREQUAL "")
target_include_directories(icsneocpp PUBLIC AFTER third-party/winpcap/include) target_include_directories(icsneocpp PUBLIC AFTER third-party/winpcap/include)
add_definitions(-DWPCAP -DHAVE_REMOTE -DWIN32_LEAN_AND_MEAN) add_definitions(-DWPCAP -DHAVE_REMOTE)
else() else()
target_include_directories(icsneocpp PUBLIC AFTER ${LIBICSNEO_NPCAP_INCLUDE_DIR}) target_include_directories(icsneocpp PUBLIC AFTER ${LIBICSNEO_NPCAP_INCLUDE_DIR})
add_definitions(-DNPCAP -DWIN32_LEAN_AND_MEAN)
endif() endif()
else() else()
find_package(PCAP REQUIRED) find_package(PCAP REQUIRED)
@@ -432,6 +382,21 @@ if(LIBICSNEO_ENABLE_RAW_ETHERNET)
endif(WIN32) endif(WIN32)
endif(LIBICSNEO_ENABLE_RAW_ETHERNET) endif(LIBICSNEO_ENABLE_RAW_ETHERNET)
# protobuf
if(DEFINED ENV{LIBICSNEO_ICSPB_REPO})
set(LIBICSNEO_ICSPB_REPO "$ENV{LIBICSNEO_ICSPB_REPO}")
endif()
if(NOT LIBICSNEO_ICSPB_REPO)
set(LIBICSNEO_ICSPB_REPO https://github.com/intrepidcs/icspb.git)
endif()
include(FetchContent)
FetchContent_Declare(icspb
GIT_REPOSITORY ${LIBICSNEO_ICSPB_REPO}
GIT_TAG 48df5dd7fd0c38034f82a2f94e0eada404d5e2b9
)
FetchContent_MakeAvailable(icspb)
target_link_libraries(icsneocpp PRIVATE icspb::icspb)
if(LIBICSNEO_BUILD_ICSNEOC) if(LIBICSNEO_BUILD_ICSNEOC)
add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc) add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc)
target_include_directories(icsneoc target_include_directories(icsneoc
@@ -443,6 +408,7 @@ if(LIBICSNEO_BUILD_ICSNEOC)
) )
target_link_libraries(icsneoc PRIVATE icsneocpp) target_link_libraries(icsneoc PRIVATE icsneocpp)
target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
target_compile_options(icsneoc PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
endif() endif()
if(LIBICSNEO_BUILD_ICSNEOC_STATIC) if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
@@ -457,6 +423,7 @@ if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
target_link_libraries(icsneoc-static PUBLIC icsneocpp) target_link_libraries(icsneoc-static PUBLIC icsneocpp)
target_compile_features(icsneoc-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_features(icsneoc-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
target_compile_definitions(icsneoc-static PUBLIC ICSNEOC_BUILD_STATIC) target_compile_definitions(icsneoc-static PUBLIC ICSNEOC_BUILD_STATIC)
target_compile_options(icsneoc-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
endif() endif()
if(LIBICSNEO_BUILD_ICSNEOLEGACY) if(LIBICSNEO_BUILD_ICSNEOLEGACY)
@@ -475,6 +442,7 @@ if(LIBICSNEO_BUILD_ICSNEOLEGACY)
) )
target_link_libraries(icsneolegacy PRIVATE icsneocpp) target_link_libraries(icsneolegacy PRIVATE icsneocpp)
target_compile_features(icsneolegacy PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_features(icsneolegacy PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
target_compile_options(icsneolegacy PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
endif() endif()
if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC) if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC)
@@ -494,23 +462,19 @@ if(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC)
target_link_libraries(icsneolegacy-static PUBLIC icsneocpp) target_link_libraries(icsneolegacy-static PUBLIC icsneocpp)
target_compile_features(icsneolegacy-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums) target_compile_features(icsneolegacy-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
target_compile_definitions(icsneolegacy-static PUBLIC ICSNEOC_BUILD_STATIC) target_compile_definitions(icsneolegacy-static PUBLIC ICSNEOC_BUILD_STATIC)
target_compile_options(icsneolegacy-static PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
endif() endif()
add_subdirectory(bindings) add_subdirectory(bindings)
# googletest # googletest
if(LIBICSNEO_BUILD_UNIT_TESTS) if(LIBICSNEO_BUILD_UNIT_TESTS)
if(WIN32) include(FetchContent)
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE) FetchContent_Declare(googletest
endif() GIT_REPOSITORY https://github.com/google/googletest.git
GIT_TAG 6986c2b575f77135401a4e1c65a7a42f20e18fef
if (NOT TARGET gtest) )
add_subdirectory(third-party/googletest-master) FetchContent_MakeAvailable(googletest)
endif()
if (CMAKE_VERSION VERSION_LESS 2.8.11)
include_directories("${gtest_SOURCE_DIR}/include")
endif()
add_executable(libicsneo-unit-tests add_executable(libicsneo-unit-tests
test/unit/main.cpp test/unit/main.cpp
@@ -525,8 +489,12 @@ 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
test/unit/periodictest.cpp
) )
target_compile_options(libicsneo-unit-tests PRIVATE ${LIBICSNEO_COMPILER_WARNINGS})
target_link_libraries(libicsneo-unit-tests gtest gtest_main) target_link_libraries(libicsneo-unit-tests gtest gtest_main)
target_link_libraries(libicsneo-unit-tests icsneocpp) target_link_libraries(libicsneo-unit-tests icsneocpp)
@@ -537,22 +505,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)
+23 -7
View File
@@ -1,13 +1,29 @@
Copyright 2018-2024 Intrepid Control Systems, Inc. Copyright (c) 2018-2025 Intrepid Control Systems, Inc.
Redistribution and use in source and binary forms, with or without modification, are permitted provided that the following conditions are met: Redistribution and use in source and binary forms, with or without modification,
are permitted provided that the following conditions are met:
1. Redistributions of source code must retain the above copyright notice, this list of conditions and the following disclaimer. 1. Redistributions of source code must retain the above copyright notice, this
list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright notice, this list of conditions and the following disclaimer in the documentation and/or other materials provided with the distribution. 2. Redistributions in binary form must reproduce the above copyright notice,
this list of conditions and the following disclaimer in the documentation
and/or other materials provided with the distribution.
3. Neither the name of the copyright holder nor the names of its contributors may be used to endorse or promote products derived from this software without specific prior written permission. 3. Neither the name of the copyright holder nor the names of its contributors
may be used to endorse or promote products derived from this software without
specific prior written permission.
4. It is forbidden to use this library or derivatives to interface with vehicle networking hardware not produced by Intrepid Control Systems, Inc. 4. It is forbidden to use this library or derivatives to interface with vehicle
networking hardware not produced by Intrepid Control Systems, Inc.
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR
ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+4
View File
@@ -23,7 +23,11 @@ each of the respective APIs.
- RAD-A2B - RAD-A2B
- RAD-Comet 2 - RAD-Comet 2
- RAD-Comet 3 - RAD-Comet 3
- RAD-Epsilon
- RAD-EpsilonXL
- RAD-Galaxy - RAD-Galaxy
- RAD-Galaxy 2
- RAD-Gemini
- RAD-Gigastar - RAD-Gigastar
- RAD-Gigastar 2 - RAD-Gigastar 2
- RAD-Moon 2 - RAD-Moon 2
+30
View File
@@ -757,3 +757,33 @@ bool icsneo_isOnlineSupported(const neodevice_t* device) {
return device->device->isOnlineSupported(); return device->device->isOnlineSupported();
} }
bool icsneo_requestTC10Wake(const neodevice_t* device, neonetid_t netid) {
if(!icsneo_isValidNeoDevice(device))
return false;
return device->device->requestTC10Wake((Network::NetID)netid);
}
bool icsneo_requestTC10Sleep(const neodevice_t* device, neonetid_t netid) {
if(!icsneo_isValidNeoDevice(device))
return false;
return device->device->requestTC10Sleep((Network::NetID)netid);
}
bool icsneo_getTC10Status(const neodevice_t* device, neonetid_t netid, neotc10status_t* status) {
if(!icsneo_isValidNeoDevice(device))
return false;
const auto statusMsg = device->device->getTC10Status((Network::NetID)netid);
if(!statusMsg)
return false;
status->wakeStatus = (neotc10wakestatus_t)statusMsg->wakeStatus;
status->sleepStatus = (neotc10sleepstatus_t)statusMsg->sleepStatus;
return true;
}
+1 -1
View File
@@ -29,7 +29,7 @@ BEGIN
VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API" VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API"
VALUE "FileVersion", VER_FILEVERSION_STR VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", "icsneoc.dll" VALUE "InternalName", "icsneoc.dll"
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2024" VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2025"
VALUE "OriginalFilename", "icsneoc.dll" VALUE "OriginalFilename", "icsneoc.dll"
VALUE "ProductName", "libicsneo" VALUE "ProductName", "libicsneo"
VALUE "ProductVersion", VER_PRODUCTVERSION_STR VALUE "ProductVersion", VER_PRODUCTVERSION_STR
+109 -103
View File
@@ -74,6 +74,9 @@ static constexpr const char* TIMEOUT = "The timeout was reached.";
static constexpr const char* WIVI_NOT_SUPPORTED = "Wireless neoVI functions are not supported on this device."; static constexpr const char* WIVI_NOT_SUPPORTED = "Wireless neoVI functions are not supported on this device.";
static constexpr const char* RESTRICTED_ENTRY_FLAG = "Attempted to set a restricted flag in a Root Directory entry."; static constexpr const char* RESTRICTED_ENTRY_FLAG = "Attempted to set a restricted flag in a Root Directory entry.";
static constexpr const char* NOT_SUPPORTED = "The requested feature is not supported."; static constexpr const char* NOT_SUPPORTED = "The requested feature is not supported.";
static constexpr const char* FIXED_POINT_OVERFLOW = "Value is too large to convert to fixed point.";
static constexpr const char* FIXED_POINT_PRECISION = "Value is too small for fixed point precision.";
static constexpr const char* SYSCALL_ERROR = "Error returned from syscall, check errno/GetLastError().";
// Device Errors // Device Errors
static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!"; static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!";
@@ -120,6 +123,12 @@ static constexpr const char* DISK_NOT_CONNECTED = "The program tried to access a
static constexpr const char* UNEXPECTED_RESPONSE = "Received an unexpected or invalid response from the device."; static constexpr const char* UNEXPECTED_RESPONSE = "Received an unexpected or invalid response from the device.";
static constexpr const char* LIN_SETTINGS_NOT_AVAILABLE = "LIN settings are not available for this device."; static constexpr const char* LIN_SETTINGS_NOT_AVAILABLE = "LIN settings are not available for this device.";
static constexpr const char* MODE_NOT_FOUND = "The mode was not found."; static constexpr const char* MODE_NOT_FOUND = "The mode was not found.";
static constexpr const char* GPTP_NOT_SUPPORTED = "GPTP clock synchronization is not supported on this device.";
static constexpr const char* SETTING_NOT_AVAILABLE = "Requested a setting that is not available on this device";
static constexpr const char* DISK_FORMAT_NOT_SUPPORTED = "Disk formatting is not supported on this device.";
static constexpr const char* DISK_FORMAT_INVALID_COUNT = "Disk format config disk count is mismatched with device disk count.";
// Transport Errors // Transport Errors
static constexpr const char* FAILED_TO_READ = "A read operation failed."; static constexpr const char* FAILED_TO_READ = "A read operation failed.";
@@ -138,41 +147,6 @@ static constexpr const char* ERROR_SETTING_SOCKET_OPTION = "A call to setsockopt
static constexpr const char* GETIFADDRS_ERROR = "A call to getifaddrs() failed."; static constexpr const char* GETIFADDRS_ERROR = "A call to getifaddrs() failed.";
static constexpr const char* SEND_TO_ERROR = "A call to sendto() failed."; static constexpr const char* SEND_TO_ERROR = "A call to sendto() failed.";
// FTD3XX
static constexpr const char* FT_OK = "FTD3XX success.";
static constexpr const char* FT_INVALID_HANDLE = "Invalid FTD3XX handle.";
static constexpr const char* FT_DEVICE_NOT_FOUND = "FTD3XX device not found.";
static constexpr const char* FT_DEVICE_NOT_OPENED = "FTD3XX device not opened.";
static constexpr const char* FT_IO_ERROR = "FTD3XX IO error.";
static constexpr const char* FT_INSUFFICIENT_RESOURCES = "Insufficient resources for FTD3XX.";
static constexpr const char* FT_INVALID_PARAMETER = "Invalid FTD3XX parameter.";
static constexpr const char* FT_INVALID_BAUD_RATE = "Invalid FTD3XX baud rate.";
static constexpr const char* FT_DEVICE_NOT_OPENED_FOR_ERASE = "FTD3XX device not opened for erase.";
static constexpr const char* FT_DEVICE_NOT_OPENED_FOR_WRITE = "FTD3XX not opened for write.";
static constexpr const char* FT_FAILED_TO_WRITE_DEVICE = "FTD3XX failed to write device.";
static constexpr const char* FT_EEPROM_READ_FAILED = "FTD3XX EEPROM read failed.";
static constexpr const char* FT_EEPROM_WRITE_FAILED = "FTD3XX EEPROM write failed.";
static constexpr const char* FT_EEPROM_ERASE_FAILED = "FTD3XX EEPROM erase failed.";
static constexpr const char* FT_EEPROM_NOT_PRESENT = "FTD3XX EEPROM not present.";
static constexpr const char* FT_EEPROM_NOT_PROGRAMMED = "FTD3XX EEPROM not programmed.";
static constexpr const char* FT_INVALID_ARGS = "Invalid FTD3XX arguments.";
static constexpr const char* FT_NOT_SUPPORTED = "FTD3XX not supported.";
static constexpr const char* FT_NO_MORE_ITEMS = "No more FTD3XX items.";
static constexpr const char* FT_TIMEOUT = "FTD3XX timeout.";
static constexpr const char* FT_OPERATION_ABORTED = "FTD3XX operation aborted.";
static constexpr const char* FT_RESERVED_PIPE = "Reserved FTD3XX pipe.";
static constexpr const char* FT_INVALID_CONTROL_REQUEST_DIRECTION = "Invalid FTD3XX control request direction.";
static constexpr const char* FT_INVALID_CONTROL_REQUEST_TYPE = "Invalid FTD3XX control request type.";
static constexpr const char* FT_IO_PENDING = "FTD3XX IO pending.";
static constexpr const char* FT_IO_INCOMPLETE = "FTD3XX IO incomplete.";
static constexpr const char* FT_HANDLE_EOF = "Handle FTD3XX EOF.";
static constexpr const char* FT_BUSY = "FTD3XX busy.";
static constexpr const char* FT_NO_SYSTEM_RESOURCES = "No FTD3XX system resources.";
static constexpr const char* FT_DEVICE_LIST_NOT_READY = "FTD3XX device list not ready.";
static constexpr const char* FT_DEVICE_NOT_CONNECTED = "FTD3XX device not connected.";
static constexpr const char* FT_INCORRECT_DEVICE_PATH = "Incorrect FTD3XX device path.";
static constexpr const char* FT_OTHER_ERROR = "Other FTD3XX error.";
// VSA // VSA
static constexpr const char* VSA_BUFFER_CORRUPTED = "VSA data in record buffer is corrupted."; static constexpr const char* VSA_BUFFER_CORRUPTED = "VSA data in record buffer is corrupted.";
static constexpr const char* VSA_TIMESTAMP_NOT_FOUND = "Unable to find a VSA record with a valid timestamp."; static constexpr const char* VSA_TIMESTAMP_NOT_FOUND = "Unable to find a VSA record with a valid timestamp.";
@@ -182,9 +156,40 @@ static constexpr const char* VSA_BYTE_PARSE_FAILURE = "Failure to parse record b
static constexpr const char* VSA_EXTENDED_MESSAGE_ERROR = "Failure to parse extended message record sequence"; static constexpr const char* VSA_EXTENDED_MESSAGE_ERROR = "Failure to parse extended message record sequence";
static constexpr const char* VSA_OTHER_ERROR = "Unknown error in VSA read API."; static constexpr const char* VSA_OTHER_ERROR = "Unknown error in VSA read API.";
// MACSEC
static constexpr const char* MACSEC_SECY_LIMIT = "Attempted to exceed the limit of SecY additions to this port";
static constexpr const char* MACSEC_RULE_LIMIT = "Attempted to exceed the limit of rule additions to this port";
static constexpr const char* MACSEC_SA_LIMIT = "Attempted to exceed the limit of SA additions to this port";
static constexpr const char* MACSEC_INVALID_SECY_INDEX = "Attempted to access an invalid SecY index";
static constexpr const char* MACSEC_INVALID_SA_INDEX = "Attempted to access an invalid SA index";
static constexpr const char* MACSEC_INVALID_RULE_INDEX = "Attempted to access an invalid rule index";
static constexpr const char* MACSEC_REKEY_NOT_ENABLED = "Attempted to set rekey SA when rekey was not enabled";
static constexpr const char* MACSEC_NOT_SUPPORTED = "MACsec is not supported on this device";
static constexpr const char* MACSEC_CONFIG_MISMATCH = "Attempted to configure device with a macsec configuration for a different device";
// Servd
static constexpr const char* SERVD_BIND_ERROR = "Error binding socket for Servd communication";
static constexpr const char* SERVD_NONBLOCK_ERROR = "Error setting non-blocking mode for Servd socket";
static constexpr const char* SERVD_TRANSCEIVE_ERROR = "Error while sending to or receiving from Servd";
static constexpr const char* SERVD_OUTDATED_ERROR = "Servd version is lower than client (libicsneo) version, update Servd";
static constexpr const char* SERVD_INVALID_RESPONSE_ERROR = "Unexpected response from Servd";
static constexpr const char* SERVD_LOCK_ERROR = "Error locking Servd mutex";
static constexpr const char* SERVD_SEND_ERROR = "Error sending to Servd";
static constexpr const char* SERVD_RECV_ERROR = "Error receiving from Servd";
static constexpr const char* SERVD_POLL_ERROR = "Error polling on Servd socket";
static constexpr const char* SERVD_NODATA_ERROR = "No data received from Servd";
static constexpr const char* SERVD_JOIN_MULTICAST_ERROR = "Error joining Servd multicast group";
// DXX
static constexpr const char* DXX_ERROR_SYS = "System error, check errno/GetLastError()";
static constexpr const char* DXX_ERROR_INT = "DXX interrupt called";
static constexpr const char* DXX_ERROR_OVERFLOW = "Overflow in DXX";
static constexpr const char* DXX_ERROR_IO = "I/O failure in DXX";
static constexpr const char* DXX_ERROR_ARG = "Invalid arg passed to DXX";
static constexpr const char* TOO_MANY_EVENTS = "Too many events have occurred. The list has been truncated."; static constexpr const char* TOO_MANY_EVENTS = "Too many events have occurred. The list has been truncated.";
static constexpr const char* UNKNOWN = "An unknown internal error occurred."; static constexpr const char* UNKNOWN = "An unknown internal error occurred.";
static constexpr const char* INVALID = "An invalid internal error occurred."; static constexpr const char* INVALID = "An invalid internal error occurred.";
const char* APIEvent::DescriptionForType(Type type) { const char* APIEvent::DescriptionForType(Type type) {
switch(type) { switch(type) {
// API Errors // API Errors
@@ -224,6 +229,12 @@ const char* APIEvent::DescriptionForType(Type type) {
return RESTRICTED_ENTRY_FLAG; return RESTRICTED_ENTRY_FLAG;
case Type::NotSupported: case Type::NotSupported:
return NOT_SUPPORTED; return NOT_SUPPORTED;
case Type::FixedPointOverflow:
return FIXED_POINT_OVERFLOW;
case Type::FixedPointPrecision:
return FIXED_POINT_PRECISION;
case Type::SyscallError:
return SYSCALL_ERROR;
// Device Errors // Device Errors
case Type::PollingMessageOverflow: case Type::PollingMessageOverflow:
@@ -314,6 +325,8 @@ const char* APIEvent::DescriptionForType(Type type) {
return LIN_SETTINGS_NOT_AVAILABLE; return LIN_SETTINGS_NOT_AVAILABLE;
case Type::ModeNotFound: case Type::ModeNotFound:
return MODE_NOT_FOUND; return MODE_NOT_FOUND;
case Type::SettingNotAvaiableDevice:
return SETTING_NOT_AVAILABLE;
// Transport Errors // Transport Errors
case Type::FailedToRead: case Type::FailedToRead:
return FAILED_TO_READ; return FAILED_TO_READ;
@@ -345,74 +358,12 @@ const char* APIEvent::DescriptionForType(Type type) {
return GETIFADDRS_ERROR; return GETIFADDRS_ERROR;
case Type::SendToError: case Type::SendToError:
return SEND_TO_ERROR; return SEND_TO_ERROR;
case Type::GPTPNotSupported:
// FTD3XX return GPTP_NOT_SUPPORTED;
case Type::FTOK: case Type::DiskFormatNotSupported:
return FT_OK; return DISK_FORMAT_NOT_SUPPORTED;
case Type::FTInvalidHandle: case Type::DiskFormatInvalidCount:
return FT_INVALID_HANDLE; return DISK_FORMAT_INVALID_COUNT;
case Type::FTDeviceNotFound:
return FT_DEVICE_NOT_FOUND;
case Type::FTDeviceNotOpened:
return FT_DEVICE_NOT_OPENED;
case Type::FTIOError:
return FT_IO_ERROR;
case Type::FTInsufficientResources:
return FT_INSUFFICIENT_RESOURCES;
case Type::FTInvalidParameter:
return FT_INVALID_PARAMETER;
case Type::FTInvalidBaudRate:
return FT_INVALID_BAUD_RATE;
case Type::FTDeviceNotOpenedForErase:
return FT_DEVICE_NOT_OPENED_FOR_ERASE;
case Type::FTDeviceNotOpenedForWrite:
return FT_DEVICE_NOT_OPENED_FOR_WRITE;
case Type::FTFailedToWriteDevice:
return FT_FAILED_TO_WRITE_DEVICE;
case Type::FTEEPROMReadFailed:
return FT_EEPROM_READ_FAILED;
case Type::FTEEPROMWriteFailed:
return FT_EEPROM_WRITE_FAILED;
case Type::FTEEPROMEraseFailed:
return FT_EEPROM_ERASE_FAILED;
case Type::FTEEPROMNotPresent:
return FT_EEPROM_NOT_PRESENT;
case Type::FTEEPROMNotProgrammed:
return FT_EEPROM_NOT_PROGRAMMED;
case Type::FTInvalidArgs:
return FT_INVALID_ARGS;
case Type::FTNotSupported:
return FT_NOT_SUPPORTED;
case Type::FTNoMoreItems:
return FT_NO_MORE_ITEMS;
case Type::FTTimeout:
return FT_TIMEOUT;
case Type::FTOperationAborted:
return FT_OPERATION_ABORTED;
case Type::FTReservedPipe:
return FT_RESERVED_PIPE;
case Type::FTInvalidControlRequestDirection:
return FT_INVALID_CONTROL_REQUEST_DIRECTION;
case Type::FTInvalidControlRequestType:
return FT_INVALID_CONTROL_REQUEST_TYPE;
case Type::FTIOPending:
return FT_IO_PENDING;
case Type::FTIOIncomplete:
return FT_IO_INCOMPLETE;
case Type::FTHandleEOF:
return FT_HANDLE_EOF;
case Type::FTBusy:
return FT_BUSY;
case Type::FTNoSystemResources:
return FT_NO_SYSTEM_RESOURCES;
case Type::FTDeviceListNotReady:
return FT_DEVICE_LIST_NOT_READY;
case Type::FTDeviceNotConnected:
return FT_DEVICE_NOT_CONNECTED;
case Type::FTIncorrectDevicePath:
return FT_INCORRECT_DEVICE_PATH;
case Type::FTOtherError:
return FT_OTHER_ERROR;
// VSA // VSA
case Type::VSABufferCorrupted: case Type::VSABufferCorrupted:
@@ -430,6 +381,61 @@ const char* APIEvent::DescriptionForType(Type type) {
case Type::VSAOtherError: case Type::VSAOtherError:
return VSA_OTHER_ERROR; return VSA_OTHER_ERROR;
// MACSEC
case Type::MACsecSecYLimit:
return MACSEC_SECY_LIMIT;
case Type::MACsecSaLimit:
return MACSEC_SA_LIMIT;
case Type::MACsecRuleLimit:
return MACSEC_RULE_LIMIT;
case Type::MACsecInvalidSecYIndex:
return MACSEC_INVALID_SECY_INDEX;
case Type::MACsecInvalidSaIndex:
return MACSEC_INVALID_SA_INDEX;
case Type::MACsecInvalidRuleIndex:
return MACSEC_INVALID_RULE_INDEX;
case Type::MACsecRekeyNotEnabled:
return MACSEC_REKEY_NOT_ENABLED;
case Type::MACsecNotSupported:
return MACSEC_NOT_SUPPORTED;
case Type::MACsecConfigMismatch:
return MACSEC_CONFIG_MISMATCH;
// Servd
case Type::ServdBindError:
return SERVD_BIND_ERROR;
case Type::ServdNonblockError:
return SERVD_NONBLOCK_ERROR;
case Type::ServdTransceiveError:
return SERVD_TRANSCEIVE_ERROR;
case Type::ServdOutdatedError:
return SERVD_OUTDATED_ERROR;
case Type::ServdInvalidResponseError:
return SERVD_INVALID_RESPONSE_ERROR;
case Type::ServdLockError:
return SERVD_LOCK_ERROR;
case Type::ServdSendError:
return SERVD_SEND_ERROR;
case Type::ServdRecvError:
return SERVD_RECV_ERROR;
case Type::ServdPollError:
return SERVD_POLL_ERROR;
case Type::ServdNoDataError:
return SERVD_NODATA_ERROR;
case Type::ServdJoinMulticastError:
return SERVD_JOIN_MULTICAST_ERROR;
// DXX
case Type::DXXErrorSys:
return DXX_ERROR_SYS;
case Type::DXXErrorInt:
return DXX_ERROR_INT;
case Type::DXXErrorOverflow:
return DXX_ERROR_OVERFLOW;
case Type::DXXErrorIO:
return DXX_ERROR_IO;
case Type::DXXErrorArg:
return DXX_ERROR_ARG;
// Other Errors // Other Errors
case Type::TooManyEvents: case Type::TooManyEvents:
return TOO_MANY_EVENTS; return TOO_MANY_EVENTS;
@@ -1,5 +1,7 @@
//FILE: icsneo40DLLAPI.H //FILE: icsneo40DLLAPI.H
#define WIN32_LEAN_AND_MEAN
#define NOMINMAX
#include <windows.h> #include <windows.h>
#include "icsneo/icsnVC40.h" #include "icsneo/icsnVC40.h"
+20 -18
View File
@@ -2,8 +2,6 @@
#error "icsneolegacy.cpp must be compiled with a C++ compiler!" #error "icsneolegacy.cpp must be compiled with a C++ compiler!"
#endif #endif
#define NOMINMAX
#define ICSNEOC_MAKEDLL #define ICSNEOC_MAKEDLL
#include "icsneo/icsneolegacy.h" #include "icsneo/icsneolegacy.h"
#include "icsneo/J2534.h" #include "icsneo/J2534.h"
@@ -29,25 +27,25 @@ static std::map<legacymaphandle_t, neodevice_t> neodevices;
static std::map<neodevice_t*, NeoDeviceEx*> openneodevices; static std::map<neodevice_t*, NeoDeviceEx*> openneodevices;
static const std::map<size_t, size_t> mp_netIDToVnetOffSet = { static const std::map<size_t, size_t> mp_netIDToVnetOffSet = {
{NETID_HSCAN, 1}, {NETID_DWCAN_01, 1},
{NETID_MSCAN, 2}, {NETID_DWCAN_08, 2},
{NETID_HSCAN2, 18}, {NETID_DWCAN_02, 18},
{NETID_HSCAN3, 19}, {NETID_DWCAN_03, 19},
{NETID_HSCAN4, 32}, {NETID_DWCAN_04, 32},
{NETID_HSCAN5, 33}, {NETID_DWCAN_05, 33},
{NETID_HSCAN6, 47}, {NETID_DWCAN_06, 47},
{NETID_HSCAN7, 48}, {NETID_DWCAN_07, 48},
}; };
static const std::map<size_t, size_t> mp_HWnetIDToCMnetID = { static const std::map<size_t, size_t> mp_HWnetIDToCMnetID = {
{NETID_HSCAN, 0}, {NETID_DWCAN_01, 0},
{NETID_MSCAN, 1}, {NETID_DWCAN_08, 1},
{NETID_HSCAN2, 5}, {NETID_DWCAN_02, 5},
{NETID_HSCAN3, 8}, {NETID_DWCAN_03, 8},
{NETID_HSCAN4, 14}, {NETID_DWCAN_04, 14},
{NETID_HSCAN5, 15}, {NETID_DWCAN_05, 15},
{NETID_HSCAN6, 32}, {NETID_DWCAN_06, 32},
{NETID_HSCAN7, 33}, {NETID_DWCAN_07, 33},
}; };
static unsigned long vnet_table[] = {0, PLASMA_SLAVE1_OFFSET, PLASMA_SLAVE2_OFFSET}; static unsigned long vnet_table[] = {0, PLASMA_SLAVE1_OFFSET, PLASMA_SLAVE2_OFFSET};
@@ -92,6 +90,7 @@ static bool NeoMessageToSpyMessage(const neodevice_t* device, const neomessage_t
copyFrameData(); copyFrameData();
break; break;
case Network::Type::Ethernet: case Network::Type::Ethernet:
case Network::Type::AutomotiveEthernet:
oldmsg.Protocol = SPY_PROTOCOL_ETHERNET; oldmsg.Protocol = SPY_PROTOCOL_ETHERNET;
oldmsg.NumberBytesData = static_cast<uint8_t>(frame.length & 0xFF); oldmsg.NumberBytesData = static_cast<uint8_t>(frame.length & 0xFF);
oldmsg.NumberBytesHeader = static_cast<uint8_t>(frame.length >> 8); oldmsg.NumberBytesHeader = static_cast<uint8_t>(frame.length >> 8);
@@ -1077,6 +1076,9 @@ int LegacyDLLExport icsneoGetDeviceSettingsType(void* hObject, EPlasmaIonVnetCha
case NEODEVICE_RADMOON3: case NEODEVICE_RADMOON3:
*pDeviceSettingsType = DeviceRADMoon3SettingsType; *pDeviceSettingsType = DeviceRADMoon3SettingsType;
break; break;
case NEODEVICE_RADGEMINI:
*pDeviceSettingsType = DeviceRADGeminiSettingsType;
break;
case NEODEVICE_RED2: case NEODEVICE_RED2:
*pDeviceSettingsType = DeviceRed2SettingsType; *pDeviceSettingsType = DeviceRed2SettingsType;
break; break;
+39 -2
View File
@@ -1,7 +1,18 @@
cmake_minimum_required(VERSION 3.20) cmake_minimum_required(VERSION 3.20)
set(PYBIND11_FINDPYTHON ON) set(PYBIND11_FINDPYTHON ON)
find_package(pybind11 CONFIG REQUIRED)
if(PYBIND11_ROOT)
find_package(pybind11 CONFIG REQUIRED)
else()
include(FetchContent)
FetchContent_Declare(
pybind11
GIT_REPOSITORY https://github.com/pybind/pybind11.git
GIT_TAG v3.0.1
)
FetchContent_MakeAvailable(pybind11)
endif()
pybind11_add_module(icsneopy pybind11_add_module(icsneopy
icsneopy/api/event.cpp icsneopy/api/event.cpp
@@ -10,15 +21,41 @@ pybind11_add_module(icsneopy
icsneopy/api/version.cpp icsneopy/api/version.cpp
icsneopy/device/devicetype.cpp icsneopy/device/devicetype.cpp
icsneopy/communication/network.cpp icsneopy/communication/network.cpp
icsneopy/communication/io.cpp
icsneopy/communication/livedata.cpp
icsneopy/communication/message/message.cpp icsneopy/communication/message/message.cpp
icsneopy/communication/message/canmessage.cpp icsneopy/communication/message/canmessage.cpp
icsneopy/communication/message/canerrormessage.cpp
icsneopy/communication/message/ethernetmessage.cpp icsneopy/communication/message/ethernetmessage.cpp
icsneopy/communication/message/linmessage.cpp
icsneopy/communication/message/tc10statusmessage.cpp icsneopy/communication/message/tc10statusmessage.cpp
icsneopy/communication/message/mdiomessage.cpp
icsneopy/communication/message/gptpstatusmessage.cpp
icsneopy/communication/message/ethernetstatusmessage.cpp
icsneopy/communication/message/spimessage.cpp
icsneopy/communication/message/scriptstatusmessage.cpp
icsneopy/communication/message/ethphymessage.cpp
icsneopy/communication/message/livedatamessage.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/core/macseccfg.cpp
icsneopy/flexray/flexray.cpp
icsneopy/disk/diskdriver.cpp
icsneopy/device/chipid.cpp
icsneopy/device/versionreport.cpp
icsneopy/device/device.cpp icsneopy/device/device.cpp
icsneopy/device/extensions/deviceextension.cpp
icsneopy/device/idevicesettings.cpp
icsneopy/icsneocpp.cpp icsneopy/icsneocpp.cpp
) )
target_link_libraries(icsneopy PRIVATE icsneocpp) target_link_libraries(icsneopy PRIVATE icsneocpp)
install(TARGETS icsneopy LIBRARY DESTINATION .) install(TARGETS icsneopy LIBRARY DESTINATION icsneopy)
find_program(STUBGEN_EXE stubgen)
if(STUBGEN_EXE)
add_custom_command(TARGET icsneopy POST_BUILD COMMAND stubgen -v -p icsneopy -o .)
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/icsneopy.pyi py.typed DESTINATION icsneopy)
endif()
install(FILES __init__.py DESTINATION icsneopy)
+1
View File
@@ -0,0 +1 @@
from .icsneopy import *
+32 -39
View File
@@ -1,14 +1,15 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/functional.h> #include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/api/event.h" #include "icsneo/api/event.h"
namespace icsneo { namespace icsneo {
void init_event(pybind11::module_& m) { void init_event(pybind11::module_& m) {
pybind11::class_<APIEvent, std::shared_ptr<APIEvent>> apiEvent(m, "APIEvent"); pybind11::classh<APIEvent> apiEvent(m, "APIEvent");
pybind11::enum_<APIEvent::Type>(apiEvent, "Type") pybind11::native_enum<APIEvent::Type>(apiEvent, "Type", "enum.IntEnum")
.value("Any", APIEvent::Type::Any) .value("Any", APIEvent::Type::Any)
.value("InvalidNeoDevice", APIEvent::Type::InvalidNeoDevice) .value("InvalidNeoDevice", APIEvent::Type::InvalidNeoDevice)
.value("RequiredParameterNull", APIEvent::Type::RequiredParameterNull) .value("RequiredParameterNull", APIEvent::Type::RequiredParameterNull)
@@ -28,6 +29,9 @@ void init_event(pybind11::module_& m) {
.value("WiVINotSupported", APIEvent::Type::WiVINotSupported) .value("WiVINotSupported", APIEvent::Type::WiVINotSupported)
.value("RestrictedEntryFlag", APIEvent::Type::RestrictedEntryFlag) .value("RestrictedEntryFlag", APIEvent::Type::RestrictedEntryFlag)
.value("NotSupported", APIEvent::Type::NotSupported) .value("NotSupported", APIEvent::Type::NotSupported)
.value("FixedPointOverflow", APIEvent::Type::FixedPointOverflow)
.value("FixedPointPrecision", APIEvent::Type::FixedPointPrecision)
.value("SyscallError", APIEvent::Type::SyscallError)
.value("PollingMessageOverflow", APIEvent::Type::PollingMessageOverflow) .value("PollingMessageOverflow", APIEvent::Type::PollingMessageOverflow)
.value("NoSerialNumber", APIEvent::Type::NoSerialNumber) .value("NoSerialNumber", APIEvent::Type::NoSerialNumber)
.value("IncorrectSerialNumber", APIEvent::Type::IncorrectSerialNumber) .value("IncorrectSerialNumber", APIEvent::Type::IncorrectSerialNumber)
@@ -84,6 +88,10 @@ void init_event(pybind11::module_& m) {
.value("LINSettingsNotAvailable", APIEvent::Type::LINSettingsNotAvailable) .value("LINSettingsNotAvailable", APIEvent::Type::LINSettingsNotAvailable)
.value("ModeNotFound", APIEvent::Type::ModeNotFound) .value("ModeNotFound", APIEvent::Type::ModeNotFound)
.value("AppErrorParsingFailed", APIEvent::Type::AppErrorParsingFailed) .value("AppErrorParsingFailed", APIEvent::Type::AppErrorParsingFailed)
.value("GPTPNotSupported", APIEvent::Type::GPTPNotSupported)
.value("SettingNotAvaiableDevice", APIEvent::Type::SettingNotAvaiableDevice)
.value("DiskFormatNotSupported", APIEvent::Type::DiskFormatNotSupported)
.value("DiskFormatInvalidCount", APIEvent::Type::DiskFormatInvalidCount)
.value("FailedToRead", APIEvent::Type::FailedToRead) .value("FailedToRead", APIEvent::Type::FailedToRead)
.value("FailedToWrite", APIEvent::Type::FailedToWrite) .value("FailedToWrite", APIEvent::Type::FailedToWrite)
.value("DriverFailedToOpen", APIEvent::Type::DriverFailedToOpen) .value("DriverFailedToOpen", APIEvent::Type::DriverFailedToOpen)
@@ -100,39 +108,6 @@ void init_event(pybind11::module_& m) {
.value("GetIfAddrsError", APIEvent::Type::GetIfAddrsError) .value("GetIfAddrsError", APIEvent::Type::GetIfAddrsError)
.value("SendToError", APIEvent::Type::SendToError) .value("SendToError", APIEvent::Type::SendToError)
.value("MDIOMessageExceedsMaxLength", APIEvent::Type::MDIOMessageExceedsMaxLength) .value("MDIOMessageExceedsMaxLength", APIEvent::Type::MDIOMessageExceedsMaxLength)
.value("FTOK", APIEvent::Type::FTOK)
.value("FTInvalidHandle", APIEvent::Type::FTInvalidHandle)
.value("FTDeviceNotFound", APIEvent::Type::FTDeviceNotFound)
.value("FTDeviceNotOpened", APIEvent::Type::FTDeviceNotOpened)
.value("FTIOError", APIEvent::Type::FTIOError)
.value("FTInsufficientResources", APIEvent::Type::FTInsufficientResources)
.value("FTInvalidParameter", APIEvent::Type::FTInvalidParameter)
.value("FTInvalidBaudRate", APIEvent::Type::FTInvalidBaudRate)
.value("FTDeviceNotOpenedForErase", APIEvent::Type::FTDeviceNotOpenedForErase)
.value("FTDeviceNotOpenedForWrite", APIEvent::Type::FTDeviceNotOpenedForWrite)
.value("FTFailedToWriteDevice", APIEvent::Type::FTFailedToWriteDevice)
.value("FTEEPROMReadFailed", APIEvent::Type::FTEEPROMReadFailed)
.value("FTEEPROMWriteFailed", APIEvent::Type::FTEEPROMWriteFailed)
.value("FTEEPROMEraseFailed", APIEvent::Type::FTEEPROMEraseFailed)
.value("FTEEPROMNotPresent", APIEvent::Type::FTEEPROMNotPresent)
.value("FTEEPROMNotProgrammed", APIEvent::Type::FTEEPROMNotProgrammed)
.value("FTInvalidArgs", APIEvent::Type::FTInvalidArgs)
.value("FTNotSupported", APIEvent::Type::FTNotSupported)
.value("FTNoMoreItems", APIEvent::Type::FTNoMoreItems)
.value("FTTimeout", APIEvent::Type::FTTimeout)
.value("FTOperationAborted", APIEvent::Type::FTOperationAborted)
.value("FTReservedPipe", APIEvent::Type::FTReservedPipe)
.value("FTInvalidControlRequestDirection", APIEvent::Type::FTInvalidControlRequestDirection)
.value("FTInvalidControlRequestType", APIEvent::Type::FTInvalidControlRequestType)
.value("FTIOPending", APIEvent::Type::FTIOPending)
.value("FTIOIncomplete", APIEvent::Type::FTIOIncomplete)
.value("FTHandleEOF", APIEvent::Type::FTHandleEOF)
.value("FTBusy", APIEvent::Type::FTBusy)
.value("FTNoSystemResources", APIEvent::Type::FTNoSystemResources)
.value("FTDeviceListNotReady", APIEvent::Type::FTDeviceListNotReady)
.value("FTDeviceNotConnected", APIEvent::Type::FTDeviceNotConnected)
.value("FTIncorrectDevicePath", APIEvent::Type::FTIncorrectDevicePath)
.value("FTOtherError", APIEvent::Type::FTOtherError)
.value("VSABufferCorrupted", APIEvent::Type::VSABufferCorrupted) .value("VSABufferCorrupted", APIEvent::Type::VSABufferCorrupted)
.value("VSATimestampNotFound", APIEvent::Type::VSATimestampNotFound) .value("VSATimestampNotFound", APIEvent::Type::VSATimestampNotFound)
.value("VSABufferFormatError", APIEvent::Type::VSABufferFormatError) .value("VSABufferFormatError", APIEvent::Type::VSABufferFormatError)
@@ -140,15 +115,33 @@ void init_event(pybind11::module_& m) {
.value("VSAByteParseFailure", APIEvent::Type::VSAByteParseFailure) .value("VSAByteParseFailure", APIEvent::Type::VSAByteParseFailure)
.value("VSAExtendedMessageError", APIEvent::Type::VSAExtendedMessageError) .value("VSAExtendedMessageError", APIEvent::Type::VSAExtendedMessageError)
.value("VSAOtherError", APIEvent::Type::VSAOtherError) .value("VSAOtherError", APIEvent::Type::VSAOtherError)
.value("ServdBindError", APIEvent::Type::ServdBindError)
.value("ServdNonblockError", APIEvent::Type::ServdNonblockError)
.value("ServdTransceiveError", APIEvent::Type::ServdTransceiveError)
.value("ServdOutdatedError", APIEvent::Type::ServdOutdatedError)
.value("ServdInvalidResponseError", APIEvent::Type::ServdInvalidResponseError)
.value("ServdLockError", APIEvent::Type::ServdLockError)
.value("ServdSendError", APIEvent::Type::ServdSendError)
.value("ServdRecvError", APIEvent::Type::ServdRecvError)
.value("ServdPollError", APIEvent::Type::ServdPollError)
.value("ServdNoDataError", APIEvent::Type::ServdNoDataError)
.value("ServdJoinMulticastError", APIEvent::Type::ServdJoinMulticastError)
.value("DXXErrorSys", APIEvent::Type::DXXErrorSys)
.value("DXXErrorInt", APIEvent::Type::DXXErrorInt)
.value("DXXErrorOverflow", APIEvent::Type::DXXErrorOverflow)
.value("DXXErrorIO", APIEvent::Type::DXXErrorIO)
.value("DXXErrorArg", APIEvent::Type::DXXErrorArg)
.value("NoErrorFound", APIEvent::Type::NoErrorFound) .value("NoErrorFound", APIEvent::Type::NoErrorFound)
.value("TooManyEvents", APIEvent::Type::TooManyEvents) .value("TooManyEvents", APIEvent::Type::TooManyEvents)
.value("Unknown", APIEvent::Type::Unknown); .value("Unknown", APIEvent::Type::Unknown)
.finalize();
pybind11::enum_<APIEvent::Severity>(apiEvent, "Severity") pybind11::native_enum<APIEvent::Severity>(apiEvent, "Severity", "enum.IntEnum")
.value("Any", APIEvent::Severity::Any) .value("Any", APIEvent::Severity::Any)
.value("EventInfo", APIEvent::Severity::EventInfo) .value("EventInfo", APIEvent::Severity::EventInfo)
.value("EventWarning", APIEvent::Severity::EventWarning) .value("EventWarning", APIEvent::Severity::EventWarning)
.value("Error", APIEvent::Severity::Error); .value("Error", APIEvent::Severity::Error)
.finalize();
apiEvent apiEvent
.def("get_type", &APIEvent::getType) .def("get_type", &APIEvent::getType)
@@ -157,7 +150,7 @@ void init_event(pybind11::module_& m) {
.def("describe", &APIEvent::describe) .def("describe", &APIEvent::describe)
.def("__repr__", &APIEvent::describe); .def("__repr__", &APIEvent::describe);
pybind11::class_<EventFilter, std::shared_ptr<EventFilter>>(m, "EventFilter") pybind11::classh<EventFilter>(m, "EventFilter")
.def(pybind11::init()) .def(pybind11::init())
.def(pybind11::init<APIEvent::Type>()) .def(pybind11::init<APIEvent::Type>())
.def(pybind11::init<APIEvent::Severity>()) .def(pybind11::init<APIEvent::Severity>())
@@ -7,7 +7,7 @@
namespace icsneo { namespace icsneo {
void init_eventcallback(pybind11::module_& m) { void init_eventcallback(pybind11::module_& m) {
pybind11::class_<EventCallback>(m, "EventCallback") pybind11::classh<EventCallback>(m, "EventCallback")
.def(pybind11::init<EventCallback::fn_eventCallback, EventFilter>()) .def(pybind11::init<EventCallback::fn_eventCallback, EventFilter>())
.def(pybind11::init<EventCallback::fn_eventCallback>()); .def(pybind11::init<EventCallback::fn_eventCallback>());
} }
@@ -7,7 +7,7 @@
namespace icsneo { namespace icsneo {
void init_eventmanager(pybind11::module_& m) { void init_eventmanager(pybind11::module_& m) {
pybind11::class_<EventManager>(m, "EventManager") pybind11::classh<EventManager>(m, "EventManager")
.def_static("get_instance", &EventManager::GetInstance, pybind11::return_value_policy::reference) .def_static("get_instance", &EventManager::GetInstance, pybind11::return_value_policy::reference)
.def("add_event_callback", &EventManager::addEventCallback) .def("add_event_callback", &EventManager::addEventCallback)
.def("remove_event_callback", &EventManager::removeEventCallback) .def("remove_event_callback", &EventManager::removeEventCallback)
+1 -1
View File
@@ -9,7 +9,7 @@
namespace icsneo { namespace icsneo {
void init_version(pybind11::module_& m) { void init_version(pybind11::module_& m) {
pybind11::class_<neoversion_t>(m, "NeoVersion") pybind11::classh<neoversion_t>(m, "NeoVersion")
.def_readonly("major", &neoversion_t::major) .def_readonly("major", &neoversion_t::major)
.def_readonly("minor", &neoversion_t::minor) .def_readonly("minor", &neoversion_t::minor)
.def_readonly("patch", &neoversion_t::patch) .def_readonly("patch", &neoversion_t::patch)
@@ -0,0 +1,19 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/io.h"
namespace icsneo {
void init_io(pybind11::module_& m) {
pybind11::enum_<IO>(m, "IO")
.value("EthernetActivation", IO::EthernetActivation)
.value("USBHostPower", IO::USBHostPower)
.value("BackupPowerEnabled", IO::BackupPowerEnabled)
.value("BackupPowerGood", IO::BackupPowerGood)
.value("Misc", IO::Misc)
.value("EMisc", IO::EMisc);
}
} // namespace icsneo
@@ -0,0 +1,79 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/communication/livedata.h"
namespace icsneo {
void init_livedata(pybind11::module_& m) {
// LiveDataValue struct
pybind11::classh<LiveDataValue>(m, "LiveDataValue")
.def(pybind11::init<>())
.def_readwrite("value", &LiveDataValue::value);
// LiveDataArgument struct
pybind11::classh<LiveDataArgument>(m, "LiveDataArgument")
.def(pybind11::init<>())
.def_readwrite("object_type", &LiveDataArgument::objectType)
.def_readwrite("object_index", &LiveDataArgument::objectIndex)
.def_readwrite("signal_index", &LiveDataArgument::signalIndex)
.def_readwrite("value_type", &LiveDataArgument::valueType);
// LiveDataCommand enum
pybind11::native_enum<LiveDataCommand>(m, "LiveDataCommand", "enum.IntEnum")
.value("STATUS", LiveDataCommand::STATUS)
.value("SUBSCRIBE", LiveDataCommand::SUBSCRIBE)
.value("UNSUBSCRIBE", LiveDataCommand::UNSUBSCRIBE)
.value("RESPONSE", LiveDataCommand::RESPONSE)
.value("CLEAR_ALL", LiveDataCommand::CLEAR_ALL)
.value("SET_VALUE", LiveDataCommand::SET_VALUE)
.finalize();
// LiveDataStatus enum
pybind11::native_enum<LiveDataStatus>(m, "LiveDataStatus", "enum.IntEnum")
.value("SUCCESS", LiveDataStatus::SUCCESS)
.value("ERR_UNKNOWN_COMMAND", LiveDataStatus::ERR_UNKNOWN_COMMAND)
.value("ERR_HANDLE", LiveDataStatus::ERR_HANDLE)
.value("ERR_DUPLICATE", LiveDataStatus::ERR_DUPLICATE)
.value("ERR_FULL", LiveDataStatus::ERR_FULL)
.finalize();
// LiveDataObjectType enum
pybind11::enum_<LiveDataObjectType>(m, "LiveDataObjectType")
.value("MISC", LiveDataObjectType::MISC)
.value("SNA", LiveDataObjectType::SNA)
.export_values();
// LiveDataValueType enum
pybind11::native_enum<LiveDataValueType>(m, "LiveDataValueType", "enum.IntEnum")
.value("GPS_LATITUDE", LiveDataValueType::GPS_LATITUDE)
.value("GPS_LONGITUDE", LiveDataValueType::GPS_LONGITUDE)
.value("GPS_ALTITUDE", LiveDataValueType::GPS_ALTITUDE)
.value("GPS_SPEED", LiveDataValueType::GPS_SPEED)
.value("GPS_VALID", LiveDataValueType::GPS_VALID)
.value("GPS_ENABLE", LiveDataValueType::GPS_ENABLE)
.value("MANUAL_TRIGGER", LiveDataValueType::MANUAL_TRIGGER)
.value("TIME_SINCE_MSG", LiveDataValueType::TIME_SINCE_MSG)
.value("GPS_ACCURACY", LiveDataValueType::GPS_ACCURACY)
.value("GPS_BEARING", LiveDataValueType::GPS_BEARING)
.value("GPS_TIME", LiveDataValueType::GPS_TIME)
.value("GPS_TIME_VALID", LiveDataValueType::GPS_TIME_VALID)
.value("DAQ_ENABLE", LiveDataValueType::DAQ_ENABLE)
.finalize();
// LiveDataUtil namespace functions
m.def("get_new_handle", &LiveDataUtil::getNewHandle,
"Generate a new unique LiveData handle");
m.def("livedata_value_to_double", &LiveDataUtil::liveDataValueToDouble,
pybind11::arg("val"),
"Convert LiveDataValue to double (32.32 fixed-point to floating-point)");
m.def("livedata_double_to_value", &LiveDataUtil::liveDataDoubleToValue,
pybind11::arg("d"),
"Convert double to LiveDataValue (32.32 fixed-point format). Returns LiveDataValue or None on failure.");
}
} // namespace icsneo
@@ -7,7 +7,7 @@
namespace icsneo { namespace icsneo {
void init_messagecallback(pybind11::module_& m) { void init_messagecallback(pybind11::module_& m) {
pybind11::class_<MessageCallback, std::shared_ptr<MessageCallback>>(m, "MessageCallback") pybind11::classh<MessageCallback>(m, "MessageCallback")
.def(pybind11::init<MessageCallback::fn_messageCallback, std::shared_ptr<MessageFilter>>()); .def(pybind11::init<MessageCallback::fn_messageCallback, std::shared_ptr<MessageFilter>>());
} }
@@ -0,0 +1,40 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/communication/message/canerrormessage.h"
namespace icsneo {
void init_errorcodes(pybind11::module_& m) {
pybind11::native_enum<CANErrorCode>(m, "CANErrorCode", "enum.IntEnum")
.value("NoError", CANErrorCode::NoError)
.value("StuffError", CANErrorCode::StuffError)
.value("FormError", CANErrorCode::FormError)
.value("AckError", CANErrorCode::AckError)
.value("Bit1Error", CANErrorCode::Bit1Error)
.value("Bit0Error", CANErrorCode::Bit0Error)
.value("CRCError", CANErrorCode::CRCError)
.value("NoChange", CANErrorCode::NoChange)
.finalize();
}
void init_canerrormessage(pybind11::module_& m) {
init_errorcodes(m);
pybind11::classh<CANErrorMessage, Message>(m, "CANErrorMessage")
.def_readonly("network", &CANErrorMessage::network)
.def_readonly("transmitErrorCount", &CANErrorMessage::transmitErrorCount)
.def_readonly("receiveErrorCount", &CANErrorMessage::receiveErrorCount)
.def_readonly("busOff", &CANErrorMessage::busOff)
.def_readonly("errorPassive", &CANErrorMessage::errorPassive)
.def_readonly("errorWarn", &CANErrorMessage::errorWarn)
.def_readonly("dataErrorCode", &CANErrorMessage::dataErrorCode)
.def_readonly("errorCode", &CANErrorMessage::errorCode);
m.attr("CANErrorCountMessage") = m.attr("CANErrorMessage");
}
} // namespace icsneo
@@ -7,7 +7,7 @@
namespace icsneo { namespace icsneo {
void init_canmessage(pybind11::module_& m) { void init_canmessage(pybind11::module_& m) {
pybind11::class_<CANMessage, std::shared_ptr<CANMessage>, Frame>(m, "CANMessage") pybind11::classh<CANMessage, Frame>(m, "CANMessage")
.def(pybind11::init()) .def(pybind11::init())
.def_readwrite("arbid", &CANMessage::arbid) .def_readwrite("arbid", &CANMessage::arbid)
.def_readwrite("dlcOnWire", &CANMessage::dlcOnWire) .def_readwrite("dlcOnWire", &CANMessage::dlcOnWire)
@@ -7,17 +7,28 @@
namespace icsneo { namespace icsneo {
void init_ethernetmessage(pybind11::module_& m) { void init_ethernetmessage(pybind11::module_& m) {
pybind11::class_<MACAddress>(m, "MACAddress") pybind11::classh<MACAddress>(m, "MACAddress")
.def("to_string", &MACAddress::toString) .def("to_string", &MACAddress::toString)
.def("__repr__", &MACAddress::toString); .def("__repr__", &MACAddress::toString);
pybind11::class_<EthernetMessage, std::shared_ptr<EthernetMessage>, Frame>(m, "EthernetMessage") pybind11::classh<EthernetMessage, Frame>(m, "EthernetMessage")
.def(pybind11::init()) .def(pybind11::init())
.def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled) .def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled)
.def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags) .def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags)
.def_readwrite("fcsAvailable", &EthernetMessage::fcsAvailable) .def_readwrite("fcs", &EthernetMessage::fcs)
.def_readwrite("frameTooShort", &EthernetMessage::frameTooShort) .def_readwrite("frameTooShort", &EthernetMessage::frameTooShort)
.def_readwrite("noPadding", &EthernetMessage::noPadding) .def_readwrite("noPadding", &EthernetMessage::noPadding)
.def_readwrite("fcsVerified", &EthernetMessage::fcsVerified)
.def_readwrite("txAborted", &EthernetMessage::txAborted)
.def_readwrite("crcError", &EthernetMessage::crcError)
.def_readwrite("isT1S", &EthernetMessage::isT1S)
.def_readwrite("isT1SSymbol", &EthernetMessage::isT1SSymbol)
.def_readwrite("isT1SBurst", &EthernetMessage::isT1SBurst)
.def_readwrite("txCollision", &EthernetMessage::txCollision)
.def_readwrite("isT1SWake", &EthernetMessage::isT1SWake)
.def_readwrite("t1sNodeId", &EthernetMessage::t1sNodeId)
.def_readwrite("t1sBurstCount", &EthernetMessage::t1sBurstCount)
.def_readwrite("t1sSymbolType", &EthernetMessage::t1sSymbolType)
.def("get_destination_mac", &EthernetMessage::getDestinationMAC, pybind11::return_value_policy::reference) .def("get_destination_mac", &EthernetMessage::getDestinationMAC, pybind11::return_value_policy::reference)
.def("get_source_mac", &EthernetMessage::getSourceMAC, pybind11::return_value_policy::reference) .def("get_source_mac", &EthernetMessage::getSourceMAC, pybind11::return_value_policy::reference)
.def("get_ether_type", &EthernetMessage::getEtherType); .def("get_ether_type", &EthernetMessage::getEtherType);
@@ -0,0 +1,36 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/ethernetstatusmessage.h"
namespace icsneo {
void init_ethernetstatusmessage(pybind11::module_& m) {
pybind11::classh<EthernetStatusMessage, Message> ethernetStatusMessage(m, "EthernetStatusMessage");
pybind11::enum_<EthernetStatusMessage::LinkSpeed>(ethernetStatusMessage, "LinkSpeed")
.value("LinkSpeedAuto", EthernetStatusMessage::LinkSpeed::LinkSpeedAuto)
.value("LinkSpeed10", EthernetStatusMessage::LinkSpeed::LinkSpeed10)
.value("LinkSpeed100", EthernetStatusMessage::LinkSpeed::LinkSpeed100)
.value("LinkSpeed1000", EthernetStatusMessage::LinkSpeed::LinkSpeed1000)
.value("LinkSpeed2500", EthernetStatusMessage::LinkSpeed::LinkSpeed2500)
.value("LinkSpeed5000", EthernetStatusMessage::LinkSpeed::LinkSpeed5000)
.value("LinkSpeed10000", EthernetStatusMessage::LinkSpeed::LinkSpeed10000);
pybind11::enum_<EthernetStatusMessage::LinkMode>(ethernetStatusMessage, "LinkMode")
.value("LinkModeAuto", EthernetStatusMessage::LinkMode::LinkModeAuto)
.value("LinkModeMaster", EthernetStatusMessage::LinkMode::LinkModeMaster)
.value("LinkModeSlave", EthernetStatusMessage::LinkMode::LinkModeSlave)
.value("LinkModeInvalid", EthernetStatusMessage::LinkMode::LinkModeInvalid)
.value("LinkModeNone", EthernetStatusMessage::LinkMode::LinkModeNone);
ethernetStatusMessage
.def_readonly("network", &EthernetStatusMessage::network)
.def_readonly("state", &EthernetStatusMessage::state)
.def_readonly("speed", &EthernetStatusMessage::speed)
.def_readonly("duplex", &EthernetStatusMessage::duplex)
.def_readonly("mode", &EthernetStatusMessage::mode);
}
} // namespace icsneo
@@ -0,0 +1,34 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/ethphymessage.h"
namespace icsneo {
void init_ethphymessage(pybind11::module_& m) {
pybind11::classh<Clause22Message>(m, "Clause22Message")
.def_readwrite("phyAddr", &Clause22Message::phyAddr)
.def_readwrite("page", &Clause22Message::page)
.def_readwrite("regAddr", &Clause22Message::regAddr)
.def_readwrite("regVal", &Clause22Message::regVal);
pybind11::classh<Clause45Message>(m, "Clause45Message")
.def_readwrite("port", &Clause45Message::port)
.def_readwrite("device", &Clause45Message::device)
.def_readwrite("regAddr", &Clause45Message::regAddr)
.def_readwrite("regVal", &Clause45Message::regVal);
pybind11::classh<PhyMessage>(m, "PhyMessage")
.def(pybind11::init())
.def_readwrite("Enabled", &PhyMessage::Enabled)
.def_readwrite("WriteEnable", &PhyMessage::WriteEnable)
.def_readwrite("Clause45Enable", &PhyMessage::Clause45Enable)
.def_readwrite("Version", &PhyMessage::Version)
.def_readwrite("BusIndex", &PhyMessage::BusIndex)
.def_readwrite("Clause22", &PhyMessage::Clause22)
.def_readwrite("Clause45", &PhyMessage::Clause45);
pybind11::classh<EthPhyMessage, Message>(m, "EthPhyMessage")
.def(pybind11::init())
.def_readwrite("messages", &EthPhyMessage::messages);
}
} // namespace icsneo
@@ -7,7 +7,9 @@
namespace icsneo { namespace icsneo {
void init_messagefilter(pybind11::module_& m) { void init_messagefilter(pybind11::module_& m) {
pybind11::class_<MessageFilter, std::shared_ptr<MessageFilter>>(m, "MessageFilter") pybind11::classh<MessageFilter>(m, "MessageFilter")
.def(pybind11::init())
.def(pybind11::init<Message::Type>())
.def(pybind11::init<Network::NetID>()); .def(pybind11::init<Network::NetID>());
} }
@@ -0,0 +1,80 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/gptpstatusmessage.h"
namespace icsneo {
void init_gptpstatusmessage(pybind11::module_& m) {
pybind11::classh<GPTPStatus, Message> gptpStatus(m, "GPTPStatus");
pybind11::classh<GPTPStatus::Timestamp>(gptpStatus, "Timestamp")
.def_readonly("seconds", &GPTPStatus::Timestamp::seconds)
.def_readonly("nanoseconds", &GPTPStatus::Timestamp::nanoseconds)
.def("to_seconds", &GPTPStatus::Timestamp::toSeconds, pybind11::call_guard<pybind11::gil_scoped_release>());
pybind11::classh<GPTPStatus::ScaledNanoSeconds>(gptpStatus, "ScaledNanoSeconds")
.def_readonly("nanoseconds_msb", &GPTPStatus::ScaledNanoSeconds::nanosecondsMSB)
.def_readonly("nanoseconds_lsb", &GPTPStatus::ScaledNanoSeconds::nanosecondsLSB)
.def_readonly("fractional_nanoseconds", &GPTPStatus::ScaledNanoSeconds::fractionalNanoseconds);
pybind11::classh<GPTPStatus::PortID>(gptpStatus, "PortID")
.def_readonly("clock_identity", &GPTPStatus::PortID::clockIdentity)
.def_readonly("port_number", &GPTPStatus::PortID::portNumber);
pybind11::classh<GPTPStatus::ClockQuality>(gptpStatus, "ClockQuality")
.def_readonly("clock_class", &GPTPStatus::ClockQuality::clockClass)
.def_readonly("clock_accuracy", &GPTPStatus::ClockQuality::clockAccuracy)
.def_readonly("offset_scaled_log_variance", &GPTPStatus::ClockQuality::offsetScaledLogVariance);
pybind11::classh<GPTPStatus::SystemID>(gptpStatus, "SystemID")
.def_readonly("priority1", &GPTPStatus::SystemID::priority1)
.def_readonly("clock_quality", &GPTPStatus::SystemID::clockQuality)
.def_readonly("priority2", &GPTPStatus::SystemID::priority2)
.def_readonly("clock_id", &GPTPStatus::SystemID::clockID);
pybind11::classh<GPTPStatus::PriorityVector>(gptpStatus, "PriorityVector")
.def_readonly("sys_id", &GPTPStatus::PriorityVector::sysID)
.def_readonly("steps_removed", &GPTPStatus::PriorityVector::stepsRemoved)
.def_readonly("port_id", &GPTPStatus::PriorityVector::portID)
.def_readonly("port_number", &GPTPStatus::PriorityVector::portNumber);
pybind11::classh<GPTPStatus::ParentDS>(gptpStatus, "ParentDS")
.def_readonly("parent_port_identity", &GPTPStatus::ParentDS::parentPortIdentity)
.def_readonly("cumulative_rate_ratio", &GPTPStatus::ParentDS::cumulativeRateRatio)
.def_readonly("grandmaster_identity", &GPTPStatus::ParentDS::grandmasterIdentity)
.def_readonly("gm_clock_quality_clock_class", &GPTPStatus::ParentDS::gmClockQualityClockClass)
.def_readonly("gm_clock_quality_clock_accuracy", &GPTPStatus::ParentDS::gmClockQualityClockAccuracy)
.def_readonly("gm_clock_quality_offset_scaled_log_variance", &GPTPStatus::ParentDS::gmClockQualityOffsetScaledLogVariance)
.def_readonly("gm_priority1", &GPTPStatus::ParentDS::gmPriority1)
.def_readonly("gm_priority2", &GPTPStatus::ParentDS::gmPriority2);
pybind11::classh<GPTPStatus::CurrentDS>(gptpStatus, "CurrentDS")
.def_readonly("steps_removed", &GPTPStatus::CurrentDS::stepsRemoved)
.def_readonly("offset_from_master", &GPTPStatus::CurrentDS::offsetFromMaster)
.def_readonly("lastgm_phase_change", &GPTPStatus::CurrentDS::lastgmPhaseChange)
.def_readonly("lastgm_freq_change", &GPTPStatus::CurrentDS::lastgmFreqChange)
.def_readonly("gm_time_base_indicator", &GPTPStatus::CurrentDS::gmTimeBaseIndicator)
.def_readonly("gm_change_count", &GPTPStatus::CurrentDS::gmChangeCount)
.def_readonly("time_of_lastgm_change_event", &GPTPStatus::CurrentDS::timeOfLastgmChangeEvent)
.def_readonly("time_of_lastgm_phase_change_event", &GPTPStatus::CurrentDS::timeOfLastgmPhaseChangeEvent)
.def_readonly("time_of_lastgm_freq_change_event", &GPTPStatus::CurrentDS::timeOfLastgmFreqChangeEvent);
gptpStatus.def_readonly("current_time", &GPTPStatus::currentTime)
.def_readonly("gm_priority", &GPTPStatus::gmPriority)
.def_readonly("ms_offset_ns", &GPTPStatus::msOffsetNs)
.def_readonly("is_sync", &GPTPStatus::isSync)
.def_readonly("link_status", &GPTPStatus::linkStatus)
.def_readonly("link_delay_ns", &GPTPStatus::linkDelayNS)
.def_readonly("selected_role", &GPTPStatus::selectedRole)
.def_readonly("as_capable", &GPTPStatus::asCapable)
.def_readonly("is_syntonized", &GPTPStatus::isSyntonized)
.def_readonly("last_rx_sync_ts", &GPTPStatus::lastRXSyncTS)
.def_readonly("current_ds", &GPTPStatus::currentDS)
.def_readonly("parent_ds", &GPTPStatus::parentDS)
.def_readonly("short_format", &GPTPStatus::shortFormat);
}
} // namespace icsneo
@@ -0,0 +1,59 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/linmessage.h"
namespace icsneo {
void init_linmessage(pybind11::module_& m) {
pybind11::classh<LINErrorFlags>(m, "LINErrorFlags")
.def_readwrite("ErrRxBreakOnly", &LINErrorFlags::ErrRxBreakOnly)
.def_readwrite("ErrRxBreakSyncOnly", &LINErrorFlags::ErrRxBreakSyncOnly)
.def_readwrite("ErrTxRxMismatch", &LINErrorFlags::ErrTxRxMismatch)
.def_readwrite("ErrRxBreakNotZero", &LINErrorFlags::ErrRxBreakNotZero)
.def_readwrite("ErrRxBreakTooShort", &LINErrorFlags::ErrRxBreakTooShort)
.def_readwrite("ErrRxSyncNot55", &LINErrorFlags::ErrRxSyncNot55)
.def_readwrite("ErrRxDataLenOver8", &LINErrorFlags::ErrRxDataLenOver8)
.def_readwrite("ErrFrameSync", &LINErrorFlags::ErrFrameSync)
.def_readwrite("ErrFrameMessageID", &LINErrorFlags::ErrFrameMessageID)
.def_readwrite("ErrFrameResponderData", &LINErrorFlags::ErrFrameResponderData)
.def_readwrite("ErrChecksumMatch", &LINErrorFlags::ErrChecksumMatch);
pybind11::classh<LINStatusFlags>(m, "LINStatusFlags")
.def_readwrite("TxChecksumEnhanced", &LINStatusFlags::TxChecksumEnhanced)
.def_readwrite("TxCommander", &LINStatusFlags::TxCommander)
.def_readwrite("TxResponder", &LINStatusFlags::TxResponder)
.def_readwrite("TxAborted", &LINStatusFlags::TxAborted)
.def_readwrite("UpdateResponderOnce", &LINStatusFlags::UpdateResponderOnce)
.def_readwrite("HasUpdatedResponderOnce", &LINStatusFlags::HasUpdatedResponderOnce)
.def_readwrite("BusRecovered", &LINStatusFlags::BusRecovered)
.def_readwrite("BreakOnly", &LINStatusFlags::BreakOnly);
pybind11::classh<LINMessage, Frame> linMessage(m, "LINMessage");
pybind11::enum_<LINMessage::Type>(linMessage, "Type")
.value("NOT_SET", LINMessage::Type::NOT_SET)
.value("LIN_COMMANDER_MSG", LINMessage::Type::LIN_COMMANDER_MSG)
.value("LIN_HEADER_ONLY", LINMessage::Type::LIN_HEADER_ONLY)
.value("LIN_BREAK_ONLY", LINMessage::Type::LIN_BREAK_ONLY)
.value("LIN_SYNC_ONLY", LINMessage::Type::LIN_SYNC_ONLY)
.value("LIN_UPDATE_RESPONDER", LINMessage::Type::LIN_UPDATE_RESPONDER)
.value("LIN_ERROR", LINMessage::Type::LIN_ERROR);
linMessage
.def(pybind11::init<>())
.def(pybind11::init<uint8_t>())
.def_static("calc_checksum", &LINMessage::calcChecksum)
.def("calc_protected_id", &LINMessage::calcProtectedID)
.def_readwrite("ID", &LINMessage::ID)
.def_readwrite("protectedID", &LINMessage::protectedID)
.def_readwrite("checksum", &LINMessage::checksum)
.def_readwrite("linMsgType", &LINMessage::linMsgType)
.def_readwrite("isEnhancedChecksum", &LINMessage::isEnhancedChecksum)
.def_readwrite("errFlags", &LINMessage::errFlags)
.def_readwrite("statusFlags", &LINMessage::statusFlags);
}
} // namespace icsneo
@@ -0,0 +1,50 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
#include "icsneo/communication/message/livedatamessage.h"
namespace icsneo {
void init_livedatamessage(pybind11::module_& m) {
// LiveDataMessage base class
pybind11::classh<LiveDataMessage, RawMessage>(m, "LiveDataMessage")
.def(pybind11::init<>())
.def_readwrite("handle", &LiveDataMessage::handle)
.def_readwrite("cmd", &LiveDataMessage::cmd);
// LiveDataCommandMessage (for subscribe/unsubscribe)
pybind11::classh<LiveDataCommandMessage, LiveDataMessage>(m, "LiveDataCommandMessage")
.def(pybind11::init<>())
.def_readwrite("update_period", &LiveDataCommandMessage::updatePeriod)
.def_readwrite("expiration_time", &LiveDataCommandMessage::expirationTime)
.def_readwrite("args", &LiveDataCommandMessage::args)
.def("append_signal_arg", &LiveDataCommandMessage::appendSignalArg,
pybind11::arg("value_type"),
"Append a signal argument to the command message");
// LiveDataValueMessage (received values)
pybind11::classh<LiveDataValueMessage, LiveDataMessage>(m, "LiveDataValueMessage")
.def(pybind11::init<>())
.def_readwrite("num_args", &LiveDataValueMessage::numArgs)
.def_readwrite("values", &LiveDataValueMessage::values);
// LiveDataStatusMessage (status responses)
pybind11::classh<LiveDataStatusMessage, LiveDataMessage>(m, "LiveDataStatusMessage")
.def(pybind11::init<>())
.def_readwrite("requested_command", &LiveDataStatusMessage::requestedCommand)
.def_readwrite("status", &LiveDataStatusMessage::status);
// LiveDataSetValueMessage (for setting values)
pybind11::classh<LiveDataSetValueMessage, LiveDataMessage>(m, "LiveDataSetValueMessage")
.def(pybind11::init<>())
.def_readwrite("args", &LiveDataSetValueMessage::args)
.def_readwrite("values", &LiveDataSetValueMessage::values)
.def("append_set_value", &LiveDataSetValueMessage::appendSetValue,
pybind11::arg("value_type"),
pybind11::arg("value"),
"Append a value to set in the message");
}
} // namespace icsneo
@@ -0,0 +1,35 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/mdiomessage.h"
namespace icsneo {
void init_mdiomessage(pybind11::module_& m) {
pybind11::classh<MDIOMessage, Frame> mdioMessage(m, "MDIOMessage");
pybind11::enum_<MDIOMessage::Clause>(mdioMessage, "Clause")
.value("Clause45", MDIOMessage::Clause::Clause45)
.value("Clause22", MDIOMessage::Clause::Clause22);
pybind11::enum_<MDIOMessage::Direction>(mdioMessage, "Direction")
.value("Write", MDIOMessage::Direction::Write)
.value("Read", MDIOMessage::Direction::Read);
mdioMessage
.def(pybind11::init())
.def_readwrite("isTXMsg", &MDIOMessage::isTXMsg)
.def_readwrite("txTimeout", &MDIOMessage::txTimeout)
.def_readwrite("txAborted", &MDIOMessage::txAborted)
.def_readwrite("txInvalidBus", &MDIOMessage::txInvalidBus)
.def_readwrite("txInvalidPhyAddr", &MDIOMessage::txInvalidPhyAddr)
.def_readwrite("txInvalidRegAddr", &MDIOMessage::txInvalidRegAddr)
.def_readwrite("txInvalidClause", &MDIOMessage::txInvalidClause)
.def_readwrite("txInvalidOpcode", &MDIOMessage::txInvalidOpcode)
.def_readwrite("phyAddress", &MDIOMessage::phyAddress)
.def_readwrite("devAddress", &MDIOMessage::devAddress)
.def_readwrite("regAddress", &MDIOMessage::regAddress)
.def_readwrite("direction", &MDIOMessage::direction)
.def_readwrite("clause", &MDIOMessage::clause);
}
} // namespace icsneo
@@ -1,16 +1,19 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/functional.h> #include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/communication/message/message.h" #include "icsneo/communication/message/message.h"
namespace icsneo { namespace icsneo {
void init_message(pybind11::module_& m) { void init_message(pybind11::module_& m) {
pybind11::class_<Message, std::shared_ptr<Message>> message(m, "Message"); // Using py::smart_holder for safer lifetime management
pybind11::enum_<Message::Type>(message, "Type") pybind11::classh<Message> message(m, "Message");
pybind11::native_enum<Message::Type>(message, "Type", "enum.IntEnum")
.value("Frame", Message::Type::Frame) .value("Frame", Message::Type::Frame)
.value("CANErrorCount", Message::Type::CANErrorCount) .value("CANErrorCount", Message::Type::CANErrorCount)
.value("CANError", Message::Type::CANError)
.value("LINHeaderOnly", Message::Type::LINHeaderOnly) .value("LINHeaderOnly", Message::Type::LINHeaderOnly)
.value("LINBreak", Message::Type::LINBreak) .value("LINBreak", Message::Type::LINBreak)
.value("Invalid", Message::Type::Invalid) .value("Invalid", Message::Type::Invalid)
@@ -31,17 +34,20 @@ void init_message(pybind11::module_& m) {
.value("LiveData", Message::Type::LiveData) .value("LiveData", Message::Type::LiveData)
.value("HardwareInfo", Message::Type::HardwareInfo) .value("HardwareInfo", Message::Type::HardwareInfo)
.value("TC10Status", Message::Type::TC10Status) .value("TC10Status", Message::Type::TC10Status)
.value("AppError", Message::Type::AppError); .value("AppError", Message::Type::AppError)
.value("GPTPStatus", Message::Type::GPTPStatus)
.value("EthernetStatus", Message::Type::EthernetStatus)
.finalize();
message.def(pybind11::init<Message::Type>()); message.def(pybind11::init<Message::Type>());
message.def_readonly("type", &Message::type); message.def_readonly("type", &Message::type);
message.def_readwrite("timestamp", &Message::timestamp); message.def_readwrite("timestamp", &Message::timestamp);
pybind11::class_<RawMessage, std::shared_ptr<RawMessage>, Message>(m, "RawMessage") pybind11::classh<RawMessage, Message>(m, "RawMessage")
.def_readwrite("network", &RawMessage::network) .def_readwrite("network", &RawMessage::network)
.def_readwrite("data", &RawMessage::data); .def_readwrite("data", &RawMessage::data);
pybind11::class_<Frame, std::shared_ptr<Frame>, RawMessage>(m, "Frame") pybind11::classh<Frame, RawMessage>(m, "Frame")
.def_readwrite("description", &Frame::description) .def_readwrite("description", &Frame::description)
.def_readwrite("transmitted", &Frame::transmitted) .def_readwrite("transmitted", &Frame::transmitted)
.def_readwrite("error", &Frame::error); .def_readwrite("error", &Frame::error);
@@ -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::classh<ScriptStatusMessage, Message>(m, "ScriptStatusMessage")
.def_readonly("isEncrypted", &ScriptStatusMessage::isEncrypted)
.def_readonly("isCoreminiRunning", &ScriptStatusMessage::isCoreminiRunning)
.def_readonly("sectorOverflows", &ScriptStatusMessage::sectorOverflows)
.def_readonly("numRemainingSectorBuffers", &ScriptStatusMessage::numRemainingSectorBuffers)
.def_readonly("lastSector", &ScriptStatusMessage::lastSector)
.def_readonly("readBinSize", &ScriptStatusMessage::readBinSize)
.def_readonly("minSector", &ScriptStatusMessage::minSector)
.def_readonly("maxSector", &ScriptStatusMessage::maxSector)
.def_readonly("currentSector", &ScriptStatusMessage::currentSector)
.def_readonly("coreminiCreateTime", &ScriptStatusMessage::coreminiCreateTime)
.def_readonly("fileChecksum", &ScriptStatusMessage::fileChecksum)
.def_readonly("coreminiVersion", &ScriptStatusMessage::coreminiVersion)
.def_readonly("coreminiHeaderSize", &ScriptStatusMessage::coreminiHeaderSize)
.def_readonly("diagnosticErrorCode", &ScriptStatusMessage::diagnosticErrorCode)
.def_readonly("diagnosticErrorCodeCount", &ScriptStatusMessage::diagnosticErrorCodeCount)
.def_readonly("maxCoreminiSizeKB", &ScriptStatusMessage::maxCoreminiSizeKB);
}
} // namespace icsneo
@@ -0,0 +1,24 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/spimessage.h"
namespace icsneo {
void init_spimessage(pybind11::module_& m) {
pybind11::classh<SPIMessage, Frame> spiMessage(m, "SPIMessage");
pybind11::enum_<SPIMessage::Direction>(spiMessage, "Direction")
.value("Write", SPIMessage::Direction::Write)
.value("Read", SPIMessage::Direction::Read);
spiMessage
.def(pybind11::init())
.def_readwrite("direction", &SPIMessage::direction)
.def_readwrite("address", &SPIMessage::address)
.def_readwrite("mms", &SPIMessage::mms)
.def_readwrite("stats", &SPIMessage::stats)
.def_readwrite("payload", &SPIMessage::payload);
}
} // namespace icsneo
@@ -17,7 +17,7 @@ void init_tc10statusmessage(pybind11::module_& m) {
.value("SleepFailed", TC10SleepStatus::SleepFailed) .value("SleepFailed", TC10SleepStatus::SleepFailed)
.value("SleepAborted", TC10SleepStatus::SleepAborted); .value("SleepAborted", TC10SleepStatus::SleepAborted);
pybind11::class_<TC10StatusMessage, std::shared_ptr<TC10StatusMessage>, Message>(m, "TC10StatusMessage") pybind11::classh<TC10StatusMessage, Message>(m, "TC10StatusMessage")
.def_readonly("wakeStatus", &TC10StatusMessage::wakeStatus) .def_readonly("wakeStatus", &TC10StatusMessage::wakeStatus)
.def_readonly("sleepStatus", &TC10StatusMessage::sleepStatus); .def_readonly("sleepStatus", &TC10StatusMessage::sleepStatus);
} }
+128 -100
View File
@@ -1,35 +1,36 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/functional.h> #include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/communication/network.h" #include "icsneo/communication/network.h"
namespace icsneo { namespace icsneo {
void init_network(pybind11::module_& m) { void init_network(pybind11::module_& m) {
pybind11::class_<Network> network(m, "Network"); pybind11::classh<Network> network(m, "Network");
pybind11::enum_<Network::NetID>(network, "NetID") pybind11::native_enum<Network::NetID>(network, "NetID", "enum.IntEnum")
.value("Device", Network::NetID::Device) .value("Device", Network::NetID::Device)
.value("HSCAN", Network::NetID::HSCAN) .value("DWCAN_01", Network::NetID::DWCAN_01)
.value("MSCAN", Network::NetID::MSCAN) .value("DWCAN_08", Network::NetID::DWCAN_08)
.value("SWCAN", Network::NetID::SWCAN) .value("SWCAN_01", Network::NetID::SWCAN_01)
.value("LSFTCAN", Network::NetID::LSFTCAN) .value("LSFTCAN_01", Network::NetID::LSFTCAN_01)
.value("FordSCP", Network::NetID::FordSCP) .value("FordSCP", Network::NetID::FordSCP)
.value("J1708", Network::NetID::J1708) .value("J1708", Network::NetID::J1708)
.value("Aux", Network::NetID::Aux) .value("Aux", Network::NetID::Aux)
.value("J1850VPW", Network::NetID::J1850VPW) .value("J1850VPW", Network::NetID::J1850VPW)
.value("ISO9141", Network::NetID::ISO9141) .value("ISO9141_01", Network::NetID::ISO9141_01)
.value("DiskData", Network::NetID::DiskData) .value("DiskData", Network::NetID::DiskData)
.value("Main51", Network::NetID::Main51) .value("Main51", Network::NetID::Main51)
.value("RED", Network::NetID::RED) .value("RED", Network::NetID::RED)
.value("SCI", Network::NetID::SCI) .value("SCI", Network::NetID::SCI)
.value("ISO9141_2", Network::NetID::ISO9141_2) .value("ISO9141_02", Network::NetID::ISO9141_02)
.value("ISO14230", Network::NetID::ISO14230) .value("ISO14230", Network::NetID::ISO14230)
.value("LIN", Network::NetID::LIN) .value("LIN_01", Network::NetID::LIN_01)
.value("OP_Ethernet1", Network::NetID::OP_Ethernet1) .value("AE_01", Network::NetID::AE_01)
.value("OP_Ethernet2", Network::NetID::OP_Ethernet2) .value("AE_02", Network::NetID::AE_02)
.value("OP_Ethernet3", Network::NetID::OP_Ethernet3) .value("AE_03", Network::NetID::AE_03)
.value("RED_EXT_MEMORYREAD", Network::NetID::RED_EXT_MEMORYREAD) .value("RED_EXT_MEMORYREAD", Network::NetID::RED_EXT_MEMORYREAD)
.value("RED_INT_MEMORYREAD", Network::NetID::RED_INT_MEMORYREAD) .value("RED_INT_MEMORYREAD", Network::NetID::RED_INT_MEMORYREAD)
.value("RED_DFLASH_READ", Network::NetID::RED_DFLASH_READ) .value("RED_DFLASH_READ", Network::NetID::RED_DFLASH_READ)
@@ -51,15 +52,15 @@ void init_network(pybind11::module_& m) {
.value("RED_SCOPE_CAPTURE", Network::NetID::RED_SCOPE_CAPTURE) .value("RED_SCOPE_CAPTURE", Network::NetID::RED_SCOPE_CAPTURE)
.value("RED_HARDWARE_EXCEP", Network::NetID::RED_HARDWARE_EXCEP) .value("RED_HARDWARE_EXCEP", Network::NetID::RED_HARDWARE_EXCEP)
.value("RED_GET_RTC", Network::NetID::RED_GET_RTC) .value("RED_GET_RTC", Network::NetID::RED_GET_RTC)
.value("ISO9141_3", Network::NetID::ISO9141_3) .value("ISO9141_03", Network::NetID::ISO9141_03)
.value("HSCAN2", Network::NetID::HSCAN2) .value("DWCAN_02", Network::NetID::DWCAN_02)
.value("HSCAN3", Network::NetID::HSCAN3) .value("DWCAN_03", Network::NetID::DWCAN_03)
.value("OP_Ethernet4", Network::NetID::OP_Ethernet4) .value("AE_04", Network::NetID::AE_04)
.value("OP_Ethernet5", Network::NetID::OP_Ethernet5) .value("AE_05", Network::NetID::AE_05)
.value("ISO9141_4", Network::NetID::ISO9141_4) .value("ISO9141_04", Network::NetID::ISO9141_04)
.value("LIN2", Network::NetID::LIN2) .value("LIN_02", Network::NetID::LIN_02)
.value("LIN3", Network::NetID::LIN3) .value("LIN_03", Network::NetID::LIN_03)
.value("LIN4", Network::NetID::LIN4) .value("LIN_04", Network::NetID::LIN_04)
.value("RED_App_Error", Network::NetID::RED_App_Error) .value("RED_App_Error", Network::NetID::RED_App_Error)
.value("CGI", Network::NetID::CGI) .value("CGI", Network::NetID::CGI)
.value("Reset_Status", Network::NetID::Reset_Status) .value("Reset_Status", Network::NetID::Reset_Status)
@@ -69,44 +70,44 @@ void init_network(pybind11::module_& m) {
.value("Read_Datalink_Cm_Rx_Msg", Network::NetID::Read_Datalink_Cm_Rx_Msg) .value("Read_Datalink_Cm_Rx_Msg", Network::NetID::Read_Datalink_Cm_Rx_Msg)
.value("Logging_Overflow", Network::NetID::Logging_Overflow) .value("Logging_Overflow", Network::NetID::Logging_Overflow)
.value("ReadSettings", Network::NetID::ReadSettings) .value("ReadSettings", Network::NetID::ReadSettings)
.value("HSCAN4", Network::NetID::HSCAN4) .value("DWCAN_04", Network::NetID::DWCAN_04)
.value("HSCAN5", Network::NetID::HSCAN5) .value("DWCAN_05", Network::NetID::DWCAN_05)
.value("RS232", Network::NetID::RS232) .value("RS232", Network::NetID::RS232)
.value("UART", Network::NetID::UART) .value("UART_01", Network::NetID::UART_01)
.value("UART2", Network::NetID::UART2) .value("UART_02", Network::NetID::UART_02)
.value("UART3", Network::NetID::UART3) .value("UART_03", Network::NetID::UART_03)
.value("UART4", Network::NetID::UART4) .value("UART_04", Network::NetID::UART_04)
.value("SWCAN2", Network::NetID::SWCAN2) .value("SWCAN_02", Network::NetID::SWCAN_02)
.value("Ethernet_DAQ", Network::NetID::Ethernet_DAQ) .value("ETHERNET_DAQ", Network::NetID::ETHERNET_DAQ)
.value("Data_To_Host", Network::NetID::Data_To_Host) .value("Data_To_Host", Network::NetID::Data_To_Host)
.value("TextAPI_To_Host", Network::NetID::TextAPI_To_Host) .value("TextAPI_To_Host", Network::NetID::TextAPI_To_Host)
.value("SPI1", Network::NetID::SPI1) .value("SPI_01", Network::NetID::SPI_01)
.value("OP_Ethernet6", Network::NetID::OP_Ethernet6) .value("AE_06", Network::NetID::AE_06)
.value("Red_VBat", Network::NetID::Red_VBat) .value("Red_VBat", Network::NetID::Red_VBat)
.value("OP_Ethernet7", Network::NetID::OP_Ethernet7) .value("AE_07", Network::NetID::AE_07)
.value("OP_Ethernet8", Network::NetID::OP_Ethernet8) .value("AE_08", Network::NetID::AE_08)
.value("OP_Ethernet9", Network::NetID::OP_Ethernet9) .value("AE_09", Network::NetID::AE_09)
.value("OP_Ethernet10", Network::NetID::OP_Ethernet10) .value("AE_10", Network::NetID::AE_10)
.value("OP_Ethernet11", Network::NetID::OP_Ethernet11) .value("AE_11", Network::NetID::AE_11)
.value("FlexRay1a", Network::NetID::FlexRay1a) .value("FLEXRAY_01A", Network::NetID::FLEXRAY_01A)
.value("FlexRay1b", Network::NetID::FlexRay1b) .value("FLEXRAY_01B", Network::NetID::FLEXRAY_01B)
.value("FlexRay2a", Network::NetID::FlexRay2a) .value("FLEXRAY_02A", Network::NetID::FLEXRAY_02A)
.value("FlexRay2b", Network::NetID::FlexRay2b) .value("FLEXRAY_02B", Network::NetID::FLEXRAY_02B)
.value("LIN5", Network::NetID::LIN5) .value("LIN_05", Network::NetID::LIN_05)
.value("FlexRay", Network::NetID::FlexRay) .value("FLEXRAY_01", Network::NetID::FLEXRAY_01)
.value("FlexRay2", Network::NetID::FlexRay2) .value("FLEXRAY_02", Network::NetID::FLEXRAY_02)
.value("OP_Ethernet12", Network::NetID::OP_Ethernet12) .value("AE_12", Network::NetID::AE_12)
.value("I2C", Network::NetID::I2C) .value("I2C_01", Network::NetID::I2C_01)
.value("MOST25", Network::NetID::MOST25) .value("MOST_25", Network::NetID::MOST_25)
.value("MOST50", Network::NetID::MOST50) .value("MOST_50", Network::NetID::MOST_50)
.value("MOST150", Network::NetID::MOST150) .value("MOST_150", Network::NetID::MOST_150)
.value("Ethernet", Network::NetID::Ethernet) .value("ETHERNET_01", Network::NetID::ETHERNET_01)
.value("GMFSA", Network::NetID::GMFSA) .value("GMFSA", Network::NetID::GMFSA)
.value("TCP", Network::NetID::TCP) .value("TCP", Network::NetID::TCP)
.value("HSCAN6", Network::NetID::HSCAN6) .value("DWCAN_06", Network::NetID::DWCAN_06)
.value("HSCAN7", Network::NetID::HSCAN7) .value("DWCAN_07", Network::NetID::DWCAN_07)
.value("LIN6", Network::NetID::LIN6) .value("LIN_06", Network::NetID::LIN_06)
.value("LSFTCAN2", Network::NetID::LSFTCAN2) .value("LSFTCAN_02", Network::NetID::LSFTCAN_02)
.value("LogicalDiskInfo", Network::NetID::LogicalDiskInfo) .value("LogicalDiskInfo", Network::NetID::LogicalDiskInfo)
.value("WiVICommand", Network::NetID::WiVICommand) .value("WiVICommand", Network::NetID::WiVICommand)
.value("ScriptStatus", Network::NetID::ScriptStatus) .value("ScriptStatus", Network::NetID::ScriptStatus)
@@ -119,55 +120,82 @@ void init_network(pybind11::module_& m) {
.value("DeviceStatus", Network::NetID::DeviceStatus) .value("DeviceStatus", Network::NetID::DeviceStatus)
.value("UDP", Network::NetID::UDP) .value("UDP", Network::NetID::UDP)
.value("ForwardedMessage", Network::NetID::ForwardedMessage) .value("ForwardedMessage", Network::NetID::ForwardedMessage)
.value("I2C2", Network::NetID::I2C2) .value("I2C_02", Network::NetID::I2C_02)
.value("I2C3", Network::NetID::I2C3) .value("I2C_03", Network::NetID::I2C_03)
.value("I2C4", Network::NetID::I2C4) .value("I2C_04", Network::NetID::I2C_04)
.value("Ethernet2", Network::NetID::Ethernet2) .value("ETHERNET_02", Network::NetID::ETHERNET_02)
.value("A2B1", Network::NetID::A2B1) .value("ETHERNET_TX_WRAP", Network::NetID::ETHERNET_TX_WRAP)
.value("A2B2", Network::NetID::A2B2) .value("A2B_01", Network::NetID::A2B_01)
.value("Ethernet3", Network::NetID::Ethernet3) .value("A2B_02", Network::NetID::A2B_02)
.value("WBMS", Network::NetID::WBMS) .value("ETHERNET_03", Network::NetID::ETHERNET_03)
.value("DWCAN9", Network::NetID::DWCAN9) .value("WBMS_01", Network::NetID::WBMS_01)
.value("DWCAN10", Network::NetID::DWCAN10) .value("DWCAN_09", Network::NetID::DWCAN_09)
.value("DWCAN11", Network::NetID::DWCAN11) .value("DWCAN_10", Network::NetID::DWCAN_10)
.value("DWCAN12", Network::NetID::DWCAN12) .value("DWCAN_11", Network::NetID::DWCAN_11)
.value("DWCAN13", Network::NetID::DWCAN13) .value("DWCAN_12", Network::NetID::DWCAN_12)
.value("DWCAN14", Network::NetID::DWCAN14) .value("DWCAN_13", Network::NetID::DWCAN_13)
.value("DWCAN15", Network::NetID::DWCAN15) .value("DWCAN_14", Network::NetID::DWCAN_14)
.value("DWCAN16", Network::NetID::DWCAN16) .value("DWCAN_15", Network::NetID::DWCAN_15)
.value("LIN7", Network::NetID::LIN7) .value("DWCAN_16", Network::NetID::DWCAN_16)
.value("LIN8", Network::NetID::LIN8) .value("LIN_07", Network::NetID::LIN_07)
.value("SPI2", Network::NetID::SPI2) .value("LIN_08", Network::NetID::LIN_08)
.value("MDIO1", Network::NetID::MDIO1) .value("SPI_02", Network::NetID::SPI_02)
.value("MDIO2", Network::NetID::MDIO2) .value("MDIO_01", Network::NetID::MDIO_01)
.value("MDIO3", Network::NetID::MDIO3) .value("MDIO_02", Network::NetID::MDIO_02)
.value("MDIO4", Network::NetID::MDIO4) .value("MDIO_03", Network::NetID::MDIO_03)
.value("MDIO5", Network::NetID::MDIO5) .value("MDIO_04", Network::NetID::MDIO_04)
.value("MDIO6", Network::NetID::MDIO6) .value("MDIO_05", Network::NetID::MDIO_05)
.value("MDIO7", Network::NetID::MDIO7) .value("MDIO_06", Network::NetID::MDIO_06)
.value("MDIO8", Network::NetID::MDIO8) .value("MDIO_07", Network::NetID::MDIO_07)
.value("OP_Ethernet13", Network::NetID::OP_Ethernet13) .value("MDIO_08", Network::NetID::MDIO_08)
.value("OP_Ethernet14", Network::NetID::OP_Ethernet14) .value("AE_13", Network::NetID::AE_13)
.value("OP_Ethernet15", Network::NetID::OP_Ethernet15) .value("AE_14", Network::NetID::AE_14)
.value("OP_Ethernet16", Network::NetID::OP_Ethernet16) .value("AE_15", Network::NetID::AE_15)
.value("SPI3", Network::NetID::SPI3) .value("AE_16", Network::NetID::AE_16)
.value("SPI4", Network::NetID::SPI4) .value("SPI_03", Network::NetID::SPI_03)
.value("SPI5", Network::NetID::SPI5) .value("SPI_04", Network::NetID::SPI_04)
.value("SPI6", Network::NetID::SPI6) .value("SPI_05", Network::NetID::SPI_05)
.value("SPI7", Network::NetID::SPI7) .value("SPI_06", Network::NetID::SPI_06)
.value("SPI8", Network::NetID::SPI8) .value("SPI_07", Network::NetID::SPI_07)
.value("LIN9", Network::NetID::LIN9) .value("SPI_08", Network::NetID::SPI_08)
.value("LIN10", Network::NetID::LIN10) .value("LIN_09", Network::NetID::LIN_09)
.value("LIN11", Network::NetID::LIN11) .value("LIN_10", Network::NetID::LIN_10)
.value("LIN12", Network::NetID::LIN12) .value("LIN_11", Network::NetID::LIN_11)
.value("LIN13", Network::NetID::LIN13) .value("LIN_12", Network::NetID::LIN_12)
.value("LIN14", Network::NetID::LIN14) .value("LIN_13", Network::NetID::LIN_13)
.value("LIN15", Network::NetID::LIN15) .value("LIN_14", Network::NetID::LIN_14)
.value("LIN16", Network::NetID::LIN16) .value("LIN_15", Network::NetID::LIN_15)
.value("LIN_16", Network::NetID::LIN_16)
.value("Any", Network::NetID::Any) .value("Any", Network::NetID::Any)
.value("Invalid", Network::NetID::Invalid); .value("Invalid", Network::NetID::Invalid)
.finalize();
network.def(pybind11::init<Network::NetID>()); pybind11::native_enum<Network::Type>(network, "Type", "enum.Enum")
.value("Invalid", Network::Type::Invalid)
.value("Internal", Network::Type::Internal)
.value("CAN", Network::Type::CAN)
.value("LIN", Network::Type::LIN)
.value("FlexRay", Network::Type::FlexRay)
.value("MOST", Network::Type::MOST)
.value("Ethernet", Network::Type::Ethernet)
.value("LSFTCAN", Network::Type::LSFTCAN)
.value("SWCAN", Network::Type::SWCAN)
.value("ISO9141", Network::Type::ISO9141)
.value("I2C", Network::Type::I2C)
.value("A2B", Network::Type::A2B)
.value("SPI", Network::Type::SPI)
.value("MDIO", Network::Type::MDIO)
.value("AutomotiveEthernet", Network::Type::AutomotiveEthernet)
.value("Any", Network::Type::Any)
.value("Other", Network::Type::Other)
.finalize();
network
.def(pybind11::init<Network::NetID>())
.def("__repr__", [](Network& self) { return Network::GetNetIDString(self.getNetID()); })
.def_static("get_net_id_string", &Network::GetNetIDString, pybind11::arg("netid"), pybind11::arg("expand") = true)
.def("get_net_id", &Network::getNetID)
.def("get_type", &Network::getType);
} }
} // namespace icsneo } // namespace icsneo
+166
View File
@@ -0,0 +1,166 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/core/macseccfg.h"
namespace icsneo {
void init_macsecconfig(pybind11::module_ & m)
{
pybind11::enum_<MACsecPacketType>(m, "MACsecPacketType")
.value("DEFAULT", MACsecPacketType::Default)
.value("SINGLE_VLAN", MACsecPacketType::SingleVLAN)
.value("DUAL_VLAN", MACsecPacketType::DualVLAN)
.value("MPLS", MACsecPacketType::MPLS)
.value("SINGLE_VLAN_FOLLOWED_BY_MPLS", MACsecPacketType::SingleVLANFollowedByMPLS)
.value("DUAL_VLAN_FOLLOWED_BY_MPLS", MACsecPacketType::DualVLANFollowedByMPLS)
.value("UNSUPPORTED", MACsecPacketType::Unsupported);
pybind11::enum_<MACsecValidation>(m, "MACsecValidation")
.value("DISABLED", MACsecValidation::Disabled)
.value("CHECK", MACsecValidation::Check)
.value("STRICT", MACsecValidation::Strict)
.value("NA", MACsecValidation::NA);
pybind11::enum_<MACsecStrip>(m, "MACsecStrip")
.value("STRIP_SECTAG_AND_ICV", MACsecStrip::StripSecTagAndIcv)
.value("STRIP_SECTAG_PRESERVE_ICV", MACsecStrip::StripSecTagPreserveICV)
.value("PRESERVE_SECTAG_STRIP_ICV", MACsecStrip::PreserveSecTagStripICV)
.value("NO_STRIP", MACsecStrip::NoStrip);
pybind11::enum_<MACsecCipherSuite>(m, "MACsecCipherSuite")
.value("GCM_AES_128", MACsecCipherSuite::GcmAes128)
.value("GCM_AES_256", MACsecCipherSuite::GcmAes256)
.value("GCM_AES_128_XPN", MACsecCipherSuite::GcmAes128Xpn)
.value("GCM_AES_256_XPN", MACsecCipherSuite::GcmAes256Xpn);
pybind11::classh<MACsecVLANTag>(m, "MACsecVLANTag")
.def(pybind11::init())
.def_readwrite("vid", &MACsecVLANTag::vid)
.def_readwrite("pri_cfi", &MACsecVLANTag::priCfi);
pybind11::classh<MACsecMPLSOuter>(m, "MACsecMPLSOuter")
.def(pybind11::init())
.def_readwrite("mpls_label", &MACsecMPLSOuter::mplsLabel)
.def_readwrite("exp", &MACsecMPLSOuter::exp);
pybind11::classh<MACsecTci>(m, "MACsecTci")
.def(pybind11::init())
.def_readwrite("es", &MACsecTci::es)
.def_readwrite("sc", &MACsecTci::sc)
.def_readwrite("scb", &MACsecTci::scb)
.def_readwrite("e", &MACsecTci::e)
.def_readwrite("c", &MACsecTci::c);
pybind11::classh<MACsecRxRule>(m, "MACsecRxRule")
.def(pybind11::init())
.def_readwrite("key_mac_da", &MACsecRxRule::keyMacDa)
.def_readwrite("mask_mac_da", &MACsecRxRule::maskMacDa)
.def_readwrite("key_mask_sa", &MACsecRxRule::keyMacSa)
.def_readwrite("mask_mac_sa", &MACsecRxRule::maskMacSa)
.def_readwrite("key_ether_type", &MACsecRxRule::keyEthertype)
.def_readwrite("mask_ether_type", &MACsecRxRule::maskEthertype)
.def_readwrite("key_vlan_tag_outer1", &MACsecRxRule::keyVlanTagOuter1)
.def_readwrite("key_mpls_outer1", &MACsecRxRule::keyMplsOuter1)
.def_readwrite("mask_vlan_tag_outer1", &MACsecRxRule::maskVlanTagOuter1)
.def_readwrite("mask_mpls_outer1", &MACsecRxRule::maskMplsOuter1)
.def_readwrite("key_vlan_tag_outer2", &MACsecRxRule::keyVlanTagOuter2)
.def_readwrite("key_mpls_outer2", &MACsecRxRule::keyMplsOuter2)
.def_readwrite("mask_vlan_tag_outer2", &MACsecRxRule::maskVlanTagOuter2)
.def_readwrite("mask_mpls_outer2", &MACsecRxRule::maskMplsOuter2)
.def_readwrite("key_bonus_data", &MACsecRxRule::keyBonusData)
.def_readwrite("mask_bonus_data", &MACsecRxRule::maskBonusData)
.def_readwrite("key_tag_match_bitmap", &MACsecRxRule::keyTagMatchBitmap)
.def_readwrite("mask_tag_match_bitmap", &MACsecRxRule::maskTagMatchBitmap)
.def_readwrite("key_packet_type", &MACsecRxRule::keyPacketType)
.def_readwrite("mask_packet_type", &MACsecRxRule::maskPacketType)
.def_readwrite("key_inner_vlan_type", &MACsecRxRule::keyInnerVlanType)
.def_readwrite("mask_inner_vlan_type", &MACsecRxRule::maskInnerVlanType)
.def_readwrite("key_outer_vlan_type", &MACsecRxRule::keyOuterVlanType)
.def_readwrite("mask_outer_vlan_type", &MACsecRxRule::maskOuterVlanType)
.def_readwrite("key_num_tags", &MACsecRxRule::keyNumTags)
.def_readwrite("mask_num_tags", &MACsecRxRule::maskNumTags)
.def_readwrite("key_express", &MACsecRxRule::keyExpress)
.def_readwrite("mask_express", &MACsecRxRule::maskExpress)
.def_readwrite("is_mpls", &MACsecRxRule::isMpls);
pybind11::classh<MACsecTxSecY>(m, "MACsecTxSecY")
.def(pybind11::init())
.def_readwrite("enable_control_port", &MACsecTxSecY::enableControlPort)
.def_readwrite("cipher", &MACsecTxSecY::cipher)
.def_readwrite("confidentiality_offset", &MACsecTxSecY::confidentialityOffset)
.def_readwrite("icv_includes_da_sa", &MACsecTxSecY::icvIncludesDaSa)
.def_readwrite("protect_frames", &MACsecTxSecY::protectFrames)
.def_readwrite("sec_tag_offset", &MACsecTxSecY::secTagOffset)
.def_readwrite("sec_tag_tci", &MACsecTxSecY::tci)
.def_readwrite("mtu", &MACsecTxSecY::mtu)
.def_readwrite("is_control_packet", &MACsecTxSecY::isControlPacket)
.def_readwrite("auxiliary_policy", &MACsecTxSecY::auxiliaryPolicy)
.def_readwrite("sci", &MACsecTxSecY::sci);
pybind11::classh<MACsecRxSecY>(m, "MACsecRxSecY")
.def(pybind11::init())
.def_readwrite("enable_control_port", &MACsecRxSecY::enableControlPort)
.def_readwrite("frame_validation", &MACsecRxSecY::frameValidation)
.def_readwrite("frame_strip", &MACsecRxSecY::frameStrip)
.def_readwrite("cipher", &MACsecRxSecY::cipher)
.def_readwrite("confidentiality_offset", &MACsecRxSecY::confidentialityOffset)
.def_readwrite("icv_includes_da_sa", &MACsecRxSecY::icvIncludesDaSa)
.def_readwrite("replay_protect", &MACsecRxSecY::replayProtect)
.def_readwrite("replay_window", &MACsecRxSecY::replayWindow)
.def_readwrite("is_control_packet", &MACsecRxSecY::isControlPacket)
.def_readwrite("sci", &MACsecRxSecY::sci);
pybind11::classh<MACsecTxSa>(m, "MACsecTxSa")
.def(pybind11::init())
.def_readwrite("sak", &MACsecTxSa::sak)
.def_readwrite("hash_key", &MACsecTxSa::hashKey)
.def_readwrite("salt", &MACsecTxSa::salt)
.def_readwrite("ssci", &MACsecTxSa::ssci)
.def_readwrite("next_pn", &MACsecTxSa::nextPn)
.def_readwrite("an", &MACsecTxSa::an);
pybind11::classh<MACsecRxSa>(m, "MACsecRxSa")
.def(pybind11::init())
.def_readwrite("sak", &MACsecRxSa::sak)
.def_readwrite("hash_key", &MACsecRxSa::hashKey)
.def_readwrite("salt", &MACsecRxSa::salt)
.def_readwrite("ssci", &MACsecRxSa::ssci)
.def_readwrite("next_pn", &MACsecRxSa::nextPn);
pybind11::classh<MACsecConfig>(m, "MACsecConfig")
.def(pybind11::init<icsneo::DeviceType>())
.def("add_rx_secy", &MACsecConfig::addRxSecY, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("add_tx_secY", &MACsecConfig::addTxSecY, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("add_rx_rule", &MACsecConfig::addRxRule, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("add_rx_sa", &MACsecConfig::addRxSa, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("add_tx_sa", &MACsecConfig::addTxSa, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_rx_secy", [](MACsecConfig& cfg, uint8_t index) -> MACsecRxSecY& { return cfg.getRxSecY(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_tx_secy", [](MACsecConfig& cfg, uint8_t index) -> MACsecTxSecY& { return cfg.getTxSecY(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_rx_sa", [](MACsecConfig& cfg, uint8_t index) -> MACsecRxSa& { return cfg.getRxSa(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_tx_sa", [](MACsecConfig& cfg, uint8_t index) -> MACsecTxSa& { return cfg.getTxSa(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_rx_rule", [](MACsecConfig& cfg, uint8_t index) -> MACsecRxRule& { return cfg.getRxRule(index); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_tx_sa_index", &MACsecConfig::setTxSaIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("enable_tx_rekey", &MACsecConfig::enableTxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_tx_sa_rekey_index", &MACsecConfig::setTxSaRekeyIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("disable_tx_rekey", &MACsecConfig::disableTxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_rx_sa_index", &MACsecConfig::setRxSaIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("enable_rx_rekey", &MACsecConfig::enableRxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_rx_sa_rekey_index", &MACsecConfig::setRxSaRekeyIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("disable_rx_rekey", &MACsecConfig::disableRxRekey, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_rx_enable", &MACsecConfig::setRxEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_tx_enable", &MACsecConfig::setTxEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_storage", &MACsecConfig::setStorage, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("clear", &MACsecConfig::clear, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("serialize", &MACsecConfig::serialize, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_bin_index", &MACsecConfig::getBinIndex, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_type", &MACsecConfig::getType, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_max_num_rule", &MACsecConfig::getMaxNumRule, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_max_num_secy", &MACsecConfig::getMaxNumSecY, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_max_num_sa", &MACsecConfig::getMaxNumSa, pybind11::call_guard<pybind11::gil_scoped_release>());
}
} // namespace icsneo
+138
View File
@@ -0,0 +1,138 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/device/chipid.h"
namespace icsneo {
void init_chipid(pybind11::module_& m) {
pybind11::native_enum<ChipID>(m, "ChipID", "enum.IntEnum")
.value("neoVIFIRE_MCHIP", ChipID::neoVIFIRE_MCHIP)
.value("neoVIFIRE_LCHIP", ChipID::neoVIFIRE_LCHIP)
.value("neoVIFIRE_UCHIP", ChipID::neoVIFIRE_UCHIP)
.value("neoVIFIRE_JCHIP", ChipID::neoVIFIRE_JCHIP)
.value("ValueCAN3_MCHIP", ChipID::ValueCAN3_MCHIP)
.value("neoVIECU_MPIC", ChipID::neoVIECU_MPIC)
.value("neoVIIEVB_MPIC", ChipID::neoVIIEVB_MPIC)
.value("neoVIPENDANT_MPIC", ChipID::neoVIPENDANT_MPIC)
.value("neoVIFIRE_VNET_MCHIP", ChipID::neoVIFIRE_VNET_MCHIP)
.value("neoVIFIRE_VNET_LCHIP", ChipID::neoVIFIRE_VNET_LCHIP)
.value("neoVIPLASMA_Core", ChipID::neoVIPLASMA_Core)
.value("neoVIPLASMA_HID", ChipID::neoVIPLASMA_HID)
.value("neoVIANALOG_MPIC", ChipID::neoVIANALOG_MPIC)
.value("neoVIPLASMA_ANALOG_Core", ChipID::neoVIPLASMA_ANALOG_Core)
.value("neoVIPLASMA_FlexRay_Core", ChipID::neoVIPLASMA_FlexRay_Core)
.value("neoVIPLASMA_Core_1_12", ChipID::neoVIPLASMA_Core_1_12)
.value("neoVIFIRE_Slave_VNET_MCHIP", ChipID::neoVIFIRE_Slave_VNET_MCHIP)
.value("neoVIFIRE_Slave_VNET_LCHIP", ChipID::neoVIFIRE_Slave_VNET_LCHIP)
.value("neoVIION_Core", ChipID::neoVIION_Core)
.value("neoVIION_HID", ChipID::neoVIION_HID)
.value("neoVIION_Core_Loader", ChipID::neoVIION_Core_Loader)
.value("neoVIION_HID_Loader", ChipID::neoVIION_HID_Loader)
.value("neoVIION_FPGA_BIT", ChipID::neoVIION_FPGA_BIT)
.value("neoVIFIRE_VNET_EP_MCHIP", ChipID::neoVIFIRE_VNET_EP_MCHIP)
.value("neoVIFIRE_VNET_EP_LCHIP", ChipID::neoVIFIRE_VNET_EP_LCHIP)
.value("neoVIAnalogOut_MCHIP", ChipID::neoVIAnalogOut_MCHIP)
.value("neoVIMOST25_MCHIP", ChipID::neoVIMOST25_MCHIP)
.value("neoVIMOST50_MCHIP", ChipID::neoVIMOST50_MCHIP)
.value("neoVIMOST150_MCHIP", ChipID::neoVIMOST150_MCHIP)
.value("ValueCAN4_4_MCHIP", ChipID::ValueCAN4_4_MCHIP)
.value("ValueCAN4_4_SCHIP", ChipID::ValueCAN4_4_SCHIP)
.value("cmProbe_ZYNQ", ChipID::cmProbe_ZYNQ)
.value("EEVB_STM32", ChipID::EEVB_STM32)
.value("neoVIFIRE_Slave_VNET_EP_MCHIP", ChipID::neoVIFIRE_Slave_VNET_EP_MCHIP)
.value("neoVIFIRE_Slave_VNET_EP_LCHIP", ChipID::neoVIFIRE_Slave_VNET_EP_LCHIP)
.value("RADStar_MCHIP", ChipID::RADStar_MCHIP)
.value("ValueCANrf_MCHIP", ChipID::ValueCANrf_MCHIP)
.value("neoVIFIRE2_MCHIP", ChipID::neoVIFIRE2_MCHIP)
.value("neoVIFIRE2_CCHIP", ChipID::neoVIFIRE2_CCHIP)
.value("neoVIFIRE2_Core", ChipID::neoVIFIRE2_Core)
.value("neoVIFIRE2_BLECHIP", ChipID::neoVIFIRE2_BLECHIP)
.value("neoVIFIRE2_ZYNQ", ChipID::neoVIFIRE2_ZYNQ)
.value("neoVIFIRE2_SECURITYCHIP", ChipID::neoVIFIRE2_SECURITYCHIP)
.value("RADGalaxy_ZYNQ", ChipID::RADGalaxy_ZYNQ)
.value("neoVIFIRE2_VNET_MCHIP", ChipID::neoVIFIRE2_VNET_MCHIP)
.value("neoVIFIRE2_Slave_VNET_A_MCHIP", ChipID::neoVIFIRE2_Slave_VNET_A_MCHIP)
.value("neoVIFIRE2_Slave_VNET_A_CCHIP", ChipID::neoVIFIRE2_Slave_VNET_A_CCHIP)
.value("neoVIFIRE2_VNET_CCHIP", ChipID::neoVIFIRE2_VNET_CCHIP)
.value("neoVIFIRE2_VNET_Core", ChipID::neoVIFIRE2_VNET_Core)
.value("RADStar2_ZYNQ", ChipID::RADStar2_ZYNQ)
.value("VividCAN_MCHIP", ChipID::VividCAN_MCHIP)
.value("neoOBD2SIM_MCHIP", ChipID::neoOBD2SIM_MCHIP)
.value("neoVIFIRE2_VNETZ_MCHIP", ChipID::neoVIFIRE2_VNETZ_MCHIP)
.value("neoVIFIRE2_VNETZ_ZYNQ", ChipID::neoVIFIRE2_VNETZ_ZYNQ)
.value("neoVIFIRE2_Slave_VNETZ_A_MCHIP", ChipID::neoVIFIRE2_Slave_VNETZ_A_MCHIP)
.value("neoVIFIRE2_Slave_VNETZ_A_ZYNQ", ChipID::neoVIFIRE2_Slave_VNETZ_A_ZYNQ)
.value("VividCAN_EXT_FLASH", ChipID::VividCAN_EXT_FLASH)
.value("VividCAN_NRF52", ChipID::VividCAN_NRF52)
.value("cmProbe_ZYNQ_Unused", ChipID::cmProbe_ZYNQ_Unused)
.value("neoOBD2PRO_MCHIP", ChipID::neoOBD2PRO_MCHIP)
.value("ValueCAN4_1_MCHIP", ChipID::ValueCAN4_1_MCHIP)
.value("ValueCAN4_2_MCHIP", ChipID::ValueCAN4_2_MCHIP)
.value("ValueCAN4_4_2EL_Core", ChipID::ValueCAN4_4_2EL_Core)
.value("neoOBD2PRO_SCHIP", ChipID::neoOBD2PRO_SCHIP)
.value("ValueCAN4_2EL_MCHIP", ChipID::ValueCAN4_2EL_MCHIP)
.value("neoECUAVBTSN_MCHIP", ChipID::neoECUAVBTSN_MCHIP)
.value("neoOBD2PRO_Core", ChipID::neoOBD2PRO_Core)
.value("RADSupermoon_ZYNQ", ChipID::RADSupermoon_ZYNQ)
.value("RADMoon2_ZYNQ", ChipID::RADMoon2_ZYNQ)
.value("VividCANPRO_MCHIP", ChipID::VividCANPRO_MCHIP)
.value("VividCANPRO_EXT_FLASH", ChipID::VividCANPRO_EXT_FLASH)
.value("RADPluto_MCHIP", ChipID::RADPluto_MCHIP)
.value("RADMars_ZYNQ", ChipID::RADMars_ZYNQ)
.value("neoECU12_MCHIP", ChipID::neoECU12_MCHIP)
.value("RADIOCANHUB_MCHIP", ChipID::RADIOCANHUB_MCHIP)
.value("FlexRay_VNETZ_ZCHIP", ChipID::FlexRay_VNETZ_ZCHIP)
.value("neoOBD2_LCBADGE_MCHIP", ChipID::neoOBD2_LCBADGE_MCHIP)
.value("neoOBD2_LCBADGE_SCHIP", ChipID::neoOBD2_LCBADGE_SCHIP)
.value("RADMoonDuo_MCHIP", ChipID::RADMoonDuo_MCHIP)
.value("neoVIFIRE3_ZCHIP", ChipID::neoVIFIRE3_ZCHIP)
.value("FlexRay_VNETZ_FCHIP", ChipID::FlexRay_VNETZ_FCHIP)
.value("RADJupiter_MCHIP", ChipID::RADJupiter_MCHIP)
.value("ValueCAN4Industrial_MCHIP", ChipID::ValueCAN4Industrial_MCHIP)
.value("EtherBADGE_MCHIP", ChipID::EtherBADGE_MCHIP)
.value("RADMars_3_ZYNQ", ChipID::RADMars_3_ZYNQ)
.value("RADGigastar_USBZ_ZYNQ", ChipID::RADGigastar_USBZ_ZYNQ)
.value("RADGigastar_ZYNQ", ChipID::RADGigastar_ZYNQ)
.value("RAD4G_MCHIP", ChipID::RAD4G_MCHIP)
.value("neoVIFIRE3_SCHIP", ChipID::neoVIFIRE3_SCHIP)
.value("RADEpsilon_MCHIP", ChipID::RADEpsilon_MCHIP)
.value("RADA2B_ZCHIP", ChipID::RADA2B_ZCHIP)
.value("neoOBD2Dev_MCHIP", ChipID::neoOBD2Dev_MCHIP)
.value("neoOBD2Dev_SCHIP", ChipID::neoOBD2Dev_SCHIP)
.value("neoOBD2SIMDoIP_MCHIP", ChipID::neoOBD2SIMDoIP_MCHIP)
.value("SFPModule_MCHIP", ChipID::SFPModule_MCHIP)
.value("RADEpsilonT_MCHIP", ChipID::RADEpsilonT_MCHIP)
.value("RADEpsilonExpress_MCHIP", ChipID::RADEpsilonExpress_MCHIP)
.value("RADProxima_MCHIP", ChipID::RADProxima_MCHIP)
.value("NewDevice57_ZCHIP", ChipID::NewDevice57_ZCHIP)
.value("RAD_GALAXY_2_ZMPCHIP_ID", ChipID::RAD_GALAXY_2_ZMPCHIP_ID)
.value("NewDevice59_MCHIP", ChipID::NewDevice59_MCHIP)
.value("RADMoon2_Z7010_ZYNQ", ChipID::RADMoon2_Z7010_ZYNQ)
.value("neoVIFIRE2_CORE_SG4", ChipID::neoVIFIRE2_CORE_SG4)
.value("RADBMS_MCHIP", ChipID::RADBMS_MCHIP)
.value("RADMoon2_ZL_MCHIP", ChipID::RADMoon2_ZL_MCHIP)
.value("RADGigastar_USBZ_Z7010_ZYNQ", ChipID::RADGigastar_USBZ_Z7010_ZYNQ)
.value("neoVIFIRE3_LINUX", ChipID::neoVIFIRE3_LINUX)
.value("RADGigastar_USBZ_Z7007S_ZYNQ", ChipID::RADGigastar_USBZ_Z7007S_ZYNQ)
.value("VEM_01_8DW_ZCHIP", ChipID::VEM_01_8DW_ZCHIP)
.value("RADGalaxy_FFG_Zynq", ChipID::RADGalaxy_FFG_Zynq)
.value("RADMoon3_MCHIP", ChipID::RADMoon3_MCHIP)
.value("RADComet_ZYNQ", ChipID::RADComet_ZYNQ)
.value("VEM_02_FR_ZCHIP", ChipID::VEM_02_FR_ZCHIP)
.value("RADA2B_REVB_ZCHIP", ChipID::RADA2B_REVB_ZCHIP)
.value("RADGigastar_FFG_ZYNQ", ChipID::RADGigastar_FFG_ZYNQ)
.value("VEM_02_FR_FCHIP", ChipID::VEM_02_FR_FCHIP)
.value("Connect_ZCHIP", ChipID::Connect_ZCHIP)
.value("RADGALAXY2_SYSMON_CHIP", ChipID::RADGALAXY2_SYSMON_CHIP)
.value("RADCOMET3_ZCHIP", ChipID::RADCOMET3_ZCHIP)
.value("Connect_LINUX", ChipID::Connect_LINUX)
.value("RADGigastar2_ZYNQ", ChipID::RADGigastar2_ZYNQ)
.value("RADGemini_MCHIP", ChipID::RADGemini_MCHIP)
.value("Invalid", ChipID::Invalid)
.finalize();
}
} // namespace icsneo
+50 -24
View File
@@ -1,42 +1,68 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/functional.h> #include <pybind11/functional.h>
#include <pybind11/chrono.h>
#include "icsneo/device/device.h" #include "icsneo/device/device.h"
#include "icsneo/device/extensions/deviceextension.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::classh<Device>(m, "Device")
.def("get_type", &Device::getType) .def("__repr__", &Device::describe)
.def("get_serial", &Device::getSerial) .def("add_message_callback", &Device::addMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_serial_number", &Device::getSerialNumber) .def("clear_script", &Device::clearScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_product_name", &Device::getProductName) .def("close", &Device::close, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("open", [](Device& device) { return device.open(); }) .def("describe", &Device::describe)
.def("close", &Device::close) .def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("is_open", &Device::isOpen) .def("enable_message_polling", &Device::enableMessagePolling, pybind11::arg("filter") = std::nullopt, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("go_online", &Device::goOnline)
.def("go_offline", &Device::goOffline)
.def("is_online", &Device::isOnline).def("enable_message_polling", &Device::enableMessagePolling)
.def("disable_message_polling", &Device::disableMessagePolling)
.def("is_message_polling_enabled", &Device::isMessagePollingEnabled)
.def("get_messages", [](Device& device) { return device.getMessages(); })
.def("get_current_message_count", &Device::getCurrentMessageCount) .def("get_current_message_count", &Device::getCurrentMessageCount)
.def("get_digital_io", &Device::getDigitalIO, pybind11::arg("type"), pybind11::arg("number"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_extension", static_cast<std::shared_ptr<DeviceExtension>(Device::*)(const std::string&) const>(&Device::getExtension)) // This has to be static_casted rather than overload_casted because DeviceExtension is forward declared in device.h
.def("get_flexray_controllers", &Device::getFlexRayControllers)
.def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_polling_message_limit", &Device::getPollingMessageLimit) .def("get_polling_message_limit", &Device::getPollingMessageLimit)
.def("set_polling_message_limit", &Device::setPollingMessageLimit) .def("get_product_name", &Device::getProductName)
.def("add_message_callback", &Device::addMessageCallback) .def("get_rtc", &Device::getRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("remove_message_callback", &Device::removeMessageCallback) .def("get_script_status", &Device::getScriptStatus, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("transmit", pybind11::overload_cast<std::shared_ptr<Frame>>(&Device::transmit)) .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) .def("get_tc10_status", &Device::getTC10Status, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_rtc", &Device::setRTC) .def("get_type", &Device::getType)
.def("describe", &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_supported", &Device::isOnlineSupported)
.def("is_online", &Device::isOnline)
.def("is_open", &Device::isOpen)
.def("open", [](Device& device) { return device.open(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("prepare_script_load", &Device::prepareScriptLoad, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("remove_message_callback", &Device::removeMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("request_tc10_sleep", &Device::requestTC10Sleep, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("request_tc10_wake", &Device::requestTC10Wake, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_digital_io", pybind11::overload_cast<IO, size_t, bool>(&Device::setDigitalIO), pybind11::arg("type"), pybind11::arg("number"), pybind11::arg("value"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_polling_message_limit", &Device::setPollingMessageLimit)
.def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("start_script", &Device::startScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("stop_script", &Device::stopScript, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("supports_tc10", &Device::supportsTC10) .def("supports_tc10", &Device::supportsTC10)
.def("request_tc10_wake", &Device::requestTC10Wake) .def("supports_live_data", &Device::supportsLiveData)
.def("request_tc10_sleep", &Device::requestTC10Sleep) .def("subscribe_live_data", &Device::subscribeLiveData, pybind11::arg("message"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("__repr__", &Device::describe); .def("unsubscribe_live_data", &Device::unsubscribeLiveData, pybind11::arg("handle"), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("clear_all_live_data", &Device::clearAllLiveData, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_value_live_data", &Device::setValueLiveData, pybind11::arg("message"), 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("upload_coremini", [](Device& device, std::string& path, Disk::MemoryType memType) { std::ifstream ifs(path, std::ios::binary); return device.uploadCoremini(ifs, memType); }, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("write_macsec_config", &Device::writeMACsecConfig, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("send_eth_phy_msg", &Device::sendEthPhyMsg, pybind11::arg("message"), pybind11::arg("timeout") = std::chrono::milliseconds(50), pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_chip_versions", &Device::getChipVersions, pybind11::arg("refreshComponents") = true, pybind11::call_guard<pybind11::gil_scoped_release>())
.def_readonly("settings", &Device::settings);
} }
} // namespace icsneo } // namespace icsneo
+10 -3
View File
@@ -1,14 +1,15 @@
#include <pybind11/pybind11.h> #include <pybind11/pybind11.h>
#include <pybind11/stl.h> #include <pybind11/stl.h>
#include <pybind11/functional.h> #include <pybind11/functional.h>
#include <pybind11/native_enum.h>
#include "icsneo/device/devicetype.h" #include "icsneo/device/devicetype.h"
namespace icsneo { namespace icsneo {
void init_devicetype(pybind11::module_& m) { void init_devicetype(pybind11::module_& m) {
pybind11::class_<DeviceType> deviceType(m, "DeviceType"); pybind11::classh<DeviceType> deviceType(m, "DeviceType");
pybind11::enum_<DeviceType::Enum>(deviceType, "Enum") pybind11::native_enum<DeviceType::Enum>(deviceType, "Enum", "enum.IntEnum")
.value("Unknown", DeviceType::Enum::Unknown) .value("Unknown", DeviceType::Enum::Unknown)
.value("BLUE", DeviceType::Enum::BLUE) .value("BLUE", DeviceType::Enum::BLUE)
.value("ECU_AVB", DeviceType::Enum::ECU_AVB) .value("ECU_AVB", DeviceType::Enum::ECU_AVB)
@@ -33,9 +34,14 @@ void init_devicetype(pybind11::module_& m) {
.value("EtherBADGE", DeviceType::Enum::EtherBADGE) .value("EtherBADGE", DeviceType::Enum::EtherBADGE)
.value("RAD_A2B", DeviceType::Enum::RAD_A2B) .value("RAD_A2B", DeviceType::Enum::RAD_A2B)
.value("RADEpsilon", DeviceType::Enum::RADEpsilon) .value("RADEpsilon", DeviceType::Enum::RADEpsilon)
.value("RADEpsilonXL", DeviceType::Enum::RADEpsilonXL)
.value("RADGalaxy2", DeviceType::Enum::RADGalaxy2)
.value("RADMoon3", DeviceType::Enum::RADMoon3) .value("RADMoon3", DeviceType::Enum::RADMoon3)
.value("RADGemini", DeviceType::Enum::RADGemini)
.value("RADComet", DeviceType::Enum::RADComet) .value("RADComet", DeviceType::Enum::RADComet)
.value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay) .value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay)
.value("FIRE3_T1S_LIN", DeviceType::Enum::FIRE3_T1S_LIN)
.value("FIRE3_T1S_SENT", DeviceType::Enum::FIRE3_T1S_SENT)
.value("Connect", DeviceType::Enum::Connect) .value("Connect", DeviceType::Enum::Connect)
.value("RADComet3", DeviceType::Enum::RADComet3) .value("RADComet3", DeviceType::Enum::RADComet3)
.value("RADMoonT1S", DeviceType::Enum::RADMoonT1S) .value("RADMoonT1S", DeviceType::Enum::RADMoonT1S)
@@ -65,7 +71,8 @@ void init_devicetype(pybind11::module_& m) {
.value("RADGalaxy", DeviceType::Enum::RADGalaxy) .value("RADGalaxy", DeviceType::Enum::RADGalaxy)
.value("RADStar2", DeviceType::Enum::RADStar2) .value("RADStar2", DeviceType::Enum::RADStar2)
.value("VividCAN", DeviceType::Enum::VividCAN) .value("VividCAN", DeviceType::Enum::VividCAN)
.value("OBD2_SIM", DeviceType::Enum::OBD2_SIM); .value("OBD2_SIM", DeviceType::Enum::OBD2_SIM)
.finalize();
deviceType.def(pybind11::init<DeviceType::Enum>()); deviceType.def(pybind11::init<DeviceType::Enum>());
deviceType.def("get_device_type", &DeviceType::getDeviceType); deviceType.def("get_device_type", &DeviceType::getDeviceType);
deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName); deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName);
@@ -0,0 +1,14 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/device/extensions/deviceextension.h"
namespace icsneo {
void init_deviceextension(pybind11::module_& m) {
pybind11::classh<DeviceExtension>(m, "DeviceExtension")
.def("get_name", &DeviceExtension::getName);
}
} // namespace icsneo
@@ -0,0 +1,80 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/stl_bind.h>
#include <pybind11/functional.h>
#include <pybind11/chrono.h>
#include "icsneo/device/idevicesettings.h"
#include <fstream>
namespace icsneo {
struct DeviceSettingsNamespace {
using EthLinkMode = AELinkMode;
using LinkSpeed = EthLinkSpeed;
};
void init_idevicesettings(pybind11::module_& m) {
pybind11::classh<DeviceSettingsNamespace> settings(m, "Settings");
pybind11::enum_<DeviceSettingsNamespace::EthLinkMode>(settings, "EthernetLinkMode")
.value("Auto", DeviceSettingsNamespace::EthLinkMode::AE_LINK_AUTO)
.value("Slave", DeviceSettingsNamespace::EthLinkMode::AE_LINK_SLAVE)
.value("Master", DeviceSettingsNamespace::EthLinkMode::AE_LINK_MASTER);
pybind11::enum_<DeviceSettingsNamespace::LinkSpeed>(settings, "EthernetLinkSpeed")
.value("Speed10M", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_10)
.value("Speed100M", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_100)
.value("Speed1G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_1000)
.value("Speed2_5G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_2500)
.value("Speed5G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_5000)
.value("Speed10G", DeviceSettingsNamespace::LinkSpeed::ETH_SPEED_10000);
pybind11::enum_<LINMode>(settings, "LINMode")
.value("Sleep", LINMode::SLEEP_MODE)
.value("Slow", LINMode::SLOW_MODE)
.value("Normal", LINMode::NORMAL_MODE)
.value("Fast", LINMode::FAST_MODE);
pybind11::classh<IDeviceSettings>(m, "IDeviceSettings")
.def("apply", &IDeviceSettings::apply, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("apply_defaults", &IDeviceSettings::applyDefaults, pybind11::arg("temporary") = 0, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("refresh", &IDeviceSettings::refresh, pybind11::call_guard<pybind11::gil_scoped_release>())
// Baudrate methods
.def("get_baudrate", &IDeviceSettings::getBaudrateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_baudrate", &IDeviceSettings::setBaudrateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_fd_baudrate", &IDeviceSettings::getFDBaudrateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_fd_baudrate", &IDeviceSettings::setFDBaudrateFor, pybind11::call_guard<pybind11::gil_scoped_release>())
// Termination methods
.def("is_termination_supported", &IDeviceSettings::isTerminationSupportedFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("can_termination_be_enabled", &IDeviceSettings::canTerminationBeEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("is_termination_enabled", &IDeviceSettings::isTerminationEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_termination", &IDeviceSettings::setTerminationFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_termination_groups", &IDeviceSettings::getTerminationGroups, pybind11::call_guard<pybind11::gil_scoped_release>())
// LIN methods
.def("is_commander_resistor_enabled", &IDeviceSettings::isCommanderResistorEnabledFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_commander_resistor", &IDeviceSettings::setCommanderResistorFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_lin_mode", &IDeviceSettings::getLINModeFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_lin_mode", &IDeviceSettings::setLINModeFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_lin_commander_response_time", &IDeviceSettings::getLINCommanderResponseTimeFor, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_lin_commander_response_time", &IDeviceSettings::setLINCommanderResponseTimeFor, pybind11::call_guard<pybind11::gil_scoped_release>())
// Ethernet PHY methods
.def("get_phy_enable", &IDeviceSettings::getPhyEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_phy_mode", &IDeviceSettings::getPhyMode, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("get_phy_speed", &IDeviceSettings::getPhySpeed, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_phy_enable", &IDeviceSettings::setPhyEnable, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_phy_mode", &IDeviceSettings::setPhyMode, pybind11::call_guard<pybind11::gil_scoped_release>())
.def("set_phy_speed", &IDeviceSettings::setPhySpeed, pybind11::call_guard<pybind11::gil_scoped_release>())
// Status properties
.def_readonly("disabled", &IDeviceSettings::disabled)
.def_readonly("readonly", &IDeviceSettings::readonly);
}
} // namespace icsneo
@@ -0,0 +1,19 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/device/versionreport.h"
namespace icsneo {
void init_versionreport(pybind11::module_& m) {
pybind11::classh<VersionReport>(m, "VersionReport")
.def_readonly("id", &VersionReport::id)
.def_readonly("name", &VersionReport::name)
.def_readonly("major", &VersionReport::major)
.def_readonly("minor", &VersionReport::minor)
.def_readonly("maintenance", &VersionReport::maintenance)
.def_readonly("build", &VersionReport::build);
}
} // namespace icsneo
@@ -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::classh<DiskNamespace> disk(m, "Disk");
pybind11::enum_<Disk::Access>(disk, "Access")
.value("None", Disk::Access::None)
.value("EntireCard", Disk::Access::EntireCard)
.value("VSA", Disk::Access::VSA);
pybind11::enum_<Disk::MemoryType>(disk, "MemoryType")
.value("Flash", Disk::MemoryType::Flash)
.value("SD", Disk::MemoryType::SD);
}
} // namespace icsneo
@@ -0,0 +1,191 @@
#include <pybind11/pybind11.h>
#include <pybind11/stl.h>
#include <pybind11/functional.h>
#include "icsneo/communication/message/flexray/flexraymessage.h"
#include "icsneo/device/extensions/flexray/symbol.h"
#include "icsneo/device/extensions/flexray/channel.h"
#include "icsneo/device/extensions/flexray/crcstatus.h"
#include "icsneo/device/extensions/flexray/controller.h"
namespace icsneo {
struct FlexRayNamespace {
using Symbol = icsneo::FlexRay::Symbol;
using CRCStatus = icsneo::FlexRay::CRCStatus;
using Channel = icsneo::FlexRay::Channel;
};
namespace FlexRay {
struct ClusterNamespace {
using SpeedType = icsneo::FlexRay::Cluster::SpeedType;
using SPPType = icsneo::FlexRay::Cluster::SPPType;
};
void init_extension(pybind11::classh<FlexRayNamespace>& c) {
pybind11::classh<MessageBuffer>(c, "MessageBuffer")
.def(pybind11::init())
.def_readwrite("is_dynamic", &MessageBuffer::isDynamic)
.def_readwrite("is_sync", &MessageBuffer::isSync)
.def_readwrite("is_startup", &MessageBuffer::isStartup)
.def_readwrite("is_network_management_frame", &MessageBuffer::isNetworkManagementFrame)
.def_readwrite("is_transmit", &MessageBuffer::isTransmit)
.def_readwrite("frame_id", &MessageBuffer::frameID)
.def_readwrite("channel_a", &MessageBuffer::channelA)
.def_readwrite("channel_b", &MessageBuffer::channelB)
.def_readwrite("frame_length_bytes", &MessageBuffer::frameLengthBytes)
.def_readwrite("base_cycle", &MessageBuffer::baseCycle)
.def_readwrite("cycle_repetition", &MessageBuffer::cycleRepetition)
.def_readwrite("continuous_mode", &MessageBuffer::continuousMode);
auto controller = pybind11::classh<Controller>(c, "Controller")
.def("get_network", &Controller::getNetwork)
.def("get_configuration", &Controller::getConfiguration)
.def("set_configuration", &Controller::setConfiguration)
.def("get_start_when_going_online", &Controller::getStartWhenGoingOnline)
.def("set_start_when_going_online", &Controller::setStartWhenGoingOnline)
.def("get_allow_coldstart", &Controller::getAllowColdstart)
.def("set_allow_coldstart", &Controller::setAllowColdstart)
.def("get_wakeup_before_start", &Controller::getWakeupBeforeStart)
.def("set_wakeup_before_start", &Controller::setWakeupBeforeStart)
.def("add_message_buffer", &Controller::addMessageBuffer)
.def("clear_message_buffers", &Controller::clearMessageBuffers)
.def("wakeup", &Controller::wakeup)
.def("configure", &Controller::getReady)
.def("start", &Controller::start)
.def("transmit", &Controller::transmit)
.def("halt", &Controller::halt)
.def("freeze", &Controller::freeze)
.def("trigger_mts", &Controller::triggerMTS);
pybind11::classh<Controller::Configuration>(controller, "Configuration")
.def(pybind11::init())
.def_readwrite("accept_startup_range_microticks", &Controller::Configuration::AcceptStartupRangeMicroticks)
.def_readwrite("allow_passive_to_active_cycle_pairs", &Controller::Configuration::AllowPassiveToActiveCyclePairs)
.def_readwrite("cluster_drift_damping", &Controller::Configuration::ClusterDriftDamping)
.def_readwrite("channel_a", &Controller::Configuration::ChannelA)
.def_readwrite("channel_b", &Controller::Configuration::ChannelB)
.def_readwrite("decoding_correction_microticks", &Controller::Configuration::DecodingCorrectionMicroticks)
.def_readwrite("delay_compensation_a_microticks", &Controller::Configuration::DelayCompensationAMicroticks)
.def_readwrite("delay_compensation_b_microticks", &Controller::Configuration::DelayCompensationBMicroticks)
.def_readwrite("extern_offset_correction_control", &Controller::Configuration::ExternOffsetCorrectionControl)
.def_readwrite("extern_rate_correction_control", &Controller::Configuration::ExternRateCorrectionControl)
.def_readwrite("extern_offset_correction_microticks", &Controller::Configuration::ExternOffsetCorrectionMicroticks)
.def_readwrite("extern_rate_correction_microticks", &Controller::Configuration::ExternRateCorrectionMicroticks)
.def_readwrite("key_slot_id", &Controller::Configuration::KeySlotID)
.def_readwrite("key_slot_used_for_startup", &Controller::Configuration::KeySlotUsedForStartup)
.def_readwrite("key_slot_used_for_sync", &Controller::Configuration::KeySlotUsedForSync)
.def_readwrite("latest_tx_minislot", &Controller::Configuration::LatestTxMinislot)
.def_readwrite("listen_timeout", &Controller::Configuration::ListenTimeout)
.def_readwrite("macro_initial_offset_a", &Controller::Configuration::MacroInitialOffsetA)
.def_readwrite("macro_initial_offset_b", &Controller::Configuration::MacroInitialOffsetB)
.def_readwrite("micro_initial_offset_a", &Controller::Configuration::MicroInitialOffsetA)
.def_readwrite("micro_initial_offset_b", &Controller::Configuration::MicroInitialOffsetB)
.def_readwrite("micro_per_cycle", &Controller::Configuration::MicroPerCycle)
.def_readwrite("mts_on_a", &Controller::Configuration::MTSOnA)
.def_readwrite("mts_on_b", &Controller::Configuration::MTSOnB)
.def_readwrite("offset_correction_out_microticks", &Controller::Configuration::OffsetCorrectionOutMicroticks)
.def_readwrite("rate_correction_out_microticks", &Controller::Configuration::RateCorrectionOutMicroticks)
.def_readwrite("second_key_slot_id", &Controller::Configuration::SecondKeySlotID)
.def_readwrite("two_key_slot_mode", &Controller::Configuration::TwoKeySlotMode)
.def_readwrite("wakeup_pattern", &Controller::Configuration::WakeupPattern)
.def_readwrite("wakeup_on_channel_b", &Controller::Configuration::WakeupOnChannelB);
// Dummy class for cluster namespace
pybind11::classh<ClusterNamespace> cluster(c, "Cluster");
pybind11::enum_<Cluster::SpeedType>(cluster, "SpeedType")
.value("FLEXRAY_BAUDRATE_10M", Cluster::SpeedType::FLEXRAY_BAUDRATE_10M)
.value("FLEXRAY_BAUDRATE_5M", Cluster::SpeedType::FLEXRAY_BAUDRATE_5M)
.value("FLEXRAY_BAUDRATE_2M5", Cluster::SpeedType::FLEXRAY_BAUDRATE_2M5)
.value("FLEXRAY_BAUDRATE_2M5_ALT", Cluster::SpeedType::FLEXRAY_BAUDRATE_2M5_ALT);
pybind11::enum_<Cluster::SPPType>(cluster, "SPPType")
.value("FLEXRAY_SPP_5", Cluster::SPPType::FLEXRAY_SPP_5)
.value("FLEXRAY_SPP_4", Cluster::SPPType::FLEXRAY_SPP_4)
.value("FLEXRAY_SPP_6", Cluster::SPPType::FLEXRAY_SPP_6)
.value("FLEXRAY_SPP_5_ALT", Cluster::SPPType::FLEXRAY_SPP_5_ALT);
pybind11::classh<Cluster::Configuration>(cluster, "Configuration")
.def(pybind11::init())
.def_readwrite("speed", &Cluster::Configuration::Speed)
.def_readwrite("strobe_point_position", &Cluster::Configuration::StrobePointPosition)
.def_readwrite("action_point_offset", &Cluster::Configuration::ActionPointOffset)
.def_readwrite("casr_x_low_max", &Cluster::Configuration::CASRxLowMax)
.def_readwrite("cold_start_attempts", &Cluster::Configuration::ColdStartAttempts)
.def_readwrite("dynamic_slot_idle_phase_minislots", &Cluster::Configuration::DynamicSlotIdlePhaseMinislots)
.def_readwrite("listen_noise_macroticks", &Cluster::Configuration::ListenNoiseMacroticks)
.def_readwrite("macroticks_per_cycle", &Cluster::Configuration::MacroticksPerCycle)
.def_readwrite("macrotick_duration_micro_sec", &Cluster::Configuration::MacrotickDurationMicroSec)
.def_readwrite("max_without_clock_correction_fatal", &Cluster::Configuration::MaxWithoutClockCorrectionFatal)
.def_readwrite("max_without_clock_correction_passive", &Cluster::Configuration::MaxWithoutClockCorrectionPassive)
.def_readwrite("minislot_action_point_offset_macroticks", &Cluster::Configuration::MinislotActionPointOffsetMacroticks)
.def_readwrite("minislot_duration_macroticks", &Cluster::Configuration::MinislotDurationMacroticks)
.def_readwrite("network_idle_time_macroticks", &Cluster::Configuration::NetworkIdleTimeMacroticks)
.def_readwrite("network_management_vector_length_bytes", &Cluster::Configuration::NetworkManagementVectorLengthBytes)
.def_readwrite("number_of_minislots", &Cluster::Configuration::NumberOfMinislots)
.def_readwrite("number_of_static_slots", &Cluster::Configuration::NumberOfStaticSlots)
.def_readwrite("offset_correction_start_macroticks", &Cluster::Configuration::OffsetCorrectionStartMacroticks)
.def_readwrite("payload_length_of_static_slot_in_words", &Cluster::Configuration::PayloadLengthOfStaticSlotInWords)
.def_readwrite("static_slot_macroticks", &Cluster::Configuration::StaticSlotMacroticks)
.def_readwrite("symbol_window_macroticks", &Cluster::Configuration::SymbolWindowMacroticks)
.def_readwrite("symbol_window_action_point_offset_macroticks", &Cluster::Configuration::SymbolWindowActionPointOffsetMacroticks)
.def_readwrite("sync_frame_id_count_max", &Cluster::Configuration::SyncFrameIDCountMax)
.def_readwrite("transmission_start_sequence_duration_bits", &Cluster::Configuration::TransmissionStartSequenceDurationBits)
.def_readwrite("wakeup_rx_idle_bits", &Cluster::Configuration::WakeupRxIdleBits)
.def_readwrite("wakeup_rx_low_bits", &Cluster::Configuration::WakeupRxLowBits)
.def_readwrite("wakeup_rx_window_bits", &Cluster::Configuration::WakeupRxWindowBits)
.def_readwrite("wakeup_tx_active_bits", &Cluster::Configuration::WakeupTxActiveBits)
.def_readwrite("wakeup_tx_idle_bits", &Cluster::Configuration::WakeupTxIdleBits);
}
} // namespace FlexRay
void init_flexraymessage(pybind11::module_& m) {
pybind11::classh<FlexRayMessage, Frame>(m, "FlexRayMessage")
.def(pybind11::init())
.def_readwrite("slotid", &FlexRayMessage::slotid)
.def_readwrite("tsslen", &FlexRayMessage::tsslen)
.def_readwrite("framelen", &FlexRayMessage::framelen)
.def_readwrite("symbol", &FlexRayMessage::symbol)
.def_readwrite("header_crc_status", &FlexRayMessage::headerCRCStatus)
.def_readwrite("header_crc", &FlexRayMessage::headerCRC)
.def_readwrite("frame_crc_status", &FlexRayMessage::crcStatus)
.def_readwrite("frame_crc", &FlexRayMessage::frameCRC)
.def_readwrite("channel", &FlexRayMessage::channel)
.def_readwrite("null_frame", &FlexRayMessage::nullFrame)
.def_readwrite("payload_preamble", &FlexRayMessage::payloadPreamble)
.def_readwrite("sync_frame", &FlexRayMessage::sync)
.def_readwrite("startup_frame", &FlexRayMessage::startup)
.def_readwrite("dynamic_frame", &FlexRayMessage::dynamic)
.def_readwrite("cycle", &FlexRayMessage::cycle);
//// TODO: Eliminate FlexRayControlMessage class references in controller class and eliminate getStatus function in bindings
}
void init_flexray(pybind11::module_& m) {
// Dummy class to act as FlexRay namespace
pybind11::classh<FlexRayNamespace> flexray(m, "FlexRay");
pybind11::enum_<FlexRayNamespace::Symbol>(flexray, "Symbol")
.value("None", FlexRayNamespace::Symbol::None)
.value("Unknown", FlexRayNamespace::Symbol::Unknown)
.value("Wakeup", FlexRayNamespace::Symbol::Wakeup)
.value("CAS", FlexRayNamespace::Symbol::CAS);
pybind11::enum_<FlexRayNamespace::CRCStatus>(flexray, "CRCStatus")
.value("OK", FlexRayNamespace::CRCStatus::OK)
.value("Error", FlexRayNamespace::CRCStatus::Error)
.value("NoCRC", FlexRayNamespace::CRCStatus::NoCRC);
pybind11::enum_<FlexRayNamespace::Channel>(flexray, "Channel")
.value("None", FlexRayNamespace::Channel::None)
.value("A", FlexRayNamespace::Channel::A)
.value("B", FlexRayNamespace::Channel::B)
.value("AB", FlexRayNamespace::Channel::AB);
init_flexraymessage(m);
FlexRay::init_extension(flexray);
}
} // namespace icsneo
+38
View File
@@ -10,17 +10,37 @@ void init_event(pybind11::module_&);
void init_eventcallback(pybind11::module_&); void init_eventcallback(pybind11::module_&);
void init_eventmanager(pybind11::module_&); void init_eventmanager(pybind11::module_&);
void init_network(pybind11::module_&); void init_network(pybind11::module_&);
void init_io(pybind11::module_&);
void init_devicetype(pybind11::module_&); void init_devicetype(pybind11::module_&);
void init_message(pybind11::module_&); void init_message(pybind11::module_&);
void init_canmessage(pybind11::module_&); void init_canmessage(pybind11::module_&);
void init_canerrormessage(pybind11::module_&);
void init_ethernetmessage(pybind11::module_&); void init_ethernetmessage(pybind11::module_&);
void init_linmessage(pybind11::module_&);
void init_tc10statusmessage(pybind11::module_&); void init_tc10statusmessage(pybind11::module_&);
void init_gptpstatusmessage(pybind11::module_&);
void init_mdiomessage(pybind11::module_&);
void init_spimessage(pybind11::module_&);
void init_ethernetstatusmessage(pybind11::module_&);
void init_macsecconfig(pybind11::module_&);
void init_scriptstatusmessage(pybind11::module_&);
void init_diskdriver(pybind11::module_&);
void init_deviceextension(pybind11::module_&);
void init_chipid(pybind11::module_&);
void init_versionreport(pybind11::module_&);
void init_device(pybind11::module_&); void init_device(pybind11::module_&);
void init_messagefilter(pybind11::module_&); void init_messagefilter(pybind11::module_&);
void init_messagecallback(pybind11::module_&); void init_messagecallback(pybind11::module_&);
void init_version(pybind11::module_&); void init_version(pybind11::module_&);
void init_flexray(pybind11::module_& m);
void init_idevicesettings(pybind11::module_&);
void init_ethphymessage(pybind11::module_&);
void init_livedata(pybind11::module_&);
void init_livedatamessage(pybind11::module_&);
PYBIND11_MODULE(icsneopy, m) { PYBIND11_MODULE(icsneopy, m) {
pybind11::options options;
options.disable_enum_members_docstring();
m.doc() = "libicsneo Python module"; m.doc() = "libicsneo Python module";
init_event(m); init_event(m);
@@ -29,13 +49,31 @@ PYBIND11_MODULE(icsneopy, m) {
init_version(m); init_version(m);
init_devicetype(m); init_devicetype(m);
init_network(m); init_network(m);
init_io(m);
init_livedata(m);
init_message(m); init_message(m);
init_canmessage(m); init_canmessage(m);
init_canerrormessage(m);
init_ethernetmessage(m); init_ethernetmessage(m);
init_linmessage(m);
init_tc10statusmessage(m); init_tc10statusmessage(m);
init_gptpstatusmessage(m);
init_mdiomessage(m);
init_ethernetstatusmessage(m);
init_macsecconfig(m);
init_scriptstatusmessage(m);
init_spimessage(m);
init_livedatamessage(m);
init_messagefilter(m); init_messagefilter(m);
init_messagecallback(m); init_messagecallback(m);
init_diskdriver(m);
init_flexray(m);
init_ethphymessage(m);
init_chipid(m);
init_versionreport(m);
init_device(m); init_device(m);
init_deviceextension(m);
init_idevicesettings(m);
m.def("find_all_devices", &FindAllDevices); m.def("find_all_devices", &FindAllDevices);
m.def("get_supported_devices", &GetSupportedDevices); m.def("get_supported_devices", &GetSupportedDevices);
+7
View File
@@ -0,0 +1,7 @@
#!/bin/sh
yum install -y flex ca-certificates || exit 1
echo "$ICS_IPA_CA_CRT" >/etc/pki/ca-trust/source/anchors/ica-ipa-ca.crt
update-ca-trust || exit 1
-21
View File
@@ -1,21 +0,0 @@
#!/bin/sh
VERSION="1.0.27"
ROOT="$PWD/libusb"
SOURCE="$ROOT/source"
BUILD="$ROOT/build"
INSTALL="$ROOT/install"
mkdir -p "$ROOT"
cd "$ROOT" || exit 1
curl -LO "https://github.com/libusb/libusb/releases/download/v$VERSION/libusb-$VERSION.tar.bz2" || exit 1
tar -xf "libusb-$VERSION.tar.bz2" || exit 1
mv "libusb-$VERSION" "$SOURCE" || exit 1
mkdir "$BUILD" || exit 1
cd "$BUILD" || exit 1
"$SOURCE/configure" --prefix="$INSTALL" --disable-shared --disable-udev --disable-eventfd --disable-timerfd --with-pic || exit 1
make || exit 1
make install || exit 1
+1 -1
View File
@@ -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
+8 -11
View File
@@ -1,12 +1,9 @@
REM clean intermediate directories @setlocal
rmdir /s /q build @echo off
mkdir build
REM build mkdir build >nul 2>&1
cd build
set CFLAGS=/WX cmake -GNinja -Bbuild -DCMAKE_BUILD_TYPE=Release -DLIBICSNEO_BUILD_UNIT_TESTS=ON ^
set CXXFLAGS=/WX -DLIBICSNEO_ENABLE_TCP=ON || exit /b 1
cmake -GNinja -DCMAKE_BUILD_TYPE=RelWithDebInfo -DLIBICSNEO_BUILD_UNIT_TESTS=ON -DLIBICSNEO_BUILD_SYSTEM_TESTS=ON -DLIBICSNEO_ENABLE_TCP=ON ..
if %errorlevel% neq 0 exit /b %errorlevel% cmake --build build || exit /b 1
cmake --build .
if %errorlevel% neq 0 exit /b %errorlevel%
+1 -1
View File
@@ -1,2 +1,2 @@
call "%VCVARS32%" call "%VCVARS32_2022%"
call "ci\build-windows.bat" call "ci\build-windows.bat"
+1 -1
View File
@@ -1,2 +1,2 @@
call "%VCVARS64%" call "%VCVARS64_2022%"
call "ci\build-windows.bat" call "ci\build-windows.bat"
-22
View File
@@ -1,22 +0,0 @@
find_path(FTD3XX_INCLUDE_DIR
NAMES ftd3xx.h FTD3XX.h
)
find_library(FTD3XX_LIBRARY
NAMES libftd3xx.a libftd3xx-static.a FTD3XX.lib
PATH_SUFFIXES x64/Static
)
mark_as_advanced(FTD3XX_FOUND FTD3XX_INCLUDE_DIR FTD3XX_LIBRARY)
include(FindPackageHandleStandardArgs)
find_package_handle_standard_args(FTD3XX
REQUIRED_VARS FTD3XX_INCLUDE_DIR FTD3XX_LIBRARY
)
if(FTD3XX_FOUND AND NOT TARGET D3XX::D3XX)
add_library(FTD3XX::FTD3XX INTERFACE IMPORTED)
set_target_properties(FTD3XX::FTD3XX PROPERTIES
INTERFACE_INCLUDE_DIRECTORIES "${FTD3XX_INCLUDE_DIR}"
INTERFACE_LINK_LIBRARIES "${FTD3XX_LIBRARY}"
)
endif()
+39 -5
View File
@@ -14,6 +14,12 @@
#include "icsneo/communication/message/readsettingsmessage.h" #include "icsneo/communication/message/readsettingsmessage.h"
#include "icsneo/communication/message/versionmessage.h" #include "icsneo/communication/message/versionmessage.h"
#include "icsneo/communication/message/componentversionsmessage.h" #include "icsneo/communication/message/componentversionsmessage.h"
#include "icsneo/communication/message/filter/extendedresponsefilter.h"
#include "icsneo/communication/message/clientidmessage.h"
#include "icsneo/communication/icspb.h"
#include <commands/generic/v1/client_id.pb.h>
#include <commands/network/v1/mutex.pb.h>
using namespace icsneo; using namespace icsneo;
@@ -37,29 +43,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();
} }
@@ -314,3 +319,32 @@ std::optional< std::vector<ComponentVersion> > Communication::getComponentVersio
return std::make_optional< std::vector<ComponentVersion> >(std::move(ver->versions)); return std::make_optional< std::vector<ComponentVersion> >(std::move(ver->versions));
} }
std::optional<uint32_t> Communication::getClientIDSync() {
constexpr auto timeout = std::chrono::milliseconds(250);
commands::generic::v1::ClientId msg;
msg.Clear();
std::vector<uint8_t> payload = protoapi::getPayload(protoapi::Command::GET, msg);
std::shared_ptr<Message> response = waitForMessageSync(
[this, payload](){
return sendCommand(ExtendedCommand::ProtobufAPI, payload);
},
std::make_shared<MessageFilter>(Message::Type::ClientId),
timeout
);
if(!response) {
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
return std::nullopt;
}
auto clientIdMessage = std::dynamic_pointer_cast<ClientIdMessage>(response);
if(!clientIdMessage) {
report(APIEvent::Type::UnexpectedResponse, APIEvent::Severity::Error);
return std::nullopt;
}
return clientIdMessage->clientId;
}
+95 -20
View File
@@ -3,7 +3,7 @@
#include "icsneo/communication/message/serialnumbermessage.h" #include "icsneo/communication/message/serialnumbermessage.h"
#include "icsneo/communication/message/resetstatusmessage.h" #include "icsneo/communication/message/resetstatusmessage.h"
#include "icsneo/communication/message/readsettingsmessage.h" #include "icsneo/communication/message/readsettingsmessage.h"
#include "icsneo/communication/message/canerrorcountmessage.h" #include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/neoreadmemorysdmessage.h" #include "icsneo/communication/message/neoreadmemorysdmessage.h"
#include "icsneo/communication/message/flashmemorymessage.h" #include "icsneo/communication/message/flashmemorymessage.h"
#include "icsneo/communication/message/extendedresponsemessage.h" #include "icsneo/communication/message/extendedresponsemessage.h"
@@ -16,10 +16,15 @@
#include "icsneo/communication/message/mdiomessage.h" #include "icsneo/communication/message/mdiomessage.h"
#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/logdatamessage.h"
#include "icsneo/communication/message/diskdatamessage.h" #include "icsneo/communication/message/diskdatamessage.h"
#include "icsneo/communication/message/hardwareinfo.h" #include "icsneo/communication/message/hardwareinfo.h"
#include "icsneo/communication/message/tc10statusmessage.h" #include "icsneo/communication/message/tc10statusmessage.h"
#include "icsneo/communication/message/gptpstatusmessage.h"
#include "icsneo/communication/message/apperrormessage.h" #include "icsneo/communication/message/apperrormessage.h"
#include "icsneo/communication/message/ethernetstatusmessage.h"
#include "icsneo/communication/message/networkmutexmessage.h"
#include "icsneo/communication/message/clientidmessage.h"
#include "icsneo/communication/command.h" #include "icsneo/communication/command.h"
#include "icsneo/device/device.h" #include "icsneo/device/device.h"
#include "icsneo/communication/packet/canpacket.h" #include "icsneo/communication/packet/canpacket.h"
@@ -40,6 +45,9 @@
#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/communication/packet/hardwareinfopacket.h" #include "icsneo/communication/packet/hardwareinfopacket.h"
#include "icsneo/communication/packet/spipacket.h"
#include "icsneo/communication/icspb.h"
#include <iostream> #include <iostream>
@@ -54,8 +62,9 @@ uint64_t Decoder::GetUInt64FromLEBytes(const uint8_t* bytes) {
bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet) { bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet) {
switch(packet->network.getType()) { switch(packet->network.getType()) {
case Network::Type::Ethernet: { case Network::Type::Ethernet:
result = HardwareEthernetPacket::DecodeToMessage(packet->data, report); case Network::Type::AutomotiveEthernet: {
result = HardwareEthernetPacket::DecodeToMessage(packet->data);
if(!result) { if(!result) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was not long enough to decode return false; // A nullptr was returned, the packet was not long enough to decode
@@ -93,7 +102,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
break; break;
} }
case Message::Type::CANErrorCount: { case Message::Type::CANErrorCount: {
CANErrorCountMessage& can = *static_cast<CANErrorCountMessage*>(result.get()); CANErrorMessage& can = *static_cast<CANErrorMessage*>(result.get());
can.network = packet->network; can.network = packet->network;
break; break;
} }
@@ -178,6 +187,20 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
LINMessage& msg = *static_cast<LINMessage*>(result.get()); LINMessage& msg = *static_cast<LINMessage*>(result.get());
msg.network = packet->network; msg.network = packet->network;
msg.timestamp *= timestampResolution;
return true;
}
case Network::Type::SPI: {
result = HardwareSPIPacket::DecodeToMessage(packet->data);
if(!result) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was not long enough to decode
}
SPIMessage& msg = *static_cast<SPIMessage*>(result.get());
msg.network = packet->network;
msg.timestamp *= timestampResolution;
return true; return true;
} }
case Network::Type::MDIO: { case Network::Type::MDIO: {
@@ -236,21 +259,26 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
return true; return true;
} }
result = HardwareCANPacket::DecodeToMessage(packet->data); const auto can = std::dynamic_pointer_cast<CANMessage>(HardwareCANPacket::DecodeToMessage(packet->data));
if(!result) { if(!can) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was malformed return false;
} }
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000 if(can->arbid == 0x162) {
// The resolution depends on the device result = EthernetStatusMessage::DecodeToMessage(can->data);
auto* raw = dynamic_cast<RawMessage*>(result.get());
if(raw == nullptr) { if(!result) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false; // A nullptr was returned, the packet was malformed return false;
}
} else {
// TODO: move more handleNeoVIMessage handling here, the Decoder layer will parse the message and the Device layer can cache the values
can->network = packet->network;
result = can;
} }
raw->timestamp *= timestampResolution;
raw->network = packet->network; result->timestamp = can->timestamp * timestampResolution;
return true; return true;
} }
case Network::NetID::DeviceStatus: { case Network::NetID::DeviceStatus: {
@@ -284,11 +312,11 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
} }
case Network::NetID::ExtendedCommand: { case Network::NetID::ExtendedCommand: {
if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse)) if(packet->data.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
break; // Handle as a raw message, might not be a generic response break; // Handle as a raw message, might not be a generic response
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data()); const auto& resp = *reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(packet->data.data());
switch(resp.header.command) { switch(resp.command) {
case ExtendedCommand::GetComponentVersions: case ExtendedCommand::GetComponentVersions:
result = ComponentVersionPacket::DecodeToMessage(packet->data); result = ComponentVersionPacket::DecodeToMessage(packet->data);
return true; return true;
@@ -298,15 +326,53 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
case ExtendedCommand::GenericBinaryInfo: case ExtendedCommand::GenericBinaryInfo:
result = GenericBinaryStatusPacket::DecodeToMessage(packet->data); result = GenericBinaryStatusPacket::DecodeToMessage(packet->data);
return true; return true;
case ExtendedCommand::GenericReturn: case ExtendedCommand::GenericReturn: {
result = std::make_shared<ExtendedResponseMessage>(resp.command, resp.returnCode); if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse))
break;
const auto& packedResp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data());
result = std::make_shared<ExtendedResponseMessage>(packedResp.command, packedResp.returnCode);
return true; return true;
}
case ExtendedCommand::LiveData: case ExtendedCommand::LiveData:
result = HardwareLiveDataPacket::DecodeToMessage(packet->data, report); result = HardwareLiveDataPacket::DecodeToMessage(packet->data, report);
return true; return true;
case ExtendedCommand::GetTC10Status: case ExtendedCommand::GetTC10Status:
result = TC10StatusMessage::DecodeToMessage(packet->data); result = TC10StatusMessage::DecodeToMessage(packet->data);
return true; return true;
case ExtendedCommand::GetGPTPStatus: {
result = GPTPStatus::DecodeToMessage(packet->data, report);
return true;
}
case ExtendedCommand::ProtobufAPI: {
// get the proto id
std::vector<uint8_t> responseBody(
packet->data.begin() + sizeof(ExtendedResponseMessage::ResponseHeader),
packet->data.end()
);
protoapi::Id protoId = protoapi::getProtoId(responseBody.data(), responseBody.size());
switch(protoId) {
case protoapi::Id::NetworkMutex:
result = NetworkMutexMessage::DecodeToMessage(responseBody);
return true;
case protoapi::Id::ClientId:
result = ClientIdMessage::DecodeToMessage(responseBody);
return true;
default:
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
return false;
}
}
case ExtendedCommand::GetDiskDetails:
case ExtendedCommand::DiskFormatProgress: {
std::vector<uint8_t> responseBody(
packet->data.begin() + sizeof(ExtendedResponseMessage::ResponseHeader),
packet->data.end()
);
auto response = std::make_shared<ExtendedResponseMessage>(resp.command);
response->data = std::move(responseBody);
result = response;
return true;
}
default: default:
// No defined handler, treat this as a RawMessage // No defined handler, treat this as a RawMessage
break; break;
@@ -475,7 +541,16 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
result = std::make_shared<DiskDataMessage>(std::move(packet->data)); result = std::make_shared<DiskDataMessage>(std::move(packet->data));
return true; return true;
} }
case Network::NetID::Data_To_Host: {
result = LogDataMessage::DecodeToMessage(packet->data);
if(!result) {
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
return false;
}
return true;
}
default: default:
break; break;
} }
break; break;
+7 -11
View File
@@ -38,18 +38,10 @@ bool Driver::waitForRx(std::function<bool()> predicate, std::chrono::millisecond
} }
bool Driver::readWait(std::vector<uint8_t>& bytes, std::chrono::milliseconds timeout, size_t limit) { bool Driver::readWait(std::vector<uint8_t>& bytes, std::chrono::milliseconds timeout, size_t limit) {
// A limit of zero indicates no limit // wait until we have enough data, or the timeout occurs
if(limit == 0)
limit = (size_t)-1;
if(limit > (readBuffer.size() + 4))
limit = (readBuffer.size() + 4);
// wait until we have enough data, or the timout occurs
waitForRx(limit, timeout); waitForRx(limit, timeout);
size_t actuallyRead = std::min(readBuffer.size(), limit); size_t actuallyRead = readBuffer.size();
bytes.resize(actuallyRead); bytes.resize(actuallyRead);
readBuffer.read(bytes.data(), 0, actuallyRead); readBuffer.read(bytes.data(), 0, actuallyRead);
@@ -79,8 +71,12 @@ bool Driver::write(const std::vector<uint8_t>& bytes) {
if(writeBlocks) { if(writeBlocks) {
if(writeQueueFull()) { if(writeQueueFull()) {
while(writeQueueAlmostFull()) // Wait until we have some decent amount of space while(writeQueueAlmostFull() && !isDisconnected() && !isClosing()) // Wait until we have some decent amount of space
std::this_thread::sleep_for(std::chrono::milliseconds(10)); std::this_thread::sleep_for(std::chrono::milliseconds(10));
if(isDisconnected() || isClosing()) {
return false;
}
} }
} else { } else {
if(writeQueueFull()) { if(writeQueueFull()) {
+31 -5
View File
@@ -13,6 +13,7 @@
#include "icsneo/communication/packet/a2bpacket.h" #include "icsneo/communication/packet/a2bpacket.h"
#include "icsneo/communication/packet/linpacket.h" #include "icsneo/communication/packet/linpacket.h"
#include "icsneo/communication/packet/mdiopacket.h" #include "icsneo/communication/packet/mdiopacket.h"
#include "icsneo/communication/packet/spipacket.h"
using namespace icsneo; using namespace icsneo;
@@ -31,19 +32,31 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
netid = uint16_t(frame->network.getNetID()); netid = uint16_t(frame->network.getNetID());
switch(frame->network.getType()) { switch(frame->network.getType()) {
case Network::Type::Ethernet: { case Network::Type::Ethernet:
case Network::Type::AutomotiveEthernet: {
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(message); auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(message);
if(!ethmsg) { if(!ethmsg) {
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error); report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
return false; // The message was not a properly formed EthernetMessage return false;
} }
shortFormat = false; // Ensure long-format RED header is added
netid = static_cast<uint16_t>(Network::NetID::ETHERNET_TX_WRAP);
buffer = &result; buffer = &result;
if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, report))
if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, report)) {
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
return false; return false;
}
if(result.empty()) {
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
return false;
}
break; break;
} // End of Network::Type::Ethernet }
case Network::Type::Internal:
case Network::Type::CAN: case Network::Type::CAN:
case Network::Type::SWCAN: case Network::Type::SWCAN:
case Network::Type::LSFTCAN: { case Network::Type::LSFTCAN: {
@@ -123,6 +136,17 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
} }
break; break;
} // End of Network::Type::MDIO } // End of Network::Type::MDIO
case Network::Type::SPI: {
auto msg = std::dynamic_pointer_cast<SPIMessage>(message);
if(!msg) {
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
return false; // The message was not a properly formed LiveDataMessage
}
if(!HardwareSPIPacket::EncodeFromMessage(*msg, result, report))
return false;
result = packetizer.packetWrap(result, false);
return true;
} // End of Network::Type::SPI
default: default:
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error); report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
return false; return false;
@@ -230,7 +254,6 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
(uint8_t)(netid >> 8) (uint8_t)(netid >> 8)
}); });
} }
result = packetizer.packetWrap(*buffer, shortFormat); result = packetizer.packetWrap(*buffer, shortFormat);
return true; return true;
} }
@@ -262,9 +285,12 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
case Command::RequestSerialNumber: case Command::RequestSerialNumber:
case Command::EnableNetworkCommunication: case Command::EnableNetworkCommunication:
case Command::EnableNetworkCommunicationEx: case Command::EnableNetworkCommunicationEx:
case Command::KeepAlive:
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;
+58
View File
@@ -1,4 +1,5 @@
#include "icsneo/communication/livedata.h" #include "icsneo/communication/livedata.h"
#include <cmath>
namespace icsneo { namespace icsneo {
namespace LiveDataUtil { namespace LiveDataUtil {
@@ -18,5 +19,62 @@ double liveDataValueToDouble(const LiveDataValue& val) {
return val.value * liveDataFixedPointToDouble; return val.value * liveDataFixedPointToDouble;
} }
std::optional<LiveDataValue> liveDataDoubleToValue(const double& dFloat) {
LiveDataValue value;
union {
struct
{
uint32_t ValueFractionPart;
int32_t ValueInt32;
} parts;
int64_t ValueLarge;
} CminiFixedPt;
constexpr double CM_FIXED_POINT_TO_DOUBLEVALUE = (1.0 / (double)(1ULL << 32)); // 2^-32
constexpr double CM_DOUBLEVALUE_TO_FIXED_POINT = ((double)(1ULL << 32)); // 2^32
// Use const for limits (C++98 compatible)
const double INT32_MAX_DOUBLE =
static_cast<double>(std::numeric_limits<int32_t>::max()) + (1.0 - std::numeric_limits<double>::epsilon());
const double INT32_MIN_DOUBLE = static_cast<double>(std::numeric_limits<int32_t>::min());
const double MIN_FIXED_POINT_DOUBLE = (double)(1ull * CM_FIXED_POINT_TO_DOUBLEVALUE);
// This needs to be assigned separately, otherwise, for dFloat >= 2^31,
// long double dBigFloat = dFloat * CM_DOUBLEVALUE_TO_FIXED_POINT overflows
// long long (value is >= 2^63) and so the assignment ValueLarge = dBigFloat is undefined
int32_t intPart; //creating temp variable due to static analysis warning about writing and reading to different union members
if(dFloat < 0.0)
intPart = (int32_t)std::floor(dFloat);
else
intPart = (int32_t)dFloat;
//using temp varialbes to avoid static analysis warning about read/write to different union members
double frac = dFloat - (double)(intPart);
uint32_t fracPart = (uint32_t)std::floor((frac * CM_DOUBLEVALUE_TO_FIXED_POINT) + 0.5);
//write temp vars back into the union
CminiFixedPt.parts.ValueInt32 = intPart;
CminiFixedPt.parts.ValueFractionPart = fracPart;
value.value = CminiFixedPt.ValueLarge;
if(dFloat == (double)0.0)
return value;
//check if double can be stored as 32.32
// 0x1 0000 0000 0000 0000 * CM_FIXED_POINT_TO_DOUBLEVALUE = 0x1 0000 0000
if(dFloat > INT32_MAX_DOUBLE || dFloat < INT32_MIN_DOUBLE) {
EventManager::GetInstance().add(APIEvent::Type::FixedPointOverflow, APIEvent::Severity::Error);
return std::nullopt;
}
// Use absolute value for minimum fixed point check
double absFloat = (dFloat < 0.0) ? -dFloat : dFloat;
if(absFloat < MIN_FIXED_POINT_DOUBLE) {
EventManager::GetInstance().add(APIEvent::Type::FixedPointPrecision, APIEvent::Severity::Error);
return std::nullopt;
}
return value;
}
} // namespace LiveDataUtil } // namespace LiveDataUtil
} // namespace icsneo } // namespace icsneo
+21
View File
@@ -0,0 +1,21 @@
#include "icsneo/communication/message/clientidmessage.h"
#include "icsneo/communication/icspb.h"
#include "icsneo/communication/command.h"
#include "icsneo/communication/message/extendedresponsemessage.h"
using namespace icsneo;
std::shared_ptr<ClientIdMessage> ClientIdMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
ClientIdMessage decoded;
commands::generic::v1::ClientId msg;
if(!protoapi::processResponse(bytestream.data(), bytestream.size(), msg)) {
return nullptr;
}
if(msg.has_client_id()) {
decoded.clientId.emplace(msg.client_id());
}
return std::make_shared<ClientIdMessage>(decoded);
}
@@ -0,0 +1,80 @@
#include "icsneo/communication/message/ethernetstatusmessage.h"
using namespace icsneo;
#pragma pack(push, 1)
enum LinkSpeed {
ethSpeed10,
ethSpeed100,
ethSpeed1000,
ethSpeedAutoNeg,
ethSpeed2500,
ethSpeed5000,
ethSpeed10000,
};
enum TLinkMode {
T_LINK_NONE,
T_LINK_MASTER,
T_LINK_SLAVE,
T_LINK_AUTO,
T_LINK_INVALID = 255,
};
enum AELinkMode {
AE_LINK_AUTO,
AE_LINK_MASTER,
AE_LINK_SLAVE,
AE_LINK_INVALID = 255,
};
struct Packet {
uint8_t state;
uint8_t speed;
uint8_t duplex;
uint16_t network;
uint8_t mode;
};
#pragma pack(pop)
std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
if(bytestream.size() < sizeof(Packet)) {
return nullptr;
}
Packet* packet = (Packet*)bytestream.data();
LinkSpeed speed;
switch(packet->speed) {
case ethSpeed10: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10; break;
case ethSpeed100: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed100; break;
case ethSpeed1000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed1000; break;
case ethSpeedAutoNeg: speed = EthernetStatusMessage::LinkSpeed::LinkSpeedAuto; break;
case ethSpeed2500: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed2500; break;
case ethSpeed5000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed5000; break;
case ethSpeed10000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10000; break;
default: return nullptr;
}
LinkMode mode;
switch(Network::GetTypeOfNetID((Network::NetID)packet->network, false)) {
case Network::Type::Ethernet:
switch(packet->mode) {
case T_LINK_NONE: mode = EthernetStatusMessage::LinkMode::LinkModeNone; break;
case T_LINK_MASTER: mode = EthernetStatusMessage::LinkMode::LinkModeMaster; break;
case T_LINK_SLAVE: mode = EthernetStatusMessage::LinkMode::LinkModeSlave; break;
case T_LINK_AUTO: mode = EthernetStatusMessage::LinkMode::LinkModeAuto; break;
case T_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
default: return nullptr;
}
break;
case Network::Type::AutomotiveEthernet:
switch(packet->mode) {
case AE_LINK_AUTO: mode = EthernetStatusMessage::LinkMode::LinkModeAuto; break;
case AE_LINK_MASTER: mode = EthernetStatusMessage::LinkMode::LinkModeMaster; break;
case AE_LINK_SLAVE: mode = EthernetStatusMessage::LinkMode::LinkModeSlave; break;
case AE_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
default: return nullptr;
}
break;
default: return nullptr;
}
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
}
+9 -9
View File
@@ -8,7 +8,7 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
msg->Clause45Enable = clause45; msg->Clause45Enable = clause45;
msg->Enabled = enabled; msg->Enabled = enabled;
msg->WriteEnable = writeEnable; msg->WriteEnable = writeEnable;
msg->version = 1u; msg->Version = 1u;
if( (FiveBits < phyAddrOrPort) || if( (FiveBits < phyAddrOrPort) ||
(clause45 && (FiveBits < pageOrDevice)) || (clause45 && (FiveBits < pageOrDevice)) ||
(!clause45 && (FiveBits < regAddr)) ) (!clause45 && (FiveBits < regAddr)) )
@@ -18,17 +18,17 @@ bool EthPhyMessage::appendPhyMessage(bool writeEnable, bool clause45, uint8_t ph
if(clause45) if(clause45)
{ {
msg->clause45.port = phyAddrOrPort; msg->Clause45.port = phyAddrOrPort;
msg->clause45.device = pageOrDevice; msg->Clause45.device = pageOrDevice;
msg->clause45.regAddr = regAddr; msg->Clause45.regAddr = regAddr;
msg->clause45.regVal = regVal; msg->Clause45.regVal = regVal;
} }
else else
{ {
msg->clause22.phyAddr = phyAddrOrPort; msg->Clause22.phyAddr = phyAddrOrPort;
msg->clause22.page = pageOrDevice; msg->Clause22.page = pageOrDevice;
msg->clause22.regAddr = regAddr; msg->Clause22.regAddr = regAddr;
msg->clause22.regVal = regVal; msg->Clause22.regVal = regVal;
} }
return appendPhyMessage(msg); return appendPhyMessage(msg);
} }
@@ -8,9 +8,8 @@ using namespace icsneo;
std::vector<uint8_t> FlexRayControlMessage::BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, const std::vector<uint8_t>& args) { std::vector<uint8_t> FlexRayControlMessage::BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, const std::vector<uint8_t>& args) {
std::vector<uint8_t> ret; std::vector<uint8_t> ret;
ret.reserve(args.size() + 4);
ret.push_back(controller); ret.push_back(controller);
const uint16_t size = uint16_t((std::min)(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode const uint16_t size = static_cast<uint16_t>(std::min(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode
ret.push_back(uint8_t(size)); ret.push_back(uint8_t(size));
ret.push_back(uint8_t(size >> 8)); ret.push_back(uint8_t(size >> 8));
ret.push_back(uint8_t(op)); ret.push_back(uint8_t(op));
+219
View File
@@ -0,0 +1,219 @@
#include <icsneo/communication/message/gptpstatusmessage.h>
#include <icsneo/communication/message/extendedresponsemessage.h>
#include <cstring>
namespace icsneo {
typedef double float64;
typedef int64_t time_interval;
typedef uint64_t _clock_identity;
#pragma pack(push, 1)
struct port_identity {
_clock_identity clock_identity;
uint16_t port_number;
};
struct _scaled_ns {
int16_t nanoseconds_msb;
int64_t nanoseconds_lsb;
int16_t fractional_nanoseconds;
};
struct _clock_quality {
uint8_t clock_class;
uint8_t clock_accuracy;
uint16_t offset_scaled_log_variance;
};
struct system_identity {
uint8_t priority_1;
struct _clock_quality clock_quality;
uint8_t priority_2;
_clock_identity clock_identity;
};
struct _timestamp {
uint16_t seconds_msb;
uint32_t seconds_lsb;
uint32_t nanoseconds;
};
struct priority_vector {
struct system_identity sysid;
uint16_t steps_removed;
struct port_identity portid;
uint16_t port_number;
};
// IEEE 802.1AS-2020 14.3
// This is a read-only data structure
struct _current_ds {
uint16_t steps_removed;
time_interval offset_from_master;
struct _scaled_ns last_gm_phase_change;
float64 last_gm_freq_change;
uint16_t gm_time_base_indicator;
uint32_t gm_change_count;
uint32_t time_of_last_gm_change_event;
uint32_t time_of_last_gm_phase_change_event;
uint32_t time_of_last_gm_freq_change_event;
};
// IEEE 802.1AS-2020 14.4
// This is a read-only data structure
struct _parent_ds {
struct port_identity parent_port_identity;
int32_t cumulative_rate_ratio;
_clock_identity grandmaster_identity;
uint8_t gm_clock_quality_clock_class;
uint8_t gm_clock_quality_clock_accuracy;
uint16_t gm_clock_quality_offset_scaled_log_variance;
uint8_t gm_priority1;
uint8_t gm_priority2;
};
struct _GPTPStatus
{
struct _timestamp current_time;
struct priority_vector gm_priority;
int64_t ms_offset_ns;
uint8_t is_sync;
uint8_t link_status;
int64_t link_delay_ns;
uint8_t selected_role;
uint8_t as_capable;
uint8_t is_syntonized;
struct _timestamp last_rx_sync_ts; // t2 in IEEE 1588-2019 Figure-16
struct _current_ds current_ds;
struct _parent_ds parent_ds;
};
#pragma pack(pop)
static void SetField(GPTPStatus::Timestamp& output, const _timestamp& input) {
output.seconds = ((uint64_t)(input.seconds_msb) << 32) | ((uint64_t)input.seconds_lsb);
output.nanoseconds = input.nanoseconds;
}
static void SetField(GPTPStatus::PortID& output, const port_identity& input) {
output.clockIdentity = input.clock_identity;
output.portNumber = input.port_number;
}
static void SetField(GPTPStatus::ClockQuality& output, const _clock_quality& input) {
output.clockClass = input.clock_class;
output.clockAccuracy = input.clock_accuracy;
output.offsetScaledLogVariance = input.offset_scaled_log_variance;
}
static void SetField(GPTPStatus::SystemID& output, const system_identity& input) {
output.priority1 = input.priority_1;
SetField(output.clockQuality, input.clock_quality);
output.priority2 = input.priority_2;
output.clockID = input.clock_identity;
}
static void SetField(GPTPStatus::ScaledNanoSeconds& output, const _scaled_ns& input) {
output.nanosecondsMSB = input.nanoseconds_msb;
output.nanosecondsLSB = input.nanoseconds_lsb;
output.fractionalNanoseconds = input.fractional_nanoseconds;
}
static void SetField(GPTPStatus::PriorityVector& output, const priority_vector& input) {
SetField(output.sysID, input.sysid);
output.stepsRemoved = input.steps_removed;
SetField(output.portID, input.portid);
output.portNumber = input.port_number;
}
static void SetField(GPTPStatus::CurrentDS& output, const _current_ds& input) {
output.stepsRemoved = input.steps_removed;
output.offsetFromMaster = input.offset_from_master;
SetField(output.lastgmPhaseChange, input.last_gm_phase_change);
output.lastgmFreqChange = input.last_gm_freq_change;
output.gmTimeBaseIndicator = input.gm_time_base_indicator;
output.gmChangeCount = input.gm_change_count;
output.timeOfLastgmChangeEvent = input.time_of_last_gm_change_event;
output.timeOfLastgmPhaseChangeEvent = input.time_of_last_gm_phase_change_event;
output.timeOfLastgmFreqChangeEvent = input.time_of_last_gm_freq_change_event;
}
static void SetField(GPTPStatus::ParentDS& output, const _parent_ds& input) {
SetField(output.parentPortIdentity, input.parent_port_identity);
output.cumulativeRateRatio = input.cumulative_rate_ratio;
output.grandmasterIdentity = input.grandmaster_identity;
output.gmClockQualityClockClass = input.gm_clock_quality_clock_class;
output.gmClockQualityClockAccuracy = input.gm_clock_quality_clock_accuracy;
output.gmClockQualityOffsetScaledLogVariance = input.gm_clock_quality_offset_scaled_log_variance;
output.gmPriority1 = input.gm_priority1;
output.gmPriority2 = input.gm_priority2;
}
[[maybe_unused]] static void SetField(uint8_t& output, const uint8_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(uint16_t& output, const uint16_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(uint32_t& output, const uint32_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(uint64_t& output, const uint64_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(int8_t& output, const int8_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(int16_t& output, const int16_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(int32_t& output, const int32_t& input) {
output = input;
}
[[maybe_unused]] static void SetField(int64_t& output, const int64_t& input) {
output = input;
}
std::shared_ptr<GPTPStatus> GPTPStatus::DecodeToMessage(std::vector<uint8_t>& bytes, const device_eventhandler_t&) {
// The following does not lead to overflow since we only call this function if it has at least ResponseHeader length bytes
std::shared_ptr<GPTPStatus> res = std::make_shared<GPTPStatus>();
auto* header = reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(bytes.data());
uint16_t length = header->length;
_GPTPStatus* input = reinterpret_cast<_GPTPStatus*>(bytes.data() + sizeof(ExtendedResponseMessage::ResponseHeader));
#define CheckLengthAndSet(output, input) if(length >= sizeof(decltype(input))) { \
SetField(output, input); \
length -= sizeof(decltype(input)); \
} else {\
memset(&output, 0, sizeof(decltype(output))); \
length = 0; \
res->shortFormat = true; \
}
CheckLengthAndSet(res->currentTime, input->current_time);
CheckLengthAndSet(res->gmPriority, input->gm_priority);
CheckLengthAndSet(res->msOffsetNs, input->ms_offset_ns);
CheckLengthAndSet(res->isSync, input->is_sync);
CheckLengthAndSet(res->linkStatus, input->link_status);
CheckLengthAndSet(res->linkDelayNS, input->link_delay_ns);
CheckLengthAndSet(res->selectedRole, input->selected_role);
CheckLengthAndSet(res->asCapable, input->as_capable);
CheckLengthAndSet(res->isSyntonized, input->is_syntonized);
CheckLengthAndSet(res->lastRXSyncTS, input->last_rx_sync_ts);
CheckLengthAndSet(res->currentDS, input->current_ds);
CheckLengthAndSet(res->parentDS, input->parent_ds);
return res;
}
}
+10
View File
@@ -12,4 +12,14 @@ void LiveDataCommandMessage::appendSignalArg(LiveDataValueType valueType) {
arg->valueType = valueType; arg->valueType = valueType;
} }
void LiveDataSetValueMessage::appendSetValue(LiveDataValueType valueType, const LiveDataValue& value) {
auto& arg = args.emplace_back(std::make_shared<LiveDataArgument>());
arg->objectType = LiveDataObjectType::MISC;
arg->objectIndex = 0u;
arg->signalIndex = 0u;
arg->valueType = valueType;
values.push_back(std::make_shared<LiveDataValue>(value));
}
} // namespace icsneo } // namespace icsneo
+12
View File
@@ -0,0 +1,12 @@
#include "icsneo/communication/message/logdatamessage.h"
#include <iostream>
using namespace icsneo;
std::shared_ptr<LogDataMessage> LogDataMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
if(bytestream.size() % 2 != 0)
return nullptr;
const auto* begin = (char16_t*)bytestream.data();
const auto* end = begin + (bytestream.size() / sizeof(char16_t));
return std::make_shared<LogDataMessage>(std::wstring(begin,end));
}
+16 -12
View File
@@ -1,7 +1,7 @@
#include "icsneo/communication/message/neomessage.h" #include "icsneo/communication/message/neomessage.h"
#include "icsneo/communication/message/canmessage.h" #include "icsneo/communication/message/canmessage.h"
#include "icsneo/communication/message/ethernetmessage.h" #include "icsneo/communication/message/ethernetmessage.h"
#include "icsneo/communication/message/canerrorcountmessage.h" #include "icsneo/communication/message/canerrormessage.h"
#include "icsneo/communication/message/linmessage.h" #include "icsneo/communication/message/linmessage.h"
using namespace icsneo; using namespace icsneo;
@@ -44,14 +44,15 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
can.status.canfdESI = canmsg->errorStateIndicator; can.status.canfdESI = canmsg->errorStateIndicator;
break; break;
} }
case Network::Type::Ethernet: { case Network::Type::Ethernet:
case Network::Type::AutomotiveEthernet: {
neomessage_eth_t& eth = *(neomessage_eth_t*)&neomsg; neomessage_eth_t& eth = *(neomessage_eth_t*)&neomsg;
auto ethmsg = std::static_pointer_cast<EthernetMessage>(message); auto ethmsg = std::static_pointer_cast<EthernetMessage>(message);
eth.preemptionFlags = ethmsg->preemptionFlags; eth.preemptionFlags = ethmsg->preemptionFlags;
eth.status.incompleteFrame = ethmsg->frameTooShort; eth.status.incompleteFrame = ethmsg->frameTooShort;
// TODO Fill in extra status bits // TODO Fill in extra status bits
//eth.status.xyz = ethmsg->preemptionEnabled; //eth.status.xyz = ethmsg->preemptionEnabled;
//eth.status.xyz = ethmsg->fcsAvailable; //eth.status.xyz = ethmsg->fcs;
//eth.status.xyz = ethmsg->noPadding; //eth.status.xyz = ethmsg->noPadding;
break; break;
} }
@@ -75,13 +76,15 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
lin.length = 1; lin.length = 1;
lin.linStatus = { lin.linStatus = {
linmsg->statusFlags.TxChecksumEnhanced, linmsg->statusFlags.TxChecksumEnhanced, // .txChecksumEnhanced
linmsg->statusFlags.TxCommander, linmsg->statusFlags.TxCommander, // .txCommander
linmsg->statusFlags.TxResponder, linmsg->statusFlags.TxResponder, // .txResponder
linmsg->statusFlags.UpdateResponderOnce, 0, // .txAborted
linmsg->statusFlags.HasUpdatedResponderOnce, linmsg->statusFlags.UpdateResponderOnce, // .updateResponderOnce
linmsg->statusFlags.BusRecovered, linmsg->statusFlags.HasUpdatedResponderOnce, // .hasUpdatedResponderOnce
linmsg->statusFlags.BreakOnly linmsg->statusFlags.BusRecovered, // .busRecovered
linmsg->statusFlags.BreakOnly // .breakOnly
}; };
lin.status.linJustBreakSync = linmsg->errFlags.ErrRxBreakSyncOnly; lin.status.linJustBreakSync = linmsg->errFlags.ErrRxBreakSyncOnly;
@@ -104,7 +107,7 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
} }
case Message::Type::CANErrorCount: { case Message::Type::CANErrorCount: {
neomessage_can_error_t& canerror = *(neomessage_can_error_t*)&neomsg; neomessage_can_error_t& canerror = *(neomessage_can_error_t*)&neomsg;
auto canerrormsg = std::static_pointer_cast<CANErrorCountMessage>(message); auto canerrormsg = std::static_pointer_cast<CANErrorMessage>(message);
canerror.transmitErrorCount = canerrormsg->transmitErrorCount; canerror.transmitErrorCount = canerrormsg->transmitErrorCount;
canerror.receiveErrorCount = canerrormsg->receiveErrorCount; canerror.receiveErrorCount = canerrormsg->receiveErrorCount;
canerror.status.canBusOff = canerrormsg->busOff; canerror.status.canBusOff = canerrormsg->busOff;
@@ -140,7 +143,8 @@ std::shared_ptr<Message> icsneo::CreateMessageFromNeoMessage(const neomessage_t*
canmsg->errorStateIndicator = can.status.canfdESI; canmsg->errorStateIndicator = can.status.canfdESI;
return canmsg; return canmsg;
} }
case Network::Type::Ethernet: { case Network::Type::Ethernet:
case Network::Type::AutomotiveEthernet: {
neomessage_eth_t& eth = *(neomessage_eth_t*)neomessage; neomessage_eth_t& eth = *(neomessage_eth_t*)neomessage;
auto ethmsg = std::make_shared<EthernetMessage>(); auto ethmsg = std::make_shared<EthernetMessage>();
ethmsg->network = network; ethmsg->network = network;
@@ -0,0 +1,89 @@
#include "icsneo/communication/message/networkmutexmessage.h"
#include "icsneo/communication/icspb.h"
#include "icsneo/communication/command.h"
#include "icsneo/communication/message/extendedresponsemessage.h"
using namespace icsneo;
std::shared_ptr<NetworkMutexMessage> NetworkMutexMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
NetworkMutexMessage decoded;
commands::network::v1::NetworkMutex msg;
if(!protoapi::processResponse(bytestream.data(), bytestream.size(), msg)) {
return nullptr;
}
if(msg.has_client_id()) {
decoded.owner_id.emplace(msg.client_id());
}
if(msg.has_type()) {
decoded.type.emplace(static_cast<NetworkMutexType>(msg.type()));
}
if(msg.has_priority()) {
decoded.priority.emplace(msg.priority());
}
if(msg.has_ttl()){
decoded.ttlMs.emplace(msg.ttl());
}
if(msg.has_event()){
decoded.event.emplace(static_cast<NetworkMutexEvent>(msg.event()));
}
for(int i = 0 ; i < msg.network_ids_size(); ++i){
decoded.networks.emplace(static_cast<Network::NetID>(msg.network_ids(i)));
}
return std::make_shared<NetworkMutexMessage>(decoded);
}
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForLock(uint32_t client_id, NetworkMutexType type, uint32_t priority, uint32_t ttlMs, const std::set<Network::NetID>& networks, const device_eventhandler_t& /* report */) {
commands::network::v1::NetworkMutex msg;
for(auto&& network_id : networks) {
msg.add_network_ids(static_cast<commands::network::v1::NetworkId>(network_id));
}
msg.set_client_id(client_id);
msg.set_priority(priority);
msg.set_ttl(ttlMs);
msg.set_type(static_cast<commands::network::v1::MutexType>(type));
return protoapi::getPayload(protoapi::Command::PUT, msg);
}
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForLockAll(uint32_t client_id, NetworkMutexType type, uint32_t priority, uint32_t ttlMs, const device_eventhandler_t& /* report */) {
commands::network::v1::NetworkMutex msg;
msg.set_client_id(client_id);
msg.set_priority(priority);
msg.set_ttl(ttlMs);
msg.set_type(static_cast<commands::network::v1::MutexType>(type));
msg.set_global(true);
return protoapi::getPayload(protoapi::Command::PUT, msg);
}
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForUnlock(uint32_t client_id, const std::set<Network::NetID>& networks, const device_eventhandler_t& /* report */) {
commands::network::v1::NetworkMutex msg;
msg.Clear();
for(auto&& network_id : networks)
{
msg.add_network_ids(static_cast<commands::network::v1::NetworkId>(network_id));
}
msg.set_client_id(client_id);
msg.set_release(true);
return protoapi::getPayload(protoapi::Command::PUT, msg);
}
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForUnlockAll(uint32_t client_id, const device_eventhandler_t& /* report */) {
commands::network::v1::NetworkMutex msg;
msg.Clear();
msg.set_client_id(client_id);
msg.set_release(true);
msg.set_global(true);
return protoapi::getPayload(protoapi::Command::PUT, msg);
}
std::vector<uint8_t> NetworkMutexMessage::EncodeArgumentsForStatus(Network::NetID network, const device_eventhandler_t& /* report */) {
commands::network::v1::NetworkMutex msg;
msg.add_network_ids(static_cast<commands::network::v1::NetworkId>(network));
return protoapi::getPayload(protoapi::Command::GET, msg);
}
+163
View File
@@ -0,0 +1,163 @@
#include "icsneo/communication/message/transmitmessage.h"
// packet defs
#include "icsneo/communication/packet/ethernetpacket.h"
#include "icsneo/communication/packet/canpacket.h"
#include "icsneo/communication/packet/linpacket.h"
using namespace icsneo;
// copied.. TODO
static std::optional<uint8_t> CAN_LengthToDLC(size_t dataLength, bool fd) {
if(dataLength <= 8)
return uint8_t(dataLength);
if(fd) {
if(dataLength <= 12)
return uint8_t(0x9);
if(dataLength <= 16)
return uint8_t(0xA);
if(dataLength <= 20)
return uint8_t(0xB);
if(dataLength <= 24)
return uint8_t(0xC);
if(dataLength <= 32)
return uint8_t(0xD);
if(dataLength <= 48)
return uint8_t(0xE);
if(dataLength <= 64)
return uint8_t(0xF);
}
return std::nullopt;
}
static std::vector<uint8_t> EncodeFromMessageEthernet(std::shared_ptr<Frame> frame, const device_eventhandler_t& report) {
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(frame);
if(!ethmsg) {
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
return {};
}
std::vector<uint8_t> encoded;
size_t messageLen = ethmsg->data.size();
encoded.resize(sizeof(TransmitMessage) + messageLen);
TransmitMessage* const msg = (TransmitMessage*)encoded.data();
HardwareEthernetPacket* const ethpacket = (HardwareEthernetPacket*)(msg->commonHeader);
uint8_t* const payload = encoded.data() + sizeof(TransmitMessage);
ethpacket->header.ENABLE_PADDING = ethmsg->noPadding ? 0 : 1;
ethpacket->header.FCS_OVERRIDE = ethmsg->fcs ? 1 : 0;
ethpacket->eid.txlen = static_cast<uint16_t>(messageLen);
ethpacket->Length = static_cast<uint16_t>(messageLen);
ethpacket->stats = ethmsg->description;
ethpacket->NetworkID = static_cast<uint16_t>(ethmsg->network.getNetID());
std::copy(ethmsg->data.begin(), ethmsg->data.end(), payload);
return encoded;
}
static std::vector<uint8_t> EncodeFromMessageCAN(std::shared_ptr<Frame> frame, const device_eventhandler_t& report) {
auto canmsg = std::dynamic_pointer_cast<CANMessage>(frame);
if(!canmsg) {
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
return {};
}
if(canmsg->isCANFD && canmsg->isRemote) {
report(APIEvent::Type::RTRNotSupported, APIEvent::Severity::Error);
return {}; // RTR frames can not be used with CAN FD
}
std::vector<uint8_t> encoded;
size_t messageLen = canmsg->data.size();
size_t extraLen = 0;
if(messageLen > 8) {
extraLen = messageLen - 8;
}
encoded.resize(sizeof(TransmitMessage) + extraLen);
TransmitMessage* const msg = (TransmitMessage*)encoded.data();
HardwareCANPacket* const canpacket = (HardwareCANPacket*)(msg->commonHeader);
uint8_t* const extra_payload = encoded.data() + sizeof(TransmitMessage);
const size_t dataSize = canmsg->data.size();
std::optional<uint8_t> dlc = CAN_LengthToDLC(dataSize, canmsg->isCANFD);
if(!dlc.has_value()) {
report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error);
return {}; // Too much data for the protocol
}
// arb id
if(canmsg->isExtended) {
canpacket->header.IDE = 1;
canpacket->header.SID = (canmsg->arbid >> 18) & 0x7FF;
canpacket->eid.EID = (canmsg->arbid >> 6) & 0xfff;
canpacket->dlc.EID2 = canmsg->arbid & 0x3f;
} else {
canpacket->header.IDE = 0;
canpacket->header.SID = canmsg->arbid & 0x7FF;
}
// DLC
canpacket->dlc.DLC = dlc.value();
// FDF/BRS or remote frames
if(canmsg->isCANFD) {
canpacket->header.EDL = 1;
canpacket->header.BRS = canmsg->baudrateSwitch ? 1 : 0;
canpacket->header.ESI = canmsg->errorStateIndicator ? 1 : 0;
canpacket->dlc.RTR = 0;
canpacket->timestamp.IsExtended = 1;
} else {
canpacket->header.EDL = 0;
canpacket->header.BRS = 0;
canpacket->header.ESI = 0;
canpacket->dlc.RTR = canmsg->isRemote ? 1 : 0;
}
// network
canpacket->NetworkID = static_cast<uint16_t>(canmsg->network.getNetID());
canpacket->Length = static_cast<uint16_t>(extraLen);
// description id
canpacket->stats = canmsg->description;
// first 8 bytes
std::copy(canmsg->data.begin(), canmsg->data.begin() + (messageLen > 8 ? 8 : messageLen), canpacket->data);
// extra bytes
if(extraLen > 0) {
// copy extra data after the can packet
std::copy(canmsg->data.begin() + 8, canmsg->data.end(), extra_payload);
}
return encoded;
}
static std::vector<uint8_t> EncodeFromMessageLIN(std::shared_ptr<Frame> /* frame */, const device_eventhandler_t& report) {
// TODO
report(APIEvent::Type::UnsupportedTXNetwork, APIEvent::Severity::Error);
return {};
}
std::vector<uint8_t> TransmitMessage::EncodeFromMessage(std::shared_ptr<Frame> frame, uint32_t client_id, const device_eventhandler_t& report) {
std::vector<uint8_t> result;
switch(frame->network.getType()) {
case Network::Type::Ethernet:
case Network::Type::AutomotiveEthernet:
result = EncodeFromMessageEthernet(frame, report);
break;
case Network::Type::Internal:
case Network::Type::CAN:
result = EncodeFromMessageCAN(frame, report);
break;
case Network::Type::LIN:
result = EncodeFromMessageLIN(frame, report);
break;
default:
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
return result;
}
// common fields
TransmitMessage* const msg = (TransmitMessage*)result.data();
msg->options.clientId = client_id;
msg->options.networkId = static_cast<uint32_t>(frame->network.getNetID());
msg->options.reserved[0] = 0;
msg->options.reserved[1] = 0;
msg->options.reserved[2] = 0;
return result;
}
+22 -13
View File
@@ -9,7 +9,7 @@ using namespace icsneo;
MultiChannelCommunication::MultiChannelCommunication(device_eventhandler_t err, std::unique_ptr<Driver> com, MultiChannelCommunication::MultiChannelCommunication(device_eventhandler_t err, std::unique_ptr<Driver> com,
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer, std::unique_ptr<Encoder> e, std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer, std::unique_ptr<Encoder> e,
std::unique_ptr<Decoder> md, size_t vnetCount) : std::unique_ptr<Decoder> md, size_t vnetCount) :
Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)), numVnets(vnetCount) { Communication(err, std::move(com), makeConfiguredPacketizer, std::move(e), std::move(md)), numVnets(vnetCount), packetRB(2048) {
vnetThreads.resize(numVnets); vnetThreads.resize(numVnets);
vnetQueues.resize(numVnets); vnetQueues.resize(numVnets);
} }
@@ -24,6 +24,7 @@ void MultiChannelCommunication::spawnThreads() {
void MultiChannelCommunication::joinThreads() { void MultiChannelCommunication::joinThreads() {
closing = true; closing = true;
ringBufCV.notify_all();
if(hidReadThread.joinable()) if(hidReadThread.joinable())
hidReadThread.join(); hidReadThread.join();
for(auto& thread : vnetThreads) { for(auto& thread : vnetThreads) {
@@ -148,9 +149,13 @@ void MultiChannelCommunication::hidReadTask() {
break; break;
} }
if(!currentQueue->enqueue(std::move(payloadBytes)) && gotPacket) {
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error)); std::unique_lock lk(ringBufMutex);
payloadBytes.clear(); if(!packetRB.write(std::move(payloadBytes)) && gotPacket)
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error));
payloadBytes.clear();
}
ringBufCV.notify_all();
gotPacket = true; gotPacket = true;
state = PreprocessState::SearchForCommand; state = PreprocessState::SearchForCommand;
break; break;
@@ -160,7 +165,6 @@ void MultiChannelCommunication::hidReadTask() {
} }
void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) { void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
moodycamel::BlockingReaderWriterQueue< std::vector<uint8_t> >& queue = vnetQueues[vnetIndex];
std::vector<uint8_t> payloadBytes; std::vector<uint8_t> payloadBytes;
std::unique_ptr<Packetizer> packetizerLifetime; std::unique_ptr<Packetizer> packetizerLifetime;
Packetizer* vnetPacketizer; Packetizer* vnetPacketizer;
@@ -174,14 +178,19 @@ void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) {
EventManager::GetInstance().downgradeErrorsOnCurrentThread(); EventManager::GetInstance().downgradeErrorsOnCurrentThread();
while(!closing) { while(!closing) {
if(queue.wait_dequeue_timed(payloadBytes, std::chrono::milliseconds(250))) { std::unique_lock lk(ringBufMutex);
if(closing) ringBufCV.wait(lk);
break; if(closing) {
break;
auto& ringBuffer = driver->getReadBuffer();
ringBuffer.write(payloadBytes);
handleInput(*vnetPacketizer);
} }
if(vnetPacketizer->input(packetRB)) {
for(const auto& packet : vnetPacketizer->output()) {
std::shared_ptr<Message> msg;
if(!decoder->decode(msg, packet))
continue;
dispatchMessage(msg);
}
}
} }
} }
+12 -10
View File
@@ -1,5 +1,5 @@
#include "icsneo/communication/packet/canpacket.h" #include "icsneo/communication/packet/canpacket.h"
#include "icsneo/communication/message/canerrorcountmessage.h" #include "icsneo/communication/message/canerrormessage.h"
using namespace icsneo; using namespace icsneo;
@@ -53,16 +53,18 @@ static std::optional<uint8_t> CAN_LengthToDLC(size_t dataLength, bool fd)
return std::nullopt; return std::nullopt;
} }
std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) { std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
const HardwareCANPacket* data = (const HardwareCANPacket*)bytestream.data(); const HardwareCANPacket* data = (const HardwareCANPacket*)bytestream.data();
const HardwareCANErrorPacket* errPacket = (const HardwareCANErrorPacket*)bytestream.data();
if(data->dlc.RB1) { // Change counts reporting if(errPacket->ERROR_INDICATOR) {
auto msg = std::make_shared<CANErrorMessage>();
const bool busOff = data->data[0] & 0b00100000; msg->receiveErrorCount = errPacket->REC;
msg->transmitErrorCount = errPacket->TEC;
auto msg = std::make_shared<CANErrorCountMessage>(data->data[2], data->data[1], busOff); msg->errorWarn = HardwareCANErrorPacket::GetErrorWarn(errPacket->flags);
msg->errorPassive = HardwareCANErrorPacket::GetErrorPassive(errPacket->flags);
msg->busOff = HardwareCANErrorPacket::GetBusOff(errPacket->flags);
msg->errorCode = (CANErrorCode)errPacket->error_code;
msg->dataErrorCode = (CANErrorCode)errPacket->brs_data_error_code;
// This timestamp is raw off the device (in timestampResolution increments) // This timestamp is raw off the device (in timestampResolution increments)
// Decoder will fix as it has information about the timestampResolution increments // Decoder will fix as it has information about the timestampResolution increments
msg->timestamp = data->timestamp.TS; msg->timestamp = data->timestamp.TS;
@@ -112,7 +114,7 @@ std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<ui
msg->data.insert(msg->data.end(), data->data, data->data + (length > 8 ? 8 : length)); msg->data.insert(msg->data.end(), data->data, data->data + (length > 8 ? 8 : length));
if(length > 8) { // If there are more than 8 bytes, they come at the end of the message if(length > 8) { // If there are more than 8 bytes, they come at the end of the message
// Messages with extra data are formatted as message, then uint16_t netid, then uint16_t length, then extra data // Messages with extra data are formatted as message, then uint16_t netid, then uint16_t length, then extra data
const auto extraDataStart = bytestream.begin() + sizeof(HardwareCANPacket) + 2 + 2; const auto extraDataStart = bytestream.begin() + sizeof(HardwareCANPacket);
msg->data.insert(msg->data.end(), extraDataStart, extraDataStart + (length - 8)); msg->data.insert(msg->data.end(), extraDataStart, extraDataStart + (length - 8));
} }
} }
@@ -31,7 +31,7 @@ std::shared_ptr<ComponentVersionsMessage> ComponentVersionPacket::DecodeToMessag
// Get a reference to the payload to fully validate the length // Get a reference to the payload to fully validate the length
const auto& response = *reinterpret_cast<const ComponentVersionsResponse*>(bytes.data()); const auto& response = *reinterpret_cast<const ComponentVersionsResponse*>(bytes.data());
// Expected size is the header, numVersions field, and numVersions ComponentVersion objects. // Expected size is the header, numVersions field, and numVersions ComponentVersion objects.
auto expectedSize = sizeof(ExtendedResponseMessage::ResponseHeader) + 2 + (response.numVersions * sizeof(ComponentVersion)); auto expectedSize = sizeof(ExtendedResponseMessage::ResponseHeader) + 2 + (response.numVersions * sizeof(PackedComponentVersion));
// If the response is malformed (too small), return an empty message. // If the response is malformed (too small), return an empty message.
if(bytes.size() < expectedSize) { if(bytes.size() < expectedSize) {
return msg; // Empty return msg; // Empty
@@ -39,7 +39,14 @@ std::shared_ptr<ComponentVersionsMessage> ComponentVersionPacket::DecodeToMessag
// Unpack into the portable class // Unpack into the portable class
for(unsigned int i = 0; i < response.numVersions; ++i) { for(unsigned int i = 0; i < response.numVersions; ++i) {
const auto& packedVersion = response.versions[i]; const auto& packedVersion = response.versions[i];
msg->versions.emplace_back(packedVersion.valid, packedVersion.componentInfo, packedVersion.identifier, packedVersion.dotVersion, packedVersion.commitHash); msg->versions.emplace_back(
packedVersion.valid,
packedVersion.componentInfo,
packedVersion.identifier,
packedVersion.dotVersion,
packedVersion.commitHash,
packedVersion.expansionSlot
);
} }
return msg; return msg;
} }
+98 -50
View File
@@ -1,98 +1,146 @@
#include "icsneo/communication/packet/ethernetpacket.h" #include "icsneo/communication/packet/ethernetpacket.h"
#include <cstring> // memcpy #include <algorithm>
#include <iostream> #include <iostream>
using namespace icsneo; using namespace icsneo;
std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) { std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
const HardwareEthernetPacket* packet = (const HardwareEthernetPacket*)((const void*)bytestream.data()); const HardwareEthernetPacket* packet = (const HardwareEthernetPacket*)((const void*)bytestream.data());
const uint16_t* rawWords = (const uint16_t*)bytestream.data(); const uint16_t* rawWords = (const uint16_t*)bytestream.data();
// Make sure we have enough to read the packet length first // Make sure we have enough to read the packet length first
if(bytestream.size() < sizeof(HardwareEthernetPacket)) if(bytestream.size() < sizeof(HardwareEthernetPacket))
return nullptr; return nullptr;
const size_t fcsSize = packet->header.FCS_AVAIL ? 4 : 0;
// packet->Length will also encompass the two uint16_t's at the end of the struct, make sure that at least they are here // Ensure Length is sufficient for FCS extraction to avoid invalid iterator arithmetic
if(packet->Length < 4) if(packet->Length < fcsSize)
return nullptr; return nullptr;
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + packet->Length;
const size_t ethernetFrameSize = packet->Length - (sizeof(uint16_t) * 2);
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + ethernetFrameSize;
const size_t bytestreamActualSize = bytestream.size(); const size_t bytestreamActualSize = bytestream.size();
if(bytestreamActualSize < bytestreamExpectedSize) if(bytestreamActualSize < bytestreamExpectedSize)
return nullptr; return nullptr;
// Check for oversized packets, noting that some devices will send an extra byte to have an even number of bytes
if(bytestreamActualSize > bytestreamExpectedSize + 1)
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
auto messagePtr = std::make_shared<EthernetMessage>(); auto messagePtr = std::make_shared<EthernetMessage>();
EthernetMessage& message = *messagePtr; EthernetMessage& message = *messagePtr;
// Standard Ethernet fields
message.transmitted = packet->eid.TXMSG; message.transmitted = packet->eid.TXMSG;
if(message.transmitted) if(message.transmitted)
message.description = packet->stats; message.description = packet->stats;
message.preemptionEnabled = packet->header.PREEMPTION_ENABLED; message.preemptionEnabled = packet->header.PREEMPTION_ENABLED;
if(message.preemptionEnabled) if(message.preemptionEnabled)
message.preemptionFlags = (uint8_t)((rawWords[0] & 0x03F8) >> 4); message.preemptionFlags = (uint8_t)((rawWords[0] & 0x03F8) >> 4);
message.fcsAvailable = packet->header.FCS_AVAIL;
message.frameTooShort = packet->header.RUNT_FRAME; message.frameTooShort = packet->header.RUNT_FRAME;
message.noPadding = !packet->header.ENABLE_PADDING;
message.fcsVerified = packet->header.FCS_VERIFIED;
message.txAborted = packet->eid.TXAborted;
message.crcError = packet->header.CRC_ERROR;
if(message.frameTooShort) if(message.frameTooShort)
message.error = true; message.error = true;
// This timestamp is raw off the device (in timestampResolution increments) // This timestamp is raw off the device (in timestampResolution increments)
// Decoder will fix as it has information about the timestampResolution increments // Decoder will fix as it has information about the timestampResolution increments
message.timestamp = packet->timestamp.TS; message.timestamp = packet->timestamp.TS;
// Network ID is also not set, this will be fixed in the Decoder as well // Check if this is a T1S packet and populate T1S-specific fields
message.isT1S = packet->header.T1S_ETHERNET;
if(message.isT1S) {
message.isT1SSymbol = packet->eid.T1S_SYMBOL;
message.isT1SBurst = packet->eid.T1S_BURST;
message.txCollision = packet->t1s_status.TXCollision;
message.isT1SWake = packet->t1s_status.T1SWake;
message.t1sNodeId = packet->t1s_node.T1S_NODE_ID;
message.t1sBurstCount = packet->t1s_node.T1S_BURST_COUNT;
}
const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + (sizeof(HardwareEthernetPacket) - (sizeof(uint16_t) * 2)); const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + sizeof(HardwareEthernetPacket);
const std::vector<uint8_t>::const_iterator dataend = databegin + ethernetFrameSize; const std::vector<uint8_t>::const_iterator dataend = databegin + packet->Length - fcsSize;
message.data.insert(message.data.begin(), databegin, dataend); message.data.insert(message.data.begin(), databegin, dataend);
if(fcsSize) {
uint32_t& fcs = message.fcs.emplace();
std::copy(dataend, dataend + fcsSize, (uint8_t*)&fcs);
}
return messagePtr; return messagePtr;
} }
bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t&) { bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t&) {
const size_t unpaddedSize = message.data.size(); const size_t unpaddedSize = message.data.size();
size_t paddedSize = unpaddedSize; if(unpaddedSize == 0)
uint16_t description = message.description; return false;
if(!message.noPadding && unpaddedSize < 60)
paddedSize = 60; // Pad out short messages
size_t sizeWithHeader = paddedSize + 4; // DescriptionID and Padded Count
// Description ID Most Significant bit is used to identify preemption frames // Description ID Most Significant bit is used to identify preemption frames
uint16_t description = message.description;
if(description & 0x8000) if(description & 0x8000)
return false; return false;
if(message.preemptionEnabled) { const bool preempt = message.preemptionEnabled;
sizeWithHeader++; // Make space for the preemption flags // full header including parent
const size_t headerByteCount = preempt ? 15 : 14;
// local header for netID, description, and flags
const size_t localHeader = preempt ? 10 : 9;
// allocate space for fcs override
const size_t fcsSize = message.fcs ? 4 : 0;
if(preempt)
description |= 0x8000; description |= 0x8000;
size_t paddedSize = unpaddedSize;
if(!message.noPadding && unpaddedSize < 60)
paddedSize = 60;
// size of full payload including optional fcs
size_t payloadSize = paddedSize + fcsSize;
// totalBufferSize is local header + ethernet payload and option fcs
const size_t totalBufferSize = localHeader + paddedSize + fcsSize;
bytestream.clear();
bytestream.reserve(totalBufferSize);
// Header size field (little endian)
bytestream.push_back(static_cast<uint8_t>(payloadSize & 0xFF));
bytestream.push_back(static_cast<uint8_t>((payloadSize >> 8) & 0xFF));
// Description (big endian)
bytestream.push_back(static_cast<uint8_t>(description >> 8));
bytestream.push_back(static_cast<uint8_t>(description));
bytestream.push_back(0x00);
bytestream.push_back(static_cast<uint8_t>(headerByteCount));
// Network ID (little endian)
uint16_t realID = static_cast<uint16_t>(message.network.getNetID());
bytestream.push_back(static_cast<uint8_t>(realID & 0xFF));
bytestream.push_back(static_cast<uint8_t>((realID >> 8) & 0xFF));
// Flags
constexpr uint8_t FLAG_PADDING = 0x01;
constexpr uint8_t FLAG_FCS = 0x04;
constexpr uint8_t FLAG_PREEMPTION = 0x08;
uint8_t flags = 0x00;
if(!message.noPadding) flags |= FLAG_PADDING;
if(message.fcs) flags |= FLAG_FCS;
if(message.preemptionEnabled) flags |= FLAG_PREEMPTION;
bytestream.push_back(flags);
if(preempt)
bytestream.push_back(static_cast<uint8_t>(message.preemptionFlags));
bytestream.insert(bytestream.end(), message.data.begin(), message.data.end());
// Only zero-fill when we want padding
if(!message.noPadding && unpaddedSize < 60) {
size_t paddingNeeded = 60 - unpaddedSize;
bytestream.insert(bytestream.end(), paddingNeeded, 0); // Zero-fill for padding
} }
bytestream.reserve(sizeWithHeader + 8); // Also reserve space for the bytes we'll use later on if(message.fcs) {
bytestream.resize(sizeWithHeader); uint32_t fcs = message.fcs.value();
size_t index = 0; const uint8_t* fcsBytes = reinterpret_cast<const uint8_t*>(&fcs);
bytestream.insert(bytestream.end(), fcsBytes, fcsBytes + sizeof(fcs));
// Padded size, little endian }
bytestream[index++] = uint8_t(paddedSize);
bytestream[index++] = uint8_t(paddedSize >> 8);
// Description ID, big endian
bytestream[index++] = uint8_t(description >> 8);
bytestream[index++] = uint8_t(description);
// The header is one byte larger if preemption is enabled, shifting the data
if(message.preemptionEnabled)
bytestream[index++] = message.preemptionFlags;
// We only copy in the unpadded size, the rest will be 0
memcpy(bytestream.data() + index, message.data.data(), unpaddedSize);
return true; return true;
} }
+18 -16
View File
@@ -34,11 +34,12 @@ std::shared_ptr<EthPhyMessage> HardwareEthernetPhyRegisterPacket::DecodeToMessag
phyMessage->Enabled = (pEntry->Enabled != 0u); phyMessage->Enabled = (pEntry->Enabled != 0u);
phyMessage->WriteEnable = (pEntry->WriteEnable != 0u); phyMessage->WriteEnable = (pEntry->WriteEnable != 0u);
phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u); phyMessage->Clause45Enable = (pEntry->Clause45Enable != 0u);
phyMessage->version = static_cast<uint8_t>(pEntry->version); phyMessage->BusIndex = static_cast<uint8_t>(pEntry->BusIndex);
phyMessage->Version = static_cast<uint8_t>(pEntry->version);
if(phyMessage->Clause45Enable) if(phyMessage->Clause45Enable)
phyMessage->clause45 = pEntry->clause45; phyMessage->Clause45 = pEntry->clause45;
else else
phyMessage->clause22 = pEntry->clause22; phyMessage->Clause22 = pEntry->clause22;
msg->messages.push_back(phyMessage); msg->messages.push_back(phyMessage);
} }
} }
@@ -69,34 +70,35 @@ bool HardwareEthernetPhyRegisterPacket::EncodeFromMessage(const EthPhyMessage& m
PhyRegisterPacket_t tempPacket; PhyRegisterPacket_t tempPacket;
tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u; tempPacket.Enabled = phyMessage->Enabled ? 0x1u : 0x0u;
tempPacket.WriteEnable = phyMessage->WriteEnable ? 0x1u : 0x0u; tempPacket.WriteEnable = phyMessage->WriteEnable ? 0x1u : 0x0u;
tempPacket.version = (phyMessage->version & 0xF); tempPacket.BusIndex = (phyMessage->BusIndex & 0xF);
tempPacket.version = (phyMessage->Version & 0xF);
if(phyMessage->Clause45Enable) if(phyMessage->Clause45Enable)
{ {
if( (FiveBits < phyMessage->clause45.port) || if( (FiveBits < phyMessage->Clause45.port) ||
(FiveBits < phyMessage->clause45.device) ) (FiveBits < phyMessage->Clause45.device) )
{ {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false; return false;
} }
tempPacket.Clause45Enable = 0x1u; tempPacket.Clause45Enable = 0x1u;
tempPacket.clause45.port = phyMessage->clause45.port; tempPacket.clause45.port = phyMessage->Clause45.port;
tempPacket.clause45.device = phyMessage->clause45.device; tempPacket.clause45.device = phyMessage->Clause45.device;
tempPacket.clause45.regAddr = phyMessage->clause45.regAddr; tempPacket.clause45.regAddr = phyMessage->Clause45.regAddr;
tempPacket.clause45.regVal = phyMessage->clause45.regVal; tempPacket.clause45.regVal = phyMessage->Clause45.regVal;
} }
else else
{ {
if( (FiveBits < phyMessage->clause22.phyAddr) || if( (FiveBits < phyMessage->Clause22.phyAddr) ||
(FiveBits < phyMessage->clause22.regAddr) ) (FiveBits < phyMessage->Clause22.regAddr) )
{ {
report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error); report(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
return false; return false;
} }
tempPacket.Clause45Enable = 0x0u; tempPacket.Clause45Enable = 0x0u;
tempPacket.clause22.phyAddr = phyMessage->clause22.phyAddr; tempPacket.clause22.phyAddr = phyMessage->Clause22.phyAddr;
tempPacket.clause22.page = phyMessage->clause22.page; tempPacket.clause22.page = phyMessage->Clause22.page;
tempPacket.clause22.regAddr = phyMessage->clause22.regAddr; tempPacket.clause22.regAddr = phyMessage->Clause22.regAddr;
tempPacket.clause22.regVal = phyMessage->clause22.regVal; tempPacket.clause22.regVal = phyMessage->Clause22.regVal;
} }
uint8_t* pktPtr = reinterpret_cast<uint8_t*>(&tempPacket); uint8_t* pktPtr = reinterpret_cast<uint8_t*>(&tempPacket);
bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t)); bytestream.insert(bytestream.end(), pktPtr, pktPtr + sizeof(PhyRegisterPacket_t));
+1 -1
View File
@@ -49,7 +49,7 @@ namespace icsneo
report(APIEvent::Type::I2CMessageExceedsMaxLength, APIEvent::Severity::Error); report(APIEvent::Type::I2CMessageExceedsMaxLength, APIEvent::Severity::Error);
return false; return false;
} }
if(message.controlBytes.empty() || message.dataBytes.empty()) if(message.controlBytes.empty() && message.dataBytes.empty())
{ {
//You'll need to provide a target R/W register in controlBytes //You'll need to provide a target R/W register in controlBytes
//alternatively, you're expecting to read without providing a dataBytes payload //alternatively, you're expecting to read without providing a dataBytes payload
+2 -3
View File
@@ -9,7 +9,7 @@ std::shared_ptr<Message> HardwareLINPacket::DecodeToMessage(const std::vector<ui
size_t numDataBytes = packet->CoreMiniBitsLIN.len; size_t numDataBytes = packet->CoreMiniBitsLIN.len;
size_t numHeaderBytes = sizeof(HardwareLINPacket::CoreMiniBitsLIN); size_t numHeaderBytes = sizeof(HardwareLINPacket::CoreMiniBitsLIN);
if( (sizeof(HardwareLINPacket) != bytestream.size()) || if( (sizeof(HardwareLINPacket) > bytestream.size()) ||
((numDataBytes + numHeaderBytes) > bytestream.size()) ) ((numDataBytes + numHeaderBytes) > bytestream.size()) )
return nullptr; return nullptr;
@@ -17,7 +17,6 @@ std::shared_ptr<Message> HardwareLINPacket::DecodeToMessage(const std::vector<ui
--numDataBytes; //If data is present, there will be a checksum included --numDataBytes; //If data is present, there will be a checksum included
auto msg = std::make_shared<LINMessage>(static_cast<uint8_t>(packet->CoreMiniBitsLIN.ID)); auto msg = std::make_shared<LINMessage>(static_cast<uint8_t>(packet->CoreMiniBitsLIN.ID));
msg->network = Network::GetNetIDFromCoreMiniNetwork(static_cast<Network::CoreMini>(packet->networkID));
msg->isEnhancedChecksum = static_cast<bool>(packet->CoreMiniBitsLIN.TxChkSumEnhanced); msg->isEnhancedChecksum = static_cast<bool>(packet->CoreMiniBitsLIN.TxChkSumEnhanced);
/* Minimum one responder byte and one checksum byte. */ /* Minimum one responder byte and one checksum byte. */
@@ -31,7 +30,7 @@ std::shared_ptr<Message> HardwareLINPacket::DecodeToMessage(const std::vector<ui
auto isChecksumInvalid = [&]() -> bool { auto isChecksumInvalid = [&]() -> bool {
/* messages with no data have no checksum (e.g. header only) */ /* messages with no data have no checksum (e.g. header only) */
if(!msg->data.size()) if(!msg->data.size())
return true; return false;
uint8_t checkSum = (8 > numDataBytes) ? *(dataStart + numDataBytes) : packet->CoreMiniBitsLIN.LINByte9; uint8_t checkSum = (8 > numDataBytes) ? *(dataStart + numDataBytes) : packet->CoreMiniBitsLIN.LINByte9;
LINMessage::calcChecksum(*msg); LINMessage::calcChecksum(*msg);
+27
View File
@@ -99,6 +99,33 @@ bool HardwareLiveDataPacket::EncodeFromMessage(LiveDataMessage& message, std::ve
clearMsg->cmd = static_cast<uint32_t>(message.cmd); clearMsg->cmd = static_cast<uint32_t>(message.cmd);
break; break;
} }
case LiveDataCommand::SET_VALUE: {
auto setValMsg = reinterpret_cast<LiveDataSetValueMessage*>(&message);
const auto numArgs = setValMsg->args.size();
if(numArgs) {
payloadSize = static_cast<uint16_t>(sizeof(LiveDataSetValue) + (sizeof(LiveDataSetValueEntry) * (numArgs-1)));
bytestream.resize((payloadSize + sizeof(ExtendedCommandHeader)),0);
LiveDataSetValue* out = reinterpret_cast<LiveDataSetValue*>(bytestream.data() + sizeof(ExtendedCommandHeader));
out->version = icsneo::LiveDataUtil::LiveDataVersion;
out->cmd = static_cast<uint32_t>(setValMsg->cmd);
if(!setValMsg->handle)
setValMsg->handle = LiveDataUtil::getNewHandle();
out->handle = setValMsg->handle;
out->numSetValues = (uint32_t)numArgs;
for(size_t i = 0; i < numArgs; ++i) {
out->values[i].arg.objectType = setValMsg->args[i]->objectType;
out->values[i].arg.objectIndex = setValMsg->args[i]->objectIndex;
out->values[i].arg.signalIndex = setValMsg->args[i]->signalIndex;
out->values[i].arg.valueType = setValMsg->args[i]->valueType;
out->values[i].value.value = setValMsg->values[i]->value;
out->values[i].value.header.length = sizeof(LiveDataValue::value);
}
} else {
report(APIEvent::Type::LiveDataInvalidArgument, APIEvent::Severity::Error);
return false;
}
break;
}
default: { default: {
report(APIEvent::Type::LiveDataInvalidCommand, APIEvent::Severity::Error); report(APIEvent::Type::LiveDataInvalidCommand, APIEvent::Severity::Error);
return false; return false;
+82
View File
@@ -0,0 +1,82 @@
#include "icsneo/communication/packet/spipacket.h"
#include "icsneo/communication/command.h"
#include <cstring>
#include <vector>
using namespace icsneo;
static size_t SPISubHeaderLength = 5u;
std::shared_ptr<Message> HardwareSPIPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
if(bytestream.size() < sizeof(HardwareSPIPacket)) {
return nullptr;
}
const HardwareSPIPacket* packet = (const HardwareSPIPacket*)bytestream.data();
size_t totalPackedLength = static_cast<size_t>(bytestream.size()) - sizeof(HardwareSPIPacket); // First 28 bytes are message header.
if(totalPackedLength < SPISubHeaderLength) {
return nullptr;
}
const uint8_t* bytes = bytestream.data() + sizeof(HardwareSPIPacket);
std::shared_ptr<SPIMessage> msg = std::make_shared<SPIMessage>();
msg->direction = static_cast<SPIMessage::Direction>(bytes[0]);
msg->address = *reinterpret_cast<const uint16_t*>(&bytes[1]);
msg->mms = bytes[3];
msg->stats = packet->stats;
msg->timestamp = packet->timestamp.TS;
size_t numWords = (totalPackedLength - SPISubHeaderLength) / 4;
msg->payload.reserve(numWords);
for(size_t offset = SPISubHeaderLength; offset < totalPackedLength; offset += 4) {
msg->payload.push_back(*reinterpret_cast<const uint32_t*>(bytes + offset));
}
return msg;
}
bool HardwareSPIPacket::EncodeFromMessage(const SPIMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& /*report*/) {
// Payload length is everything excluding cmdHeader (note at the beginning there is an offset of 2)
uint16_t payloadLength = static_cast<uint16_t>(
2 +
sizeof(HardwareSPIPacket) +
SPISubHeaderLength +
message.payload.size() * sizeof(uint32_t)
);
if(payloadLength % 2) {
// Pad payload to even number
payloadLength++;
}
// +1 for AA, another +1 for firmware nuance
uint16_t fullSize = 1 + sizeof(ExtendedCommandHeader) + payloadLength + 1;
uint16_t unwrappedSize = sizeof(ExtendedCommandHeader) + payloadLength; // fullSize without AA and firmware nuance
bytestream.resize(unwrappedSize, 0);
uint32_t offset = 0;
auto* cmdHeader = reinterpret_cast<ExtendedCommandHeader*>(bytestream.data() + offset);
cmdHeader->netid = static_cast<uint8_t>(Network::NetID::Main51);
cmdHeader->fullLength = fullSize;
cmdHeader->command = static_cast<uint8_t>(Command::Extended);
cmdHeader->extendedCommand = static_cast<uint16_t>(ExtendedCommand::TransmitCoreminiMessage);
cmdHeader->payloadLength = payloadLength;
offset += sizeof(ExtendedCommandHeader) + 2; // Offset of 2 between header and packet
auto* packet = reinterpret_cast<HardwareSPIPacket*>(bytestream.data() + offset);
packet->header.frameLength = static_cast<uint16_t>(SPISubHeaderLength + message.payload.size() * sizeof(uint32_t));
packet->networkID = static_cast<uint16_t>(message.network.getNetID());
packet->length = packet->header.frameLength;
packet->timestamp.IsExtended = 1;
offset += sizeof(HardwareSPIPacket);
// Write the sub header details
bytestream[offset++] = static_cast<uint8_t>(message.direction);
bytestream[offset++] = static_cast<uint8_t>(message.address & 0xFF);
bytestream[offset++] = static_cast<uint8_t>((message.address >> 8) & 0xFF);
bytestream[offset++] = static_cast<uint8_t>(message.mms);
bytestream[offset++] = static_cast<uint8_t>(message.payload.size());
// Write the words
for(uint32_t word : message.payload) {
*reinterpret_cast<uint32_t*>(bytestream.data() + offset) = word;
offset += sizeof(uint32_t);
}
return true;
}
+41 -7
View File
@@ -31,24 +31,46 @@ std::shared_ptr<WiVI::ResponseMessage> WiVI::CommandPacket::DecodeToMessage(cons
break; break;
} }
case WiVI::Command::GetAll: { case WiVI::Command::GetAll: {
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAll)) if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAllHeader))
return {}; return {};
const auto& getAll = *reinterpret_cast<const WiVI::CommandPacket::GetAll*>(bytestream.data()); const auto& getAll = *reinterpret_cast<const WiVI::CommandPacket::GetAllHeader*>(bytestream.data());
msg->responseTo = WiVI::Command::GetAll; msg->responseTo = WiVI::Command::GetAll;
msg->info.emplace(); msg->info.emplace();
msg->info->sleepRequest = getAll.sleepRequest; msg->info->sleepRequest = getAll.sleepRequest;
msg->info->connectionTimeoutMinutes = getAll.connectionTimeoutMinutes; msg->info->connectionTimeoutMinutes = getAll.connectionTimeoutMinutes;
// Check that we have enough data for the capture infos // Check that we have enough data for the capture infos
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAll) + (sizeof(WiVI::CaptureInfo) * getAll.numCaptureInfos)) size_t captureInfosSize = sizeof(WiVI::CaptureInfo) * getAll.numCaptureInfos;
if(bytestream.size() < sizeof(WiVI::CommandPacket::GetAllHeader) + captureInfosSize)
return {}; return {};
const WiVI::CaptureInfo* const captureInfos = (const WiVI::CaptureInfo*)(bytestream.data() + sizeof(WiVI::CommandPacket::GetAllHeader));
msg->info->captures.resize(getAll.numCaptureInfos); msg->info->captures.resize(getAll.numCaptureInfos);
for(uint16_t i = 0; i < getAll.numCaptureInfos; i++) for(uint16_t i = 0; i < getAll.numCaptureInfos; i++)
msg->info->captures[i] = getAll.captureInfos[i]; msg->info->captures[i] = captureInfos[i];
// New field vinAvail was added - check if it is present:
if(bytestream.size() >= sizeof(WiVI::CommandPacket::GetAllHeader) + captureInfosSize + 2) {
msg->info->vinAvailable = *(bytestream.data() + sizeof(WiVI::CommandPacket::GetAllHeader) + captureInfosSize);
} else {
msg->info->vinAvailable = 0;
}
break; break;
} }
case WiVI::Command::GetVIN: {
if (bytestream.size() < sizeof(WiVI::CommandPacket::GetVIN))
return {};
const auto& getVIN = *reinterpret_cast<const WiVI::CommandPacket::GetVIN*>(bytestream.data());
msg->responseTo = WiVI::Command::GetVIN;
msg->vin = getVIN.VIN;
break;
}
default: // Unknown command response default: // Unknown command response
return {}; return {};
} }
@@ -78,9 +100,9 @@ std::vector<uint8_t> WiVI::CommandPacket::SetSignal::Encode(WiVI::SignalType typ
return ret; return ret;
} }
std::vector<uint8_t> WiVI::CommandPacket::GetAll::Encode() { std::vector<uint8_t> WiVI::CommandPacket::GetAllHeader::Encode() {
std::vector<uint8_t> ret(sizeof(WiVI::CommandPacket::GetAll)); std::vector<uint8_t> ret(sizeof(WiVI::CommandPacket::GetAllHeader));
auto& frame = *reinterpret_cast<WiVI::CommandPacket::GetAll*>(ret.data()); auto& frame = *reinterpret_cast<WiVI::CommandPacket::GetAllHeader*>(ret.data());
frame.header.cmd = WiVI::Command::GetAll; frame.header.cmd = WiVI::Command::GetAll;
frame.header.length = sizeof(frame) - sizeof(frame.header); frame.header.length = sizeof(frame) - sizeof(frame.header);
@@ -98,3 +120,15 @@ std::vector<uint8_t> WiVI::CommandPacket::ClearUploads::Encode(const std::vector
return ret; return ret;
} }
std::vector<uint8_t> WiVI::CommandPacket::GetVIN::Encode()
{
std::vector<uint8_t> ret(sizeof(WiVI::CommandPacket::GetVIN));
auto& frame = *reinterpret_cast<WiVI::CommandPacket::GetVIN*>(ret.data());
frame.header.cmd = WiVI::Command::GetVIN;
frame.header.length = sizeof(frame) - sizeof(frame.header);
return ret;
}
-91
View File
@@ -1,91 +0,0 @@
#include "icsneo/communication/ringbuffer.h"
#include <stdexcept>
namespace icsneo {
RingBuffer::RingBuffer(size_t bufferSize) : readCursor(0), writeCursor(0) {
// round the buffer size to the nearest power of 2
bufferSize = RoundUp(bufferSize);
mask = bufferSize - 1;
buf = new uint8_t[bufferSize];
}
RingBuffer::~RingBuffer() {
delete[] buf;
buf = nullptr;
}
const uint8_t& RingBuffer::operator[](size_t offset) const {
return get(offset);
}
size_t RingBuffer::size() const {
// The values in the cursors are monotonic, i.e. they only ever increment. They can be considered to be the total number of elements ever written or read
auto currentWriteCursor = writeCursor.load(std::memory_order_relaxed);
auto currentReadCursor = readCursor.load(std::memory_order_relaxed);
// Using unmasked values, writeCursor is guaranteed to be >= readCursor. If they are equal that means the buffer is empty
return currentWriteCursor - currentReadCursor;
}
void RingBuffer::pop_front() {
pop(1);
}
void RingBuffer::pop(size_t count) {
if (size() < count) {
throw std::runtime_error("RingBuffer: Underflow");
}
readCursor.fetch_add(count, std::memory_order_release);
}
const uint8_t& RingBuffer::get(size_t offset) const {
if (offset >= size()) {
throw std::runtime_error("RingBuffer: Index out of range");
}
auto currentReadCursor = readCursor.load(std::memory_order_acquire);
return *resolve(currentReadCursor, offset);
}
bool RingBuffer::write(const uint8_t* addr, size_t length) {
const auto freeSpace = (capacity() - size());
if (length > freeSpace) {
return false;
}
auto currentWriteCursor = writeCursor.load(std::memory_order_relaxed);
auto spaceAtEnd = std::min(freeSpace, capacity() - (currentWriteCursor & mask)); // number of bytes from (masked) writeCursor to the end of the writable space (i.e. we reach the masked read cursor or the end of the buffer)
auto firstCopySize = std::min(spaceAtEnd, length);
(void)memcpy(resolve(currentWriteCursor, 0), addr, firstCopySize);
if (firstCopySize < length)
{
(void)memcpy(buf, &addr[firstCopySize], length - firstCopySize);
}
writeCursor.store(currentWriteCursor + length, std::memory_order_release);
return true;
}
bool RingBuffer::write(const std::vector<uint8_t>& source) {
return write(source.data(), source.size());
}
bool RingBuffer::read(uint8_t* dest, size_t startIndex, size_t length) const {
auto currentSize = size();
if ((startIndex >= currentSize) || ((startIndex + length) > size())) {
return false;
}
auto currentReadCursor = readCursor.load(std::memory_order_relaxed);
auto bytesAtEnd = std::min<size_t>(capacity() - ((currentReadCursor + startIndex) & mask), length);
const auto bytesAtStart = (length - bytesAtEnd);
(void)memcpy(dest, resolve(currentReadCursor, startIndex), bytesAtEnd);
if (bytesAtStart > 0) {
(void)memcpy(&dest[bytesAtEnd], buf, bytesAtStart);
}
return true;
}
void RingBuffer::clear() {
pop(size());
}
}
+69
View File
@@ -0,0 +1,69 @@
/*
* crc32.c
*
* Created on: Jun 22, 2020
* Author: BJones
*/
#include "icsneo/core/crc32.h"
static const unsigned long crc32_table[256] = { 0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535,
0x9E6495A3, 0x0EDB8832, 0x79DCB8A4, 0xE0D5E91E, 0x97D2D988, 0x09B64C2B, 0x7EB17CBD, 0xE7B82D07, 0x90BF1D91, 0x1DB71064, 0x6AB020F2,
0xF3B97148, 0x84BE41DE, 0x1ADAD47D, 0x6DDDE4EB, 0xF4D4B551, 0x83D385C7, 0x136C9856, 0x646BA8C0, 0xFD62F97A, 0x8A65C9EC, 0x14015C4F,
0x63066CD9, 0xFA0F3D63, 0x8D080DF5, 0x3B6E20C8, 0x4C69105E, 0xD56041E4, 0xA2677172, 0x3C03E4D1, 0x4B04D447, 0xD20D85FD, 0xA50AB56B,
0x35B5A8FA, 0x42B2986C, 0xDBBBC9D6, 0xACBCF940, 0x32D86CE3, 0x45DF5C75, 0xDCD60DCF, 0xABD13D59, 0x26D930AC, 0x51DE003A, 0xC8D75180,
0xBFD06116, 0x21B4F4B5, 0x56B3C423, 0xCFBA9599, 0xB8BDA50F, 0x2802B89E, 0x5F058808, 0xC60CD9B2, 0xB10BE924, 0x2F6F7C87, 0x58684C11,
0xC1611DAB, 0xB6662D3D, 0x76DC4190, 0x01DB7106, 0x98D220BC, 0xEFD5102A, 0x71B18589, 0x06B6B51F, 0x9FBFE4A5, 0xE8B8D433, 0x7807C9A2,
0x0F00F934, 0x9609A88E, 0xE10E9818, 0x7F6A0DBB, 0x086D3D2D, 0x91646C97, 0xE6635C01, 0x6B6B51F4, 0x1C6C6162, 0x856530D8, 0xF262004E,
0x6C0695ED, 0x1B01A57B, 0x8208F4C1, 0xF50FC457, 0x65B0D9C6, 0x12B7E950, 0x8BBEB8EA, 0xFCB9887C, 0x62DD1DDF, 0x15DA2D49, 0x8CD37CF3,
0xFBD44C65, 0x4DB26158, 0x3AB551CE, 0xA3BC0074, 0xD4BB30E2, 0x4ADFA541, 0x3DD895D7, 0xA4D1C46D, 0xD3D6F4FB, 0x4369E96A, 0x346ED9FC,
0xAD678846, 0xDA60B8D0, 0x44042D73, 0x33031DE5, 0xAA0A4C5F, 0xDD0D7CC9, 0x5005713C, 0x270241AA, 0xBE0B1010, 0xC90C2086, 0x5768B525,
0x206F85B3, 0xB966D409, 0xCE61E49F, 0x5EDEF90E, 0x29D9C998, 0xB0D09822, 0xC7D7A8B4, 0x59B33D17, 0x2EB40D81, 0xB7BD5C3B, 0xC0BA6CAD,
0xEDB88320, 0x9ABFB3B6, 0x03B6E20C, 0x74B1D29A, 0xEAD54739, 0x9DD277AF, 0x04DB2615, 0x73DC1683, 0xE3630B12, 0x94643B84, 0x0D6D6A3E,
0x7A6A5AA8, 0xE40ECF0B, 0x9309FF9D, 0x0A00AE27, 0x7D079EB1, 0xF00F9344, 0x8708A3D2, 0x1E01F268, 0x6906C2FE, 0xF762575D, 0x806567CB,
0x196C3671, 0x6E6B06E7, 0xFED41B76, 0x89D32BE0, 0x10DA7A5A, 0x67DD4ACC, 0xF9B9DF6F, 0x8EBEEFF9, 0x17B7BE43, 0x60B08ED5, 0xD6D6A3E8,
0xA1D1937E, 0x38D8C2C4, 0x4FDFF252, 0xD1BB67F1, 0xA6BC5767, 0x3FB506DD, 0x48B2364B, 0xD80D2BDA, 0xAF0A1B4C, 0x36034AF6, 0x41047A60,
0xDF60EFC3, 0xA867DF55, 0x316E8EEF, 0x4669BE79, 0xCB61B38C, 0xBC66831A, 0x256FD2A0, 0x5268E236, 0xCC0C7795, 0xBB0B4703, 0x220216B9,
0x5505262F, 0xC5BA3BBE, 0xB2BD0B28, 0x2BB45A92, 0x5CB36A04, 0xC2D7FFA7, 0xB5D0CF31, 0x2CD99E8B, 0x5BDEAE1D, 0x9B64C2B0, 0xEC63F226,
0x756AA39C, 0x026D930A, 0x9C0906A9, 0xEB0E363F, 0x72076785, 0x05005713, 0x95BF4A82, 0xE2B87A14, 0x7BB12BAE, 0x0CB61B38, 0x92D28E9B,
0xE5D5BE0D, 0x7CDCEFB7, 0x0BDBDF21, 0x86D3D2D4, 0xF1D4E242, 0x68DDB3F8, 0x1FDA836E, 0x81BE16CD, 0xF6B9265B, 0x6FB077E1, 0x18B74777,
0x88085AE6, 0xFF0F6A70, 0x66063BCA, 0x11010B5C, 0x8F659EFF, 0xF862AE69, 0x616BFFD3, 0x166CCF45, 0xA00AE278, 0xD70DD2EE, 0x4E048354,
0x3903B3C2, 0xA7672661, 0xD06016F7, 0x4969474D, 0x3E6E77DB, 0xAED16A4A, 0xD9D65ADC, 0x40DF0B66, 0x37D83BF0, 0xA9BCAE53, 0xDEBB9EC5,
0x47B2CF7F, 0x30B5FFE9, 0xBDBDF21C, 0xCABAC28A, 0x53B39330, 0x24B4A3A6, 0xBAD03605, 0xCDD70693, 0x54DE5729, 0x23D967BF, 0xB3667A2E,
0xC4614AB8, 0x5D681B02, 0x2A6F2B94, 0xB40BBE37, 0xC30C8EA1, 0x5A05DF1B, 0x2D02EF8D };
uint32_t icsneo::crc32(uint32_t crc, const unsigned char* buf, uint32_t len)
{
unsigned char octet;
const unsigned char* p = buf;
crc = ~crc;
while (len--)
{
octet = *p++; /* Cast to unsigned octet. */
crc = (crc >> 8) ^ crc32_table[(crc & 0xff) ^ octet];
}
return ~crc;
}
static unsigned char rev_crc32_table[256];
static void revgen(void)
{
uint16_t k;
for (k = 0; k < 256; k++)
rev_crc32_table[crc32_table[k] >> 24] = (unsigned char)k;
}
uint32_t icsneo::revcrc32(uint32_t crc, const unsigned char* buf, uint32_t len)
{
unsigned char k;
revgen();
crc = ~crc;
while (len--)
{
k = rev_crc32_table[crc >> 24];
crc = ((crc ^ crc32_table[k]) << 8) | (k ^ buf[len]);
}
return ~crc;
}
+776
View File
@@ -0,0 +1,776 @@
#include "icsneo/core/macseccfg.h"
#include "icsneo/api/eventmanager.h"
#include "icsneo/core/crc32.h"
#include <cstring>
namespace icsneo {
#ifdef _MSC_VER
#pragma warning(push)
#pragma warning(disable : 4201) // nameless struct/union
#endif
#pragma pack(push, 1)
typedef struct
{
uint16_t VID; /*!< 12 bits */
uint8_t PRI_CFI; /*!< PRI - 3 bits, CFI - 1bit */
} MACSEC_VLANTAG_t;
/**
* @brief Structure of MPLS
*
*/
typedef struct
{
uint32_t MPLS_label; /*!< 20 bits */
uint8_t exp; /*!< 3 bits */
} MACSEC_MPLS_OUTER_t;
#define MACSEC_SETTINGS_RULE_SIZE (88)
typedef union _MACSecRule
{
struct
{
uint8_t index;
uint8_t key_MAC_DA[6]; /*!< MAC DA field extracted from the packet */
uint8_t mask_MAC_DA[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint8_t key_MAC_SA[6]; /*!< MAC SA field extracted from the packet */
uint8_t mask_MAC_SA[6]; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint16_t key_Ethertype; /*!< First E-Type found in the packet that doesn't match one of the preconfigured custom tag. */
uint16_t mask_Ethertype; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
MACSEC_VLANTAG_t key_vlantag_outer1; /*!< outermost/1st VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
MACSEC_MPLS_OUTER_t key_MPLS_outer1;
MACSEC_VLANTAG_t mask_vlantag_outer1; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
MACSEC_MPLS_OUTER_t mask_MPLS_outer1;
MACSEC_VLANTAG_t key_vlantag_outer2; /*!< 2nd outermost VLAN ID {8'd0, VLAN_ID[11:0]}, or 20-bit MPLS label. */
MACSEC_MPLS_OUTER_t key_MPLS_outer2;
MACSEC_VLANTAG_t mask_vlantag_outer2; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
MACSEC_MPLS_OUTER_t mask_MPLS_outer2;
uint16_t key_bonus_data; /*!< 2 bytes of additional bonus data extracted from one of the custom tags. */
uint16_t mask_bonus_data; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint8_t
key_tag_match_bitmap; /*!< 8 bits total. Maps 1 to 1 bitwise with the set of custom tags. (set bit[N]=1 if check Nth custom tag) */
uint8_t mask_tag_match_bitmap; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
MACsecPacketType key_packet_type; /*!< Encoded Packet Type, see MACSEC_PACKET_TYPE */
uint8_t mask_packet_type; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint16_t
key_inner_vlan_type; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the second outermost VLAN Tag. */
uint16_t mask_inner_vlan_type; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint16_t key_outer_vlan_type; /*!< 3 bits total. Encoded value indicating which VLAN TPID value matched for the outermost VLAN Tag. */
uint16_t mask_outer_vlan_type; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint8_t
key_num_tags; /*!< 7 bits total. Number of VLAN/custom tags or MPLS lables detected. Ingress: before SecTag; Egress: total detected. Exclude MCS header tags. i.e. Bit 2: 2 tags/labels before SecTAG...Bit 6: 6 or more tags/labels before SecTAG. */
uint8_t mask_num_tags; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint8_t key_express; /*!< 1 bits. Express packet. */
uint8_t mask_express; /*!< Set bits to 1 to mask/exclude corresponding flowid_tcam_data bit from compare */
uint8_t isMPLS;
uint8_t rsvd[5];
uint8_t enable;
};
uint8_t byte[MACSEC_SETTINGS_RULE_SIZE];
} MACSecRule_t;
/* MACsec Map */
#define MACSEC_SETTINGS_MAP_SIZE (20)
typedef union _MACSecMap
{
struct
{
uint8_t index;
uint64_t sectag_sci; /*!< Identifies the SecTAG SCI for this Flow. */
uint8_t secYIndex; /*!< index for entry in Egress secY Policy */
uint8_t isControlPacket; /*!< Identifies all packets matching this index lookup as control packets. */
uint8_t scIndex; /*!< Identifies the SC for this Flow. */
uint8_t auxiliary_plcy; /*!< Auxiliary policy bits. */
uint8_t ruleId; /*!< Identifies the Rule for this Flow. */
uint8_t rsvd[5];
uint8_t enable;
};
uint8_t byte[MACSEC_SETTINGS_MAP_SIZE];
} MACSecMap_t;
/* MACsec SecY */
#define MACSEC_SETTINGS_SECY_SIZE (24)
typedef union _MACSecSecY
{
struct
{
uint8_t index; /*!< Identifies the SecY for this Flow. */
uint8_t controlled_port_enabled; /*!< Enable (or disable) operation of the Controlled port associated with this SecY */
MACsecValidation validate_frames; /*!< see MACSEC_VALIDATEFRAME */
MACsecStrip strip_sectag_icv; /*!< see MACSEC_STRIP_SECTAG_ICV */
MACsecCipherSuite cipher; /*!< Define the cipher suite to use for this SecY */
uint8_t confidential_offset; /*!< Define the number of bytes that are unencrypted following the SecTag. */
uint8_t icv_includes_da_sa; /*!< When set, the outer DA/SA bytes are included in the authentication GHASH calculation */
uint8_t replay_protect; /*!< Enables Anti-Replay protection */
uint32_t replay_window; /*!< Unsigned value indicating the size of the anti-replay window. */
uint8_t
protect_frames; /*!< 0 = do not encrypt or authenticate this packet; 1 = always Authenticate frame and if SecTag.TCI.E = 1 encrypt the packet as well. */
uint8_t
sectag_offset; /*!< Define the offset in bytes from either the start of the packet or a matching Etype depending on SecTag_Insertion_Mode. */
uint8_t sectag_tci; /*!< Tag Control Information excluding the AN field which originates from the SA Policy table */
uint16_t mtu; /*!< Specifies the outgoing MTU for this SecY */
uint8_t rsvd[6];
uint8_t enable;
};
uint8_t byte[MACSEC_SETTINGS_SECY_SIZE];
} MACSecSecY_t;
/* MACsec SC */
#define MACSEC_SETTINGS_SC_SIZE (24)
typedef union _MACSecSc
{
struct
{
uint8_t index; /*!< SC index. */
uint8_t secYIndex; /*!< SecY associated with this packet. */
uint64_t sci; /*!< The Secure Channel Identifier. */
uint8_t sa_index0; /*!< Define the 1st SA to use */
uint8_t sa_index1; /*!< Define the 2nd SA to use */
uint8_t sa_index0_in_use; /*!< Specifies whether 1st SA is in use or not. */
uint8_t sa_index1_in_use; /*!< Specifies whether 2nd SA is in use or not. */
uint8_t enable_auto_rekey; /*!< If enabled, then once the pn_threshold is reached, auto rekey will happen. */
uint8_t
isActiveSA1; /*!< If set, then sa_index1 is the currently active SA index. If cleared, the sa_index0 is the currently active SA index). */
uint8_t rsvd[7];
uint8_t enable;
};
uint8_t byte[MACSEC_SETTINGS_SC_SIZE];
} MACSecSc_t;
/* MACsec SA */
#define MACSEC_SETTINGS_SA_SIZE (80)
typedef union _MACSecSa
{
struct
{
uint8_t index; /*!< SA index */
uint8_t
sak[32]; /*!< 256b SAK: Define the encryption key to be used to encrypte this packet. The lower 128 bits are used for 128-bit ciphers. */
uint8_t hashKey[16]; /*!< 128b Hash Key: Key used for authentication. */
uint8_t salt[12]; /*!< 96b Salt value: Salt value used in XPN ciphers. */
uint32_t ssci; /*!< 32b SSCI value: Short Secure Channel Identifier, used in XPN ciphers. */
uint8_t AN; /*!< 2b SecTag Association Number (AN) */
uint64_t nextPN; /*!< 64b next_pn value: Next packet number to insert into outgoing packet on a particular SA. */
uint8_t rsvd[5];
uint8_t enable;
};
uint8_t byte[MACSEC_SETTINGS_SA_SIZE];
} MACSecSa_t;
/* MACsec Flags */
#define MACSEC_SETTINGS_FLAGS_SIZE (4)
typedef union _MACSecFlags
{
struct
{
uint32_t en : 1; // '1' = enable; '0' = disable
uint32_t reserved : 31;
};
uint32_t flags_32b;
} MACSecFlags_t;
/* MACSec Settings for 1 port/phy */
#define MACSEC_NUM_FLAGS_PER_CONFIG (1)
#define MACSEC_NUM_RULES_PER_CONFIG (2)
#define MACSEC_NUM_MAPS_PER_CONFIG (2)
#define MACSEC_NUM_SECY_PER_CONFIG (2)
#define MACSEC_NUM_SC_PER_CONFIG (2)
#define MACSEC_NUM_SA_PER_CONFIG (4)
typedef struct MACSEC_CONFIG_t
{
MACSecFlags_t flags;
MACSecRule_t rule[MACSEC_NUM_RULES_PER_CONFIG];
MACSecMap_t map[MACSEC_NUM_MAPS_PER_CONFIG];
MACSecSecY_t secy[MACSEC_NUM_SECY_PER_CONFIG];
MACSecSc_t sc[MACSEC_NUM_SC_PER_CONFIG];
MACSecSa_t sa[MACSEC_NUM_SA_PER_CONFIG];
} MACSEC_CONFIG;
typedef union _MACSecGlobalFlags
{
struct
{
uint32_t en : 1; // '1' = enable; '0' = disable
uint32_t nvm : 1; // store macsec config in non-volatile memory
uint32_t reserved : 30;
};
uint32_t flags_32b;
} MACSecGlobalFlags_t;
#define MACSEC_SETTINGS_SIZE (2040) // leave space for expansion and keep nicely aligned for flashing
typedef union _MACSEC_SETTINGS
{
struct
{
MACSecGlobalFlags_t flags;
MACSEC_CONFIG rx;
MACSEC_CONFIG tx;
};
uint8_t byte[MACSEC_SETTINGS_SIZE];
} MACSEC_SETTINGS;
#define MACSEC_SETTINGS_VERSION 1
typedef struct MACSEC_SETTINGS_W_HDR
{
uint16_t version;
uint16_t len;
uint32_t crc32;
MACSEC_SETTINGS macsec;
} MACSEC_SETTINGS_W_HDR;
#define MACSEC_SETTINGS_W_HDR_SIZE (2048)
#pragma pack(pop)
#ifdef _MSC_VER
#pragma warning(pop)
#endif
static void ReportEvent(APIEvent::Type event, APIEvent::Severity severity) {
auto& em = EventManager::GetInstance();
em.add(APIEvent(event, severity));
}
MACsecConfig::MACsecConfig(const DeviceType& deviceType) : type(deviceType) {
switch(deviceType.getDeviceType()) {
case icsneo::DeviceType::Enum::RADMoon2:
case icsneo::DeviceType::Enum::RADMoon3:
case icsneo::DeviceType::Enum::RADEpsilon:
maxSecY = 2;
maxRule = 2;
maxSa = 4;
binIndex = 0;
break;
default:
maxSecY = 0;
maxSa = 0;
maxRule = 0;
binIndex = 0;
ReportEvent(APIEvent::Type::MACsecNotSupported, APIEvent::Severity::Error);
return;
}
}
int MACsecConfig::addRxSecY(const MACsecRxSecY& secY, uint8_t saIndex) {
if(rxSecY.size() >= maxSecY) {
ReportEvent(APIEvent::Type::MACsecSecYLimit, APIEvent::Severity::Error);
return -1;
}
if(saIndex >= rxSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return -1;
}
int ret = static_cast<int>(rxSecY.size());
rxSecY.emplace_back(secY);
rxSecYSaIndices.emplace_back(saIndex, saIndex + 1);
rxSecYRekey.emplace_back(false);
rxRuleIndices.emplace_back(0);
return ret;
}
int MACsecConfig::addTxSecY(const MACsecTxSecY& secY, uint8_t saIndex) {
if(txSecY.size() >= maxSecY) {
ReportEvent(APIEvent::Type::MACsecSecYLimit, APIEvent::Severity::Error);
return -1;
}
if(saIndex >= txSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return -1;
}
int ret = static_cast<int>(txSecY.size());
txSecY.emplace_back(secY);
txSecYSaIndices.emplace_back(saIndex, saIndex + 1);
txSecYRekey.emplace_back(false);
return ret;
}
int MACsecConfig::addRxSa(const MACsecRxSa& sa) {
if(rxSa.size() >= maxSa) {
ReportEvent(APIEvent::Type::MACsecSaLimit, APIEvent::Severity::Error);
return -1;
}
int ret = static_cast<int>(rxSa.size());
rxSa.emplace_back(sa);
return ret;
}
int MACsecConfig::addTxSa(const MACsecTxSa& sa) {
if(txSa.size() >= maxSa) {
ReportEvent(APIEvent::Type::MACsecSaLimit, APIEvent::Severity::Error);
return -1;
}
int ret = static_cast<int>(txSa.size());
txSa.emplace_back(sa);
return ret;
}
int MACsecConfig::addRxRule(const MACsecRxRule& rule, uint8_t secYIndex) {
if(rxRule.size() >= maxRule) {
ReportEvent(APIEvent::Type::MACsecSaLimit, APIEvent::Severity::Error);
return -1;
}
if(maxSecY >= rxRule.size()) {
ReportEvent(APIEvent::Type::MACsecSecYLimit, APIEvent::Severity::Error);
return -1;
}
int ret = static_cast<int>(rxRule.size());
rxRuleIndices[secYIndex] = static_cast<uint8_t>(rxRule.size());
rxRule.emplace_back(rule);
return ret;
}
MACsecRxRule& MACsecConfig::getRxRule(uint8_t ruleIndex) {
return rxRule[ruleIndex];
}
const MACsecRxRule& MACsecConfig::getRxRule(uint8_t ruleIndex) const {
return rxRule[ruleIndex];
}
MACsecRxSecY& MACsecConfig::getRxSecY(uint8_t secYIndex) {
return rxSecY[secYIndex];
}
const MACsecRxSecY& MACsecConfig::getRxSecY(uint8_t secYIndex) const {
return rxSecY[secYIndex];
}
MACsecTxSecY& MACsecConfig::getTxSecY(uint8_t secYIndex) {
return txSecY[secYIndex];
}
const MACsecTxSecY& MACsecConfig::getTxSecY(uint8_t secYIndex) const {
return txSecY[secYIndex];
}
MACsecRxSa& MACsecConfig::getRxSa(uint8_t saIndex) {
return rxSa[saIndex];
}
const MACsecRxSa& MACsecConfig::getRxSa(uint8_t saIndex) const {
return rxSa[saIndex];
}
MACsecTxSa& MACsecConfig::getTxSa(uint8_t saIndex) {
return txSa[saIndex];
}
const MACsecTxSa& MACsecConfig::getTxSa(uint8_t saIndex) const {
return txSa[saIndex];
}
bool MACsecConfig::setTxSaIndex(uint8_t secYIndex, uint8_t saIndex) {
if(secYIndex >= txSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
return false;
}
if(saIndex >= txSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return false;
}
txSecYSaIndices[secYIndex].first = saIndex;
return true;
}
bool MACsecConfig::enableTxRekey(uint8_t secYIndex, uint8_t rekeySaIndex) {
if(secYIndex >= txSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
return false;
}
if(rekeySaIndex >= txSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return false;
}
txSecYSaIndices[secYIndex].second = rekeySaIndex;
txSecYRekey[secYIndex] = true;
return true;
}
bool MACsecConfig::setTxSaRekeyIndex(uint8_t secYIndex, uint8_t saIndex) {
if(secYIndex >= txSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
return false;
}
if(saIndex >= txSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return false;
}
txSecYSaIndices[secYIndex].second = saIndex;
return true;
}
void MACsecConfig::disableTxRekey(uint8_t secYIndex) {
if(secYIndex >= txSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::EventWarning);
return;
}
txSecYRekey[secYIndex] = false;
}
bool MACsecConfig::setRxSaIndex(uint8_t secYIndex, uint8_t saIndex) {
if(secYIndex >= rxSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
return false;
}
if(saIndex >= rxSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return false;
}
rxSecYSaIndices[secYIndex].first = saIndex;
return true;
}
bool MACsecConfig::enableRxRekey(uint8_t secYIndex, uint8_t rekeySaIndex) {
if(secYIndex >= rxSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
return false;
}
if(rekeySaIndex >= rxSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return false;
}
rxSecYSaIndices[secYIndex].second = rekeySaIndex;
rxSecYRekey[secYIndex] = true;
return true;
}
bool MACsecConfig::setRxSaRekeyIndex(uint8_t secYIndex, uint8_t saIndex) {
if(secYIndex >= rxSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::Error);
return false;
}
if(saIndex >= rxSa.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSaIndex, APIEvent::Severity::Error);
return false;
}
rxSecYSaIndices[secYIndex].second = saIndex;
return true;
}
void MACsecConfig::disableRxRekey(uint8_t secYIndex) {
if(secYIndex >= rxSecY.size()) {
ReportEvent(APIEvent::Type::MACsecInvalidSecYIndex, APIEvent::Severity::EventWarning);
return;
}
rxSecYRekey[secYIndex] = false;
}
void MACsecConfig::setRxEnable(bool newRxEnable) {
enableRx = newRxEnable;
}
void MACsecConfig::setTxEnable(bool newTxEnable) {
enableTx = newTxEnable;
}
void MACsecConfig::setStorage(bool temporary) {
nvm = !temporary;
}
void MACsecConfig::clear() {
// Set everything back to default, except device maximums
rxSecY.clear();
txSecY.clear();
rxSa.clear();
txSa.clear();
rxRule.clear();
rxSecYRekey.clear();
txSecYRekey.clear();
rxSecYSaIndices.clear();
txSecYSaIndices.clear();
rxRuleIndices.clear();
enableRx = false;
enableTx = false;
nvm = false;
}
MACsecConfig::operator bool() const {
return (maxSa != 0) || (maxSecY != 0) || (maxRule != 0);
}
uint16_t MACsecConfig::getBinIndex() const {
return binIndex;
}
DeviceType MACsecConfig::getType() const {
return type;
}
uint8_t MACsecConfig::getMaxNumRule() const {
return maxRule;
}
uint8_t MACsecConfig::getMaxNumSecY() const {
return maxSecY;
}
uint8_t MACsecConfig::getMaxNumSa() const {
return maxSa;
}
static uint8_t TCItoInt(const MACsecTci& tci) {
uint8_t res = 0;
res |= tci.c ? 0x01u : 0;
res |= tci.e ? 0x02u : 0;
res |= tci.scb ? 0x04u : 0;
res |= tci.sc ? 0x08u : 0;
res |= tci.es ? 0x10u : 0;
return res;
}
static void SetHardwareTxSecY(
MACSEC_SETTINGS_W_HDR* hwSettings,
const MACsecTxSecY& secY,
bool rekeyEnabled,
const std::pair<uint8_t, uint8_t>& saIndices,
uint8_t index
) {
MACSecSecY_t* hwSecY = &hwSettings->macsec.tx.secy[index];
MACSecSc_t* hwSc = &hwSettings->macsec.tx.sc[index];
MACSecMap_t* hwMap = &hwSettings->macsec.tx.map[index];
hwSecY->index = index;
hwSecY->enable = true;
hwSecY->controlled_port_enabled = secY.enableControlPort ? 0x1u : 0x0u;
hwSecY->cipher = secY.cipher;
hwSecY->confidential_offset = secY.confidentialityOffset;
hwSecY->icv_includes_da_sa = secY.icvIncludesDaSa ? 0x1u : 0x0u;
hwSecY->mtu = secY.mtu;
hwSecY->sectag_tci = TCItoInt(secY.tci);
hwSecY->sectag_offset = secY.secTagOffset;
hwSecY->protect_frames = secY.protectFrames;
hwSc->index = index;
hwSc->enable = true;
hwSc->secYIndex = index;
hwSc->enable_auto_rekey = rekeyEnabled ? 0x1u : 0x0u;
hwSc->sa_index0 = saIndices.first;
hwSc->sa_index1 = saIndices.second;
hwSc->sa_index0_in_use = true;
hwSc->sa_index1_in_use = rekeyEnabled ? true : false;
hwSc->isActiveSA1 = rekeyEnabled ? true : false;
hwSc->sci = secY.sci;
hwMap->index = index;
hwMap->enable = true;
hwMap->auxiliary_plcy = secY.auxiliaryPolicy;
hwMap->secYIndex = index;
hwMap->isControlPacket = secY.isControlPacket ? 0x1u : 0x0u;
hwMap->scIndex = index;
hwMap->sectag_sci = secY.sci;
}
static void SetHardwareRxSecY(
MACSEC_SETTINGS_W_HDR* hwSettings,
const MACsecRxSecY& secY,
bool rekeyEnabled,
uint8_t ruleIndex,
const std::pair<uint8_t, uint8_t>& saIndices,
uint8_t index
) {
MACSecSecY_t* hwSecY = &hwSettings->macsec.rx.secy[index];
MACSecSc_t* hwSc = &hwSettings->macsec.rx.sc[index];
MACSecMap_t* hwMap = &hwSettings->macsec.rx.map[index];
hwSecY->index = index;
hwSecY->enable = 0x1u;
hwSecY->controlled_port_enabled = secY.enableControlPort ? 0x1u : 0x0u;
hwSecY->cipher = secY.cipher;
hwSecY->confidential_offset = secY.confidentialityOffset;
hwSecY->icv_includes_da_sa = secY.icvIncludesDaSa ? 0x1u : 0x0u;
hwSecY->replay_protect = secY.replayProtect ? 0x1u : 0x0u;
hwSecY->replay_window = secY.replayWindow;
hwSecY->validate_frames = secY.frameValidation;
hwSecY->strip_sectag_icv = secY.frameStrip;
hwSecY->sectag_offset = 12;
hwSc->index = index;
hwSc->enable = 0x1u;
hwSc->secYIndex = index;
hwSc->enable_auto_rekey = rekeyEnabled ? 0x1u : 0x0u;
hwSc->sa_index0 = saIndices.first;
hwSc->sa_index1 = saIndices.second;
hwSc->sa_index0_in_use = 0x1u;
hwSc->sa_index1_in_use = rekeyEnabled ? 0x1u : 0x0u;
hwSc->isActiveSA1 = rekeyEnabled ? 0x1u : 0x0u;
hwSc->sci = secY.sci;
hwMap->index = index;
hwMap->enable = 0x1u;
hwMap->secYIndex = index;
hwMap->ruleId = ruleIndex;
hwMap->isControlPacket = secY.isControlPacket ? 0x1u : 0x0u;
hwMap->scIndex = index;
hwMap->sectag_sci = secY.sci;
}
static void SetHardwareTxSa(MACSEC_SETTINGS_W_HDR* hwSettings, const MACsecTxSa& sa, uint8_t index) {
MACSecSa_t* hwSa = &hwSettings->macsec.tx.sa[index];
hwSa->index = index;
hwSa->enable = 0x1u;
memcpy(hwSa->sak, sa.sak.data(), 32);
memcpy(hwSa->hashKey, sa.hashKey.data(), 16);
memcpy(hwSa->salt, sa.salt.data(), 12);
hwSa->ssci = sa.ssci;
hwSa->AN = sa.an;
hwSa->nextPN = sa.nextPn;
}
static void SetHardwareRxSa(MACSEC_SETTINGS_W_HDR* hwSettings, const MACsecRxSa& sa, uint8_t index) {
MACSecSa_t* hwSa = &hwSettings->macsec.rx.sa[index];
hwSa->index = index;
hwSa->enable = 0x1u;
memcpy(hwSa->sak, sa.sak.data(), 32);
memcpy(hwSa->hashKey, sa.hashKey.data(), 16);
memcpy(hwSa->salt, sa.salt.data(), 12);
hwSa->ssci = sa.ssci;
hwSa->nextPN = sa.nextPn;
}
static void SetHardwareRxRule(MACSecRule_t* hwRule, const MACsecRxRule& rule, uint8_t index) {
hwRule->enable = 0x1u;
hwRule->index = index;
memcpy(hwRule->key_MAC_DA, rule.keyMacDa.data(), 6);
memcpy(hwRule->mask_MAC_DA, rule.maskMacDa.data(), 6);
memcpy(hwRule->key_MAC_SA, rule.keyMacSa.data(), 6);
memcpy(hwRule->mask_MAC_SA, rule.maskMacSa.data(), 6);
hwRule->key_Ethertype = rule.keyEthertype;
hwRule->mask_Ethertype = rule.maskEthertype;
hwRule->key_vlantag_outer1.PRI_CFI = rule.keyVlanTagOuter1.priCfi;
hwRule->key_vlantag_outer1.VID = rule.keyVlanTagOuter1.vid;
hwRule->key_MPLS_outer1.exp = rule.keyMplsOuter1.exp;
hwRule->key_MPLS_outer1.MPLS_label = rule.keyMplsOuter1.mplsLabel;
hwRule->mask_vlantag_outer1.PRI_CFI = rule.maskVlanTagOuter1.priCfi;
hwRule->mask_vlantag_outer1.VID = rule.maskVlanTagOuter1.vid;
hwRule->mask_MPLS_outer1.exp = rule.maskMplsOuter1.exp;
hwRule->mask_MPLS_outer1.MPLS_label = rule.maskMplsOuter1.mplsLabel;
hwRule->key_vlantag_outer2.PRI_CFI = rule.keyVlanTagOuter2.priCfi;
hwRule->key_vlantag_outer2.VID = rule.keyVlanTagOuter2.vid;
hwRule->key_MPLS_outer2.exp = rule.keyMplsOuter2.exp;
hwRule->key_MPLS_outer2.MPLS_label = rule.keyMplsOuter2.mplsLabel;
hwRule->mask_vlantag_outer2.PRI_CFI = rule.maskVlanTagOuter2.priCfi;
hwRule->mask_vlantag_outer2.VID = rule.maskVlanTagOuter2.vid;
hwRule->mask_MPLS_outer2.exp = rule.maskMplsOuter2.exp;
hwRule->mask_MPLS_outer2.MPLS_label = rule.maskMplsOuter2.mplsLabel;
hwRule->key_bonus_data = rule.keyBonusData;
hwRule->mask_bonus_data = rule.maskBonusData;
hwRule->key_tag_match_bitmap = rule.keyTagMatchBitmap;
hwRule->mask_tag_match_bitmap = rule.maskTagMatchBitmap;
hwRule->key_packet_type = rule.keyPacketType;
hwRule->mask_packet_type = rule.maskPacketType;
hwRule->key_inner_vlan_type = rule.keyInnerVlanType;
hwRule->mask_inner_vlan_type = rule.maskInnerVlanType;
hwRule->key_outer_vlan_type = rule.keyOuterVlanType;
hwRule->mask_outer_vlan_type = rule.maskOuterVlanType;
hwRule->key_num_tags = rule.keyNumTags;
hwRule->mask_num_tags = rule.maskNumTags;
hwRule->key_express = rule.keyExpress ? 0x1u : 0x0u;
hwRule->mask_express = rule.maskExpress ? 0x1u : 0x0u;
hwRule->isMPLS = rule.isMpls ? 0x1u : 0x0u;
}
std::vector<uint8_t> MACsecConfig::serialize() const {
std::vector<uint8_t> res(sizeof(MACSEC_SETTINGS_W_HDR), 0);
MACSEC_SETTINGS_W_HDR* hwSettings = (MACSEC_SETTINGS_W_HDR*)(res.data());
for(uint8_t i = 0; i < maxSecY; i++) {
if(i < rxSecY.size()) {
SetHardwareRxSecY(
hwSettings,
rxSecY[i],
rxSecYRekey[i],
rxRuleIndices[i],
rxSecYSaIndices[i],
i
);
} else {
hwSettings->macsec.rx.secy[i].enable = false;
hwSettings->macsec.rx.map[i].enable = false;
hwSettings->macsec.rx.sc[i].enable = false;
}
if(i < txSecY.size()) {
SetHardwareTxSecY(
hwSettings,
txSecY[i],
txSecYRekey[i],
txSecYSaIndices[i],
i
);
} else {
hwSettings->macsec.tx.secy[i].enable = false;
hwSettings->macsec.tx.map[i].enable = false;
hwSettings->macsec.tx.sc[i].enable = false;
}
}
for(uint8_t i = 0; i < maxSa; i++) {
if(i < rxSa.size()) {
SetHardwareRxSa(hwSettings, rxSa[i], i);
} else {
hwSettings->macsec.rx.sa[i].enable = false;
}
if(i < txSa.size()) {
SetHardwareTxSa(hwSettings, txSa[i], i);
} else {
hwSettings->macsec.tx.sa[i].enable = false;
}
}
if(rxRule.size() == 0) {
MACsecRxRule defaultRule;
MACSecRule_t* hwRxRule = &hwSettings->macsec.rx.rule[0];
MACSecRule_t* hwTxRule = &hwSettings->macsec.tx.rule[0];
SetHardwareRxRule(hwRxRule, defaultRule, 0);
SetHardwareRxRule(hwTxRule, defaultRule, 0);
//hwSettings->macsec.tx.rule[0].enable = false;
for(uint8_t i = 1; i < maxRule; i++) {
hwSettings->macsec.rx.rule[i].enable = false;
hwSettings->macsec.tx.rule[i].enable = false;
}
} else {
for(uint8_t i = 0; i < maxRule; i++) {
if(i < rxRule.size()) {
auto* hwRxRule = &hwSettings->macsec.rx.rule[i];
SetHardwareRxRule(hwRxRule, rxRule[i], i);
} else {
hwSettings->macsec.rx.rule[i].enable = false;
hwSettings->macsec.tx.rule[i].enable = false;
}
}
}
hwSettings->len = sizeof(MACSEC_SETTINGS_W_HDR);
hwSettings->version = MACSEC_SETTINGS_VERSION;
hwSettings->macsec.flags.en = (enableRx || enableTx) ? 1u : 0u;
hwSettings->macsec.flags.nvm = nvm ? 1u : 0u;
hwSettings->macsec.rx.flags.en = enableRx ? 1u : 0u;
hwSettings->macsec.tx.flags.en = enableTx ? 1u : 0u;
hwSettings->crc32 = crc32(0, (uint8_t*)&hwSettings->macsec, sizeof(MACSEC_SETTINGS));
return res;
}
}
+91
View File
@@ -0,0 +1,91 @@
#include "icsneo/core/ringbuffer.h"
#include <stdexcept>
namespace icsneo {
RingBuffer::RingBuffer(size_t bufferSize) : readCursor(0), writeCursor(0) {
// round the buffer size to the nearest power of 2
bufferSize = RoundUp(bufferSize);
mask = bufferSize - 1;
buf = new uint8_t[bufferSize];
}
RingBuffer::~RingBuffer() {
delete[] buf;
buf = nullptr;
}
const uint8_t& RingBuffer::operator[](size_t offset) const {
return get(offset);
}
size_t RingBuffer::size() const {
// The values in the cursors are monotonic, i.e. they only ever increment. They can be considered to be the total number of elements ever written or read
auto currentWriteCursor = writeCursor.load(std::memory_order_relaxed);
auto currentReadCursor = readCursor.load(std::memory_order_relaxed);
// Using unmasked values, writeCursor is guaranteed to be >= readCursor. If they are equal that means the buffer is empty
return currentWriteCursor - currentReadCursor;
}
void RingBuffer::pop_front() {
pop(1);
}
void RingBuffer::pop(size_t count) {
if (size() < count) {
throw std::runtime_error("RingBuffer: Underflow");
}
readCursor.fetch_add(count, std::memory_order_release);
}
const uint8_t& RingBuffer::get(size_t offset) const {
if (offset >= size()) {
throw std::runtime_error("RingBuffer: Index out of range");
}
auto currentReadCursor = readCursor.load(std::memory_order_acquire);
return *resolve(currentReadCursor, offset);
}
bool RingBuffer::write(const uint8_t* addr, size_t length) {
const auto freeSpace = (capacity() - size());
if (length > freeSpace) {
return false;
}
auto currentWriteCursor = writeCursor.load(std::memory_order_relaxed);
auto spaceAtEnd = std::min(freeSpace, capacity() - (currentWriteCursor & mask)); // number of bytes from (masked) writeCursor to the end of the writable space (i.e. we reach the masked read cursor or the end of the buffer)
auto firstCopySize = std::min(spaceAtEnd, length);
(void)memcpy(resolve(currentWriteCursor, 0), addr, firstCopySize);
if (firstCopySize < length)
{
(void)memcpy(buf, &addr[firstCopySize], length - firstCopySize);
}
writeCursor.store(currentWriteCursor + length, std::memory_order_release);
return true;
}
bool RingBuffer::write(const std::vector<uint8_t>& source) {
return write(source.data(), source.size());
}
bool RingBuffer::read(uint8_t* dest, size_t startIndex, size_t length) const {
auto currentSize = size();
if ((startIndex >= currentSize) || ((startIndex + length) > size())) {
return false;
}
auto currentReadCursor = readCursor.load(std::memory_order_relaxed);
auto bytesAtEnd = std::min<size_t>(capacity() - ((currentReadCursor + startIndex) & mask), length);
const auto bytesAtStart = (length - bytesAtEnd);
(void)memcpy(dest, resolve(currentReadCursor, startIndex), bytesAtEnd);
if (bytesAtStart > 0) {
(void)memcpy(&dest[bytesAtEnd], buf, bytesAtStart);
}
return true;
}
void RingBuffer::clear() {
pop(size());
}
}
+830 -68
View File
File diff suppressed because it is too large Load Diff
+58 -38
View File
@@ -2,6 +2,7 @@
#include "icsneo/platform/devices.h" #include "icsneo/platform/devices.h"
#include "icsneo/device/founddevice.h" #include "icsneo/device/founddevice.h"
#include "generated/extensions/builtin.h" #include "generated/extensions/builtin.h"
#include "icsneo/platform/servd.h"
#ifdef ICSNEO_ENABLE_FIRMIO #ifdef ICSNEO_ENABLE_FIRMIO
#include "icsneo/platform/firmio.h" #include "icsneo/platform/firmio.h"
@@ -15,12 +16,8 @@
#include "icsneo/platform/cdcacm.h" #include "icsneo/platform/cdcacm.h"
#endif #endif
#ifdef ICSNEO_ENABLE_FTDI #ifdef ICSNEO_ENABLE_DXX
#include "icsneo/platform/ftdi.h" #include "icsneo/platform/dxx.h"
#endif
#ifdef ICSNEO_ENABLE_FTD3XX
#include "icsneo/platform/ftd3xx.h"
#endif #endif
#ifdef ICSNEO_ENABLE_TCP #ifdef ICSNEO_ENABLE_TCP
@@ -38,15 +35,6 @@ static void makeIfSerialMatches(const FoundDevice& dev, std::vector<std::shared_
into.push_back(std::make_shared<T>(dev)); into.push_back(std::make_shared<T>(dev));
} }
template<typename T>
static void makeIfPIDMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
// Relies on the subclass to have a `static constexpr uint16_t PRODUCT_ID = 0x1111`
// and also a public constructor `T(const FoundDevice& dev)`
// Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these
if(dev.productId == T::PRODUCT_ID)
into.push_back(std::make_shared<T>(dev));
}
template<typename T> template<typename T>
static void makeIfSerialRangeMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) { static void makeIfSerialRangeMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
// Relies on the subclass to have // Relies on the subclass to have
@@ -63,29 +51,29 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
static std::vector<FoundDevice> newDriverFoundDevices; static std::vector<FoundDevice> newDriverFoundDevices;
newDriverFoundDevices.clear(); newDriverFoundDevices.clear();
#ifdef ICSNEO_ENABLE_FIRMIO if(Servd::Enabled()) {
FirmIO::Find(newDriverFoundDevices); Servd::Find(newDriverFoundDevices);
#endif } else {
#ifdef ICSNEO_ENABLE_FIRMIO
FirmIO::Find(newDriverFoundDevices);
#endif
#ifdef ICSNEO_ENABLE_TCP #ifdef ICSNEO_ENABLE_TCP
TCP::Find(newDriverFoundDevices); TCP::Find(newDriverFoundDevices);
#endif #endif
#ifdef ICSNEO_ENABLE_RAW_ETHERNET #ifdef ICSNEO_ENABLE_RAW_ETHERNET
PCAP::Find(newDriverFoundDevices); PCAP::Find(newDriverFoundDevices);
#endif #endif
#ifdef ICSNEO_ENABLE_CDCACM #ifdef ICSNEO_ENABLE_CDCACM
CDCACM::Find(newDriverFoundDevices); CDCACM::Find(newDriverFoundDevices);
#endif #endif
#ifdef ICSNEO_ENABLE_FTDI #ifdef ICSNEO_ENABLE_DXX
FTDI::Find(newDriverFoundDevices); DXX::Find(newDriverFoundDevices);
#endif #endif
}
#ifdef ICSNEO_ENABLE_FTD3XX
FTD3XX::Find(newDriverFoundDevices);
#endif
// Weak because we don't want to keep devices open if they go out of scope elsewhere // Weak because we don't want to keep devices open if they go out of scope elsewhere
static std::vector<std::weak_ptr<Device>> foundDevices; static std::vector<std::weak_ptr<Device>> foundDevices;
@@ -142,7 +130,7 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
#endif #endif
#ifdef __NEOVIFIRE_H_ #ifdef __NEOVIFIRE_H_
makeIfPIDMatches<NeoVIFIRE>(dev, newFoundDevices); makeIfSerialRangeMatches<NeoVIFIRE>(dev, newFoundDevices);
#endif #endif
#ifdef __NEOVIFIRE2_H_ #ifdef __NEOVIFIRE2_H_
@@ -157,16 +145,20 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
makeIfSerialMatches<NeoVIFIRE3FlexRay>(dev, newFoundDevices); makeIfSerialMatches<NeoVIFIRE3FlexRay>(dev, newFoundDevices);
#endif #endif
#ifdef __NEOVIFIRE3T1SLIN_H_
makeIfSerialMatches<NeoVIFIRE3T1SLIN>(dev, newFoundDevices);
#endif
#ifdef __NEOVIRED2_H_ #ifdef __NEOVIRED2_H_
makeIfSerialMatches<NeoVIRED2>(dev, newFoundDevices); makeIfSerialMatches<NeoVIRED2>(dev, newFoundDevices);
#endif #endif
#ifdef __NEOVIION_H_ #ifdef __NEOVIION_H_
makeIfPIDMatches<NeoVIION>(dev, newFoundDevices); makeIfSerialMatches<NeoVIION>(dev, newFoundDevices);
#endif #endif
#ifdef __NEOVIPLASMA_H_ #ifdef __NEOVIPLASMA_H_
makeIfPIDMatches<NeoVIPLASMA>(dev, newFoundDevices); makeIfSerialMatches<NeoVIPLASMA>(dev, newFoundDevices);
#endif #endif
#ifdef __RADA2B_H_ #ifdef __RADA2B_H_
@@ -193,10 +185,18 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
makeIfSerialMatches<RADEpsilon>(dev, newFoundDevices); makeIfSerialMatches<RADEpsilon>(dev, newFoundDevices);
#endif #endif
#ifdef __RADEPSILONXL_H_
makeIfSerialMatches<RADEpsilonXL>(dev, newFoundDevices);
#endif
#ifdef __RADGALAXY_H_ #ifdef __RADGALAXY_H_
makeIfSerialMatches<RADGalaxy>(dev, newFoundDevices); makeIfSerialMatches<RADGalaxy>(dev, newFoundDevices);
#endif #endif
#ifdef __RADGALAXY2_H_
makeIfSerialMatches<RADGalaxy2>(dev, newFoundDevices);
#endif
#ifdef __RADMARS_H_ #ifdef __RADMARS_H_
makeIfSerialMatches<RADMars>(dev, newFoundDevices); makeIfSerialMatches<RADMars>(dev, newFoundDevices);
#endif #endif
@@ -225,6 +225,10 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
makeIfSerialMatches<RADMoon3>(dev, newFoundDevices); makeIfSerialMatches<RADMoon3>(dev, newFoundDevices);
#endif #endif
#ifdef __RADGEMINI_H_
makeIfSerialMatches<RADGemini>(dev, newFoundDevices);
#endif
#ifdef __RADMOONDUO_H_ #ifdef __RADMOONDUO_H_
makeIfSerialMatches<RADMoonDuo>(dev, newFoundDevices); makeIfSerialMatches<RADMoonDuo>(dev, newFoundDevices);
#endif #endif
@@ -242,7 +246,7 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
#endif #endif
#ifdef __VALUECAN3_H_ #ifdef __VALUECAN3_H_
makeIfPIDMatches<ValueCAN3>(dev, newFoundDevices); makeIfSerialRangeMatches<ValueCAN3>(dev, newFoundDevices);
#endif #endif
#ifdef __VALUECAN4_1_H_ #ifdef __VALUECAN4_1_H_
@@ -320,6 +324,10 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
NeoVIFIRE3FlexRay::DEVICE_TYPE, NeoVIFIRE3FlexRay::DEVICE_TYPE,
#endif #endif
#ifdef __NEOVIFIRE3T1SLIN_H_
NeoVIFIRE3T1SLIN::DEVICE_TYPE,
#endif
#ifdef __NEOVIION_H_ #ifdef __NEOVIION_H_
NeoVIION::DEVICE_TYPE, NeoVIION::DEVICE_TYPE,
#endif #endif
@@ -348,10 +356,18 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
RADEpsilon::DEVICE_TYPE, RADEpsilon::DEVICE_TYPE,
#endif #endif
#ifdef __RADEPSILONXL_H_
RADEpsilonXL::DEVICE_TYPE,
#endif
#ifdef __RADGALAXY_H_ #ifdef __RADGALAXY_H_
RADGalaxy::DEVICE_TYPE, RADGalaxy::DEVICE_TYPE,
#endif #endif
#ifdef __RADGALAXY2_H_
RADGalaxy2::DEVICE_TYPE,
#endif
#ifdef __RADMARS_H_ #ifdef __RADMARS_H_
RADMars::DEVICE_TYPE, RADMars::DEVICE_TYPE,
#endif #endif
@@ -372,6 +388,10 @@ const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
RADMoon3::DEVICE_TYPE, RADMoon3::DEVICE_TYPE,
#endif #endif
#ifdef __RADGEMINI_H_
RADGemini::DEVICE_TYPE,
#endif
#ifdef __RADMOONDUO_H_ #ifdef __RADMOONDUO_H_
RADMoonDuo::DEVICE_TYPE, RADMoonDuo::DEVICE_TYPE,
#endif #endif
+45 -53
View File
@@ -3,16 +3,6 @@
using namespace icsneo; using namespace icsneo;
void FlexRay::Controller::_setStatus(std::shared_ptr<FlexRayControlMessage> msg) {
std::lock_guard<std::mutex> lk(statusLock);
status = msg;
}
std::shared_ptr<FlexRayControlMessage> FlexRay::Controller::getStatus() const {
std::lock_guard<std::mutex> lk(statusLock);
return status;
}
std::pair<const FlexRay::Cluster::Configuration&, const FlexRay::Controller::Configuration&> FlexRay::Controller::getConfiguration() const { std::pair<const FlexRay::Cluster::Configuration&, const FlexRay::Controller::Configuration&> FlexRay::Controller::getConfiguration() const {
return { clusterConfig, controllerConfig }; return { clusterConfig, controllerConfig };
} }
@@ -74,7 +64,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
((controllerConfig.KeySlotUsedForStartup & 0x1) << 8) | // TXST ((controllerConfig.KeySlotUsedForStartup & 0x1) << 8) | // TXST
((controllerConfig.KeySlotUsedForSync & 0x1) << 9) | // TXSY ((controllerConfig.KeySlotUsedForSync & 0x1) << 9) | // TXSY
((clusterConfig.ColdStartAttempts & 0x1f) << 11) | // CSA ((clusterConfig.ColdStartAttempts & 0x1f) << 11) | // CSA
((controllerConfig.AllowPassiveToActiveCyclePairs & 0x1f) << 16) | // PTA ((controllerConfig.AllowPassiveToActiveCyclePairs & 0x1F) << 16) | // PTA
((controllerConfig.WakeupOnChannelB & 0x1) << 21) | // WUCS ((controllerConfig.WakeupOnChannelB & 0x1) << 21) | // WUCS
((controllerConfig.KeySlotOnlyEnabled & 0x1) << 22) | // TSM ((controllerConfig.KeySlotOnlyEnabled & 0x1) << 22) | // TSM
((controllerConfig.AllowHaltDueToClock & 0x1) << 23) | // HCSE ((controllerConfig.AllowHaltDueToClock & 0x1) << 23) | // HCSE
@@ -85,99 +75,100 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
}); });
registerWrites.push_back({ ERAYRegister::SUCC2, registerWrites.push_back({ ERAYRegister::SUCC2,
((controllerConfig.ListenTimeout & 0x1fffff)) | ((controllerConfig.ListenTimeout & 0x1FFFFF)) |
((clusterConfig.ListenNoiseMacroticks - 1) << 24) (((clusterConfig.ListenNoiseMacroticks - 1) & 0xF) << 24)
}); });
registerWrites.push_back({ ERAYRegister::SUCC3, registerWrites.push_back({ ERAYRegister::SUCC3,
(clusterConfig.MaxWithoutClockCorrectionPassive & 0xF) | (clusterConfig.MaxWithoutClockCorrectionPassive & 0xF) |
((clusterConfig.MaxWithoutClockCorrectionFatal) << 4) ((clusterConfig.MaxWithoutClockCorrectionFatal & 0xF) << 4)
}); });
registerWrites.push_back({ ERAYRegister::NEMC, registerWrites.push_back({ ERAYRegister::NEMC,
clusterConfig.NetworkManagementVectorLengthBytes clusterConfig.NetworkManagementVectorLengthBytes & 0xF
}); });
registerWrites.push_back({ ERAYRegister::PRTC1, registerWrites.push_back({ ERAYRegister::PRTC1,
(clusterConfig.TransmissionStartSequenceDurationBits & 0xF) | (clusterConfig.TransmissionStartSequenceDurationBits & 0xF) |
((clusterConfig.CASRxLowMax & 0x3F) << 4) | ((clusterConfig.CASRxLowMax & 0x1F) << 4) |
(0x1 << 10) | // Most significant bit of CASRxLowMax. Hardwired to 1 and cannot be modified
((clusterConfig.StrobePointPosition & 0x3) << 12) | ((clusterConfig.StrobePointPosition & 0x3) << 12) |
((clusterConfig.Speed & 0x3) << 14) | ((clusterConfig.Speed & 0x3) << 14) |
((clusterConfig.WakeupRxWindowBits & 0x1ff) << 16) | ((clusterConfig.WakeupRxWindowBits & 0x1FF) << 16) |
((controllerConfig.WakeupPattern) << 26) ((controllerConfig.WakeupPattern & 0x3F) << 26)
}); });
registerWrites.push_back({ ERAYRegister::PRTC2, registerWrites.push_back({ ERAYRegister::PRTC2,
(clusterConfig.WakeupRxIdleBits) | (clusterConfig.WakeupRxIdleBits & 0x3F) |
((clusterConfig.WakeupRxLowBits) << 8) | ((clusterConfig.WakeupRxLowBits & 0x3F) << 8) |
((clusterConfig.WakeupTxIdleBits) << 16) | ((clusterConfig.WakeupTxIdleBits) << 16) |
((clusterConfig.WakeupTxActiveBits) << 24) ((clusterConfig.WakeupTxActiveBits & 0x3F) << 24)
}); });
registerWrites.push_back({ ERAYRegister::MHDC, registerWrites.push_back({ ERAYRegister::MHDC,
(clusterConfig.PayloadLengthOfStaticSlotInWords) | (clusterConfig.PayloadLengthOfStaticSlotInWords & 0x7F) |
((controllerConfig.LatestTxMinislot) << 16) ((controllerConfig.LatestTxMinislot & 0x1FFF) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC1, registerWrites.push_back({ ERAYRegister::GTUC1,
controllerConfig.MicroPerCycle controllerConfig.MicroPerCycle & 0xFFFFF
}); });
registerWrites.push_back({ ERAYRegister::GTUC2, registerWrites.push_back({ ERAYRegister::GTUC2,
(clusterConfig.SyncFrameIDCountMax << 16) | (clusterConfig.SyncFrameIDCountMax << 16) |
clusterConfig.MacroticksPerCycle (clusterConfig.MacroticksPerCycle & 0x3FFF)
}); });
registerWrites.push_back({ ERAYRegister::GTUC3, registerWrites.push_back({ ERAYRegister::GTUC3,
(controllerConfig.MicroInitialOffsetA) | (controllerConfig.MicroInitialOffsetA) |
((controllerConfig.MicroInitialOffsetB) << 8) | ((controllerConfig.MicroInitialOffsetB) << 8) |
((controllerConfig.MacroInitialOffsetA) << 16) | ((controllerConfig.MacroInitialOffsetA & 0x7F) << 16) |
((controllerConfig.MacroInitialOffsetB) << 24) ((controllerConfig.MacroInitialOffsetB & 0x7F) << 24)
}); });
registerWrites.push_back({ ERAYRegister::GTUC4, registerWrites.push_back({ ERAYRegister::GTUC4,
((clusterConfig.MacroticksPerCycle - clusterConfig.NetworkIdleTimeMacroticks - 1) & 0xFFFF) | ((clusterConfig.MacroticksPerCycle - clusterConfig.NetworkIdleTimeMacroticks - 1) & 0x3FFF) |
((clusterConfig.OffsetCorrectionStartMacroticks - 1) << 16) (((clusterConfig.OffsetCorrectionStartMacroticks - 1) & 0x3FFF) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC5, registerWrites.push_back({ ERAYRegister::GTUC5,
controllerConfig.DelayCompensationAMicroticks | controllerConfig.DelayCompensationAMicroticks |
(controllerConfig.DelayCompensationBMicroticks << 8) | (controllerConfig.DelayCompensationBMicroticks << 8) |
(controllerConfig.ClusterDriftDamping << 16) | ((controllerConfig.ClusterDriftDamping & 0x1F) << 16) |
(controllerConfig.DecodingCorrectionMicroticks << 24) (controllerConfig.DecodingCorrectionMicroticks << 24)
}); });
registerWrites.push_back({ ERAYRegister::GTUC6, registerWrites.push_back({ ERAYRegister::GTUC6,
controllerConfig.AcceptStartupRangeMicroticks | (controllerConfig.AcceptStartupRangeMicroticks & 0x7FF) |
(controllerConfig.RateCorrectionOutMicroticks << 16) ((controllerConfig.RateCorrectionOutMicroticks & 0x7FF) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC7, registerWrites.push_back({ ERAYRegister::GTUC7,
(clusterConfig.StaticSlotMacroticks) | (clusterConfig.StaticSlotMacroticks & 0x3FF) |
(clusterConfig.NumberOfStaticSlots << 16) ((clusterConfig.NumberOfStaticSlots & 0x3FF) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC8, registerWrites.push_back({ ERAYRegister::GTUC8,
clusterConfig.MinislotDurationMacroticks | (clusterConfig.MinislotDurationMacroticks & 0x3F) |
(clusterConfig.NumberOfMinislots << 16) ((clusterConfig.NumberOfMinislots & 0x1FFF) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC9, registerWrites.push_back({ ERAYRegister::GTUC9,
clusterConfig.ActionPointOffset | (clusterConfig.ActionPointOffset & 0x3F) |
(clusterConfig.MinislotActionPointOffsetMacroticks << 8) | ((clusterConfig.MinislotActionPointOffsetMacroticks & 0x1F) << 8) |
(clusterConfig.DynamicSlotIdlePhaseMinislots << 16) ((clusterConfig.DynamicSlotIdlePhaseMinislots & 0x03) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC10, registerWrites.push_back({ ERAYRegister::GTUC10,
controllerConfig.OffsetCorrectionOutMicroticks | (controllerConfig.OffsetCorrectionOutMicroticks & 0x3FFF) |
(controllerConfig.RateCorrectionOutMicroticks << 16) ((controllerConfig.RateCorrectionOutMicroticks & 0x7FF) << 16)
}); });
registerWrites.push_back({ ERAYRegister::GTUC11, registerWrites.push_back({ ERAYRegister::GTUC11,
controllerConfig.ExternOffsetCorrectionControl | (controllerConfig.ExternOffsetCorrectionControl & 0x3) |
(controllerConfig.ExternRateCorrectionControl << 8) | ((controllerConfig.ExternRateCorrectionControl & 0x3) << 8) |
(controllerConfig.ExternOffsetCorrectionMicroticks << 16) | ((controllerConfig.ExternOffsetCorrectionMicroticks & 0x7) << 16) |
(controllerConfig.ExternRateCorrectionMicroticks << 24) ((controllerConfig.ExternRateCorrectionMicroticks & 0x7) << 24)
}); });
std::vector<std::shared_ptr<MessageBuffer>> staticTx; std::vector<std::shared_ptr<MessageBuffer>> staticTx;
@@ -210,7 +201,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
second->isStartup = controllerConfig.KeySlotUsedForStartup; second->isStartup = controllerConfig.KeySlotUsedForStartup;
second->isSync = controllerConfig.KeySlotUsedForSync; second->isSync = controllerConfig.KeySlotUsedForSync;
second->isTransmit = true; second->isTransmit = true;
second->channelB =true; second->channelB = true;
second->frameID = controllerConfig.SecondKeySlotID; second->frameID = controllerConfig.SecondKeySlotID;
second->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2; second->frameLengthBytes = clusterConfig.PayloadLengthOfStaticSlotInWords * 2;
second->baseCycle = 0; second->baseCycle = 0;
@@ -266,7 +257,7 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
totalBuffers = 128; totalBuffers = 128;
registerWrites.push_back({ ERAYRegister::MRC, registerWrites.push_back({ ERAYRegister::MRC,
(uint8_t(staticTx.size())) | // FDB[7:0] message buffers exclusively for the static segment (static_cast<uint8_t>(staticTx.size())) | // FDB[7:0] message buffers exclusively for the static segment
// FFB[7:0] set to 0x80, No message buffer assigned to the FIFO // FFB[7:0] set to 0x80, No message buffer assigned to the FIFO
(0x80 << 8) | (0x80 << 8) |
(uint8_t(totalBuffers - 1) << 16) | (uint8_t(totalBuffers - 1) << 16) |
@@ -287,12 +278,12 @@ bool FlexRay::Controller::configure(std::chrono::milliseconds timeout) {
buf.frameID = static_cast<uint16_t>(i | (1 << 10)); buf.frameID = static_cast<uint16_t>(i | (1 << 10));
uint32_t hs1 = ( uint32_t hs1 = (
(buf.frameID) | (buf.frameID) | // FID
(CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition) << 16) | (CalculateCycleFilter(buf.baseCycle, buf.cycleRepetition) << 16) | // CYA
((buf.channelA & 0x1) << 24) | ((buf.channelA & 0x1) << 24) | // CHA
((buf.channelB & 0x1) << 25) | ((buf.channelB & 0x1) << 25) | // CHB
((buf.isTransmit & 0x1) << 26) | // CFG ((buf.isTransmit & 0x1) << 26) | // CFG
((buf.isNMFrame & 0x1) << 27) | // PPIT ((buf.isNetworkManagementFrame & 0x1) << 27) | // PPIT
((!buf.continuousMode & 0x1) << 28) | // TXM ((!buf.continuousMode & 0x1) << 28) | // TXM
((0 & 0x1) << 29) // MBI, disabled for now but we might want confirmations in the future ((0 & 0x1) << 29) // MBI, disabled for now but we might want confirmations in the future
); );
@@ -610,7 +601,8 @@ uint16_t FlexRay::Controller::CalculateCycleFilter(uint8_t baseCycle, uint8_t cy
} }
std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const { std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const {
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(icsneo::Network::NetID::FlexRayControl); static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>();
filter->includeInternalInAny = true;
if(timeout.count() <= 20) if(timeout.count() <= 20)
return {false, 0}; // Out of time! return {false, 0}; // Out of time!
-20
View File
@@ -25,26 +25,6 @@ void FlexRay::Extension::onGoOffline() {
controller->halt(); controller->halt();
} }
void FlexRay::Extension::handleMessage(const std::shared_ptr<Message>& message) {
switch(message->type) {
case Message::Type::FlexRayControl: {
auto msg = std::dynamic_pointer_cast<FlexRayControlMessage>(message);
if(!msg || !msg->decoded)
return;
switch(msg->opcode) {
case FlexRay::Opcode::ReadCCStatus:
if(msg->controller >= controllers.size())
return; // TODO error
controllers[msg->controller]->_setStatus(msg);
break;
}
break;
}
default:
break;
}
}
bool FlexRay::Extension::transmitHook(const std::shared_ptr<Frame>& frame, bool& success) { bool FlexRay::Extension::transmitHook(const std::shared_ptr<Frame>& frame, bool& success) {
if(!frame || frame->network.getType() != Network::Type::FlexRay) if(!frame || frame->network.getType() != Network::Type::FlexRay)
return true; // Don't hook non-FlexRay messages return true; // Don't hook non-FlexRay messages
+9 -35
View File
@@ -4,9 +4,9 @@
using namespace icsneo; using namespace icsneo;
std::optional<uint16_t> IDeviceSettings::CalculateGSChecksum(const std::vector<uint8_t>& settings, std::optional<size_t> knownSize) { std::optional<uint16_t> IDeviceSettings::CalculateGSChecksum(const std::vector<uint8_t>& settings) {
const uint16_t* p = reinterpret_cast<const uint16_t*>(settings.data()); const uint16_t* p = reinterpret_cast<const uint16_t*>(settings.data());
size_t words = std::min(knownSize.value_or(0), settings.size()); size_t words = settings.size();
if(words % 2 == 1) if(words % 2 == 1)
return std::nullopt; // Somehow settings is not word aligned return std::nullopt; // Somehow settings is not word aligned
words /= 2; words /= 2;
@@ -159,15 +159,12 @@ bool IDeviceSettings::ValidateLINBaudrate(int64_t baudrate) {
} }
} }
bool IDeviceSettings::refresh(bool ignoreChecksum) { bool IDeviceSettings::refresh() {
if(disabled) { if(disabled) {
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
return false; return false;
} }
if(disableGSChecksumming)
ignoreChecksum = true;
std::vector<uint8_t> rxSettings; std::vector<uint8_t> rxSettings;
bool ret = com->getSettingsSync(rxSettings); bool ret = com->getSettingsSync(rxSettings);
if(!ret) { if(!ret) {
@@ -175,24 +172,14 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) {
return false; return false;
} }
constexpr size_t GsSize = 3 * sizeof(uint16_t); constexpr size_t GsSize = 3 * sizeof(uint16_t); // <version> <length> <checksum>
if(rxSettings.size() < GsSize) { // We need to at least have the header of GLOBAL_SETTINGS if(rxSettings.size() < GsSize) { // We need to at least have the header of GLOBAL_SETTINGS
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
return false; return false;
} }
// The length of the settings structure sent to us
// This is the length the firmware thinks the current version of the structure is
const size_t rxLen = rxSettings.size() - GsSize;
const uint16_t gsVersion = rxSettings[0] | (rxSettings[1] << 8); const uint16_t gsVersion = rxSettings[0] | (rxSettings[1] << 8);
// The length of the settings last saved
// If the firmware is updated, it will have either extended (with zeros) or truncated
// the structure, but this value will continue to be set to the last saved value
const uint16_t gsLen = rxSettings[2] | (rxSettings[3] << 8);
const uint16_t gsChecksum = rxSettings[4] | (rxSettings[5] << 8);
rxSettings.erase(rxSettings.begin(), rxSettings.begin() + GsSize); rxSettings.erase(rxSettings.begin(), rxSettings.begin() + GsSize);
if(gsVersion != GS_VERSION) { if(gsVersion != GS_VERSION) {
@@ -200,19 +187,6 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) {
return false; return false;
} }
if(rxLen < gsLen) {
// We got less data, i.e. the firmware thinks the strucure is smaller than what
// was last saved. Usually this is due to a firmware downgrade. We'll ignore the
// checksum for now, because it will definitely be wrong.
ignoreChecksum = true;
}
// We check the checksum against the data last saved
if(!ignoreChecksum && gsChecksum != CalculateGSChecksum(rxSettings, gsLen)) {
report(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error);
return false;
}
settings = std::move(rxSettings); settings = std::move(rxSettings);
settingsInDeviceRAM = settings; settingsInDeviceRAM = settings;
settingsLoaded = true; settingsLoaded = true;
@@ -261,7 +235,7 @@ bool IDeviceSettings::apply(bool temporary) {
std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() { std::shared_ptr<Main51Message> msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
return com->sendCommand(Command::SetSettings, bytestream); return com->sendCommand(Command::SetSettings, bytestream);
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(2000)));
if(!msg || msg->data[0] != 1) { // We did not receive a response if(!msg || msg->data[0] != 1) { // We did not receive a response
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
@@ -272,7 +246,7 @@ bool IDeviceSettings::apply(bool temporary) {
return false; return false;
} }
refresh(true); // Refresh ignoring checksum refresh();
// The device might modify the settings once they are applied, however in this case it does not update the checksum // The device might modify the settings once they are applied, however in this case it does not update the checksum
// We refresh to get these updates, update the checksum, and send it back so it's all in sync // We refresh to get these updates, update the checksum, and send it back so it's all in sync
gsChecksum = CalculateGSChecksum(settings); gsChecksum = CalculateGSChecksum(settings);
@@ -287,7 +261,7 @@ bool IDeviceSettings::apply(bool temporary) {
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() { msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
return com->sendCommand(Command::SetSettings, bytestream); return com->sendCommand(Command::SetSettings, bytestream);
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(2000)));
if(!msg || msg->data[0] != 1) { if(!msg || msg->data[0] != 1) {
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
if(refresh()) { if(refresh()) {
@@ -342,7 +316,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
// This short wait helps on FIRE devices, otherwise the checksum might be wrong! // This short wait helps on FIRE devices, otherwise the checksum might be wrong!
std::this_thread::sleep_for(std::chrono::milliseconds(3)); std::this_thread::sleep_for(std::chrono::milliseconds(3));
refresh(true); // Refresh ignoring checksum refresh();
// The device might modify the settings once they are applied, however in this case it does not update the checksum // The device might modify the settings once they are applied, however in this case it does not update the checksum
// We refresh to get these updates, update the checksum, and send it back so it's all in sync // We refresh to get these updates, update the checksum, and send it back so it's all in sync
std::vector<uint8_t> bytestream; std::vector<uint8_t> bytestream;
@@ -364,7 +338,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() { msg = std::dynamic_pointer_cast<Main51Message>(com->waitForMessageSync([this, &bytestream]() {
return com->sendCommand(Command::SetSettings, bytestream); return com->sendCommand(Command::SetSettings, bytestream);
}, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000))); }, std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(2000)));
if(!msg || msg->data[0] != 1) { if(!msg || msg->data[0] != 1) {
// Attempt to get the settings from the device so we're up to date if possible // Attempt to get the settings from the device so we're up to date if possible
if(refresh()) { if(refresh()) {
+81
View File
@@ -0,0 +1,81 @@
#include <icsneo/disk/diskdetails.h>
#include <icsneo/device/idevicesettings.h>
using namespace icsneo;
#pragma pack(push, 2)
struct DISK_STATUS {
uint16_t status;
uint64_t sectors;
uint32_t bytesPerSector;
};
struct DISK_DETAILS {
DISK_SETTINGS settings;
uint16_t options;
DISK_STATUS status[12];
};
#pragma pack(pop)
static constexpr uint8_t DISK_FORMAT_FAT32 = 0x01u;
static constexpr uint8_t DISK_STATUS_PRESENT = 0x01u;
static constexpr uint8_t DISK_STATUS_INITIALIZED = 0x02u;
static constexpr uint16_t DISK_DETAILS_FULL_FORMAT = 0x01u;
std::vector<uint8_t> DiskDetails::Encode(const DiskDetails& config) {
std::vector<uint8_t> result(sizeof(DISK_DETAILS), 0);
DISK_DETAILS* details = reinterpret_cast<DISK_DETAILS*>(result.data());
details->settings.disk_layout = static_cast<uint8_t>(config.layout);
details->settings.disk_format = DISK_FORMAT_FAT32; // Always FAT32
details->options = config.fullFormat ? DISK_DETAILS_FULL_FORMAT : 0;
uint32_t& enables = details->settings.disk_enables;
enables = 0u;
for(size_t i = 0; i < config.disks.size(); i++) {
auto& disk = config.disks[i];
details->status[i].sectors = disk.sectors;
details->status[i].bytesPerSector = disk.bytesPerSector;
uint16_t& status = details->status[i].status;
status = 0u;
if(disk.initialized) {
status |= DISK_STATUS_INITIALIZED;
}
if(disk.present) {
status |= DISK_STATUS_PRESENT;
}
if(disk.formatted) {
enables |= (1u << i);
}
}
return result;
}
std::shared_ptr<DiskDetails> DiskDetails::Decode(const std::vector<uint8_t>& bytes, size_t diskCount, device_eventhandler_t report) {
if(bytes.size() < sizeof(DISK_DETAILS)) {
report(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
return nullptr;
}
auto result = std::make_shared<DiskDetails>();
const DISK_DETAILS* details = reinterpret_cast<const DISK_DETAILS*>(bytes.data());
result->layout = static_cast<DiskLayout>(details->settings.disk_layout);
result->fullFormat = details->options & DISK_DETAILS_FULL_FORMAT;
result->disks.reserve(diskCount);
for(size_t i = 0; i < diskCount; i++) {
auto& disk = details->status[i];
result->disks.emplace_back();
auto& info = result->disks.back();
info.present = static_cast<bool>(disk.status & DISK_STATUS_PRESENT);
info.initialized = static_cast<bool>(disk.status & DISK_STATUS_INITIALIZED);
info.formatted = static_cast<bool>(details->settings.disk_enables & (1u << i));
info.sectors = disk.sectors;
info.bytesPerSector = disk.bytesPerSector;
}
return result;
}
+1 -1
View File
@@ -32,7 +32,7 @@ std::optional<uint64_t> ExtExtractorDiskReadDriver::readLogicalDiskAligned(Commu
return ret; return ret;
} }
std::optional<uint64_t> ExtExtractorDiskReadDriver::attemptReadLogicalDiskAligned(Communication& com, device_eventhandler_t report, std::optional<uint64_t> ExtExtractorDiskReadDriver::attemptReadLogicalDiskAligned(Communication& com, device_eventhandler_t,
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType) { uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType) {
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead); static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead);
+1 -1
View File
@@ -58,7 +58,7 @@ std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio
return SectorSize; return SectorSize;
} }
std::optional<uint64_t> NeoMemoryDiskDriver::writeLogicalDiskAligned(Communication& com, device_eventhandler_t report, std::optional<uint64_t> NeoMemoryDiskDriver::writeLogicalDiskAligned(Communication& com, device_eventhandler_t,
uint64_t pos, const uint8_t* from, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) { uint64_t pos, const uint8_t* from, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) {
static std::shared_ptr<MessageFilter> NeoMemoryDone = std::make_shared<MessageFilter>(Network::NetID::NeoMemoryWriteDone); static std::shared_ptr<MessageFilter> NeoMemoryDone = std::make_shared<MessageFilter>(Network::NetID::NeoMemoryWriteDone);
+1 -1
View File
@@ -6,7 +6,7 @@
using namespace icsneo; using namespace icsneo;
using namespace icsneo::Disk; using namespace icsneo::Disk;
std::optional<uint64_t> PlasionDiskReadDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report, std::optional<uint64_t> PlasionDiskReadDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t,
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType) { uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType) {
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead); static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead);
-15
View File
@@ -26,18 +26,3 @@ void VSAExtendedMessage::appendPacket(std::shared_ptr<Packet> packet) const
packet->network = network; packet->network = network;
} }
} }
void VSAExtendedMessage::truncatePacket(std::shared_ptr<Packet> packet)
{
static constexpr auto EthernetLengthOffset = 26u;
switch(packet->network.getType()) {
case Network::Type::Ethernet:
{
const auto& packetLength = *reinterpret_cast<uint16_t*>(packet->data.data() + EthernetLengthOffset);
const size_t ethernetFrameSize = packetLength - (sizeof(uint16_t) * 2);
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + ethernetFrameSize;
packet->data.resize(bytestreamExpectedSize);
}
break;
}
}
+1 -1
View File
@@ -9,7 +9,7 @@ VSA02::VSA02(uint8_t* const recordBytes)
constantIndex = *reinterpret_cast<uint16_t*>(recordBytes + 2); constantIndex = *reinterpret_cast<uint16_t*>(recordBytes + 2);
flags = *reinterpret_cast<Flags*>(recordBytes + 4); flags = *reinterpret_cast<Flags*>(recordBytes + 4);
pieceCount = recordBytes[5]; pieceCount = recordBytes[5];
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6);
samples.insert(samples.end(), recordBytes + 14, recordBytes + 30); samples.insert(samples.end(), recordBytes + 14, recordBytes + 30);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30);
doChecksum(recordBytes); doChecksum(recordBytes);
+1 -1
View File
@@ -8,7 +8,7 @@ VSA03::VSA03(uint8_t* const recordBytes)
setType(VSA::Type::AA03); setType(VSA::Type::AA03);
eventType = static_cast<EventType>(*reinterpret_cast<uint16_t*>(recordBytes + 2)); eventType = static_cast<EventType>(*reinterpret_cast<uint16_t*>(recordBytes + 2));
eventData = *reinterpret_cast<uint16_t*>(recordBytes + 4); eventData = *reinterpret_cast<uint16_t*>(recordBytes + 4);
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 14); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 14);
doChecksum(recordBytes); doChecksum(recordBytes);
} }
+1 -1
View File
@@ -8,7 +8,7 @@ VSA04::VSA04(uint8_t* const recordBytes)
setType(VSA::Type::AA04); setType(VSA::Type::AA04);
flags = *reinterpret_cast<Flags*>(recordBytes + 2); flags = *reinterpret_cast<Flags*>(recordBytes + 2);
partitionIndex = *reinterpret_cast<uint16_t*>(recordBytes + 4); partitionIndex = *reinterpret_cast<uint16_t*>(recordBytes + 4);
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 14); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 14);
doChecksum(recordBytes); doChecksum(recordBytes);
} }
+1 -1
View File
@@ -8,7 +8,7 @@ VSA05::VSA05(uint8_t* const recordBytes)
setType(VSA::Type::AA05); setType(VSA::Type::AA05);
errorType = static_cast<ErrorType>(*reinterpret_cast<uint16_t*>(recordBytes + 2)); errorType = static_cast<ErrorType>(*reinterpret_cast<uint16_t*>(recordBytes + 2));
errorNetwork = *reinterpret_cast<uint16_t*>(recordBytes + 4); errorNetwork = *reinterpret_cast<uint16_t*>(recordBytes + 4);
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 6);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 14); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 14);
} }
+1 -1
View File
@@ -9,7 +9,7 @@ VSA06::VSA06(uint8_t* const recordBytes)
savedSectors.insert(savedSectors.end(), reinterpret_cast<uint32_t*>(recordBytes + 2), reinterpret_cast<uint32_t*>(recordBytes + 18)); savedSectors.insert(savedSectors.end(), reinterpret_cast<uint32_t*>(recordBytes + 2), reinterpret_cast<uint32_t*>(recordBytes + 18));
error = *reinterpret_cast<uint16_t*>(recordBytes + 18); error = *reinterpret_cast<uint16_t*>(recordBytes + 18);
savedSectorsHigh = *reinterpret_cast<uint16_t*>(recordBytes + 20); savedSectorsHigh = *reinterpret_cast<uint16_t*>(recordBytes + 20);
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 22) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 22);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30);
doChecksum(recordBytes); doChecksum(recordBytes);
} }
+1 -1
View File
@@ -9,7 +9,7 @@ VSA07::VSA07(uint8_t* const recordBytes)
lastSector = *reinterpret_cast<uint32_t*>(recordBytes + 2); lastSector = *reinterpret_cast<uint32_t*>(recordBytes + 2);
currentSector = *reinterpret_cast<uint32_t*>(recordBytes + 6); currentSector = *reinterpret_cast<uint32_t*>(recordBytes + 6);
reserved.insert(reserved.end(), recordBytes + 10, recordBytes + 22); reserved.insert(reserved.end(), recordBytes + 10, recordBytes + 22);
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 22) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 22);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30);
doChecksum(recordBytes); doChecksum(recordBytes);
} }
+2 -2
View File
@@ -7,8 +7,8 @@ VSA08::VSA08(uint8_t* const recordBytes)
{ {
setType(VSA::Type::AA08); setType(VSA::Type::AA08);
troubleSramCount.insert(troubleSramCount.end(), recordBytes + 2, recordBytes + 6); troubleSramCount.insert(troubleSramCount.end(), recordBytes + 2, recordBytes + 6);
troubleSectors.insert(troubleSectors.end(), reinterpret_cast<uint32_t*>(recordBytes + 6), reinterpret_cast<uint32_t*>(recordBytes + 20)); troubleSectors.insert(troubleSectors.end(), reinterpret_cast<uint32_t*>(recordBytes + 6), reinterpret_cast<uint32_t*>(recordBytes + 22));
timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 22) & UINT63_MAX; timestamp = *reinterpret_cast<uint64_t*>(recordBytes + 22);
checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30); checksum = *reinterpret_cast<uint16_t*>(recordBytes + 30);
doChecksum(recordBytes); doChecksum(recordBytes);
} }

Some files were not shown because too many files have changed in this diff Show More