Compare commits
17 Commits
3b84dcbc5c
...
6dd4456f9a
| Author | SHA1 | Date |
|---|---|---|
|
|
6dd4456f9a | |
|
|
c5ba2d8d32 | |
|
|
a22791c9e0 | |
|
|
dc2a364afb | |
|
|
114b664d78 | |
|
|
2acf248583 | |
|
|
f18aa00322 | |
|
|
87baa97c3f | |
|
|
8dcbbe0d72 | |
|
|
b624d06ca0 | |
|
|
c249df8756 | |
|
|
b2161211c5 | |
|
|
0ee8a990a7 | |
|
|
dc0f16b1d2 | |
|
|
c4ce803d62 | |
|
|
34cacf4cf2 | |
|
|
4157558e84 |
|
|
@ -15,4 +15,3 @@ third-party/concurrentqueue/tests
|
|||
examples/csharp/bin
|
||||
examples/csharp/obj
|
||||
test/system
|
||||
.venv
|
||||
|
|
@ -21,7 +21,7 @@ build windows/x64:
|
|||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
|
||||
unit_test windows/x64:
|
||||
stage: unit_test
|
||||
|
|
@ -32,7 +32,7 @@ unit_test windows/x64:
|
|||
needs:
|
||||
- build windows/x64
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
timeout: 5m
|
||||
|
||||
build windows/x86:
|
||||
|
|
@ -45,7 +45,7 @@ build windows/x86:
|
|||
- build
|
||||
expire_in: 3 days
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
|
||||
unit_test windows/x86:
|
||||
stage: unit_test
|
||||
|
|
@ -56,7 +56,7 @@ unit_test windows/x86:
|
|||
needs:
|
||||
- build windows/x86
|
||||
tags:
|
||||
- icsneo-windows
|
||||
- libicsneo-win-x64
|
||||
timeout: 5m
|
||||
|
||||
#-------------------------------------------------------------------------------
|
||||
|
|
|
|||
|
|
@ -10,10 +10,10 @@ option(LIBICSNEO_BUILD_UNIT_TESTS "Build unit tests." OFF)
|
|||
option(LIBICSNEO_BUILD_SYSTEM_TESTS "Build system tests." OFF)
|
||||
option(LIBICSNEO_BUILD_DOCS "Build documentation. Don't use in Visual Studio." OFF)
|
||||
option(LIBICSNEO_BUILD_EXAMPLES "Build examples." ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEO "Build dynamic C library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEO_STATIC "Build static C library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C legacy library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C legacy library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC2 "Build dynamic C2 library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOC2_STATIC "Build static C2 library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOLEGACY "Build icsnVC40 compatibility library" ON)
|
||||
option(LIBICSNEO_BUILD_ICSNEOLEGACY_STATIC "Build static icsnVC40 compatibility library" ON)
|
||||
set(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to build with Npcap")
|
||||
|
|
@ -249,6 +249,8 @@ set(SRC_FILES
|
|||
communication/message/linmessage.cpp
|
||||
communication/message/livedatamessage.cpp
|
||||
communication/message/tc10statusmessage.cpp
|
||||
communication/message/gptpstatusmessage.cpp
|
||||
communication/message/ethernetstatusmessage.cpp
|
||||
communication/packet/flexraypacket.cpp
|
||||
communication/packet/canpacket.cpp
|
||||
communication/packet/a2bpacket.cpp
|
||||
|
|
@ -335,7 +337,7 @@ endif()
|
|||
|
||||
configure_file(api/icsneocpp/buildinfo.h.template ${CMAKE_CURRENT_BINARY_DIR}/generated/buildinfo.h)
|
||||
configure_file(api/icsneoc/version.rc.template ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc)
|
||||
configure_file(api/icsneo/version.rc.template ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneo/version.rc)
|
||||
configure_file(api/icsneoc2/version.rc.template ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc2/version.rc)
|
||||
|
||||
foreach(EXTINC ${LIBICSNEO_EXTENSION_INCLUDES})
|
||||
message("Including " ${EXTINC})
|
||||
|
|
@ -436,42 +438,6 @@ if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
|||
endif(WIN32)
|
||||
endif(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEO)
|
||||
add_library(icsneo SHARED api/icsneo/icsneo.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneo/version.rc)
|
||||
target_include_directories(icsneo
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(icsneo PRIVATE icsneocpp)
|
||||
target_compile_definitions(icsneo
|
||||
PRIVATE
|
||||
ICSNEO_EXPORTS _CRT_SECURE_NO_WARNINGS
|
||||
PUBLIC
|
||||
ICSNEO_IMPORTS _CRT_SECURE_NO_WARNINGS
|
||||
INTERFACE
|
||||
ICSNEO_IMPORTS _CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
target_compile_features(icsneo PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEO_STATIC)
|
||||
add_library(icsneo-static STATIC api/icsneo/icsneo.cpp)
|
||||
target_include_directories(icsneo-static
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(icsneo-static PUBLIC icsneocpp)
|
||||
target_compile_features(icsneo-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(icsneo-static PUBLIC ICSNEO_BUILD_STATIC)
|
||||
endif()
|
||||
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOC)
|
||||
add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc)
|
||||
target_include_directories(icsneoc
|
||||
|
|
@ -499,6 +465,42 @@ if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
|
|||
target_compile_definitions(icsneoc-static PUBLIC ICSNEOC_BUILD_STATIC)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOC2)
|
||||
add_library(icsneoc2 SHARED api/icsneoc2/icsneoc2.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc2/version.rc)
|
||||
target_include_directories(icsneoc2
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(icsneoc2 PRIVATE icsneocpp)
|
||||
target_compile_definitions(icsneoc2
|
||||
PRIVATE
|
||||
ICSNEO_EXPORTS _CRT_SECURE_NO_WARNINGS
|
||||
PUBLIC
|
||||
ICSNEO_IMPORTS _CRT_SECURE_NO_WARNINGS
|
||||
INTERFACE
|
||||
ICSNEO_IMPORTS _CRT_SECURE_NO_WARNINGS
|
||||
)
|
||||
target_compile_features(icsneoc2 PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||
target_compile_definitions(icsneoc2 PUBLIC ICSNEOC2_BUILD_DYNAMIC)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOC2_STATIC)
|
||||
add_library(icsneoc2-static STATIC api/icsneoc2/icsneoc2.cpp)
|
||||
target_include_directories(icsneoc2-static
|
||||
PUBLIC
|
||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||
$<INSTALL_INTERFACE:>
|
||||
PRIVATE
|
||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||
)
|
||||
target_link_libraries(icsneoc2-static PUBLIC icsneocpp)
|
||||
target_compile_features(icsneoc2-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(icsneoc2-static PUBLIC ICSNEOC2_BUILD_STATIC)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_ICSNEOLEGACY)
|
||||
add_library(icsneolegacy SHARED
|
||||
api/icsneolegacy/icsneolegacy.cpp
|
||||
|
|
@ -565,10 +567,12 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
|||
test/unit/livedataencoderdecodertest.cpp
|
||||
test/unit/ringbuffertest.cpp
|
||||
test/unit/apperrordecodertest.cpp
|
||||
test/unit/icsneoc2.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||
target_link_libraries(libicsneo-unit-tests icsneocpp)
|
||||
target_link_libraries(libicsneo-unit-tests icsneoc2-static)
|
||||
|
||||
target_include_directories(libicsneo-unit-tests PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
|
||||
|
||||
|
|
@ -584,13 +588,12 @@ if(LIBICSNEO_BUILD_SYSTEM_TESTS)
|
|||
FetchContent_Declare(
|
||||
SystemTests
|
||||
GIT_REPOSITORY $ENV{LIBICSNEO_SYSTEM_TESTS}
|
||||
GIT_TAG icsneo_api
|
||||
GIT_TAG main
|
||||
SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/test/system
|
||||
)
|
||||
FetchContent_MakeAvailable(SystemTests)
|
||||
else()
|
||||
message(WARNING "LIBICSNEO_SYSTEM_TESTS env variable not defined, attempting to use ${CMAKE_CURRENT_SOURCE_DIR}/test/system anyways...")
|
||||
add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/test/system)
|
||||
message("System test repo not defined!")
|
||||
endif()
|
||||
endif()
|
||||
|
||||
|
|
|
|||
30
LICENSE
30
LICENSE
|
|
@ -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.
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -274,10 +274,10 @@ bool icsneo_removeMessageCallback(const neodevice_t* device, int id) {
|
|||
return device->device->removeMessageCallback(id);
|
||||
}
|
||||
|
||||
icsneo_netid_t icsneo_getNetworkByNumber(const neodevice_t* device, icsneo_msg_bus_type_t type, unsigned int number) {
|
||||
neonetid_t icsneo_getNetworkByNumber(const neodevice_t* device, neonettype_t type, unsigned int number) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
return icsneo_netid_t(device->device->getNetworkByNumber(icsneo_msg_bus_type_t(type), size_t(number)).getNetID());
|
||||
return neonetid_t(device->device->getNetworkByNumber(icsneo::Network::Type(type), size_t(number)).getNetID());
|
||||
}
|
||||
|
||||
bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength) {
|
||||
|
|
@ -306,14 +306,14 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng
|
|||
return true;
|
||||
}
|
||||
|
||||
bool icsneo_getProductNameForType(icsneo_devicetype_t type, char* str, size_t* maxLength) {
|
||||
bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength) {
|
||||
// TAG String copy function
|
||||
if(maxLength == nullptr) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::string output = DeviceType(type).getProductName();
|
||||
std::string output = DeviceType(type).getGenericProductName();
|
||||
|
||||
if(str == nullptr) {
|
||||
*maxLength = output.length();
|
||||
|
|
@ -430,28 +430,28 @@ bool icsneo_settingsApplyStructureTemporary(const neodevice_t* device, const voi
|
|||
return icsneo_settingsWriteStructure(device, structure, structureSize) && icsneo_settingsApplyTemporary(device);
|
||||
}
|
||||
|
||||
int64_t icsneo_getBaudrate(const neodevice_t* device, icsneo_netid_t netid) {
|
||||
int64_t icsneo_getBaudrate(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return -1;
|
||||
|
||||
return device->device->settings->getBaudrateFor(netid);
|
||||
}
|
||||
|
||||
bool icsneo_setBaudrate(const neodevice_t* device, icsneo_netid_t netid, int64_t newBaudrate) {
|
||||
bool icsneo_setBaudrate(const neodevice_t* device, neonetid_t netid, int64_t newBaudrate) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->settings->setBaudrateFor(netid, newBaudrate);
|
||||
}
|
||||
|
||||
int64_t icsneo_getFDBaudrate(const neodevice_t* device, icsneo_netid_t netid) {
|
||||
int64_t icsneo_getFDBaudrate(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return -1;
|
||||
|
||||
return device->device->settings->getFDBaudrateFor(netid);
|
||||
}
|
||||
|
||||
bool icsneo_setFDBaudrate(const neodevice_t* device, icsneo_netid_t netid, int64_t newBaudrate) {
|
||||
bool icsneo_setFDBaudrate(const neodevice_t* device, neonetid_t netid, int64_t newBaudrate) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
|
|
@ -608,7 +608,7 @@ size_t icsneo_getEventLimit(void) {
|
|||
return icsneo::GetEventLimit();
|
||||
}
|
||||
|
||||
bool icsneo_getSupportedDevices(icsneo_devicetype_t* devices, size_t* count) {
|
||||
bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) {
|
||||
if(count == nullptr) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -628,7 +628,7 @@ bool icsneo_getSupportedDevices(icsneo_devicetype_t* devices, size_t* count) {
|
|||
}
|
||||
|
||||
for(size_t i = 0; i < len; i++)
|
||||
devices[i] = supported[i].getDeviceType();
|
||||
devices[i] = supported[i];
|
||||
*count = len;
|
||||
|
||||
return true;
|
||||
|
|
@ -671,28 +671,28 @@ bool icsneo_setDigitalIO(const neodevice_t* device, neoio_t type, uint32_t numbe
|
|||
return device->device->setDigitalIO(static_cast<icsneo::IO>(type), number, value);
|
||||
}
|
||||
|
||||
bool icsneo_isTerminationSupportedFor(const neodevice_t* device, icsneo_netid_t netid) {
|
||||
bool icsneo_isTerminationSupportedFor(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->settings->isTerminationSupportedFor(Network(netid));
|
||||
}
|
||||
|
||||
bool icsneo_canTerminationBeEnabledFor(const neodevice_t* device, icsneo_netid_t netid) {
|
||||
bool icsneo_canTerminationBeEnabledFor(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->settings->canTerminationBeEnabledFor(Network(netid));
|
||||
}
|
||||
|
||||
bool icsneo_isTerminationEnabledFor(const neodevice_t* device, icsneo_netid_t netid) {
|
||||
bool icsneo_isTerminationEnabledFor(const neodevice_t* device, neonetid_t netid) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
return device->device->settings->isTerminationEnabledFor(Network(netid)).value_or(false);
|
||||
}
|
||||
|
||||
bool icsneo_setTerminationFor(const neodevice_t* device, icsneo_netid_t netid, bool enabled) {
|
||||
bool icsneo_setTerminationFor(const neodevice_t* device, neonetid_t netid, bool enabled) {
|
||||
if(!icsneo_isValidNeoDevice(device))
|
||||
return false;
|
||||
|
||||
|
|
@ -733,13 +733,13 @@ int icsneo_getDeviceStatus(const neodevice_t* device, void* status, size_t* size
|
|||
|
||||
std::shared_ptr<Message> msg = device->device->com->waitForMessageSync([&]() {
|
||||
return device->device->com->sendCommand(Command::RequestStatusUpdate);
|
||||
}, std::make_shared<MessageFilter>(icsneo_netid_device_status), std::chrono::milliseconds(100));
|
||||
}, std::make_shared<MessageFilter>(Network::NetID::DeviceStatus), std::chrono::milliseconds(100));
|
||||
|
||||
if(!msg) // Did not receive a message
|
||||
return false;
|
||||
|
||||
auto rawMessage = std::static_pointer_cast<InternalMessage>(msg);
|
||||
if(!rawMessage || (rawMessage->network.getNetID() != icsneo_netid_device_status))
|
||||
if(!rawMessage || (rawMessage->network.getNetID() != Network::NetID::DeviceStatus))
|
||||
return false;
|
||||
|
||||
if(*size < rawMessage->data.size())
|
||||
|
|
|
|||
|
|
@ -29,7 +29,7 @@ BEGIN
|
|||
VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "icsneoc.dll"
|
||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2024"
|
||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2025"
|
||||
VALUE "OriginalFilename", "icsneoc.dll"
|
||||
VALUE "ProductName", "libicsneo"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load Diff
|
|
@ -0,0 +1,51 @@
|
|||
#define VER_FILEVERSION @PROJECT_VERSION_MAJOR@,@PROJECT_VERSION_MINOR@,@PROJECT_VERSION_PATCH@
|
||||
#define VER_FILEVERSION_STR "v@PROJECT_VERSION_MAJOR@.@PROJECT_VERSION_MINOR@.@PROJECT_VERSION_PATCH@@BUILD_METADATA_PLUS@ @BUILD_GIT_INFO@"
|
||||
|
||||
#define VER_PRODUCTVERSION VER_FILEVERSION
|
||||
#define VER_PRODUCTVERSION_STR VER_FILEVERSION_STR
|
||||
|
||||
#ifndef DEBUG
|
||||
#define VER_DEBUG 0
|
||||
#else
|
||||
#define VER_DEBUG VS_FF_DEBUG
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
|
||||
VS_VERSION_INFO VERSIONINFO
|
||||
FILEVERSION VER_FILEVERSION
|
||||
PRODUCTVERSION VER_PRODUCTVERSION
|
||||
FILEFLAGSMASK (VS_FF_DEBUG)
|
||||
FILEFLAGS (VER_DEBUG)
|
||||
FILEOS VOS__WINDOWS32
|
||||
FILETYPE VFT_DLL
|
||||
FILESUBTYPE VFT2_UNKNOWN
|
||||
BEGIN
|
||||
BLOCK "StringFileInfo"
|
||||
BEGIN
|
||||
BLOCK "040904E4"
|
||||
BEGIN
|
||||
VALUE "CompanyName", "Intrepid Control Systems, Inc."
|
||||
VALUE "FileDescription", "Intrepid Control Systems Open Device Communication C API"
|
||||
VALUE "FileVersion", VER_FILEVERSION_STR
|
||||
VALUE "InternalName", "icsneo.dll"
|
||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2024"
|
||||
VALUE "OriginalFilename", "icsneo.dll"
|
||||
VALUE "ProductName", "libicsneo"
|
||||
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
|
||||
END
|
||||
END
|
||||
|
||||
BLOCK "VarFileInfo"
|
||||
BEGIN
|
||||
/* The following line should only be modified for localized versions. */
|
||||
/* It consists of any number of WORD,WORD pairs, with each pair */
|
||||
/* describing a language,codepage combination supported by the file. */
|
||||
/* */
|
||||
/* For example, a file might have values "0x409,1252" indicating that it */
|
||||
/* supports English language (0x409) in the Windows ANSI codepage (1252). */
|
||||
|
||||
VALUE "Translation", 0x409, 1252
|
||||
|
||||
END
|
||||
END
|
||||
|
|
@ -120,6 +120,7 @@ static constexpr const char* DISK_NOT_CONNECTED = "The program tried to access a
|
|||
static constexpr const char* UNEXPECTED_RESPONSE = "Received an unexpected or invalid response from the device.";
|
||||
static constexpr const char* LIN_SETTINGS_NOT_AVAILABLE = "LIN settings are not available for this device.";
|
||||
static constexpr const char* MODE_NOT_FOUND = "The mode was not found.";
|
||||
static constexpr const char* GPTP_NOT_SUPPORTED = "GPTP clock synchronization is not supported on this device.";
|
||||
|
||||
// Transport Errors
|
||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
||||
|
|
@ -185,6 +186,7 @@ static constexpr const char* VSA_OTHER_ERROR = "Unknown error in VSA read API.";
|
|||
static constexpr const char* TOO_MANY_EVENTS = "Too many events have occurred. The list has been truncated.";
|
||||
static constexpr const char* UNKNOWN = "An unknown internal error occurred.";
|
||||
static constexpr const char* INVALID = "An invalid internal error occurred.";
|
||||
|
||||
const char* APIEvent::DescriptionForType(Type type) {
|
||||
switch(type) {
|
||||
// API Errors
|
||||
|
|
@ -345,6 +347,8 @@ const char* APIEvent::DescriptionForType(Type type) {
|
|||
return GETIFADDRS_ERROR;
|
||||
case Type::SendToError:
|
||||
return SEND_TO_ERROR;
|
||||
case Type::GPTPNotSupported:
|
||||
return GPTP_NOT_SUPPORTED;
|
||||
|
||||
// FTD3XX
|
||||
case Type::FTOK:
|
||||
|
|
|
|||
|
|
@ -81,23 +81,23 @@ static bool NeoMessageToSpyMessage(const neodevice_t* device, const neomessage_t
|
|||
copyStatusData();
|
||||
};
|
||||
|
||||
switch (frame.type)
|
||||
switch (Network::Type(frame.type))
|
||||
{
|
||||
case icsneo_msg_bus_type_can:
|
||||
case icsneo_msg_bus_type_swcan:
|
||||
case icsneo_msg_bus_type_lsftcan:
|
||||
case Network::Type::CAN:
|
||||
case Network::Type::SWCAN:
|
||||
case Network::Type::LSFTCAN:
|
||||
oldmsg.Protocol = frame.status.canfdFDF ? SPY_PROTOCOL_CANFD : SPY_PROTOCOL_CAN;
|
||||
oldmsg.NumberBytesData = static_cast<uint8_t>(std::min(frame.length, (size_t)255));
|
||||
oldmsg.NumberBytesHeader = 4;
|
||||
copyFrameData();
|
||||
break;
|
||||
case icsneo_msg_bus_type_ethernet:
|
||||
case Network::Type::Ethernet:
|
||||
oldmsg.Protocol = SPY_PROTOCOL_ETHERNET;
|
||||
oldmsg.NumberBytesData = static_cast<uint8_t>(frame.length & 0xFF);
|
||||
oldmsg.NumberBytesHeader = static_cast<uint8_t>(frame.length >> 8);
|
||||
copyFrameData();
|
||||
break;
|
||||
case icsneo_msg_bus_type_lin:
|
||||
case Network::Type::LIN:
|
||||
{
|
||||
const neomessage_lin_t& linFrame = *reinterpret_cast<const neomessage_lin_t*>(&frame);
|
||||
icsSpyMessageJ1850& linSpyMsg = *reinterpret_cast<icsSpyMessageJ1850*>(&oldmsg);
|
||||
|
|
|
|||
|
|
@ -12,7 +12,7 @@ if(LIBICSNEO_ENABLE_BINDINGS_RUST)
|
|||
)
|
||||
FetchContent_MakeAvailable(Corrosion)
|
||||
|
||||
corrosion_import_crate(MANIFEST_PATH ${CMAKE_SOURCE_DIR}/bindings/rust/icsneors/Cargo.toml)
|
||||
corrosion_import_crate(MANIFEST_PATH ${CMAKE_SOURCE_DIR}/bindings/rust/icsneoc2rs/Cargo.toml)
|
||||
else()
|
||||
message(STATUS "Not building rust bindings")
|
||||
endif()
|
||||
|
|
@ -12,10 +12,13 @@ pybind11_add_module(icsneopy
|
|||
icsneopy/communication/network.cpp
|
||||
icsneopy/communication/message/message.cpp
|
||||
icsneopy/communication/message/canmessage.cpp
|
||||
icsneopy/communication/message/canerrormessage.cpp
|
||||
icsneopy/communication/message/ethernetmessage.cpp
|
||||
icsneopy/communication/message/linmessage.cpp
|
||||
icsneopy/communication/message/tc10statusmessage.cpp
|
||||
icsneopy/communication/message/mdiomessage.cpp
|
||||
icsneopy/communication/message/gptpstatusmessage.cpp
|
||||
icsneopy/communication/message/ethernetstatusmessage.cpp
|
||||
icsneopy/communication/message/callback/messagecallback.cpp
|
||||
icsneopy/communication/message/filter/messagefilter.cpp
|
||||
icsneopy/device/device.cpp
|
||||
|
|
@ -23,4 +26,9 @@ pybind11_add_module(icsneopy
|
|||
)
|
||||
target_link_libraries(icsneopy PRIVATE icsneocpp)
|
||||
|
||||
install(TARGETS icsneopy LIBRARY DESTINATION .)
|
||||
install(TARGETS icsneopy LIBRARY DESTINATION icsneopy)
|
||||
|
||||
find_program(STUBGEN stubgen REQUIRED)
|
||||
add_custom_command(TARGET icsneopy POST_BUILD COMMAND ${STUBGEN} -m icsneopy -o .)
|
||||
|
||||
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/icsneopy.pyi __init__.py py.typed DESTINATION icsneopy)
|
||||
|
|
|
|||
|
|
@ -0,0 +1 @@
|
|||
from .icsneopy import *
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_errorcodes(pybind11::module_& m) {
|
||||
pybind11::enum_<CANErrorCode>(m, "CANErrorCode")
|
||||
.value("NoError", CANErrorCode::NoError)
|
||||
.value("StuffError", CANErrorCode::StuffError)
|
||||
.value("FormError", CANErrorCode::FormError)
|
||||
.value("AckError", CANErrorCode::AckError)
|
||||
.value("Bit1Error", CANErrorCode::Bit1Error)
|
||||
.value("Bit0Error", CANErrorCode::Bit0Error)
|
||||
.value("CRCError", CANErrorCode::CRCError)
|
||||
.value("NoChange", CANErrorCode::NoChange);
|
||||
}
|
||||
|
||||
void init_canerrormessage(pybind11::module_& m) {
|
||||
init_errorcodes(m);
|
||||
pybind11::class_<CANErrorMessage, std::shared_ptr<CANErrorMessage>, Message>(m, "CANErrorMessage")
|
||||
.def_readonly("network", &CANErrorMessage::network)
|
||||
.def_readonly("transmitErrorCount", &CANErrorMessage::transmitErrorCount)
|
||||
.def_readonly("receiveErrorCount", &CANErrorMessage::receiveErrorCount)
|
||||
.def_readonly("busOff", &CANErrorMessage::busOff)
|
||||
.def_readonly("errorPassive", &CANErrorMessage::errorPassive)
|
||||
.def_readonly("errorWarn", &CANErrorMessage::errorWarn)
|
||||
.def_readonly("dataErrorCode", &CANErrorMessage::dataErrorCode)
|
||||
.def_readonly("errorCode", &CANErrorMessage::errorCode);
|
||||
|
||||
|
||||
m.attr("CANErrorCountMessage") = m.attr("CANErrorMessage");
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
|
|
@ -15,7 +15,7 @@ void init_ethernetmessage(pybind11::module_& m) {
|
|||
.def(pybind11::init())
|
||||
.def_readwrite("preemptionEnabled", &EthernetMessage::preemptionEnabled)
|
||||
.def_readwrite("preemptionFlags", &EthernetMessage::preemptionFlags)
|
||||
.def_readwrite("fcsAvailable", &EthernetMessage::fcsAvailable)
|
||||
.def_readwrite("fcs", &EthernetMessage::fcs)
|
||||
.def_readwrite("frameTooShort", &EthernetMessage::frameTooShort)
|
||||
.def_readwrite("noPadding", &EthernetMessage::noPadding)
|
||||
.def("get_destination_mac", &EthernetMessage::getDestinationMAC, pybind11::return_value_policy::reference)
|
||||
|
|
|
|||
|
|
@ -0,0 +1,35 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_ethernetstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<EthernetStatusMessage, std::shared_ptr<EthernetStatusMessage>, Message> ethernetStatusMessage(m, "EthernetStatusMessage");
|
||||
|
||||
pybind11::enum_<EthernetStatusMessage::LinkSpeed>(ethernetStatusMessage, "LinkSpeed")
|
||||
.value("LinkSpeedAuto", EthernetStatusMessage::LinkSpeed::LinkSpeedAuto)
|
||||
.value("LinkSpeed10", EthernetStatusMessage::LinkSpeed::LinkSpeed10)
|
||||
.value("LinkSpeed100", EthernetStatusMessage::LinkSpeed::LinkSpeed100)
|
||||
.value("LinkSpeed1000", EthernetStatusMessage::LinkSpeed::LinkSpeed1000)
|
||||
.value("LinkSpeed2500", EthernetStatusMessage::LinkSpeed::LinkSpeed2500)
|
||||
.value("LinkSpeed5000", EthernetStatusMessage::LinkSpeed::LinkSpeed5000)
|
||||
.value("LinkSpeed10000", EthernetStatusMessage::LinkSpeed::LinkSpeed10000);
|
||||
|
||||
pybind11::enum_<EthernetStatusMessage::LinkMode>(ethernetStatusMessage, "LinkMode")
|
||||
.value("LinkModeAuto", EthernetStatusMessage::LinkMode::LinkModeAuto)
|
||||
.value("LinkModeMaster", EthernetStatusMessage::LinkMode::LinkModeMaster)
|
||||
.value("LinkModeSlave", EthernetStatusMessage::LinkMode::LinkModeSlave)
|
||||
.value("LinkModeInvalid", EthernetStatusMessage::LinkMode::LinkModeInvalid);
|
||||
|
||||
ethernetStatusMessage
|
||||
.def_readonly("network", &EthernetStatusMessage::network)
|
||||
.def_readonly("state", &EthernetStatusMessage::state)
|
||||
.def_readonly("speed", &EthernetStatusMessage::speed)
|
||||
.def_readonly("duplex", &EthernetStatusMessage::duplex)
|
||||
.def_readonly("mode", &EthernetStatusMessage::mode);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
|
@ -9,7 +9,8 @@ namespace icsneo {
|
|||
void init_messagefilter(pybind11::module_& m) {
|
||||
pybind11::class_<MessageFilter, std::shared_ptr<MessageFilter>>(m, "MessageFilter")
|
||||
.def(pybind11::init())
|
||||
.def(pybind11::init<_icsneo_netid_t>());
|
||||
.def(pybind11::init<Message::Type>())
|
||||
.def(pybind11::init<Network::NetID>());
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
|
|
|||
|
|
@ -0,0 +1,79 @@
|
|||
#include <pybind11/pybind11.h>
|
||||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_gptpstatusmessage(pybind11::module_& m) {
|
||||
pybind11::class_<GPTPStatus, std::shared_ptr<GPTPStatus>, Message> gptpStatus(m, "GPTPStatus");
|
||||
|
||||
pybind11::class_<GPTPStatus::Timestamp>(gptpStatus, "Timestamp")
|
||||
.def_readonly("seconds", &GPTPStatus::Timestamp::seconds)
|
||||
.def_readonly("nanoseconds", &GPTPStatus::Timestamp::nanoseconds)
|
||||
.def("to_seconds", &GPTPStatus::Timestamp::toSeconds, pybind11::call_guard<pybind11::gil_scoped_release>());
|
||||
|
||||
pybind11::class_<GPTPStatus::ScaledNanoSeconds>(gptpStatus, "ScaledNanoSeconds")
|
||||
.def_readonly("nanosecondsMSB", &GPTPStatus::ScaledNanoSeconds::nanosecondsMSB)
|
||||
.def_readonly("nanosecondsLSB", &GPTPStatus::ScaledNanoSeconds::nanosecondsLSB)
|
||||
.def_readonly("fractionalNanoseconds", &GPTPStatus::ScaledNanoSeconds::fractionalNanoseconds);
|
||||
|
||||
pybind11::class_<GPTPStatus::PortID>(gptpStatus, "PortID")
|
||||
.def_readonly("clockIdentity", &GPTPStatus::PortID::clockIdentity)
|
||||
.def_readonly("portNumber", &GPTPStatus::PortID::portNumber);
|
||||
|
||||
pybind11::class_<GPTPStatus::ClockQuality>(gptpStatus, "ClockQuality")
|
||||
.def_readonly("clockClass", &GPTPStatus::ClockQuality::clockClass)
|
||||
.def_readonly("clockAccuracy", &GPTPStatus::ClockQuality::clockAccuracy)
|
||||
.def_readonly("offsetScaledLogVariance", &GPTPStatus::ClockQuality::offsetScaledLogVariance);
|
||||
|
||||
pybind11::class_<GPTPStatus::SystemID>(gptpStatus, "SystemID")
|
||||
.def_readonly("priority1", &GPTPStatus::SystemID::priority1)
|
||||
.def_readonly("clockQuality", &GPTPStatus::SystemID::clockQuality)
|
||||
.def_readonly("priority2", &GPTPStatus::SystemID::priority2)
|
||||
.def_readonly("clockID", &GPTPStatus::SystemID::clockID);
|
||||
|
||||
pybind11::class_<GPTPStatus::PriorityVector>(gptpStatus, "PriorityVector")
|
||||
.def_readonly("sysID", &GPTPStatus::PriorityVector::sysID)
|
||||
.def_readonly("stepsRemoved", &GPTPStatus::PriorityVector::stepsRemoved)
|
||||
.def_readonly("portID", &GPTPStatus::PriorityVector::portID)
|
||||
.def_readonly("portNumber", &GPTPStatus::PriorityVector::portNumber);
|
||||
|
||||
pybind11::class_<GPTPStatus::ParentDS>(gptpStatus, "ParentDS")
|
||||
.def_readonly("parentPortIdentity", &GPTPStatus::ParentDS::parentPortIdentity)
|
||||
.def_readonly("cumulativeRateRatio", &GPTPStatus::ParentDS::cumulativeRateRatio)
|
||||
.def_readonly("grandmasterIdentity", &GPTPStatus::ParentDS::grandmasterIdentity)
|
||||
.def_readonly("gmClockQualityClockClass", &GPTPStatus::ParentDS::gmClockQualityClockClass)
|
||||
.def_readonly("gmClockQualityClockAccuracy", &GPTPStatus::ParentDS::gmClockQualityClockAccuracy)
|
||||
.def_readonly("gmClockQualityOffsetScaledLogVariance", &GPTPStatus::ParentDS::gmClockQualityOffsetScaledLogVariance)
|
||||
.def_readonly("gmPriority1", &GPTPStatus::ParentDS::gmPriority1)
|
||||
.def_readonly("gmPriority2", &GPTPStatus::ParentDS::gmPriority2);
|
||||
|
||||
pybind11::class_<GPTPStatus::CurrentDS>(gptpStatus, "CurrentDS")
|
||||
.def_readonly("stepsRemoved", &GPTPStatus::CurrentDS::stepsRemoved)
|
||||
.def_readonly("offsetFromMaster", &GPTPStatus::CurrentDS::offsetFromMaster)
|
||||
.def_readonly("lastgmPhaseChange", &GPTPStatus::CurrentDS::lastgmPhaseChange)
|
||||
.def_readonly("lastgmFreqChange", &GPTPStatus::CurrentDS::lastgmFreqChange)
|
||||
.def_readonly("gmTimeBaseIndicator", &GPTPStatus::CurrentDS::gmTimeBaseIndicator)
|
||||
.def_readonly("gmChangeCount", &GPTPStatus::CurrentDS::gmChangeCount)
|
||||
.def_readonly("timeOfLastgmChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmChangeEvent)
|
||||
.def_readonly("timeOfLastgmPhaseChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmPhaseChangeEvent)
|
||||
.def_readonly("timeOfLastgmFreqChangeEvent", &GPTPStatus::CurrentDS::timeOfLastgmFreqChangeEvent);
|
||||
|
||||
gptpStatus.def_readonly("currentTime", &GPTPStatus::currentTime)
|
||||
.def_readonly("gmPriority", &GPTPStatus::gmPriority)
|
||||
.def_readonly("msOffsetNs", &GPTPStatus::msOffsetNs)
|
||||
.def_readonly("isSync", &GPTPStatus::isSync)
|
||||
.def_readonly("linkStatus", &GPTPStatus::linkStatus)
|
||||
.def_readonly("linkDelayNS", &GPTPStatus::linkDelayNS)
|
||||
.def_readonly("selectedRole", &GPTPStatus::selectedRole)
|
||||
.def_readonly("asCapable", &GPTPStatus::asCapable)
|
||||
.def_readonly("isSyntonized", &GPTPStatus::isSyntonized)
|
||||
.def_readonly("lastRXSyncTS", &GPTPStatus::lastRXSyncTS)
|
||||
.def_readonly("currentDS", &GPTPStatus::currentDS)
|
||||
.def_readonly("parentDS", &GPTPStatus::parentDS);
|
||||
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
|
@ -11,6 +11,7 @@ void init_message(pybind11::module_& m) {
|
|||
pybind11::enum_<Message::Type>(message, "Type")
|
||||
.value("BusMessage", Message::Type::BusMessage)
|
||||
.value("CANErrorCount", Message::Type::CANErrorCount)
|
||||
.value("CANError", Message::Type::CANError)
|
||||
.value("LINHeaderOnly", Message::Type::LINHeaderOnly)
|
||||
.value("LINBreak", Message::Type::LINBreak)
|
||||
.value("Invalid", Message::Type::Invalid)
|
||||
|
|
@ -31,7 +32,9 @@ void init_message(pybind11::module_& m) {
|
|||
.value("LiveData", Message::Type::LiveData)
|
||||
.value("HardwareInfo", Message::Type::HardwareInfo)
|
||||
.value("TC10Status", Message::Type::TC10Status)
|
||||
.value("AppError", Message::Type::AppError);
|
||||
.value("AppError", Message::Type::AppError)
|
||||
.value("GPTPStatus", Message::Type::GPTPStatus)
|
||||
.value("EthernetStatus", Message::Type::EthernetStatus);
|
||||
|
||||
message.def(pybind11::init<Message::Type>());
|
||||
message.def_readonly("type", &Message::type);
|
||||
|
|
|
|||
|
|
@ -9,186 +9,184 @@ namespace icsneo {
|
|||
void init_network(pybind11::module_& m) {
|
||||
pybind11::class_<Network> network(m, "Network");
|
||||
|
||||
pybind11::enum_<_icsneo_netid_t>(network, "icsneo_netid_t")
|
||||
.value("Device", _icsneo_netid_t::icsneo_netid_device)
|
||||
.value("HSCAN", _icsneo_netid_t::icsneo_netid_hscan)
|
||||
.value("MSCAN", _icsneo_netid_t::icsneo_netid_mscan)
|
||||
.value("SWCAN", _icsneo_netid_t::icsneo_netid_swcan)
|
||||
.value("LSFTCAN", _icsneo_netid_t::icsneo_netid_lsftcan)
|
||||
.value("FordSCP", _icsneo_netid_t::icsneo_netid_fordscp)
|
||||
.value("J1708", _icsneo_netid_t::icsneo_netid_j1708)
|
||||
.value("Aux", _icsneo_netid_t::icsneo_netid_aux)
|
||||
.value("J1850VPW", _icsneo_netid_t::icsneo_netid_j1850vpw)
|
||||
.value("ISO9141", _icsneo_netid_t::icsneo_netid_iso9141)
|
||||
.value("DiskData", _icsneo_netid_t::icsneo_netid_disk_data)
|
||||
.value("Main51", _icsneo_netid_t::icsneo_netid_main51)
|
||||
.value("RED", _icsneo_netid_t::icsneo_netid_red)
|
||||
.value("SCI", _icsneo_netid_t::icsneo_netid_sci)
|
||||
.value("ISO9141_2", _icsneo_netid_t::icsneo_netid_iso9141_2)
|
||||
.value("ISO14230", _icsneo_netid_t::icsneo_netid_iso14230)
|
||||
.value("LIN", _icsneo_netid_t::icsneo_netid_lin)
|
||||
.value("OP_Ethernet1", _icsneo_netid_t::icsneo_netid_op_ethernet1)
|
||||
.value("OP_Ethernet2", _icsneo_netid_t::icsneo_netid_op_ethernet2)
|
||||
.value("OP_Ethernet3", _icsneo_netid_t::icsneo_netid_op_ethernet3)
|
||||
.value("RED_EXT_MEMORYREAD", _icsneo_netid_t::icsneo_netid_red_ext_memoryread)
|
||||
.value("RED_INT_MEMORYREAD", _icsneo_netid_t::icsneo_netid_red_int_memoryread)
|
||||
.value("RED_DFLASH_READ", _icsneo_netid_t::icsneo_netid_red_dflash_read)
|
||||
.value("NeoMemorySDRead", _icsneo_netid_t::icsneo_netid_neo_memory_sdread)
|
||||
.value("CAN_ERRBITS", _icsneo_netid_t::icsneo_netid_can_errbits)
|
||||
.value("NeoMemoryWriteDone", _icsneo_netid_t::icsneo_netid_neo_memory_write_done)
|
||||
.value("RED_WAVE_CAN1_LOGICAL", _icsneo_netid_t::icsneo_netid_red_wave_can1_logical)
|
||||
.value("RED_WAVE_CAN2_LOGICAL", _icsneo_netid_t::icsneo_netid_red_wave_can2_logical)
|
||||
.value("RED_WAVE_LIN1_LOGICAL", _icsneo_netid_t::icsneo_netid_red_wave_lin1_logical)
|
||||
.value("RED_WAVE_LIN2_LOGICAL", _icsneo_netid_t::icsneo_netid_red_wave_lin2_logical)
|
||||
.value("RED_WAVE_LIN1_ANALOG", _icsneo_netid_t::icsneo_netid_red_wave_lin1_analog)
|
||||
.value("RED_WAVE_LIN2_ANALOG", _icsneo_netid_t::icsneo_netid_red_wave_lin2_analog)
|
||||
.value("RED_WAVE_MISC_ANALOG", _icsneo_netid_t::icsneo_netid_red_wave_misc_analog)
|
||||
.value("RED_WAVE_MISCDIO2_LOGICAL", _icsneo_netid_t::icsneo_netid_red_wave_miscdio2_logical)
|
||||
.value("RED_NETWORK_COM_ENABLE_EX", _icsneo_netid_t::icsneo_netid_red_network_com_enable_ex)
|
||||
.value("RED_NEOVI_NETWORK", _icsneo_netid_t::icsneo_netid_red_neovi_network)
|
||||
.value("RED_READ_BAUD_SETTINGS", _icsneo_netid_t::icsneo_netid_red_read_baud_settings)
|
||||
.value("RED_OLDFORMAT", _icsneo_netid_t::icsneo_netid_red_oldformat)
|
||||
.value("RED_SCOPE_CAPTURE", _icsneo_netid_t::icsneo_netid_red_scope_capture)
|
||||
.value("RED_HARDWARE_EXCEP", _icsneo_netid_t::icsneo_netid_red_hardware_excep)
|
||||
.value("RED_GET_RTC", _icsneo_netid_t::icsneo_netid_red_get_rtc)
|
||||
.value("ISO9141_3", _icsneo_netid_t::icsneo_netid_iso9141_3)
|
||||
.value("HSCAN2", _icsneo_netid_t::icsneo_netid_hscan2)
|
||||
.value("HSCAN3", _icsneo_netid_t::icsneo_netid_hscan3)
|
||||
.value("OP_Ethernet4", _icsneo_netid_t::icsneo_netid_op_ethernet4)
|
||||
.value("OP_Ethernet5", _icsneo_netid_t::icsneo_netid_op_ethernet5)
|
||||
.value("ISO9141_4", _icsneo_netid_t::icsneo_netid_iso9141_4)
|
||||
.value("LIN2", _icsneo_netid_t::icsneo_netid_lin2)
|
||||
.value("LIN3", _icsneo_netid_t::icsneo_netid_lin3)
|
||||
.value("LIN4", _icsneo_netid_t::icsneo_netid_lin4)
|
||||
.value("RED_App_Error", _icsneo_netid_t::icsneo_netid_red_app_error)
|
||||
.value("CGI", _icsneo_netid_t::icsneo_netid_cgi)
|
||||
.value("Reset_Status", _icsneo_netid_t::icsneo_netid_reset_status)
|
||||
.value("FB_Status", _icsneo_netid_t::icsneo_netid_fb_status)
|
||||
.value("App_Signal_Status", _icsneo_netid_t::icsneo_netid_app_signal_status)
|
||||
.value("Read_Datalink_Cm_Tx_Msg", _icsneo_netid_t::icsneo_netid_read_datalink_cm_tx_msg)
|
||||
.value("Read_Datalink_Cm_Rx_Msg", _icsneo_netid_t::icsneo_netid_read_datalink_cm_rx_msg)
|
||||
.value("Logging_Overflow", _icsneo_netid_t::icsneo_netid_logging_overflow)
|
||||
.value("ReadSettings", _icsneo_netid_t::icsneo_netid_read_settings)
|
||||
.value("HSCAN4", _icsneo_netid_t::icsneo_netid_hscan4)
|
||||
.value("HSCAN5", _icsneo_netid_t::icsneo_netid_hscan5)
|
||||
.value("RS232", _icsneo_netid_t::icsneo_netid_rs232)
|
||||
.value("UART", _icsneo_netid_t::icsneo_netid_uart)
|
||||
.value("UART2", _icsneo_netid_t::icsneo_netid_uart2)
|
||||
.value("UART3", _icsneo_netid_t::icsneo_netid_uart3)
|
||||
.value("UART4", _icsneo_netid_t::icsneo_netid_uart4)
|
||||
.value("SWCAN2", _icsneo_netid_t::icsneo_netid_swcan2)
|
||||
.value("Ethernet_DAQ", _icsneo_netid_t::icsneo_netid_ethernet_daq)
|
||||
.value("Data_To_Host", _icsneo_netid_t::icsneo_netid_data_to_host)
|
||||
.value("TextAPI_To_Host", _icsneo_netid_t::icsneo_netid_textapi_to_host)
|
||||
.value("SPI1", _icsneo_netid_t::icsneo_netid_spi1)
|
||||
.value("OP_Ethernet6", _icsneo_netid_t::icsneo_netid_op_ethernet6)
|
||||
.value("Red_VBat", _icsneo_netid_t::icsneo_netid_red_vbat)
|
||||
.value("OP_Ethernet7", _icsneo_netid_t::icsneo_netid_op_ethernet7)
|
||||
.value("OP_Ethernet8", _icsneo_netid_t::icsneo_netid_op_ethernet8)
|
||||
.value("OP_Ethernet9", _icsneo_netid_t::icsneo_netid_op_ethernet9)
|
||||
.value("OP_Ethernet10", _icsneo_netid_t::icsneo_netid_op_ethernet10)
|
||||
.value("OP_Ethernet11", _icsneo_netid_t::icsneo_netid_op_ethernet11)
|
||||
.value("FlexRay1a", _icsneo_netid_t::icsneo_netid_flexray1a)
|
||||
.value("FlexRay1b", _icsneo_netid_t::icsneo_netid_flexray1b)
|
||||
.value("FlexRay2a", _icsneo_netid_t::icsneo_netid_flexray2a)
|
||||
.value("FlexRay2b", _icsneo_netid_t::icsneo_netid_flexray2b)
|
||||
.value("LIN5", _icsneo_netid_t::icsneo_netid_lin5)
|
||||
.value("FlexRay", _icsneo_netid_t::icsneo_netid_flexray)
|
||||
.value("FlexRay2", _icsneo_netid_t::icsneo_netid_flexray2)
|
||||
.value("OP_Ethernet12", _icsneo_netid_t::icsneo_netid_op_ethernet12)
|
||||
.value("I2C", _icsneo_netid_t::icsneo_netid_i2c)
|
||||
.value("MOST25", _icsneo_netid_t::icsneo_netid_most25)
|
||||
.value("MOST50", _icsneo_netid_t::icsneo_netid_most50)
|
||||
.value("MOST150", _icsneo_netid_t::icsneo_netid_most150)
|
||||
.value("Ethernet", _icsneo_netid_t::icsneo_netid_ethernet)
|
||||
.value("GMFSA", _icsneo_netid_t::icsneo_netid_gmfsa)
|
||||
.value("TCP", _icsneo_netid_t::icsneo_netid_tcp)
|
||||
.value("HSCAN6", _icsneo_netid_t::icsneo_netid_hscan6)
|
||||
.value("HSCAN7", _icsneo_netid_t::icsneo_netid_hscan7)
|
||||
.value("LIN6", _icsneo_netid_t::icsneo_netid_lin6)
|
||||
.value("LSFTCAN2", _icsneo_netid_t::icsneo_netid_lsftcan2)
|
||||
.value("LogicalDiskInfo", _icsneo_netid_t::icsneo_netid_logical_disk_info)
|
||||
.value("WiVICommand", _icsneo_netid_t::icsneo_netid_wivi_command)
|
||||
.value("ScriptStatus", _icsneo_netid_t::icsneo_netid_script_status)
|
||||
.value("EthPHYControl", _icsneo_netid_t::icsneo_netid_eth_phy_control)
|
||||
.value("ExtendedCommand", _icsneo_netid_t::icsneo_netid_extended_command)
|
||||
.value("ExtendedData", _icsneo_netid_t::icsneo_netid_extended_data)
|
||||
.value("FlexRayControl", _icsneo_netid_t::icsneo_netid_flexray_control)
|
||||
.value("CoreMiniPreLoad", _icsneo_netid_t::icsneo_netid_coremini_preload)
|
||||
.value("HW_COM_Latency_Test", _icsneo_netid_t::icsneo_netid_hw_com_latency_test)
|
||||
.value("DeviceStatus", _icsneo_netid_t::icsneo_netid_device_status)
|
||||
.value("UDP", _icsneo_netid_t::icsneo_netid_udp)
|
||||
.value("ForwardedMessage", _icsneo_netid_t::icsneo_netid_forwarded_message)
|
||||
.value("I2C2", _icsneo_netid_t::icsneo_netid_i2c2)
|
||||
.value("I2C3", _icsneo_netid_t::icsneo_netid_i2c3)
|
||||
.value("I2C4", _icsneo_netid_t::icsneo_netid_i2c4)
|
||||
.value("Ethernet2", _icsneo_netid_t::icsneo_netid_ethernet2)
|
||||
.value("A2B1", _icsneo_netid_t::icsneo_netid_a2b1)
|
||||
.value("A2B2", _icsneo_netid_t::icsneo_netid_a2b2)
|
||||
.value("Ethernet3", _icsneo_netid_t::icsneo_netid_ethernet3)
|
||||
.value("WBMS", _icsneo_netid_t::icsneo_netid_wbms)
|
||||
.value("DWCAN9", _icsneo_netid_t::icsneo_netid_dwcan9)
|
||||
.value("DWCAN10", _icsneo_netid_t::icsneo_netid_dwcan10)
|
||||
.value("DWCAN11", _icsneo_netid_t::icsneo_netid_dwcan11)
|
||||
.value("DWCAN12", _icsneo_netid_t::icsneo_netid_dwcan12)
|
||||
.value("DWCAN13", _icsneo_netid_t::icsneo_netid_dwcan13)
|
||||
.value("DWCAN14", _icsneo_netid_t::icsneo_netid_dwcan14)
|
||||
.value("DWCAN15", _icsneo_netid_t::icsneo_netid_dwcan15)
|
||||
.value("DWCAN16", _icsneo_netid_t::icsneo_netid_dwcan16)
|
||||
.value("LIN7", _icsneo_netid_t::icsneo_netid_lin7)
|
||||
.value("LIN8", _icsneo_netid_t::icsneo_netid_lin8)
|
||||
.value("SPI2", _icsneo_netid_t::icsneo_netid_spi2)
|
||||
.value("MDIO1", _icsneo_netid_t::icsneo_netid_mdio1)
|
||||
.value("MDIO2", _icsneo_netid_t::icsneo_netid_mdio2)
|
||||
.value("MDIO3", _icsneo_netid_t::icsneo_netid_mdio3)
|
||||
.value("MDIO4", _icsneo_netid_t::icsneo_netid_mdio4)
|
||||
.value("MDIO5", _icsneo_netid_t::icsneo_netid_mdio5)
|
||||
.value("MDIO6", _icsneo_netid_t::icsneo_netid_mdio6)
|
||||
.value("MDIO7", _icsneo_netid_t::icsneo_netid_mdio7)
|
||||
.value("MDIO8", _icsneo_netid_t::icsneo_netid_mdio8)
|
||||
.value("OP_Ethernet13", _icsneo_netid_t::icsneo_netid_op_ethernet13)
|
||||
.value("OP_Ethernet14", _icsneo_netid_t::icsneo_netid_op_ethernet14)
|
||||
.value("OP_Ethernet15", _icsneo_netid_t::icsneo_netid_op_ethernet15)
|
||||
.value("OP_Ethernet16", _icsneo_netid_t::icsneo_netid_op_ethernet16)
|
||||
.value("SPI3", _icsneo_netid_t::icsneo_netid_spi3)
|
||||
.value("SPI4", _icsneo_netid_t::icsneo_netid_spi4)
|
||||
.value("SPI5", _icsneo_netid_t::icsneo_netid_spi5)
|
||||
.value("SPI6", _icsneo_netid_t::icsneo_netid_spi6)
|
||||
.value("SPI7", _icsneo_netid_t::icsneo_netid_spi7)
|
||||
.value("SPI8", _icsneo_netid_t::icsneo_netid_spi8)
|
||||
.value("LIN9", _icsneo_netid_t::icsneo_netid_lin9)
|
||||
.value("LIN10", _icsneo_netid_t::icsneo_netid_lin10)
|
||||
.value("LIN11", _icsneo_netid_t::icsneo_netid_lin11)
|
||||
.value("LIN12", _icsneo_netid_t::icsneo_netid_lin12)
|
||||
.value("LIN13", _icsneo_netid_t::icsneo_netid_lin13)
|
||||
.value("LIN14", _icsneo_netid_t::icsneo_netid_lin14)
|
||||
.value("LIN15", _icsneo_netid_t::icsneo_netid_lin15)
|
||||
.value("LIN16", _icsneo_netid_t::icsneo_netid_lin16)
|
||||
.value("Any", _icsneo_netid_t::icsneo_netid_any)
|
||||
.value("Invalid", _icsneo_netid_t::icsneo_netid_invalid);
|
||||
pybind11::enum_<Network::NetID>(network, "NetID")
|
||||
.value("Device", Network::NetID::Device)
|
||||
.value("HSCAN", Network::NetID::HSCAN)
|
||||
.value("MSCAN", Network::NetID::MSCAN)
|
||||
.value("SWCAN", Network::NetID::SWCAN)
|
||||
.value("LSFTCAN", Network::NetID::LSFTCAN)
|
||||
.value("FordSCP", Network::NetID::FordSCP)
|
||||
.value("J1708", Network::NetID::J1708)
|
||||
.value("Aux", Network::NetID::Aux)
|
||||
.value("J1850VPW", Network::NetID::J1850VPW)
|
||||
.value("ISO9141", Network::NetID::ISO9141)
|
||||
.value("DiskData", Network::NetID::DiskData)
|
||||
.value("Main51", Network::NetID::Main51)
|
||||
.value("RED", Network::NetID::RED)
|
||||
.value("SCI", Network::NetID::SCI)
|
||||
.value("ISO9141_2", Network::NetID::ISO9141_2)
|
||||
.value("ISO14230", Network::NetID::ISO14230)
|
||||
.value("LIN", Network::NetID::LIN)
|
||||
.value("OP_Ethernet1", Network::NetID::OP_Ethernet1)
|
||||
.value("OP_Ethernet2", Network::NetID::OP_Ethernet2)
|
||||
.value("OP_Ethernet3", Network::NetID::OP_Ethernet3)
|
||||
.value("RED_EXT_MEMORYREAD", Network::NetID::RED_EXT_MEMORYREAD)
|
||||
.value("RED_INT_MEMORYREAD", Network::NetID::RED_INT_MEMORYREAD)
|
||||
.value("RED_DFLASH_READ", Network::NetID::RED_DFLASH_READ)
|
||||
.value("NeoMemorySDRead", Network::NetID::NeoMemorySDRead)
|
||||
.value("CAN_ERRBITS", Network::NetID::CAN_ERRBITS)
|
||||
.value("NeoMemoryWriteDone", Network::NetID::NeoMemoryWriteDone)
|
||||
.value("RED_WAVE_CAN1_LOGICAL", Network::NetID::RED_WAVE_CAN1_LOGICAL)
|
||||
.value("RED_WAVE_CAN2_LOGICAL", Network::NetID::RED_WAVE_CAN2_LOGICAL)
|
||||
.value("RED_WAVE_LIN1_LOGICAL", Network::NetID::RED_WAVE_LIN1_LOGICAL)
|
||||
.value("RED_WAVE_LIN2_LOGICAL", Network::NetID::RED_WAVE_LIN2_LOGICAL)
|
||||
.value("RED_WAVE_LIN1_ANALOG", Network::NetID::RED_WAVE_LIN1_ANALOG)
|
||||
.value("RED_WAVE_LIN2_ANALOG", Network::NetID::RED_WAVE_LIN2_ANALOG)
|
||||
.value("RED_WAVE_MISC_ANALOG", Network::NetID::RED_WAVE_MISC_ANALOG)
|
||||
.value("RED_WAVE_MISCDIO2_LOGICAL", Network::NetID::RED_WAVE_MISCDIO2_LOGICAL)
|
||||
.value("RED_NETWORK_COM_ENABLE_EX", Network::NetID::RED_NETWORK_COM_ENABLE_EX)
|
||||
.value("RED_NEOVI_NETWORK", Network::NetID::RED_NEOVI_NETWORK)
|
||||
.value("RED_READ_BAUD_SETTINGS", Network::NetID::RED_READ_BAUD_SETTINGS)
|
||||
.value("RED_OLDFORMAT", Network::NetID::RED_OLDFORMAT)
|
||||
.value("RED_SCOPE_CAPTURE", Network::NetID::RED_SCOPE_CAPTURE)
|
||||
.value("RED_HARDWARE_EXCEP", Network::NetID::RED_HARDWARE_EXCEP)
|
||||
.value("RED_GET_RTC", Network::NetID::RED_GET_RTC)
|
||||
.value("ISO9141_3", Network::NetID::ISO9141_3)
|
||||
.value("HSCAN2", Network::NetID::HSCAN2)
|
||||
.value("HSCAN3", Network::NetID::HSCAN3)
|
||||
.value("OP_Ethernet4", Network::NetID::OP_Ethernet4)
|
||||
.value("OP_Ethernet5", Network::NetID::OP_Ethernet5)
|
||||
.value("ISO9141_4", Network::NetID::ISO9141_4)
|
||||
.value("LIN2", Network::NetID::LIN2)
|
||||
.value("LIN3", Network::NetID::LIN3)
|
||||
.value("LIN4", Network::NetID::LIN4)
|
||||
.value("RED_App_Error", Network::NetID::RED_App_Error)
|
||||
.value("CGI", Network::NetID::CGI)
|
||||
.value("Reset_Status", Network::NetID::Reset_Status)
|
||||
.value("FB_Status", Network::NetID::FB_Status)
|
||||
.value("App_Signal_Status", Network::NetID::App_Signal_Status)
|
||||
.value("Read_Datalink_Cm_Tx_Msg", Network::NetID::Read_Datalink_Cm_Tx_Msg)
|
||||
.value("Read_Datalink_Cm_Rx_Msg", Network::NetID::Read_Datalink_Cm_Rx_Msg)
|
||||
.value("Logging_Overflow", Network::NetID::Logging_Overflow)
|
||||
.value("ReadSettings", Network::NetID::ReadSettings)
|
||||
.value("HSCAN4", Network::NetID::HSCAN4)
|
||||
.value("HSCAN5", Network::NetID::HSCAN5)
|
||||
.value("RS232", Network::NetID::RS232)
|
||||
.value("UART", Network::NetID::UART)
|
||||
.value("UART2", Network::NetID::UART2)
|
||||
.value("UART3", Network::NetID::UART3)
|
||||
.value("UART4", Network::NetID::UART4)
|
||||
.value("SWCAN2", Network::NetID::SWCAN2)
|
||||
.value("Ethernet_DAQ", Network::NetID::Ethernet_DAQ)
|
||||
.value("Data_To_Host", Network::NetID::Data_To_Host)
|
||||
.value("TextAPI_To_Host", Network::NetID::TextAPI_To_Host)
|
||||
.value("SPI1", Network::NetID::SPI1)
|
||||
.value("OP_Ethernet6", Network::NetID::OP_Ethernet6)
|
||||
.value("Red_VBat", Network::NetID::Red_VBat)
|
||||
.value("OP_Ethernet7", Network::NetID::OP_Ethernet7)
|
||||
.value("OP_Ethernet8", Network::NetID::OP_Ethernet8)
|
||||
.value("OP_Ethernet9", Network::NetID::OP_Ethernet9)
|
||||
.value("OP_Ethernet10", Network::NetID::OP_Ethernet10)
|
||||
.value("OP_Ethernet11", Network::NetID::OP_Ethernet11)
|
||||
.value("FlexRay1a", Network::NetID::FlexRay1a)
|
||||
.value("FlexRay1b", Network::NetID::FlexRay1b)
|
||||
.value("FlexRay2a", Network::NetID::FlexRay2a)
|
||||
.value("FlexRay2b", Network::NetID::FlexRay2b)
|
||||
.value("LIN5", Network::NetID::LIN5)
|
||||
.value("FlexRay", Network::NetID::FlexRay)
|
||||
.value("FlexRay2", Network::NetID::FlexRay2)
|
||||
.value("OP_Ethernet12", Network::NetID::OP_Ethernet12)
|
||||
.value("I2C", Network::NetID::I2C)
|
||||
.value("MOST25", Network::NetID::MOST25)
|
||||
.value("MOST50", Network::NetID::MOST50)
|
||||
.value("MOST150", Network::NetID::MOST150)
|
||||
.value("Ethernet", Network::NetID::Ethernet)
|
||||
.value("GMFSA", Network::NetID::GMFSA)
|
||||
.value("TCP", Network::NetID::TCP)
|
||||
.value("HSCAN6", Network::NetID::HSCAN6)
|
||||
.value("HSCAN7", Network::NetID::HSCAN7)
|
||||
.value("LIN6", Network::NetID::LIN6)
|
||||
.value("LSFTCAN2", Network::NetID::LSFTCAN2)
|
||||
.value("LogicalDiskInfo", Network::NetID::LogicalDiskInfo)
|
||||
.value("WiVICommand", Network::NetID::WiVICommand)
|
||||
.value("ScriptStatus", Network::NetID::ScriptStatus)
|
||||
.value("EthPHYControl", Network::NetID::EthPHYControl)
|
||||
.value("ExtendedCommand", Network::NetID::ExtendedCommand)
|
||||
.value("ExtendedData", Network::NetID::ExtendedData)
|
||||
.value("FlexRayControl", Network::NetID::FlexRayControl)
|
||||
.value("CoreMiniPreLoad", Network::NetID::CoreMiniPreLoad)
|
||||
.value("HW_COM_Latency_Test", Network::NetID::HW_COM_Latency_Test)
|
||||
.value("DeviceStatus", Network::NetID::DeviceStatus)
|
||||
.value("UDP", Network::NetID::UDP)
|
||||
.value("ForwardedMessage", Network::NetID::ForwardedMessage)
|
||||
.value("I2C2", Network::NetID::I2C2)
|
||||
.value("I2C3", Network::NetID::I2C3)
|
||||
.value("I2C4", Network::NetID::I2C4)
|
||||
.value("Ethernet2", Network::NetID::Ethernet2)
|
||||
.value("A2B1", Network::NetID::A2B1)
|
||||
.value("A2B2", Network::NetID::A2B2)
|
||||
.value("Ethernet3", Network::NetID::Ethernet3)
|
||||
.value("WBMS", Network::NetID::WBMS)
|
||||
.value("DWCAN9", Network::NetID::DWCAN9)
|
||||
.value("DWCAN10", Network::NetID::DWCAN10)
|
||||
.value("DWCAN11", Network::NetID::DWCAN11)
|
||||
.value("DWCAN12", Network::NetID::DWCAN12)
|
||||
.value("DWCAN13", Network::NetID::DWCAN13)
|
||||
.value("DWCAN14", Network::NetID::DWCAN14)
|
||||
.value("DWCAN15", Network::NetID::DWCAN15)
|
||||
.value("DWCAN16", Network::NetID::DWCAN16)
|
||||
.value("LIN7", Network::NetID::LIN7)
|
||||
.value("LIN8", Network::NetID::LIN8)
|
||||
.value("SPI2", Network::NetID::SPI2)
|
||||
.value("MDIO1", Network::NetID::MDIO1)
|
||||
.value("MDIO2", Network::NetID::MDIO2)
|
||||
.value("MDIO3", Network::NetID::MDIO3)
|
||||
.value("MDIO4", Network::NetID::MDIO4)
|
||||
.value("MDIO5", Network::NetID::MDIO5)
|
||||
.value("MDIO6", Network::NetID::MDIO6)
|
||||
.value("MDIO7", Network::NetID::MDIO7)
|
||||
.value("MDIO8", Network::NetID::MDIO8)
|
||||
.value("OP_Ethernet13", Network::NetID::OP_Ethernet13)
|
||||
.value("OP_Ethernet14", Network::NetID::OP_Ethernet14)
|
||||
.value("OP_Ethernet15", Network::NetID::OP_Ethernet15)
|
||||
.value("OP_Ethernet16", Network::NetID::OP_Ethernet16)
|
||||
.value("SPI3", Network::NetID::SPI3)
|
||||
.value("SPI4", Network::NetID::SPI4)
|
||||
.value("SPI5", Network::NetID::SPI5)
|
||||
.value("SPI6", Network::NetID::SPI6)
|
||||
.value("SPI7", Network::NetID::SPI7)
|
||||
.value("SPI8", Network::NetID::SPI8)
|
||||
.value("LIN9", Network::NetID::LIN9)
|
||||
.value("LIN10", Network::NetID::LIN10)
|
||||
.value("LIN11", Network::NetID::LIN11)
|
||||
.value("LIN12", Network::NetID::LIN12)
|
||||
.value("LIN13", Network::NetID::LIN13)
|
||||
.value("LIN14", Network::NetID::LIN14)
|
||||
.value("LIN15", Network::NetID::LIN15)
|
||||
.value("LIN16", Network::NetID::LIN16)
|
||||
.value("Any", Network::NetID::Any)
|
||||
.value("Invalid", Network::NetID::Invalid);
|
||||
|
||||
network.def(pybind11::init<_icsneo_netid_t>());
|
||||
|
||||
pybind11::enum_<_icsneo_msg_bus_type_t>(network, "icsneo_msg_bus_type_t")
|
||||
.value("Invalid", icsneo_msg_bus_type_invalid)
|
||||
.value("Internal", icsneo_msg_bus_type_internal)
|
||||
.value("CAN", icsneo_msg_bus_type_can)
|
||||
.value("LIN", icsneo_msg_bus_type_lin)
|
||||
.value("FlexRay", icsneo_msg_bus_type_flexray)
|
||||
.value("MOST", icsneo_msg_bus_type_most)
|
||||
.value("Ethernet", icsneo_msg_bus_type_ethernet)
|
||||
.value("LSFTCAN", icsneo_msg_bus_type_lsftcan)
|
||||
.value("SWCAN", icsneo_msg_bus_type_swcan)
|
||||
.value("ISO9141", icsneo_msg_bus_type_iso9141)
|
||||
.value("I2C", icsneo_msg_bus_type_i2c)
|
||||
.value("A2B", icsneo_msg_bus_type_a2b)
|
||||
.value("SPI", icsneo_msg_bus_type_spi)
|
||||
.value("MDIO", icsneo_msg_bus_type_mdio)
|
||||
.value("Any", icsneo_msg_bus_type_any)
|
||||
.value("Other", icsneo_msg_bus_type_other);
|
||||
pybind11::enum_<Network::Type>(network, "Type")
|
||||
.value("Invalid", Network::Type::Invalid)
|
||||
.value("Internal", Network::Type::Internal)
|
||||
.value("CAN", Network::Type::CAN)
|
||||
.value("LIN", Network::Type::LIN)
|
||||
.value("FlexRay", Network::Type::FlexRay)
|
||||
.value("MOST", Network::Type::MOST)
|
||||
.value("Ethernet", Network::Type::Ethernet)
|
||||
.value("LSFTCAN", Network::Type::LSFTCAN)
|
||||
.value("SWCAN", Network::Type::SWCAN)
|
||||
.value("ISO9141", Network::Type::ISO9141)
|
||||
.value("I2C", Network::Type::I2C)
|
||||
.value("A2B", Network::Type::A2B)
|
||||
.value("SPI", Network::Type::SPI)
|
||||
.value("MDIO", Network::Type::MDIO)
|
||||
.value("Any", Network::Type::Any)
|
||||
.value("Other", Network::Type::Other);
|
||||
|
||||
network
|
||||
.def(pybind11::init<_icsneo_msg_bus_type_t>())
|
||||
.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)
|
||||
|
|
|
|||
|
|
@ -13,31 +13,33 @@ void init_device(pybind11::module_& m) {
|
|||
.def("get_serial", &Device::getSerial)
|
||||
.def("get_serial_number", &Device::getSerialNumber)
|
||||
.def("get_product_name", &Device::getProductName)
|
||||
.def("open", [](Device& device) { return device.open(); })
|
||||
.def("close", &Device::close)
|
||||
.def("open", [](Device& device) { return device.open(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("close", &Device::close, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_open", &Device::isOpen)
|
||||
.def("go_online", &Device::goOnline)
|
||||
.def("go_offline", &Device::goOffline)
|
||||
.def("is_online", &Device::isOnline).def("enable_message_polling", &Device::enableMessagePolling)
|
||||
.def("disable_message_polling", &Device::disableMessagePolling)
|
||||
.def("go_online", &Device::goOnline, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("go_offline", &Device::goOffline, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_online", &Device::isOnline)
|
||||
.def("enable_message_polling", &Device::enableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("disable_message_polling", &Device::disableMessagePolling, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("is_message_polling_enabled", &Device::isMessagePollingEnabled)
|
||||
.def("get_messages", [](Device& device) { return device.getMessages(); })
|
||||
.def("get_messages", [](Device& device) { return device.getMessages(); }, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_current_message_count", &Device::getCurrentMessageCount)
|
||||
.def("get_polling_message_limit", &Device::getPollingMessageLimit)
|
||||
.def("set_polling_message_limit", &Device::setPollingMessageLimit)
|
||||
.def("add_message_callback", &Device::addMessageCallback)
|
||||
.def("remove_message_callback", &Device::removeMessageCallback)
|
||||
.def("transmit", pybind11::overload_cast<std::shared_ptr<BusMessage>>(&Device::transmit))
|
||||
.def("add_message_callback", &Device::addMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("remove_message_callback", &Device::removeMessageCallback, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("transmit", pybind11::overload_cast<std::shared_ptr<BusMessage>>(&Device::transmit), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_supported_rx_networks", &Device::getSupportedRXNetworks, pybind11::return_value_policy::reference)
|
||||
.def("get_supported_tx_networks", &Device::getSupportedTXNetworks, pybind11::return_value_policy::reference)
|
||||
.def("get_rtc", &Device::getRTC)
|
||||
.def("set_rtc", &Device::setRTC)
|
||||
.def("get_rtc", &Device::getRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("set_rtc", &Device::setRTC, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("describe", &Device::describe)
|
||||
.def("is_online_supported", &Device::isOnlineSupported)
|
||||
.def("supports_tc10", &Device::supportsTC10)
|
||||
.def("request_tc10_wake", &Device::requestTC10Wake)
|
||||
.def("request_tc10_sleep", &Device::requestTC10Sleep)
|
||||
.def("get_tc10_status", &Device::getTC10Status)
|
||||
.def("request_tc10_wake", &Device::requestTC10Wake, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("request_tc10_sleep", &Device::requestTC10Sleep, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_tc10_status", &Device::getTC10Status, pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("get_gptp_status", &Device::getGPTPStatus, pybind11::arg("timeout") = std::chrono::milliseconds(100), pybind11::call_guard<pybind11::gil_scoped_release>())
|
||||
.def("__repr__", &Device::describe);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -2,69 +2,70 @@
|
|||
#include <pybind11/stl.h>
|
||||
#include <pybind11/functional.h>
|
||||
|
||||
#include <icsneo/device/devicetype.h>
|
||||
#include <icsneo/icsneotypes.h>
|
||||
#include "icsneo/device/devicetype.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
void init_devicetype(pybind11::module_& m) {
|
||||
pybind11::class_<DeviceType> deviceType(m, "DeviceType");
|
||||
pybind11::enum_<DeviceType::Enum>(deviceType, "Enum")
|
||||
.value("Unknown", DeviceType::Enum::Unknown)
|
||||
.value("BLUE", DeviceType::Enum::BLUE)
|
||||
.value("ECU_AVB", DeviceType::Enum::ECU_AVB)
|
||||
.value("RADSupermoon", DeviceType::Enum::RADSupermoon)
|
||||
.value("DW_VCAN", DeviceType::Enum::DW_VCAN)
|
||||
.value("RADMoon2", DeviceType::Enum::RADMoon2)
|
||||
.value("RADMars", DeviceType::Enum::RADMars)
|
||||
.value("VCAN4_1", DeviceType::Enum::VCAN4_1)
|
||||
.value("FIRE", DeviceType::Enum::FIRE)
|
||||
.value("RADPluto", DeviceType::Enum::RADPluto)
|
||||
.value("VCAN4_2EL", DeviceType::Enum::VCAN4_2EL)
|
||||
.value("RADIO_CANHUB", DeviceType::Enum::RADIO_CANHUB)
|
||||
.value("NEOECU12", DeviceType::Enum::NEOECU12)
|
||||
.value("OBD2_LCBADGE", DeviceType::Enum::OBD2_LCBADGE)
|
||||
.value("RADMoonDuo", DeviceType::Enum::RADMoonDuo)
|
||||
.value("FIRE3", DeviceType::Enum::FIRE3)
|
||||
.value("VCAN3", DeviceType::Enum::VCAN3)
|
||||
.value("RADJupiter", DeviceType::Enum::RADJupiter)
|
||||
.value("VCAN4_IND", DeviceType::Enum::VCAN4_IND)
|
||||
.value("RADGigastar", DeviceType::Enum::RADGigastar)
|
||||
.value("RED2", DeviceType::Enum::RED2)
|
||||
.value("EtherBADGE", DeviceType::Enum::EtherBADGE)
|
||||
.value("RAD_A2B", DeviceType::Enum::RAD_A2B)
|
||||
.value("RADEpsilon", DeviceType::Enum::RADEpsilon)
|
||||
.value("RADGalaxy2", DeviceType::Enum::RADGalaxy2)
|
||||
.value("RADMoon3", DeviceType::Enum::RADMoon3)
|
||||
.value("RADComet", DeviceType::Enum::RADComet)
|
||||
.value("FIRE3_FlexRay", DeviceType::Enum::FIRE3_FlexRay)
|
||||
.value("Connect", DeviceType::Enum::Connect)
|
||||
.value("RADComet3", DeviceType::Enum::RADComet3)
|
||||
.value("RADMoonT1S", DeviceType::Enum::RADMoonT1S)
|
||||
.value("RADGigastar2", DeviceType::Enum::RADGigastar2)
|
||||
.value("RED", DeviceType::Enum::RED)
|
||||
.value("ECU", DeviceType::Enum::ECU)
|
||||
.value("IEVB", DeviceType::Enum::IEVB)
|
||||
.value("Pendant", DeviceType::Enum::Pendant)
|
||||
.value("OBD2_PRO", DeviceType::Enum::OBD2_PRO)
|
||||
.value("ECUChip_UART", DeviceType::Enum::ECUChip_UART)
|
||||
.value("PLASMA", DeviceType::Enum::PLASMA)
|
||||
.value("NEOAnalog", DeviceType::Enum::NEOAnalog)
|
||||
.value("CT_OBD", DeviceType::Enum::CT_OBD)
|
||||
.value("ION", DeviceType::Enum::ION)
|
||||
.value("RADStar", DeviceType::Enum::RADStar)
|
||||
.value("VCAN4_4", DeviceType::Enum::VCAN4_4)
|
||||
.value("VCAN4_2", DeviceType::Enum::VCAN4_2)
|
||||
.value("CMProbe", DeviceType::Enum::CMProbe)
|
||||
.value("EEVB", DeviceType::Enum::EEVB)
|
||||
.value("VCANrf", DeviceType::Enum::VCANrf)
|
||||
.value("FIRE2", DeviceType::Enum::FIRE2)
|
||||
.value("Flex", DeviceType::Enum::Flex)
|
||||
.value("RADGalaxy", DeviceType::Enum::RADGalaxy)
|
||||
.value("RADStar2", DeviceType::Enum::RADStar2)
|
||||
.value("VividCAN", DeviceType::Enum::VividCAN)
|
||||
.value("OBD2_SIM", DeviceType::Enum::OBD2_SIM);
|
||||
deviceType.def(pybind11::init<DeviceType::Enum>());
|
||||
deviceType.def("get_device_type", &DeviceType::getDeviceType);
|
||||
deviceType.def(
|
||||
"get_generic_product_name", [](DeviceType &self) -> std::string {
|
||||
return self.getGenericProductName(self.getDeviceType());
|
||||
});
|
||||
|
||||
pybind11::enum_<_icsneo_devicetype_t>(m, "icsneo_devicetype_t")
|
||||
.value("unknown", icsneo_devicetype_unknown)
|
||||
.value("blue", icsneo_devicetype_blue)
|
||||
.value("ecu_avb", icsneo_devicetype_ecu_avb)
|
||||
.value("rad_supermoon", icsneo_devicetype_rad_supermoon)
|
||||
.value("dw_vcan", icsneo_devicetype_dw_vcan)
|
||||
.value("rad_moon2", icsneo_devicetype_rad_moon2)
|
||||
.value("rad_mars", icsneo_devicetype_rad_mars)
|
||||
.value("vcan41", icsneo_devicetype_vcan41)
|
||||
.value("fire", icsneo_devicetype_fire)
|
||||
.value("rad_pluto", icsneo_devicetype_rad_pluto)
|
||||
.value("vcan42_el", icsneo_devicetype_vcan42_el)
|
||||
.value("radio_canhub", icsneo_devicetype_radio_canhub)
|
||||
.value("neo_ecu12", icsneo_devicetype_neo_ecu12)
|
||||
.value("obd2_lc_badge", icsneo_devicetype_obd2_lc_badge)
|
||||
.value("rad_moon_duo", icsneo_devicetype_rad_moon_duo)
|
||||
.value("fire3", icsneo_devicetype_fire3)
|
||||
.value("vcan3", icsneo_devicetype_vcan3)
|
||||
.value("rad_jupiter", icsneo_devicetype_rad_jupiter)
|
||||
.value("vcan4_industrial", icsneo_devicetype_vcan4_industrial)
|
||||
.value("rad_gigastar", icsneo_devicetype_rad_gigastar)
|
||||
.value("red2", icsneo_devicetype_red2)
|
||||
.value("etherbadge", icsneo_devicetype_etherbadge)
|
||||
.value("rad_a2b", icsneo_devicetype_rad_a2b)
|
||||
.value("rad_epsilon", icsneo_devicetype_rad_epsilon)
|
||||
.value("rad_moon3", icsneo_devicetype_rad_moon3)
|
||||
.value("rad_comet", icsneo_devicetype_rad_comet)
|
||||
.value("fire3_flexray", icsneo_devicetype_fire3_flexray)
|
||||
.value("connect", icsneo_devicetype_connect)
|
||||
.value("rad_comet3", icsneo_devicetype_rad_comet3)
|
||||
.value("rad_moon_t1s", icsneo_devicetype_rad_moon_t1s)
|
||||
.value("rad_gigastar2", icsneo_devicetype_rad_gigastar2)
|
||||
.value("red", icsneo_devicetype_red)
|
||||
.value("ecu", icsneo_devicetype_ecu)
|
||||
.value("ievb", icsneo_devicetype_ievb)
|
||||
.value("pendant", icsneo_devicetype_pendant)
|
||||
.value("obd2_pro", icsneo_devicetype_obd2_pro)
|
||||
.value("plasma", icsneo_devicetype_plasma)
|
||||
.value("ion", icsneo_devicetype_ion)
|
||||
.value("rad_star", icsneo_devicetype_rad_star)
|
||||
.value("vcan44", icsneo_devicetype_vcan44)
|
||||
.value("vcan42", icsneo_devicetype_vcan42)
|
||||
.value("cm_probe", icsneo_devicetype_cm_probe)
|
||||
.value("eevb", icsneo_devicetype_eevb)
|
||||
.value("fire2", icsneo_devicetype_fire2)
|
||||
.value("flex", icsneo_devicetype_flex)
|
||||
.value("rad_galaxy", icsneo_devicetype_rad_galaxy)
|
||||
.value("rad_star2", icsneo_devicetype_rad_star2)
|
||||
.value("vividcan", icsneo_devicetype_vividcan)
|
||||
.value("obd2_sim", icsneo_devicetype_obd2_sim);
|
||||
deviceType.def("get_generic_product_name", &DeviceType::getGenericProductName);
|
||||
}
|
||||
|
||||
} // namespace icsneo
|
||||
|
|
|
|||
|
|
@ -13,16 +13,21 @@ void init_network(pybind11::module_&);
|
|||
void init_devicetype(pybind11::module_&);
|
||||
void init_message(pybind11::module_&);
|
||||
void init_canmessage(pybind11::module_&);
|
||||
void init_canerrormessage(pybind11::module_&);
|
||||
void init_ethernetmessage(pybind11::module_&);
|
||||
void init_linmessage(pybind11::module_&);
|
||||
void init_tc10statusmessage(pybind11::module_&);
|
||||
void init_gptpstatusmessage(pybind11::module_&);
|
||||
void init_mdiomessage(pybind11::module_&);
|
||||
void init_ethernetstatusmessage(pybind11::module_&);
|
||||
void init_device(pybind11::module_&);
|
||||
void init_messagefilter(pybind11::module_&);
|
||||
void init_messagecallback(pybind11::module_&);
|
||||
void init_version(pybind11::module_&);
|
||||
|
||||
PYBIND11_MODULE(icsneopy, m) {
|
||||
pybind11::options options;
|
||||
options.disable_enum_members_docstring();
|
||||
m.doc() = "libicsneo Python module";
|
||||
|
||||
init_event(m);
|
||||
|
|
@ -33,10 +38,13 @@ PYBIND11_MODULE(icsneopy, m) {
|
|||
init_network(m);
|
||||
init_message(m);
|
||||
init_canmessage(m);
|
||||
init_canerrormessage(m);
|
||||
init_ethernetmessage(m);
|
||||
init_linmessage(m);
|
||||
init_tc10statusmessage(m);
|
||||
init_gptpstatusmessage(m);
|
||||
init_mdiomessage(m);
|
||||
init_ethernetstatusmessage(m);
|
||||
init_messagefilter(m);
|
||||
init_messagecallback(m);
|
||||
init_device(m);
|
||||
|
|
|
|||
|
|
@ -3,10 +3,6 @@
|
|||
debug/
|
||||
target/
|
||||
|
||||
# Remove Cargo.lock from gitignore if creating an executable, leave it for libraries
|
||||
# More information here https://doc.rust-lang.org/cargo/guide/cargo-toml-vs-cargo-lock.html
|
||||
Cargo.lock
|
||||
|
||||
# These are backup files generated by rustfmt
|
||||
**/*.rs.bk
|
||||
|
||||
|
|
@ -0,0 +1,293 @@
|
|||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aho-corasick"
|
||||
version = "1.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e60d3430d3a69478ad0993f19238d2df97c507009a52b3c10addcd7f6bcb916"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bindgen"
|
||||
version = "0.71.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "5f58bf3d7db68cfbac37cfc485a8d711e87e064c3d0fe0435b92f7a407f9d6b3"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"cexpr",
|
||||
"clang-sys",
|
||||
"itertools",
|
||||
"log",
|
||||
"prettyplease",
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"regex",
|
||||
"rustc-hash",
|
||||
"shlex",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "bitflags"
|
||||
version = "2.8.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f68f53c83ab957f72c32642f3868eec03eb974d1fb82e453128456482613d36"
|
||||
|
||||
[[package]]
|
||||
name = "cexpr"
|
||||
version = "0.6.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6fac387a98bb7c37292057cffc56d62ecb629900026402633ae9160df93a8766"
|
||||
dependencies = [
|
||||
"nom",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "cfg-if"
|
||||
version = "1.0.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
|
||||
|
||||
[[package]]
|
||||
name = "clang-sys"
|
||||
version = "1.8.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0b023947811758c97c59bf9d1c188fd619ad4718dcaa767947df1cadb14f39f4"
|
||||
dependencies = [
|
||||
"glob",
|
||||
"libc",
|
||||
"libloading",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "either"
|
||||
version = "1.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60b1af1c220855b6ceac025d3f6ecdd2b7c4894bfe9cd9bda4fbb4bc7c0d4cf0"
|
||||
|
||||
[[package]]
|
||||
name = "glob"
|
||||
version = "0.3.2"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a8d1add55171497b4705a648c6b583acafb01d58050a51727785f0b2c8e0a2b2"
|
||||
|
||||
[[package]]
|
||||
name = "icsneoc2rs"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bindgen",
|
||||
"scopeguard",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "itertools"
|
||||
version = "0.13.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "413ee7dfc52ee1a4949ceeb7dbc8a33f2d6c088194d9f922fb8318faf1f01186"
|
||||
dependencies = [
|
||||
"either",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "libc"
|
||||
version = "0.2.169"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a"
|
||||
|
||||
[[package]]
|
||||
name = "libloading"
|
||||
version = "0.8.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "fc2f4eb4bc735547cfed7c0a4922cbd04a4655978c09b54f1f7b228750664c34"
|
||||
dependencies = [
|
||||
"cfg-if",
|
||||
"windows-targets",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "log"
|
||||
version = "0.4.25"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f"
|
||||
|
||||
[[package]]
|
||||
name = "memchr"
|
||||
version = "2.7.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
|
||||
|
||||
[[package]]
|
||||
name = "minimal-lexical"
|
||||
version = "0.2.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "68354c5c6bd36d73ff3feceb05efa59b6acb7626617f4962be322a825e61f79a"
|
||||
|
||||
[[package]]
|
||||
name = "nom"
|
||||
version = "7.1.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d273983c5a657a70a3e8f2a01329822f3b8c8172b73826411a55751e404a0a4a"
|
||||
dependencies = [
|
||||
"memchr",
|
||||
"minimal-lexical",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "prettyplease"
|
||||
version = "0.2.29"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6924ced06e1f7dfe3fa48d57b9f74f55d8915f5036121bef647ef4b204895fac"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "proc-macro2"
|
||||
version = "1.0.93"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99"
|
||||
dependencies = [
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "quote"
|
||||
version = "1.0.38"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex"
|
||||
version = "1.11.1"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-automata",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-automata"
|
||||
version = "0.4.9"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908"
|
||||
dependencies = [
|
||||
"aho-corasick",
|
||||
"memchr",
|
||||
"regex-syntax",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "regex-syntax"
|
||||
version = "0.8.5"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c"
|
||||
|
||||
[[package]]
|
||||
name = "rustc-hash"
|
||||
version = "2.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "c7fb8039b3032c191086b10f11f319a6e99e1e82889c5cc6046f515c9db1d497"
|
||||
|
||||
[[package]]
|
||||
name = "scopeguard"
|
||||
version = "1.2.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
||||
|
||||
[[package]]
|
||||
name = "shlex"
|
||||
version = "1.3.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
|
||||
|
||||
[[package]]
|
||||
name = "syn"
|
||||
version = "2.0.96"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80"
|
||||
dependencies = [
|
||||
"proc-macro2",
|
||||
"quote",
|
||||
"unicode-ident",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "unicode-ident"
|
||||
version = "1.0.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a210d160f08b701c8721ba1c726c11662f877ea6b7094007e1ca9a1041945034"
|
||||
|
||||
[[package]]
|
||||
name = "windows-targets"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973"
|
||||
dependencies = [
|
||||
"windows_aarch64_gnullvm",
|
||||
"windows_aarch64_msvc",
|
||||
"windows_i686_gnu",
|
||||
"windows_i686_gnullvm",
|
||||
"windows_i686_msvc",
|
||||
"windows_x86_64_gnu",
|
||||
"windows_x86_64_gnullvm",
|
||||
"windows_x86_64_msvc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3"
|
||||
|
||||
[[package]]
|
||||
name = "windows_aarch64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_i686_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnu"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_gnullvm"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d"
|
||||
|
||||
[[package]]
|
||||
name = "windows_x86_64_msvc"
|
||||
version = "0.52.6"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
|
||||
|
|
@ -0,0 +1,22 @@
|
|||
[package]
|
||||
name = "icsneoc2rs"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
name = "icsneoc2rs"
|
||||
crate-type = ["rlib", "staticlib", "cdylib"]
|
||||
path = "src/lib.rs"
|
||||
|
||||
[[example]]
|
||||
name = "simple"
|
||||
path = "examples/simple.rs"
|
||||
|
||||
[dev-dependencies]
|
||||
scopeguard = "1.2.0"
|
||||
|
||||
[features]
|
||||
static = []
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.71.1"
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
use std::env;
|
||||
use std::path::PathBuf;
|
||||
|
||||
pub fn main() {
|
||||
// Tell cargo to look for shared libraries in the specified directory
|
||||
println!("cargo:rustc-link-search=../../../build");
|
||||
|
||||
// Tell cargo to tell rustc to link the system
|
||||
// shared library.
|
||||
println!("cargo:rustc-link-lib=icsneoc2");
|
||||
|
||||
// The bindgen::Builder is the main entry point
|
||||
// to bindgen, and lets you build up options for
|
||||
// the resulting bindings.
|
||||
let bindings = bindgen::Builder::default()
|
||||
// The input header we would like to generate
|
||||
// bindings for.
|
||||
.header("../../../include/icsneo/icsneoc2.h")
|
||||
.clang_arg("-I../../../include")
|
||||
// Tell cargo to invalidate the built crate whenever any of the
|
||||
// included header files changed.
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
.derive_default(true)
|
||||
.derive_debug(true)
|
||||
.derive_partialeq(true)
|
||||
.derive_copy(true)
|
||||
.default_enum_style(bindgen::EnumVariation::Rust { non_exhaustive: true })
|
||||
.default_alias_style(bindgen::AliasVariation::TypeAlias)
|
||||
.generate_cstr(true)
|
||||
// Finish the builder and generate the bindings.
|
||||
.generate()
|
||||
// Unwrap the Result and panic on failure.
|
||||
.expect("Unable to generate bindings");
|
||||
|
||||
// Write the bindings to the $OUT_DIR/bindings.rs file.
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
|
|
@ -0,0 +1,333 @@
|
|||
use icsneoc2rs::ffi::_icsneoc2_msg_bus_type_t::*;
|
||||
use icsneoc2rs::ffi::_icsneoc2_msg_type_t::*;
|
||||
use icsneoc2rs::ffi::_icsneoc2_netid_t;
|
||||
use icsneoc2rs::ffi::_icsneoc2_netid_t::*;
|
||||
use icsneoc2rs::ffi::_icsneoc2_open_options_t::*;
|
||||
use icsneoc2rs::ffi::icsneoc2_message_t;
|
||||
use icsneoc2rs::ffi::icsneoc2_msg_bus_type_t;
|
||||
use icsneoc2rs::ffi::icsneoc2_msg_type_t;
|
||||
use icsneoc2rs::ffi::icsneoc2_netid_t;
|
||||
use icsneoc2rs::Device;
|
||||
use icsneoc2rs::Error;
|
||||
use icsneoc2rs::Result as ICSNeoResult;
|
||||
|
||||
use scopeguard::defer;
|
||||
|
||||
fn main() -> ICSNeoResult<()> {
|
||||
print!("Finding devices... ");
|
||||
let devices = Device::find_all(255)?;
|
||||
println!(
|
||||
"OK, {} device{} found...",
|
||||
devices.len(),
|
||||
if devices.len() > 1 { "s" } else { "" }
|
||||
);
|
||||
for device in devices {
|
||||
device.device_is_valid()?;
|
||||
// Get description of the device
|
||||
let description = match device.device_description_get() {
|
||||
Ok(description) => description,
|
||||
Err(err) => {
|
||||
println!("Failed to get description of device: {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{} @ Handle {:?}", description, device.handle);
|
||||
// Get/Set open options
|
||||
let mut open_options = match device.device_open_options_get() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
println!("Failed to get open options of device: {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
// Disable Syncing RTC and going online
|
||||
open_options &= !(icsneoc2_open_options_sync_rtc as u32);
|
||||
open_options &= !(icsneoc2_open_options_go_online as u32);
|
||||
match device.device_open_options_set(open_options) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("\tDevice open options: {open_options:#02x}");
|
||||
// Open the device
|
||||
print!("\tOpening device... ");
|
||||
match device.device_open() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("OK");
|
||||
defer! {
|
||||
print_device_events(&device, &description).expect("Critical: Failed to print device events");
|
||||
}
|
||||
// Get timestamp resolution of the device
|
||||
print!("\tGetting timestamp resolution... ");
|
||||
let timestamp_resolution = match device.device_timestamp_resolution_get() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{timestamp_resolution}ns");
|
||||
// Get baudrates for HSCAN
|
||||
print!("\tGetting HSCAN baudrate... ");
|
||||
let baudrate = match device.device_baudrate_get(icsneoc2_netid_hscan) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{baudrate}mbit/s");
|
||||
// Get FD baudrates for HSCAN
|
||||
print!("\tGetting FD HSCAN baudrate... ");
|
||||
let fd_baudrate = match device.device_canfd_baudrate_get(icsneoc2_netid_hscan) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{fd_baudrate}mbit/s");
|
||||
// Set baudrates for HSCAN
|
||||
// saveToDevice: If this is set to true, the baudrate will be saved on the device
|
||||
// and will persist through a power cycle
|
||||
print!("\tSetting HSCAN baudrate... ");
|
||||
let save_to_device = false;
|
||||
match device.device_baudrate_set(icsneoc2_netid_hscan, baudrate, save_to_device) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("OK");
|
||||
// Set FD baudrates for HSCAN
|
||||
print!("\tSetting FD HSCAN baudrate... ");
|
||||
match device.device_canfd_baudrate_set(icsneoc2_netid_hscan, fd_baudrate, save_to_device) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("OK");
|
||||
// Get RTC
|
||||
print!("\tGetting RTC... ");
|
||||
let current_rtc = match device.device_rtc_get() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{current_rtc}");
|
||||
// Set RTC
|
||||
print!("\tSetting RTC... ");
|
||||
match device.device_rtc_set(current_rtc) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("OK");
|
||||
// Get RTC
|
||||
print!("\tGetting RTC... ");
|
||||
let rtc = match device.device_rtc_get() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{rtc}");
|
||||
// Go online, start acking traffic
|
||||
print!("\tGoing online... ");
|
||||
match device.device_go_online(true) {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
// Redundant check to show how to check if the device is online, if the previous
|
||||
// icsneoc2_device_go_online call was successful we can assume we are online already
|
||||
let is_online = match device.device_is_online() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("{}", if is_online { "Online" } else { "Offline" });
|
||||
// Transmit CAN messages
|
||||
if transmit_can_messages(&device).is_err() {
|
||||
continue;
|
||||
}
|
||||
println!("\tWaiting 1 second for messages...");
|
||||
std::thread::sleep(std::time::Duration::from_secs(1));
|
||||
// Get the messages
|
||||
let messages = match device.device_messages_get(20000, 3000) {
|
||||
Ok(messages) => messages,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
// Process the messages
|
||||
if process_messages(&device, messages).is_err() {
|
||||
continue;
|
||||
}
|
||||
// Close the device
|
||||
print!("\tClosing device... ");
|
||||
match device.device_close() {
|
||||
Ok(value) => value,
|
||||
Err(err) => {
|
||||
print_error(&device, &description, err);
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("OK");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_error(device: &Device, device_description: &String, err: Error) {
|
||||
println!("Failed: {err}");
|
||||
print_device_events(device, device_description)
|
||||
.expect("Critical: Failed to print device events");
|
||||
}
|
||||
|
||||
fn transmit_can_messages(device: &Device) -> ICSNeoResult<()> {
|
||||
const MESSAGE_COUNT: usize = 100;
|
||||
println!("\tTransmitting {MESSAGE_COUNT} messages...");
|
||||
for i in 0..MESSAGE_COUNT {
|
||||
let message = match device.message_can_create(1) {
|
||||
Ok(messages) => messages[0],
|
||||
Err(err) => {
|
||||
println!("Failed to create CAN message #{i}: {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
device.message_netid_set(message, icsneoc2_netid_hscan)?;
|
||||
device.message_can_arbid_set(message, 0x10)?;
|
||||
device.message_can_canfd_set(message, true)?;
|
||||
device.message_can_extended_set(message, true)?;
|
||||
device.message_can_baudrate_switch_set(message, true)?;
|
||||
device.message_data_set(
|
||||
message,
|
||||
vec![
|
||||
(i >> 56 & 0xFF) as u8,
|
||||
(i >> 48 & 0xFF) as u8,
|
||||
(i >> 40 & 0xFF) as u8,
|
||||
(i >> 32 & 0xFF) as u8,
|
||||
(i >> 24 & 0xFF) as u8,
|
||||
(i >> 16 & 0xFF) as u8,
|
||||
(i >> 8 & 0xFF) as u8,
|
||||
(i & 0xFF) as u8,
|
||||
],
|
||||
)?;
|
||||
device.message_can_dlc_set(message, -1)?;
|
||||
device.device_messages_transmit(vec![message])?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn process_messages(device: &Device, messages: Vec<*mut icsneoc2_message_t>) -> ICSNeoResult<()> {
|
||||
let mut tx_count: u32 = 0;
|
||||
for (i, message) in messages.iter().enumerate() {
|
||||
// Get the message type
|
||||
let msg_type = device.message_type_get(*message)?;
|
||||
// Get the message type name
|
||||
let msg_type_name = device.message_type_name_get(msg_type)?;
|
||||
// Check if the message is a bus message, ignore otherwise
|
||||
if msg_type != icsneoc2_msg_type_bus as icsneoc2_msg_type_t {
|
||||
println!("\tIgnoring message type : {msg_type} ({msg_type_name})");
|
||||
continue;
|
||||
}
|
||||
// Get the message bus type
|
||||
let msg_bus_type = device.message_bus_type_get(*message)?;
|
||||
// Get the message type name
|
||||
let msg_bus_type_name = device.bus_type_name_get(msg_bus_type)?;
|
||||
// Check if message is a transmit message
|
||||
if device.message_is_transmit(*message)? {
|
||||
tx_count += 1;
|
||||
continue;
|
||||
}
|
||||
println!("\t{i} Message type: {msg_type} bus type: {msg_bus_type_name} ({msg_bus_type})\n");
|
||||
// Check if the message is a CAN message, ignore otherwise
|
||||
if msg_bus_type == icsneoc2_msg_bus_type_can as icsneoc2_msg_bus_type_t {
|
||||
let netid = device.message_netid_get(*message)?;
|
||||
let netid_name = device.netid_name_get(netid)?;
|
||||
let arbid = device.message_can_arbid_get(*message)?;
|
||||
let dlc = device.message_can_dlc_get(*message)?;
|
||||
let is_remote = device.message_can_is_remote(*message)?;
|
||||
let is_canfd = device.message_can_is_canfd(*message)?;
|
||||
let is_extended = device.message_can_is_extended(*message)?;
|
||||
let data = device.message_data_get(*message, 64)?;
|
||||
// Finally lets print the RX message
|
||||
println!("\t NetID: {netid_name} ({:#02x})\tArbID: {arbid:#02x}\t DLC: {dlc}\t Remote: {is_remote}\t \
|
||||
CANFD: {is_canfd}\t Extended: {is_extended}\t Data length: {}\n", netid as icsneoc2_netid_t,data.len());
|
||||
println!("\t Data: {data:#02x?}\n");
|
||||
} else {
|
||||
println!("\tIgnoring bus message type: {msg_bus_type} ({msg_bus_type_name})\n");
|
||||
}
|
||||
}
|
||||
println!(
|
||||
"\tReceived {} messages total, {} were TX messages",
|
||||
messages.len(),
|
||||
tx_count
|
||||
);
|
||||
Ok(())
|
||||
}
|
||||
|
||||
fn print_device_events(device: &Device, device_description: &String) -> ICSNeoResult<()> {
|
||||
let events = match device.device_events_get(1024) {
|
||||
Ok(events) => events,
|
||||
Err(err) => {
|
||||
println!("Failed to get device events: {err}");
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
for (i, event) in events.iter().enumerate() {
|
||||
let description = match device.event_description_get(*event) {
|
||||
Ok(description) => description,
|
||||
Err(err) => {
|
||||
println!("Failed to get event description: {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("\t{device_description}: Event {i}: {description}");
|
||||
}
|
||||
// Get global events
|
||||
let global_events = match device.events_get(1024) {
|
||||
Ok(events) => events,
|
||||
Err(err) => {
|
||||
println!("Failed to get global events: {err}");
|
||||
return Err(err);
|
||||
}
|
||||
};
|
||||
for (i, event) in global_events.iter().enumerate() {
|
||||
let description = match device.event_description_get(*event) {
|
||||
Ok(description) => description,
|
||||
Err(err) => {
|
||||
println!("Failed to get event description: {err}");
|
||||
continue;
|
||||
}
|
||||
};
|
||||
println!("\t{device_description}: Global Event {i}: {description}");
|
||||
}
|
||||
println!(
|
||||
"\t{device_description}: Received {} events and {} global events\n",
|
||||
events.len(),
|
||||
global_events.len()
|
||||
);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -0,0 +1,5 @@
|
|||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
|
@ -0,0 +1,902 @@
|
|||
pub mod ffi;
|
||||
|
||||
use ffi::_icsneoc2_error_t::{icsneoc2_error_invalid_device, icsneoc2_error_success};
|
||||
use ffi::_icsneoc2_open_options_t::*;
|
||||
use ffi::*;
|
||||
|
||||
use std::ffi::CString;
|
||||
use std::fmt::Display;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub enum Error {
|
||||
/// icsneoc2 API error
|
||||
APIError(icsneoc2_error_t, String),
|
||||
}
|
||||
|
||||
impl Display for Error {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
match self {
|
||||
Error::APIError(error_code, error_string) => write!(f, "API Error: \"{}\" ({})", error_string, error_code),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub type Result<T> = core::result::Result<T, Error>;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Device {
|
||||
/// Handle to the device.
|
||||
pub handle: *mut icsneoc2_device_t,
|
||||
}
|
||||
|
||||
impl Drop for Device {
|
||||
fn drop(&mut self) {
|
||||
// Make sure the device is closed before we go out of scope.
|
||||
self.device_close().expect("Failed to close device!");
|
||||
}
|
||||
}
|
||||
|
||||
impl Device {
|
||||
pub fn find_all(device_count: u32) -> Result<Vec<Self>> {
|
||||
// Find all the devices
|
||||
const MAX_DEVICE_COUNT: u32 = 255;
|
||||
let mut devices: [*mut icsneoc2_device_t; MAX_DEVICE_COUNT as usize] =
|
||||
[std::ptr::null_mut(); 255];
|
||||
let mut devices_count: u32 = if device_count > MAX_DEVICE_COUNT {
|
||||
MAX_DEVICE_COUNT
|
||||
} else {
|
||||
device_count
|
||||
};
|
||||
let res = unsafe {
|
||||
icsneoc2_device_find_all(
|
||||
devices.as_mut_ptr(),
|
||||
&mut devices_count as *mut u32,
|
||||
std::ptr::null_mut(),
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Return the results
|
||||
let found_devices: Vec<Self> = devices[..devices_count as usize]
|
||||
.iter()
|
||||
.map(|d| Self { handle: *d })
|
||||
.collect();
|
||||
Ok(found_devices)
|
||||
}
|
||||
|
||||
pub fn bus_type_name_get(&self, bus_type: icsneoc2_msg_bus_type_t) -> Result<String> {
|
||||
// Get the string
|
||||
let mut str: Vec<u8> = vec![0; 255];
|
||||
let mut str_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_bus_type_name_get(bus_type, str.as_mut_ptr() as *mut i8, &mut str_length)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
str.resize(str_length as usize, 0);
|
||||
let str_string = {
|
||||
CString::new(str)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(str_string)
|
||||
}
|
||||
|
||||
pub fn device_baudrate_get(&self, netid: _icsneoc2_netid_t) -> Result<u64> {
|
||||
let mut value: u64 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_baudrate_get(self.handle, netid as icsneoc2_netid_t, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_baudrate_set(
|
||||
&self,
|
||||
netid: _icsneoc2_netid_t,
|
||||
value: u64,
|
||||
save: bool,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_baudrate_set(self.handle, netid as icsneoc2_netid_t, value, save) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_canfd_baudrate_get(&self, netid: _icsneoc2_netid_t) -> Result<u64> {
|
||||
let mut value: u64 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_canfd_baudrate_get(self.handle, netid as icsneoc2_netid_t, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_canfd_baudrate_set(
|
||||
&self,
|
||||
netid: _icsneoc2_netid_t,
|
||||
value: u64,
|
||||
save: bool,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_canfd_baudrate_set(self.handle, netid as icsneoc2_netid_t, value, save) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_close(&self) -> Result<()> {
|
||||
let res: icsneoc2_error_t = unsafe { ffi::icsneoc2_device_close(self.handle) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_description_get(&self) -> Result<String> {
|
||||
// Get the error code
|
||||
let mut description: Vec<u8> = vec![0; 255];
|
||||
let mut description_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_device_description_get(
|
||||
self.handle,
|
||||
description.as_mut_ptr() as *mut i8,
|
||||
&mut description_length,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
description.resize(description_length as usize, 0);
|
||||
let description_str = {
|
||||
CString::new(description)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(description_str)
|
||||
}
|
||||
|
||||
pub fn device_events_get(&self, event_count: u32) -> Result<Vec<*mut icsneoc2_event_t>> {
|
||||
let mut events: Vec<*mut icsneoc2_event_t> =
|
||||
vec![std::ptr::null_mut(); event_count as usize];
|
||||
let mut event_count: u32 = event_count;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_device_events_get(self.handle, events.as_mut_ptr(), &mut event_count)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
events.resize(event_count as usize, std::ptr::null_mut());
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
pub fn device_go_online(&self, go_online: bool) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_go_online(self.handle, go_online) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_is_online(&self) -> Result<bool> {
|
||||
let mut is_online: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_is_online(self.handle, &mut is_online) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(is_online)
|
||||
}
|
||||
|
||||
pub fn device_is_online_supported(&self) -> Result<bool> {
|
||||
let mut is_online_supported: bool = false;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_device_is_online_supported(self.handle, &mut is_online_supported)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(is_online_supported)
|
||||
}
|
||||
|
||||
pub fn device_is_valid(&self) -> Result<bool> {
|
||||
let res: icsneoc2_error_t = unsafe { icsneoc2_device_is_valid(self.handle) };
|
||||
match res {
|
||||
res if res == icsneoc2_error_success as icsneoc2_error_t => Ok(true),
|
||||
res if res == icsneoc2_error_invalid_device as icsneoc2_error_t => Ok(false),
|
||||
_ => Err(Self::error_code_get(res)),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn device_is_open(&self) -> Result<bool> {
|
||||
let mut is_open: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_is_open(self.handle, &mut is_open) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(is_open)
|
||||
}
|
||||
|
||||
pub fn device_is_disconnected(&self) -> Result<bool> {
|
||||
let mut is_disconnected: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_is_disconnected(self.handle, &mut is_disconnected) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(is_disconnected)
|
||||
}
|
||||
|
||||
pub fn device_load_default_settings(&self, save: bool) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_load_default_settings(self.handle, save) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_message_count_get(&self) -> Result<u32> {
|
||||
let mut value: u32 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_message_count_get(self.handle, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_message_polling_get(&self) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_message_polling_get(self.handle, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_message_polling_limit_get(&self) -> Result<u32> {
|
||||
let mut value: u32 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_message_polling_limit_get(self.handle, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_message_polling_set(&self, enable: bool) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_message_polling_set(self.handle, enable) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_message_polling_set_limit(&self, value: u32) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_message_polling_set_limit(self.handle, value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_messages_get(
|
||||
&self,
|
||||
message_count: u32,
|
||||
timeout_ms: u32,
|
||||
) -> Result<Vec<*mut icsneoc2_message_t>> {
|
||||
let mut messages: Vec<*mut icsneoc2_message_t> =
|
||||
vec![std::ptr::null_mut(); message_count as usize];
|
||||
let mut message_count: u32 = message_count;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_device_messages_get(
|
||||
self.handle,
|
||||
messages.as_mut_ptr(),
|
||||
&mut message_count,
|
||||
timeout_ms,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
messages.resize(message_count as usize, std::ptr::null_mut());
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
pub fn device_messages_transmit(&self, messages: Vec<*mut icsneoc2_message_t>) -> Result<u32> {
|
||||
let mut messages_count: u32 = messages.len() as u32;
|
||||
let mut messages = messages;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_device_messages_transmit(
|
||||
self.handle,
|
||||
messages.as_mut_ptr(),
|
||||
&mut messages_count,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(messages_count)
|
||||
}
|
||||
|
||||
pub fn device_open(&self) -> Result<()> {
|
||||
let res: icsneoc2_error_t = unsafe { ffi::icsneoc2_device_open(self.handle) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_open_options_get(&self) -> Result<ffi::icsneoc2_open_options_t> {
|
||||
let mut open_options: ffi::icsneoc2_open_options_t =
|
||||
icsneoc2_open_options_none as ffi::icsneoc2_open_options_t;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_open_options_get(self.handle, &mut open_options) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(open_options)
|
||||
}
|
||||
|
||||
pub fn device_open_options_set(
|
||||
&self,
|
||||
open_options: ffi::icsneoc2_open_options_t,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_open_options_set(self.handle, open_options) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_rtc_get(&self) -> Result<i64> {
|
||||
let mut value: i64 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_rtc_get(self.handle, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_rtc_set(&self, value: i64) -> Result<()> {
|
||||
let res: icsneoc2_error_t = unsafe { ffi::icsneoc2_device_rtc_set(self.handle, value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn device_serial_get(&self) -> Result<String> {
|
||||
// Get the string
|
||||
let mut str: Vec<u8> = vec![0; 255];
|
||||
let mut str_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_device_serial_get(self.handle, str.as_mut_ptr() as *mut i8, &mut str_length)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
str.resize(str_length as usize, 0);
|
||||
let str_string = {
|
||||
CString::new(str)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(str_string)
|
||||
}
|
||||
|
||||
pub fn device_supports_tc10(&self) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_supports_tc10(self.handle, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn device_timestamp_resolution_get(&self) -> Result<u32> {
|
||||
let mut timestamp_resolution: u32 = 0;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_device_timestamp_resolution_get(self.handle, &mut timestamp_resolution)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(timestamp_resolution)
|
||||
}
|
||||
|
||||
pub fn device_type_from_type(&self, device_type: icsneoc2_devicetype_t) -> Result<String> {
|
||||
// Get the string
|
||||
let mut str: Vec<u8> = vec![0; 255];
|
||||
let mut str_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_device_type_name_get(
|
||||
device_type,
|
||||
str.as_mut_ptr() as *mut i8,
|
||||
&mut str_length,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
str.resize(str_length as usize, 0);
|
||||
let str_string = {
|
||||
CString::new(str)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(str_string)
|
||||
}
|
||||
|
||||
pub fn device_type_get(&self) -> Result<icsneoc2_devicetype_t> {
|
||||
let mut value: icsneoc2_devicetype_t = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_device_type_get(self.handle, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn error_code_get(error_code: icsneoc2_error_t) -> Error {
|
||||
// Get the error code
|
||||
let mut error_description: Vec<u8> = vec![0; 255];
|
||||
let mut error_description_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_error_code_get(
|
||||
error_code,
|
||||
error_description.as_mut_ptr() as *mut i8,
|
||||
&mut error_description_length,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Error::APIError(res, "icsneoc2_error_code_get() failed.".to_string());
|
||||
}
|
||||
// Convert the vec to an String
|
||||
error_description.resize(error_description_length as usize, 0);
|
||||
let error_str = CString::new(error_description)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string");
|
||||
Error::APIError(error_code, error_str)
|
||||
}
|
||||
|
||||
pub fn event_description_get(&self, event: *mut icsneoc2_event_t) -> Result<String> {
|
||||
// Get the string
|
||||
let mut str: Vec<u8> = vec![0; 255];
|
||||
let mut str_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_event_description_get(event, str.as_mut_ptr() as *mut i8, &mut str_length)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
str.resize(str_length as usize, 0);
|
||||
let str_string = {
|
||||
CString::new(str)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(str_string)
|
||||
}
|
||||
|
||||
pub fn events_get(&self, event_count: u32) -> Result<Vec<*mut icsneoc2_event_t>> {
|
||||
let mut events: Vec<*mut icsneoc2_event_t> =
|
||||
vec![std::ptr::null_mut(); event_count as usize];
|
||||
let mut event_count: u32 = event_count;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_events_get(events.as_mut_ptr(), &mut event_count) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
events.resize(event_count as usize, std::ptr::null_mut());
|
||||
Ok(events)
|
||||
}
|
||||
|
||||
pub fn message_bus_type_get(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
) -> Result<icsneoc2_msg_bus_type_t> {
|
||||
let mut value: icsneoc2_msg_bus_type_t = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_bus_type_get(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_arbid_get(&self, message: *mut icsneoc2_message_t) -> Result<u32> {
|
||||
let mut value: u32 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_arbid_get(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_arbid_set(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
value: u32,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_arbid_set(self.handle, message, value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_can_baudrate_switch_get(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_message_can_baudrate_switch_get(self.handle, message, &mut value)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_baudrate_switch_set(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
value: bool,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_message_can_baudrate_switch_set(self.handle, message, value)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_can_canfd_set(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
value: bool,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_canfd_set(self.handle, message, value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_can_create(&self, message_count: u32) -> Result<Vec<*mut icsneoc2_message_t>> {
|
||||
let mut messages: Vec<*mut icsneoc2_message_t> =
|
||||
vec![std::ptr::null_mut(); message_count as usize];
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_message_can_create(self.handle, messages.as_mut_ptr(), message_count)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(messages)
|
||||
}
|
||||
|
||||
pub fn message_can_dlc_get(&self, message: *mut icsneoc2_message_t) -> Result<i32> {
|
||||
let mut value: i32 = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_dlc_get(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_dlc_set(&self, message: *mut icsneoc2_message_t, value: i32) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_dlc_set(self.handle, message, value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_can_error_state_indicator_get(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_message_can_error_state_indicator_get(self.handle, message, &mut value)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_extended_set(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
value: bool,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_extended_set(self.handle, message, value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_can_free(&self, message: *mut icsneoc2_message_t) -> Result<()> {
|
||||
let res: icsneoc2_error_t = unsafe { ffi::icsneoc2_message_can_free(self.handle, message) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_can_is_canfd(&self, message: *mut icsneoc2_message_t) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_is_canfd(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_is_extended(&self, message: *mut icsneoc2_message_t) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_is_extended(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_can_is_remote(&self, message: *mut icsneoc2_message_t) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_can_is_remote(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_data_get(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
data_length: u32,
|
||||
) -> Result<Vec<u8>> {
|
||||
let mut data: Vec<u8> = vec![0; data_length as usize];
|
||||
let mut data_length = data_length;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_message_data_get(
|
||||
self.handle,
|
||||
message,
|
||||
data.as_mut_ptr(),
|
||||
&mut data_length,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
data.resize(data_length as usize, 0);
|
||||
Ok(data)
|
||||
}
|
||||
|
||||
pub fn message_data_set(&self, message: *mut icsneoc2_message_t, data: Vec<u8>) -> Result<()> {
|
||||
let mut data = data;
|
||||
let res: icsneoc2_error_t = unsafe {
|
||||
ffi::icsneoc2_message_data_set(
|
||||
self.handle,
|
||||
message,
|
||||
data.as_mut_ptr(),
|
||||
data.len() as u32,
|
||||
)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_is_transmit(&self, message: *mut icsneoc2_message_t) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_is_transmit(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_is_valid(&self, message: *mut icsneoc2_message_t) -> Result<bool> {
|
||||
let mut value: bool = false;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_is_valid(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_netid_get(&self, message: *mut icsneoc2_message_t) -> Result<_icsneoc2_netid_t> {
|
||||
let mut value: icsneoc2_netid_t = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_netid_get(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// TODO: This is gross, there is probably a better way to do this.
|
||||
// TryFrom impl would be a lot of work to implement because there are so many values.
|
||||
// We are relying on the function call to always return a valid value.
|
||||
let value: _icsneoc2_netid_t = unsafe { std::mem::transmute(value as u32) };
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_netid_set(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
value: _icsneoc2_netid_t,
|
||||
) -> Result<()> {
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_netid_set(self.handle, message, value as icsneoc2_netid_t) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn message_type_get(
|
||||
&self,
|
||||
message: *mut icsneoc2_message_t,
|
||||
) -> Result<icsneoc2_msg_type_t> {
|
||||
let mut value: icsneoc2_msg_type_t = 0;
|
||||
let res: icsneoc2_error_t =
|
||||
unsafe { ffi::icsneoc2_message_type_get(self.handle, message, &mut value) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
Ok(value)
|
||||
}
|
||||
|
||||
pub fn message_type_name_get(&self, msg_type: icsneoc2_msg_type_t) -> Result<String> {
|
||||
// Get the string
|
||||
let mut str: Vec<u8> = vec![0; 255];
|
||||
let mut str_length: u32 = 255;
|
||||
let res = unsafe {
|
||||
icsneoc2_message_type_name_get(msg_type, str.as_mut_ptr() as *mut i8, &mut str_length)
|
||||
};
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
str.resize(str_length as usize, 0);
|
||||
let str_string = {
|
||||
CString::new(str)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(str_string)
|
||||
}
|
||||
|
||||
pub fn netid_name_get(&self, netid: _icsneoc2_netid_t) -> Result<String> {
|
||||
// Get the string
|
||||
let mut str: Vec<u8> = vec![0; 255];
|
||||
let mut str_length: u32 = 255;
|
||||
let res =
|
||||
unsafe { icsneoc2_netid_name_get(netid as icsneoc2_netid_t, str.as_mut_ptr() as *mut i8, &mut str_length) };
|
||||
// Check the error code
|
||||
if res != icsneoc2_error_success as icsneoc2_error_t {
|
||||
return Err(Self::error_code_get(res));
|
||||
}
|
||||
// Convert the vec to an String
|
||||
str.resize(str_length as usize, 0);
|
||||
let str_string = {
|
||||
CString::new(str)
|
||||
.expect("CString::new failed")
|
||||
.into_string()
|
||||
.expect("CString::new::into_string")
|
||||
};
|
||||
Ok(str_string)
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
fn test_device_find_all() {
|
||||
let devices = Device::find_all(0).unwrap();
|
||||
assert_eq!(devices.len(), 0);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,18 +0,0 @@
|
|||
[package]
|
||||
name = "icsneors"
|
||||
version = "0.1.0"
|
||||
edition = "2021"
|
||||
|
||||
[lib]
|
||||
crate-type = ["cdylib"]
|
||||
|
||||
[features]
|
||||
static = []
|
||||
|
||||
[dependencies]
|
||||
|
||||
[build-dependencies]
|
||||
bindgen = "0.71.1"
|
||||
path-clean = "1.0.1"
|
||||
cmake = "0.1.52"
|
||||
which = "7.0.0"
|
||||
|
|
@ -1,197 +0,0 @@
|
|||
use cmake::Config;
|
||||
use path_clean::{clean, PathClean};
|
||||
use std::{env, path::PathBuf};
|
||||
|
||||
fn libicsneo_path() -> PathBuf {
|
||||
// Get the path of libicsneo
|
||||
let path = std::env::var("LIBICSNEO_PATH")
|
||||
.unwrap_or(format!("{}/../../../", env!("CARGO_MANIFEST_DIR")));
|
||||
let libicsneo_path = std::path::PathBuf::from(clean(&path));
|
||||
|
||||
libicsneo_path
|
||||
}
|
||||
|
||||
fn libicsneo_include_path() -> PathBuf {
|
||||
let path = libicsneo_path().join("include");
|
||||
path.clean()
|
||||
}
|
||||
|
||||
fn libicsneo_header_path() -> PathBuf {
|
||||
let path = libicsneo_include_path().join("icsneo").join("icsneo.h");
|
||||
path.clean()
|
||||
}
|
||||
|
||||
// Detects the cargo build profile, true = release, otherwise false
|
||||
fn is_release_build() -> bool {
|
||||
let profile = std::env::var("PROFILE").unwrap();
|
||||
match profile.as_str() {
|
||||
"debug" => return false,
|
||||
"release" => return true,
|
||||
_ => return false,
|
||||
}
|
||||
}
|
||||
|
||||
// returns the cmake build string that is normally passed to -DCMAKE_BUILD_TYPE=
|
||||
fn cmake_build_config_type() -> String {
|
||||
let build_config_type = if is_release_build() {
|
||||
"Release"
|
||||
} else {
|
||||
if cfg!(target_os = "windows") {
|
||||
// Rust runtime is linked with /MD on windows MSVC... MSVC takes Debug and forces /MDd
|
||||
// https://www.reddit.com/r/rust/comments/dvmzo2/cargo_external_c_library_windows_debugrelease_hell/
|
||||
"RelWithDebInfo"
|
||||
} else {
|
||||
"Debug"
|
||||
}
|
||||
};
|
||||
build_config_type.to_string()
|
||||
}
|
||||
|
||||
// Build libicsneo through cmake, returns the build directory
|
||||
fn build_libicsneo() -> PathBuf {
|
||||
let libicsneo_path = libicsneo_path();
|
||||
// Check to make sure CMakeLists.txt exists
|
||||
if !libicsneo_path.join("CMakeLists.txt").exists() {
|
||||
panic!("CMakeLists.txt not found at {}", libicsneo_path.display());
|
||||
}
|
||||
let build_config_type = cmake_build_config_type();
|
||||
// Run cmake on libicsneo
|
||||
let mut config = Config::new(libicsneo_path.clone());
|
||||
let config = config
|
||||
.build_target("ALL_BUILD")
|
||||
// .define("LIBICSNEO_BUILD_ICSNEOC_STATIC:BOOL", "ON")
|
||||
// .define("LIBICSNEO_BUILD_EXAMPLES:BOOL", "OFF")
|
||||
// .define("LIBICSNEO_BUILD_ICSNEOLEGACY:BOOL", "OFF")
|
||||
.profile(&build_config_type);
|
||||
// Lets use ninja if it exists
|
||||
let config = match which::which("ninja") {
|
||||
Ok(_) => config.generator("Ninja Multi-Config").build_target("all"),
|
||||
Err(_e) => config,
|
||||
};
|
||||
config.build()
|
||||
}
|
||||
|
||||
fn setup_linker_libs(build_path: &PathBuf) {
|
||||
let build_config_type = cmake_build_config_type();
|
||||
// output for lib path
|
||||
println!(
|
||||
"cargo:warning=build search path: {:?}",
|
||||
build_path
|
||||
.join(format!("build/{build_config_type}"))
|
||||
.display()
|
||||
);
|
||||
// icsneo lib/dll linker search path
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}",
|
||||
build_path
|
||||
.join(format!("build/{build_config_type}"))
|
||||
.display()
|
||||
);
|
||||
// fatfs linker search path and addition
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}/build/third-party/fatfs/{build_config_type}",
|
||||
build_path.display()
|
||||
);
|
||||
// libicsneo libraries
|
||||
println!("cargo:rustc-link-lib=fatfs");
|
||||
println!("cargo:rustc-link-lib=static=icsneocpp");
|
||||
if cfg!(feature = "static") {
|
||||
println!("cargo:rustc-link-lib=static=icsneo-static");
|
||||
} else {
|
||||
println!("cargo:rustc-link-lib=dylib=icsneo");
|
||||
}
|
||||
// Platform specific libraries
|
||||
match env::var("CARGO_CFG_TARGET_OS").unwrap().as_str() {
|
||||
"windows" => {
|
||||
// FTD3xx linker search path and addition
|
||||
println!(
|
||||
"cargo:rustc-link-search=native={}/build/_deps/ftdi3xx-src",
|
||||
build_path.display()
|
||||
);
|
||||
println!("cargo:rustc-link-lib=FTD3XX");
|
||||
}
|
||||
"linux" => {}
|
||||
"macos" => {
|
||||
println!("cargo:rustc-link-lib=static=icsneo-static");
|
||||
println!("cargo:rustc-link-lib=framework=IOKit");
|
||||
println!("cargo:rustc-link-lib=framework=CoreFoundation");
|
||||
}
|
||||
target_os => panic!("Target OS not supported: {target_os}"),
|
||||
}
|
||||
}
|
||||
|
||||
fn prepare_git_submodule() {
|
||||
// We don't need to checkout the submodule if we are using a custom libicsneo path
|
||||
if std::env::var("LIBICSNEO_PATH").is_ok() {
|
||||
println!("cargo:warning=Using custom LIBICSNEO_PATH, skipping checking out submodules");
|
||||
return;
|
||||
}
|
||||
let libicsneo_path = libicsneo_path();
|
||||
// This seems to not be needed when including this as a dependency? Why?
|
||||
// checkout the submodule if needed
|
||||
let output = std::process::Command::new("git")
|
||||
.args(["submodule", "update", "--init"])
|
||||
.current_dir(libicsneo_path)
|
||||
.output()
|
||||
.expect("Failed to fetch git submodules!");
|
||||
// Make sure git was successful!
|
||||
if !output.status.success() {
|
||||
println!("cargo:warning=git return code: {}", output.status);
|
||||
let stdout = std::str::from_utf8(&output.stdout).unwrap();
|
||||
for line in stdout.split("\n") {
|
||||
println!("cargo:warning=git stdout: {}", line);
|
||||
}
|
||||
let stderr = std::str::from_utf8(&output.stderr).unwrap();
|
||||
for line in stderr.split("\n") {
|
||||
println!("cargo:warning=git stderr: {}", line);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn generate_bindings() {
|
||||
let header = libicsneo_header_path();
|
||||
let bindings = bindgen::Builder::default()
|
||||
.header(header.to_str().unwrap())
|
||||
.default_enum_style(bindgen::EnumVariation::Rust {
|
||||
non_exhaustive: false,
|
||||
})
|
||||
.clang_args(&[format!("-I{}", libicsneo_include_path().display()).as_str()])
|
||||
.blocklist_file("stdint.h")
|
||||
.blocklist_file("stdbool.h")
|
||||
.use_core()
|
||||
.formatter(bindgen::Formatter::Rustfmt)
|
||||
.derive_default(true)
|
||||
.derive_debug(true)
|
||||
.derive_partialeq(true)
|
||||
.derive_copy(true)
|
||||
.default_alias_style(bindgen::AliasVariation::NewType)
|
||||
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
|
||||
//.clang_args(clang_args())
|
||||
.generate()
|
||||
.expect("Unable to generate bindings");
|
||||
let out_path = PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
println!("cargo:warning=out_path: {:?}", out_path.display());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings");
|
||||
|
||||
let out_path = std::path::PathBuf::from(env::var("OUT_DIR").unwrap());
|
||||
bindings
|
||||
.write_to_file(out_path.join("bindings.rs"))
|
||||
.expect("Couldn't write bindings!");
|
||||
}
|
||||
|
||||
fn main() {
|
||||
let header = libicsneo_header_path();
|
||||
println!("cargo:rerun-if-changed=build.rs");
|
||||
println!("cargo:rerun-if-changed={}", header.to_str().unwrap());
|
||||
println!("cargo:rerun-if-env-changed=LIBMSVC_PATH");
|
||||
|
||||
prepare_git_submodule();
|
||||
generate_bindings();
|
||||
// We can skip building if its for docs.rs
|
||||
if std::env::var("DOCS_RS").is_err() {
|
||||
let build_directory = build_libicsneo();
|
||||
setup_linker_libs(&build_directory);
|
||||
}
|
||||
}
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
// Suppress the flurry of warnings caused by using "C" naming conventions
|
||||
#![allow(non_upper_case_globals)]
|
||||
#![allow(non_camel_case_types)]
|
||||
#![allow(non_snake_case)]
|
||||
include!(concat!(env!("OUT_DIR"), "/bindings.rs"));
|
||||
|
||||
pub unsafe fn find_devices() {
|
||||
let mut devices: [*mut icsneo_device_t; 255] = [std::ptr::null_mut(); 255];
|
||||
let mut device_count: u32 = 255;
|
||||
let res = icsneo_device_find_all(devices.as_mut_ptr(), &mut device_count as *mut u32, std::ptr::null_mut());
|
||||
|
||||
if res.0 != _icsneo_error_t::icsneo_error_success as u32 {
|
||||
return;
|
||||
}
|
||||
println!("Found {} devices", device_count);
|
||||
for i in 0..device_count as usize {
|
||||
let device = devices[i];
|
||||
let res = icsneo_device_is_valid(device);
|
||||
if res.0 != _icsneo_error_t::icsneo_error_success as u32 {
|
||||
return;
|
||||
}
|
||||
|
||||
let mut description_length: u32 = 255;
|
||||
let mut description: [::core::ffi::c_char; 255] = [0i8; 255];
|
||||
let res = icsneo_device_get_description(device, description.as_mut_ptr(), &mut description_length);
|
||||
if res.0 != _icsneo_error_t::icsneo_error_success as u32 {
|
||||
return;
|
||||
}
|
||||
let description_str = std::ffi::CStr::from_ptr(description.as_ptr()).to_str().unwrap().to_string();
|
||||
println!("\t{}: {}", i, description_str);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn it_works() {
|
||||
unsafe { find_devices(); }
|
||||
}
|
||||
}
|
||||
|
|
@ -1,2 +1,2 @@
|
|||
call "%VCVARS32%"
|
||||
call "%VCVARS32_2022%"
|
||||
call "ci\build-windows.bat"
|
||||
|
|
|
|||
|
|
@ -1,2 +1,2 @@
|
|||
call "%VCVARS64%"
|
||||
call "%VCVARS64_2022%"
|
||||
call "ci\build-windows.bat"
|
||||
|
|
|
|||
|
|
@ -100,7 +100,7 @@ bool Communication::sendCommand(ExtendedCommand cmd, std::vector<uint8_t> argume
|
|||
}
|
||||
|
||||
bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout) {
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_read_settings);
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::ReadSettings);
|
||||
std::shared_ptr<Message> msg = waitForMessageSync([this]() {
|
||||
return sendCommand(Command::ReadSettings, { 0, 0, 0, 1 /* Get Global Settings */, 0, 1 /* Subversion 1 */ });
|
||||
}, filter, timeout);
|
||||
|
|
|
|||
|
|
@ -3,7 +3,7 @@
|
|||
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||
#include "icsneo/communication/message/readsettingsmessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||
#include "icsneo/communication/message/flashmemorymessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
|
|
@ -19,7 +19,9 @@
|
|||
#include "icsneo/communication/message/diskdatamessage.h"
|
||||
#include "icsneo/communication/message/hardwareinfo.h"
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/message/gptpstatusmessage.h"
|
||||
#include "icsneo/communication/message/apperrormessage.h"
|
||||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
|
|
@ -54,7 +56,7 @@ uint64_t Decoder::GetUInt64FromLEBytes(const uint8_t* bytes) {
|
|||
|
||||
bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet) {
|
||||
switch(packet->network.getType()) {
|
||||
case icsneo_msg_bus_type_ethernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
result = HardwareEthernetPacket::DecodeToMessage(packet->data, report);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
|
|
@ -68,9 +70,9 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
eth.network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_can:
|
||||
case icsneo_msg_bus_type_swcan:
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
case Network::Type::CAN:
|
||||
case Network::Type::SWCAN:
|
||||
case Network::Type::LSFTCAN: {
|
||||
if(packet->data.size() < 24) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -93,7 +95,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
break;
|
||||
}
|
||||
case Message::Type::CANErrorCount: {
|
||||
CANErrorCountMessage& can = *static_cast<CANErrorCountMessage*>(result.get());
|
||||
CANErrorMessage& can = *static_cast<CANErrorMessage*>(result.get());
|
||||
can.network = packet->network;
|
||||
break;
|
||||
}
|
||||
|
|
@ -105,7 +107,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_flexray: {
|
||||
case Network::Type::FlexRay: {
|
||||
if(packet->data.size() < 24) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -124,7 +126,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
fr.network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_iso9141: {
|
||||
case Network::Type::ISO9141: {
|
||||
if(packet->data.size() < sizeof(HardwareISO9141Packet)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -141,7 +143,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
iso.network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_i2c: {
|
||||
case Network::Type::I2C: {
|
||||
if(packet->data.size() < sizeof(HardwareI2CPacket)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -155,7 +157,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_a2b: {
|
||||
case Network::Type::A2B: {
|
||||
result = HardwareA2BPacket::DecodeToMessage(packet->data);
|
||||
|
||||
if(!result) {
|
||||
|
|
@ -168,7 +170,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
msg.timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
result = HardwareLINPacket::DecodeToMessage(packet->data);
|
||||
|
||||
if(!result) {
|
||||
|
|
@ -178,9 +180,10 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
|
||||
LINMessage& msg = *static_cast<LINMessage*>(result.get());
|
||||
msg.network = packet->network;
|
||||
msg.timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_mdio: {
|
||||
case Network::Type::MDIO: {
|
||||
result = HardwareMDIOPacket::DecodeToMessage(packet->data);
|
||||
|
||||
if(!result) {
|
||||
|
|
@ -192,9 +195,9 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
msg.network = packet->network;
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_internal: {
|
||||
case Network::Type::Internal: {
|
||||
switch(packet->network.getNetID()) {
|
||||
case _icsneo_netid_t::icsneo_netid_reset_status: {
|
||||
case Network::NetID::Reset_Status: {
|
||||
// We can deal with not having the last two fields (voltage and temperature)
|
||||
if(packet->data.size() < (sizeof(HardwareResetStatusPacket) - (sizeof(uint16_t) * 2))) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
|
|
@ -225,40 +228,45 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
result = msg;
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_device: {
|
||||
case Network::NetID::Device: {
|
||||
// These are neoVI network messages
|
||||
// They come in as CAN but we will handle them in the device rather than
|
||||
// passing them onto the user.
|
||||
if(packet->data.size() < 24) {
|
||||
auto rawmsg = std::make_shared<InternalMessage>(_icsneo_netid_t::icsneo_netid_device);
|
||||
auto rawmsg = std::make_shared<InternalMessage>(Network::NetID::Device);
|
||||
result = rawmsg;
|
||||
rawmsg->data = packet->data;
|
||||
return true;
|
||||
}
|
||||
|
||||
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
const auto can = std::dynamic_pointer_cast<CANMessage>(HardwareCANPacket::DecodeToMessage(packet->data));
|
||||
if(!can) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
return false;
|
||||
}
|
||||
|
||||
if(can->arbid == 0x162) {
|
||||
result = EthernetStatusMessage::DecodeToMessage(can->data);
|
||||
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
// TODO: move more handleNeoVIMessage handling here, the Decoder layer will parse the message and the Device layer can cache the values
|
||||
can->network = packet->network;
|
||||
result = can;
|
||||
}
|
||||
|
||||
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
||||
// The resolution depends on the device
|
||||
auto* raw = dynamic_cast<InternalMessage*>(result.get());
|
||||
if(raw == nullptr) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // A nullptr was returned, the packet was malformed
|
||||
}
|
||||
raw->timestamp *= timestampResolution;
|
||||
raw->network = packet->network;
|
||||
result->timestamp *= timestampResolution;
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_device_status: {
|
||||
case Network::NetID::DeviceStatus: {
|
||||
// Just pass along the data, the device needs to handle this itself
|
||||
result = std::make_shared<InternalMessage>(packet->network, packet->data);
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_red_int_memoryread: {
|
||||
case Network::NetID::RED_INT_MEMORYREAD: {
|
||||
if(packet->data.size() != 512 + sizeof(uint16_t)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // Should get enough data for a start address and sector
|
||||
|
|
@ -270,7 +278,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
msg->data.insert(msg->data.end(), packet->data.begin() + 2, packet->data.end());
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_neo_memory_sdread: {
|
||||
case Network::NetID::NeoMemorySDRead: {
|
||||
if(packet->data.size() != 512 + sizeof(uint32_t)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // Should get enough data for a start address and sector
|
||||
|
|
@ -282,13 +290,13 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
msg->data.insert(msg->data.end(), packet->data.begin() + 4, packet->data.end());
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_extended_command: {
|
||||
case Network::NetID::ExtendedCommand: {
|
||||
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse))
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::ResponseHeader))
|
||||
break; // Handle as a raw message, might not be a generic response
|
||||
|
||||
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data());
|
||||
switch(resp.header.command) {
|
||||
const auto& resp = *reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(packet->data.data());
|
||||
switch(resp.command) {
|
||||
case ExtendedCommand::GetComponentVersions:
|
||||
result = ComponentVersionPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
|
|
@ -298,22 +306,30 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
case ExtendedCommand::GenericBinaryInfo:
|
||||
result = GenericBinaryStatusPacket::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::GenericReturn:
|
||||
result = std::make_shared<ExtendedResponseMessage>(resp.command, resp.returnCode);
|
||||
case ExtendedCommand::GenericReturn: {
|
||||
if(packet->data.size() < sizeof(ExtendedResponseMessage::PackedGenericResponse))
|
||||
break;
|
||||
const auto& packedResp = *reinterpret_cast<ExtendedResponseMessage::PackedGenericResponse*>(packet->data.data());
|
||||
result = std::make_shared<ExtendedResponseMessage>(packedResp.command, packedResp.returnCode);
|
||||
return true;
|
||||
}
|
||||
case ExtendedCommand::LiveData:
|
||||
result = HardwareLiveDataPacket::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
case ExtendedCommand::GetTC10Status:
|
||||
result = TC10StatusMessage::DecodeToMessage(packet->data);
|
||||
return true;
|
||||
case ExtendedCommand::GetGPTPStatus: {
|
||||
result = GPTPStatus::DecodeToMessage(packet->data, report);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
// No defined handler, treat this as a InternalMessage
|
||||
break;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_extended_data: {
|
||||
case Network::NetID::ExtendedData: {
|
||||
if(packet->data.size() < sizeof(ExtendedDataMessage::ExtendedDataHeader))
|
||||
break;
|
||||
const auto& header = *reinterpret_cast<ExtendedDataMessage::ExtendedDataHeader*>(packet->data.data());
|
||||
|
|
@ -328,7 +344,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
|
||||
std::copy(packet->data.begin() + sizeof(header), packet->data.begin() + sizeof(header) + numRead, extDataMsg->data.begin());
|
||||
|
||||
extDataMsg->network = Network(static_cast<uint16_t>(_icsneo_netid_t::icsneo_netid_extended_data), false);
|
||||
extDataMsg->network = Network(static_cast<uint16_t>(Network::NetID::ExtendedData), false);
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
|
|
@ -336,7 +352,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
}
|
||||
break;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_flexray_control: {
|
||||
case Network::NetID::FlexRayControl: {
|
||||
auto frResult = std::make_shared<FlexRayControlMessage>(*packet);
|
||||
if(!frResult->decoded) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
|
|
@ -345,7 +361,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
result = frResult;
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_main51: {
|
||||
case Network::NetID::Main51: {
|
||||
switch((Command)packet->data[0]) {
|
||||
case Command::RequestSerialNumber: {
|
||||
auto msg = std::make_shared<SerialNumberMessage>();
|
||||
|
|
@ -397,7 +413,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
return true;
|
||||
}
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_red_oldformat: {
|
||||
case Network::NetID::RED_OLDFORMAT: {
|
||||
/* So-called "old format" messages are a "new style, long format" wrapper around the old short messages.
|
||||
* They consist of a 16-bit LE length first, then the 8-bit length and netid combo byte, then the payload
|
||||
* with no checksum. The upper-nibble length of the combo byte should be ignored completely, using the
|
||||
|
|
@ -412,7 +428,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
packet->data.resize(length);
|
||||
return decode(result, packet);
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_red_app_error: {
|
||||
case Network::NetID::RED_App_Error: {
|
||||
result = AppErrorMessage::DecodeToMessage(packet->data, report);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
|
|
@ -420,7 +436,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_read_settings: {
|
||||
case Network::NetID::ReadSettings: {
|
||||
auto msg = std::make_shared<ReadSettingsMessage>();
|
||||
msg->response = ReadSettingsMessage::Response(packet->data[0]);
|
||||
|
||||
|
|
@ -439,7 +455,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
result = msg;
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_logical_disk_info: {
|
||||
case Network::NetID::LogicalDiskInfo: {
|
||||
result = LogicalDiskInfoPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
|
|
@ -447,7 +463,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_wivi_command: {
|
||||
case Network::NetID::WiVICommand: {
|
||||
result = WiVI::CommandPacket::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
|
|
@ -455,7 +471,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_eth_phy_control: {
|
||||
case Network::NetID::EthPHYControl: {
|
||||
result = HardwareEthernetPhyRegisterPacket::DecodeToMessage(packet->data, report);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
|
|
@ -463,7 +479,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_script_status: {
|
||||
case Network::NetID::ScriptStatus: {
|
||||
result = ScriptStatus::DecodeToMessage(packet->data);
|
||||
if(!result) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||
|
|
@ -471,7 +487,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
}
|
||||
return true;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_disk_data: {
|
||||
case Network::NetID::DiskData: {
|
||||
result = std::make_shared<DiskDataMessage>(std::move(packet->data));
|
||||
return true;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -26,12 +26,12 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
case Message::Type::BusMessage: {
|
||||
auto frame = std::dynamic_pointer_cast<BusMessage>(message);
|
||||
|
||||
// BusMessage uses frame->data as the buffer unless directed otherwise
|
||||
// Frame uses frame->data as the buffer unless directed otherwise
|
||||
buffer = &frame->data;
|
||||
netid = uint16_t(frame->network.getNetID());
|
||||
|
||||
switch(frame->network.getType()) {
|
||||
case icsneo_msg_bus_type_ethernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(message);
|
||||
if(!ethmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -43,10 +43,10 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
return false;
|
||||
|
||||
break;
|
||||
} // End of icsneo_msg_bus_type_ethernet
|
||||
case icsneo_msg_bus_type_can:
|
||||
case icsneo_msg_bus_type_swcan:
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
} // End of Network::Type::Ethernet
|
||||
case Network::Type::CAN:
|
||||
case Network::Type::SWCAN:
|
||||
case Network::Type::LSFTCAN: {
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(!canmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -63,8 +63,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
return false; // The CANMessage was malformed
|
||||
|
||||
break;
|
||||
} // End of icsneo_msg_bus_type_can
|
||||
case icsneo_msg_bus_type_iso9141: {
|
||||
} // End of Network::Type::CAN
|
||||
case Network::Type::ISO9141: {
|
||||
auto isomsg = std::dynamic_pointer_cast<ISO9141Message>(message);
|
||||
if(!isomsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -74,8 +74,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
// Skip the normal message wrapping at the bottom since we need to send multiple
|
||||
// packets to the device. This function just encodes them back to back into `result`
|
||||
return HardwareISO9141Packet::EncodeFromMessage(*isomsg, result, report, packetizer);
|
||||
} // End of icsneo_msg_bus_type_iso9141
|
||||
case icsneo_msg_bus_type_a2b: {
|
||||
} // End of Network::Type::ISO9141
|
||||
case Network::Type::A2B: {
|
||||
auto a2bmsg = std::dynamic_pointer_cast<A2BMessage>(message);
|
||||
if(!a2bmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -86,8 +86,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
} // End of icsneo_msg_bus_type_a2b
|
||||
case icsneo_msg_bus_type_i2c: {
|
||||
} // End of Network::Type::A2B
|
||||
case Network::Type::I2C: {
|
||||
auto i2cmsg = std::dynamic_pointer_cast<I2CMessage>(message);
|
||||
if(!i2cmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -98,8 +98,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
} // End of icsneo_msg_bus_type_i2c
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
} // End of Network::Type::I2C
|
||||
case Network::Type::LIN: {
|
||||
auto linmsg = std::dynamic_pointer_cast<LINMessage>(message);
|
||||
if(!linmsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -110,8 +110,8 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
} // End of icsneo_msg_bus_type_lin
|
||||
case icsneo_msg_bus_type_mdio: {
|
||||
} // End of Network::Type::LIN
|
||||
case Network::Type::MDIO: {
|
||||
auto mdiomsg = std::dynamic_pointer_cast<MDIOMessage>(message);
|
||||
if(!mdiomsg) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
@ -122,7 +122,7 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
return false;
|
||||
}
|
||||
break;
|
||||
} // End of icsneo_msg_bus_type_mdio
|
||||
} // End of Network::Type::MDIO
|
||||
default:
|
||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -138,10 +138,10 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
netid = uint16_t(raw->network.getNetID());
|
||||
|
||||
switch(raw->network.getNetID()) {
|
||||
case _icsneo_netid_t::icsneo_netid_device:
|
||||
case Network::NetID::Device:
|
||||
shortFormat = true;
|
||||
break;
|
||||
case _icsneo_netid_t::icsneo_netid_red_oldformat: {
|
||||
case Network::NetID::RED_OLDFORMAT: {
|
||||
// See the decoder for an explanation
|
||||
// We expect the network byte to be populated already in data, but not the length
|
||||
uint16_t length = uint16_t(raw->data.size()) - 1;
|
||||
|
|
@ -162,7 +162,7 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
}
|
||||
|
||||
buffer = &m51msg->data;
|
||||
netid = uint16_t(_icsneo_netid_t::icsneo_netid_main51);
|
||||
netid = uint16_t(Network::NetID::Main51);
|
||||
|
||||
if(!m51msg->forceShortFormat) {
|
||||
// Main51 can be sent as a long message without setting the NetID to RED first
|
||||
|
|
@ -172,7 +172,7 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
size += 1; // Even though we are not including the NetID bytes, the device expects them to be counted in the length
|
||||
size += 1; // Main51 Command
|
||||
m51msg->data.insert(m51msg->data.begin(), {
|
||||
(uint8_t)_icsneo_netid_t::icsneo_netid_main51, // 0x0B for long message
|
||||
(uint8_t)Network::NetID::Main51, // 0x0B for long message
|
||||
(uint8_t)size, // Size, little endian 16-bit
|
||||
(uint8_t)(size >> 8),
|
||||
(uint8_t)m51msg->command
|
||||
|
|
@ -223,7 +223,7 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
uint16_t size = static_cast<uint16_t>(buffer->size()) + 1 + 1 + 2 + 2 + 1;
|
||||
|
||||
buffer->insert(buffer->begin(), {
|
||||
(uint8_t)_icsneo_netid_t::icsneo_netid_red, // 0x0C for long message
|
||||
(uint8_t)Network::NetID::RED, // 0x0C for long message
|
||||
(uint8_t)size, // Size, little endian 16-bit
|
||||
(uint8_t)(size >> 8),
|
||||
(uint8_t)netid, // NetID, little endian 16-bit
|
||||
|
|
@ -238,12 +238,12 @@ bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result,
|
|||
bool Encoder::encode(const Packetizer& packetizer, std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments) {
|
||||
std::shared_ptr<Message> msg;
|
||||
if(cmd == Command::UpdateLEDState) {
|
||||
/* _icsneo_netid_t::Device is a super old command type.
|
||||
/* NetID::Device is a super old command type.
|
||||
* It has a leading 0x00 byte, a byte for command, and a byte for an argument.
|
||||
* In this case, command 0x06 is SetLEDState.
|
||||
* This old command type is not really used anywhere else.
|
||||
*/
|
||||
auto canmsg = std::make_shared<InternalMessage>(_icsneo_netid_t::icsneo_netid_device);
|
||||
auto canmsg = std::make_shared<InternalMessage>(Network::NetID::Device);
|
||||
msg = canmsg;
|
||||
if(arguments.empty()) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
|
|
|
|||
|
|
@ -21,10 +21,10 @@ std::shared_ptr<Message> AppErrorMessage::DecodeToMessage(const std::vector<uint
|
|||
}
|
||||
auto appErr = std::make_shared<AppErrorMessage>();
|
||||
appErr->errorType = data->error_type;
|
||||
appErr->errorNetID = static_cast<_icsneo_netid_t>(data->network_id);
|
||||
appErr->errorNetID = static_cast<Network::NetID>(data->network_id);
|
||||
appErr->timestamp10us = data->uiTimeStamp10uS;
|
||||
appErr->timestamp10usMSB = data->uiTimeStamp10uSMSB;
|
||||
appErr->network = _icsneo_netid_t::icsneo_netid_red_app_error;
|
||||
appErr->network = Network::NetID::RED_App_Error;
|
||||
return appErr;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -112,7 +112,7 @@ bool A2BWAVOutput::callIfMatch(const std::shared_ptr<Message>& message) const {
|
|||
return false;
|
||||
}
|
||||
|
||||
if(frameMsg->network.getType() != icsneo_msg_bus_type_a2b)
|
||||
if(frameMsg->network.getType() != Network::Type::A2B)
|
||||
return false;
|
||||
|
||||
const auto& a2bMsg = std::dynamic_pointer_cast<A2BMessage>(frameMsg);
|
||||
|
|
|
|||
|
|
@ -0,0 +1,57 @@
|
|||
#include "icsneo/communication/message/ethernetstatusmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
#pragma pack(push, 1)
|
||||
enum LinkSpeed {
|
||||
ethSpeed10,
|
||||
ethSpeed100,
|
||||
ethSpeed1000,
|
||||
ethSpeedAutoNeg,
|
||||
ethSpeed2500,
|
||||
ethSpeed5000,
|
||||
ethSpeed10000,
|
||||
};
|
||||
|
||||
enum LinkMode {
|
||||
OPETH_LINK_AUTO,
|
||||
OPETH_LINK_MASTER,
|
||||
OPETH_LINK_SLAVE,
|
||||
OPETH_LINK_INVALID = 255,
|
||||
};
|
||||
|
||||
struct Packet {
|
||||
uint8_t state;
|
||||
uint8_t speed;
|
||||
uint8_t duplex;
|
||||
uint16_t network;
|
||||
uint8_t mode;
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
std::shared_ptr<Message> EthernetStatusMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
if(bytestream.size() < sizeof(Packet)) {
|
||||
return nullptr;
|
||||
}
|
||||
Packet* packet = (Packet*)bytestream.data();
|
||||
LinkSpeed speed;
|
||||
switch(packet->speed) {
|
||||
case ethSpeed10: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10; break;
|
||||
case ethSpeed100: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed100; break;
|
||||
case ethSpeed1000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed1000; break;
|
||||
case ethSpeedAutoNeg: speed = EthernetStatusMessage::LinkSpeed::LinkSpeedAuto; break;
|
||||
case ethSpeed2500: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed2500; break;
|
||||
case ethSpeed5000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed5000; break;
|
||||
case ethSpeed10000: speed = EthernetStatusMessage::LinkSpeed::LinkSpeed10000; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
LinkMode mode;
|
||||
switch(packet->mode) {
|
||||
case OPETH_LINK_INVALID: mode = EthernetStatusMessage::LinkMode::LinkModeInvalid; break;
|
||||
case OPETH_LINK_AUTO: mode = EthernetStatusMessage::LinkMode::LinkModeAuto; break;
|
||||
case OPETH_LINK_MASTER: mode = EthernetStatusMessage::LinkMode::LinkModeMaster; break;
|
||||
case OPETH_LINK_SLAVE: mode = EthernetStatusMessage::LinkMode::LinkModeSlave; break;
|
||||
default: return nullptr;
|
||||
}
|
||||
return std::make_shared<EthernetStatusMessage>(packet->network, packet->state, speed, packet->duplex, mode);
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
#include <icsneo/communication/message/gptpstatusmessage.h>
|
||||
#include <icsneo/communication/message/extendedresponsemessage.h>
|
||||
#include <cstring>
|
||||
|
||||
namespace icsneo {
|
||||
typedef double float64;
|
||||
typedef int64_t time_interval;
|
||||
typedef uint64_t _clock_identity;
|
||||
|
||||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
struct port_identity {
|
||||
_clock_identity clock_identity;
|
||||
uint16_t port_number;
|
||||
};
|
||||
|
||||
struct _scaled_ns {
|
||||
int16_t nanoseconds_msb;
|
||||
int64_t nanoseconds_lsb;
|
||||
int16_t fractional_nanoseconds;
|
||||
};
|
||||
|
||||
struct _clock_quality {
|
||||
uint8_t clock_class;
|
||||
uint8_t clock_accuracy;
|
||||
uint16_t offset_scaled_log_variance;
|
||||
};
|
||||
|
||||
struct system_identity {
|
||||
uint8_t priority_1;
|
||||
struct _clock_quality clock_quality;
|
||||
uint8_t priority_2;
|
||||
_clock_identity clock_identity;
|
||||
};
|
||||
|
||||
struct _timestamp {
|
||||
uint16_t seconds_msb;
|
||||
uint32_t seconds_lsb;
|
||||
uint32_t nanoseconds;
|
||||
};
|
||||
|
||||
struct priority_vector {
|
||||
struct system_identity sysid;
|
||||
uint16_t steps_removed;
|
||||
struct port_identity portid;
|
||||
uint16_t port_number;
|
||||
};
|
||||
|
||||
|
||||
// IEEE 802.1AS-2020 14.3
|
||||
// This is a read-only data structure
|
||||
struct _current_ds {
|
||||
uint16_t steps_removed;
|
||||
time_interval offset_from_master;
|
||||
struct _scaled_ns last_gm_phase_change;
|
||||
float64 last_gm_freq_change;
|
||||
uint16_t gm_time_base_indicator;
|
||||
uint32_t gm_change_count;
|
||||
uint32_t time_of_last_gm_change_event;
|
||||
uint32_t time_of_last_gm_phase_change_event;
|
||||
uint32_t time_of_last_gm_freq_change_event;
|
||||
};
|
||||
|
||||
// IEEE 802.1AS-2020 14.4
|
||||
// This is a read-only data structure
|
||||
struct _parent_ds {
|
||||
struct port_identity parent_port_identity;
|
||||
int32_t cumulative_rate_ratio;
|
||||
_clock_identity grandmaster_identity;
|
||||
uint8_t gm_clock_quality_clock_class;
|
||||
uint8_t gm_clock_quality_clock_accuracy;
|
||||
uint16_t gm_clock_quality_offset_scaled_log_variance;
|
||||
uint8_t gm_priority1;
|
||||
uint8_t gm_priority2;
|
||||
};
|
||||
|
||||
struct _GPTPStatus
|
||||
{
|
||||
struct _timestamp current_time;
|
||||
struct priority_vector gm_priority;
|
||||
int64_t ms_offset_ns;
|
||||
uint8_t is_sync;
|
||||
uint8_t link_status;
|
||||
int64_t link_delay_ns;
|
||||
uint8_t selected_role;
|
||||
uint8_t as_capable;
|
||||
uint8_t is_syntonized;
|
||||
struct _timestamp last_rx_sync_ts; // t2 in IEEE 1588-2019 Figure-16
|
||||
struct _current_ds current_ds;
|
||||
struct _parent_ds parent_ds;
|
||||
};
|
||||
|
||||
#pragma pack(pop)
|
||||
|
||||
static void SetField(GPTPStatus::Timestamp& output, const _timestamp& input) {
|
||||
output.seconds = ((uint64_t)(input.seconds_msb) << 32) | ((uint64_t)input.seconds_lsb);
|
||||
output.nanoseconds = input.nanoseconds;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::PortID& output, const port_identity& input) {
|
||||
output.clockIdentity = input.clock_identity;
|
||||
output.portNumber = input.port_number;
|
||||
}
|
||||
static void SetField(GPTPStatus::ClockQuality& output, const _clock_quality& input) {
|
||||
output.clockClass = input.clock_class;
|
||||
output.clockAccuracy = input.clock_accuracy;
|
||||
output.offsetScaledLogVariance = input.offset_scaled_log_variance;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::SystemID& output, const system_identity& input) {
|
||||
output.priority1 = input.priority_1;
|
||||
SetField(output.clockQuality, input.clock_quality);
|
||||
output.priority2 = input.priority_2;
|
||||
output.clockID = input.clock_identity;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::ScaledNanoSeconds& output, const _scaled_ns& input) {
|
||||
output.nanosecondsMSB = input.nanoseconds_msb;
|
||||
output.nanosecondsLSB = input.nanoseconds_lsb;
|
||||
output.fractionalNanoseconds = input.fractional_nanoseconds;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::PriorityVector& output, const priority_vector& input) {
|
||||
SetField(output.sysID, input.sysid);
|
||||
output.stepsRemoved = input.steps_removed;
|
||||
SetField(output.portID, input.portid);
|
||||
output.portNumber = input.port_number;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::CurrentDS& output, const _current_ds& input) {
|
||||
output.stepsRemoved = input.steps_removed;
|
||||
output.offsetFromMaster = input.offset_from_master;
|
||||
SetField(output.lastgmPhaseChange, input.last_gm_phase_change);
|
||||
output.lastgmFreqChange = input.last_gm_freq_change;
|
||||
output.gmTimeBaseIndicator = input.gm_time_base_indicator;
|
||||
output.gmChangeCount = input.gm_change_count;
|
||||
output.timeOfLastgmChangeEvent = input.time_of_last_gm_change_event;
|
||||
output.timeOfLastgmPhaseChangeEvent = input.time_of_last_gm_phase_change_event;
|
||||
output.timeOfLastgmFreqChangeEvent = input.time_of_last_gm_freq_change_event;
|
||||
}
|
||||
|
||||
static void SetField(GPTPStatus::ParentDS& output, const _parent_ds& input) {
|
||||
SetField(output.parentPortIdentity, input.parent_port_identity);
|
||||
output.cumulativeRateRatio = input.cumulative_rate_ratio;
|
||||
output.grandmasterIdentity = input.grandmaster_identity;
|
||||
output.gmClockQualityClockClass = input.gm_clock_quality_clock_class;
|
||||
output.gmClockQualityClockAccuracy = input.gm_clock_quality_clock_accuracy;
|
||||
output.gmClockQualityOffsetScaledLogVariance = input.gm_clock_quality_offset_scaled_log_variance;
|
||||
output.gmPriority1 = input.gm_priority1;
|
||||
output.gmPriority2 = input.gm_priority2;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint8_t& output, const uint8_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint16_t& output, const uint16_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint32_t& output, const uint32_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(uint64_t& output, const uint64_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int8_t& output, const int8_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int16_t& output, const int16_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int32_t& output, const int32_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
[[maybe_unused]] static void SetField(int64_t& output, const int64_t& input) {
|
||||
output = input;
|
||||
}
|
||||
|
||||
std::shared_ptr<GPTPStatus> GPTPStatus::DecodeToMessage(std::vector<uint8_t>& bytes, const device_eventhandler_t&) {
|
||||
|
||||
// The following does not lead to overflow since we only call this function if it has at least ResponseHeader length bytes
|
||||
std::shared_ptr<GPTPStatus> res = std::make_shared<GPTPStatus>();
|
||||
auto* header = reinterpret_cast<ExtendedResponseMessage::ResponseHeader*>(bytes.data());
|
||||
uint16_t length = header->length;
|
||||
_GPTPStatus* input = reinterpret_cast<_GPTPStatus*>(bytes.data() + sizeof(ExtendedResponseMessage::ResponseHeader));
|
||||
|
||||
#define CheckLengthAndSet(output, input) if(length >= sizeof(decltype(input))) { \
|
||||
SetField(output, input); \
|
||||
length -= sizeof(decltype(input)); \
|
||||
} else {\
|
||||
memset(&output, 0, sizeof(decltype(output))); \
|
||||
length = 0; \
|
||||
res->shortFormat = true; \
|
||||
}
|
||||
|
||||
CheckLengthAndSet(res->currentTime, input->current_time);
|
||||
CheckLengthAndSet(res->gmPriority, input->gm_priority);
|
||||
CheckLengthAndSet(res->msOffsetNs, input->ms_offset_ns);
|
||||
CheckLengthAndSet(res->isSync, input->is_sync);
|
||||
CheckLengthAndSet(res->linkStatus, input->link_status);
|
||||
CheckLengthAndSet(res->linkDelayNS, input->link_delay_ns);
|
||||
CheckLengthAndSet(res->selectedRole, input->selected_role);
|
||||
CheckLengthAndSet(res->asCapable, input->as_capable);
|
||||
CheckLengthAndSet(res->isSyntonized, input->is_syntonized);
|
||||
CheckLengthAndSet(res->lastRXSyncTS, input->last_rx_sync_ts);
|
||||
CheckLengthAndSet(res->currentDS, input->current_ds);
|
||||
CheckLengthAndSet(res->parentDS, input->parent_ds);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
@ -1,7 +1,7 @@
|
|||
#include "icsneo/communication/message/neomessage.h"
|
||||
#include "icsneo/communication/message/canmessage.h"
|
||||
#include "icsneo/communication/message/ethernetmessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
#include "icsneo/communication/message/linmessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
|
@ -19,8 +19,8 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
|||
auto framemsg = std::static_pointer_cast<BusMessage>(message);
|
||||
const auto netType = framemsg->network.getType();
|
||||
|
||||
frame.netid = (icsneo_netid_t)framemsg->network.getNetID();
|
||||
frame.type = (icsneo_msg_bus_type_t)netType;
|
||||
frame.netid = (neonetid_t)framemsg->network.getNetID();
|
||||
frame.type = (neonettype_t)netType;
|
||||
frame.description = framemsg->description;
|
||||
frame.length = framemsg->data.size();
|
||||
frame.data = framemsg->data.data();
|
||||
|
|
@ -29,9 +29,9 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
|||
frame.status.transmitMessage = framemsg->transmitted;
|
||||
|
||||
switch(netType) {
|
||||
case icsneo_msg_bus_type_can:
|
||||
case icsneo_msg_bus_type_swcan:
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
case Network::Type::CAN:
|
||||
case Network::Type::SWCAN:
|
||||
case Network::Type::LSFTCAN: {
|
||||
neomessage_can_t& can = *(neomessage_can_t*)&neomsg;
|
||||
auto canmsg = std::static_pointer_cast<CANMessage>(message);
|
||||
can.arbid = canmsg->arbid;
|
||||
|
|
@ -44,18 +44,18 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
|||
can.status.canfdESI = canmsg->errorStateIndicator;
|
||||
break;
|
||||
}
|
||||
case icsneo_msg_bus_type_ethernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
neomessage_eth_t& eth = *(neomessage_eth_t*)&neomsg;
|
||||
auto ethmsg = std::static_pointer_cast<EthernetMessage>(message);
|
||||
eth.preemptionFlags = ethmsg->preemptionFlags;
|
||||
eth.status.incompleteFrame = ethmsg->frameTooShort;
|
||||
// TODO Fill in extra status bits
|
||||
//eth.status.xyz = ethmsg->preemptionEnabled;
|
||||
//eth.status.xyz = ethmsg->fcsAvailable;
|
||||
//eth.status.xyz = ethmsg->fcs;
|
||||
//eth.status.xyz = ethmsg->noPadding;
|
||||
break;
|
||||
}
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
neomessage_lin_t& lin = *(neomessage_lin_t*)&neomsg;
|
||||
auto linmsg = std::static_pointer_cast<LINMessage>(message);
|
||||
if(!linmsg) { break; }
|
||||
|
|
@ -104,12 +104,12 @@ neomessage_t icsneo::CreateNeoMessage(const std::shared_ptr<Message> message) {
|
|||
}
|
||||
case Message::Type::CANErrorCount: {
|
||||
neomessage_can_error_t& canerror = *(neomessage_can_error_t*)&neomsg;
|
||||
auto canerrormsg = std::static_pointer_cast<CANErrorCountMessage>(message);
|
||||
auto canerrormsg = std::static_pointer_cast<CANErrorMessage>(message);
|
||||
canerror.transmitErrorCount = canerrormsg->transmitErrorCount;
|
||||
canerror.receiveErrorCount = canerrormsg->receiveErrorCount;
|
||||
canerror.status.canBusOff = canerrormsg->busOff;
|
||||
canerror.netid = (icsneo_netid_t)canerrormsg->network.getNetID();
|
||||
canerror.type = (icsneo_msg_bus_type_t)canerrormsg->network.getType();
|
||||
canerror.netid = (neonetid_t)canerrormsg->network.getNetID();
|
||||
canerror.type = (neonettype_t)canerrormsg->network.getType();
|
||||
break;
|
||||
}
|
||||
default:
|
||||
|
|
@ -123,9 +123,9 @@ std::shared_ptr<Message> icsneo::CreateMessageFromNeoMessage(const neomessage_t*
|
|||
case Message::Type::BusMessage: {
|
||||
const Network network = ((neomessage_frame_t*)neomessage)->netid;
|
||||
switch(network.getType()) {
|
||||
case icsneo_msg_bus_type_can:
|
||||
case icsneo_msg_bus_type_swcan:
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
case Network::Type::CAN:
|
||||
case Network::Type::SWCAN:
|
||||
case Network::Type::LSFTCAN: {
|
||||
neomessage_can_t& can = *(neomessage_can_t*)neomessage;
|
||||
auto canmsg = std::make_shared<CANMessage>();
|
||||
canmsg->network = network;
|
||||
|
|
@ -140,7 +140,7 @@ std::shared_ptr<Message> icsneo::CreateMessageFromNeoMessage(const neomessage_t*
|
|||
canmsg->errorStateIndicator = can.status.canfdESI;
|
||||
return canmsg;
|
||||
}
|
||||
case icsneo_msg_bus_type_ethernet: {
|
||||
case Network::Type::Ethernet: {
|
||||
neomessage_eth_t& eth = *(neomessage_eth_t*)neomessage;
|
||||
auto ethmsg = std::make_shared<EthernetMessage>();
|
||||
ethmsg->network = network;
|
||||
|
|
@ -148,7 +148,7 @@ std::shared_ptr<Message> icsneo::CreateMessageFromNeoMessage(const neomessage_t*
|
|||
ethmsg->data.insert(ethmsg->data.end(), eth.data, eth.data + eth.length);
|
||||
return ethmsg;
|
||||
}
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
neomessage_lin_t& lin = *(neomessage_lin_t*)neomessage;
|
||||
auto linmsg = std::make_shared<LINMessage>();
|
||||
linmsg->network = network;
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
#include "icsneo/communication/packet/canpacket.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/canerrormessage.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
|
|
@ -29,7 +29,8 @@ std::optional<uint8_t> icsneo::CAN_DLCToLength(uint8_t length, bool fd) {
|
|||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<uint8_t> icsneo::CAN_LengthToDLC(size_t dataLength, bool fd) {
|
||||
std::optional<uint8_t> icsneo::CAN_LengthToDLC(size_t dataLength, bool fd)
|
||||
{
|
||||
if (dataLength <= 8)
|
||||
return uint8_t(dataLength);
|
||||
|
||||
|
|
@ -52,23 +53,25 @@ std::optional<uint8_t> icsneo::CAN_LengthToDLC(size_t dataLength, bool fd) {
|
|||
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
||||
const HardwareCANPacket* data = (const HardwareCANPacket*)bytestream.data();
|
||||
|
||||
if(data->dlc.RB1) { // Change counts reporting
|
||||
|
||||
const bool busOff = data->data[0] & 0b00100000;
|
||||
|
||||
auto msg = std::make_shared<CANErrorCountMessage>(data->data[2], data->data[1], busOff);
|
||||
|
||||
const HardwareCANErrorPacket* errPacket = (const HardwareCANErrorPacket*)bytestream.data();
|
||||
if(errPacket->ERROR_INDICATOR) {
|
||||
auto msg = std::make_shared<CANErrorMessage>();
|
||||
msg->receiveErrorCount = errPacket->REC;
|
||||
msg->transmitErrorCount = errPacket->TEC;
|
||||
msg->errorWarn = HardwareCANErrorPacket::GetErrorWarn(errPacket->flags);
|
||||
msg->errorPassive = HardwareCANErrorPacket::GetErrorPassive(errPacket->flags);
|
||||
msg->busOff = HardwareCANErrorPacket::GetBusOff(errPacket->flags);
|
||||
msg->errorCode = (CANErrorCode)errPacket->error_code;
|
||||
msg->dataErrorCode = (CANErrorCode)errPacket->brs_data_error_code;
|
||||
// This timestamp is raw off the device (in timestampResolution increments)
|
||||
// Decoder will fix as it has information about the timestampResolution increments
|
||||
msg->timestamp = data->timestamp.TS;
|
||||
|
||||
return msg;
|
||||
|
||||
} else { // CAN BusMessage
|
||||
} else { // CAN Frame
|
||||
auto msg = std::make_shared<CANMessage>();
|
||||
|
||||
// Arb ID
|
||||
|
|
@ -103,7 +106,7 @@ std::shared_ptr<Message> HardwareCANPacket::DecodeToMessage(const std::vector<ui
|
|||
|
||||
// Data
|
||||
// The first 8 bytes are always in the standard place
|
||||
if((data->dlc.RTR && data->header.IDE) || (!data->header.IDE && data->header.SRR)) { // Remote Request BusMessage
|
||||
if((data->dlc.RTR && data->header.IDE) || (!data->header.IDE && data->header.SRR)) { // Remote Request Frame
|
||||
msg->data.resize(length); // This data will be all zeros, but the length will be set
|
||||
msg->isRemote = true;
|
||||
} else {
|
||||
|
|
@ -196,7 +199,7 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector
|
|||
|
||||
// Status and DLC bits
|
||||
if(message.isCANFD) {
|
||||
result.push_back(0x0F); // FD BusMessage
|
||||
result.push_back(0x0F); // FD Frame
|
||||
uint8_t fdStatusByte = *dlc;
|
||||
if(message.baudrateSwitch)
|
||||
fdStatusByte |= 0x80; // BRS status bit
|
||||
|
|
|
|||
|
|
@ -16,8 +16,8 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
|||
if(packet->Length < 4)
|
||||
return nullptr;
|
||||
|
||||
const size_t ethernetFrameSize = packet->Length - (sizeof(uint16_t) * 2);
|
||||
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + ethernetFrameSize;
|
||||
const size_t fcsSize = packet->header.FCS_AVAIL ? 4 : 0;
|
||||
const size_t bytestreamExpectedSize = sizeof(HardwareEthernetPacket) + packet->Length;
|
||||
const size_t bytestreamActualSize = bytestream.size();
|
||||
if(bytestreamActualSize < bytestreamExpectedSize)
|
||||
return nullptr;
|
||||
|
|
@ -36,8 +36,6 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
|||
message.preemptionEnabled = packet->header.PREEMPTION_ENABLED;
|
||||
if(message.preemptionEnabled)
|
||||
message.preemptionFlags = (uint8_t)((rawWords[0] & 0x03F8) >> 4);
|
||||
|
||||
message.fcsAvailable = packet->header.FCS_AVAIL;
|
||||
|
||||
message.frameTooShort = packet->header.RUNT_FRAME;
|
||||
if(message.frameTooShort)
|
||||
|
|
@ -47,11 +45,14 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
|||
// Decoder will fix as it has information about the timestampResolution increments
|
||||
message.timestamp = packet->timestamp.TS;
|
||||
|
||||
// Network ID is also not set, this will be fixed in the Decoder as well
|
||||
|
||||
const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + (sizeof(HardwareEthernetPacket) - (sizeof(uint16_t) * 2));
|
||||
const std::vector<uint8_t>::const_iterator dataend = databegin + ethernetFrameSize;
|
||||
const std::vector<uint8_t>::const_iterator databegin = bytestream.begin() + sizeof(HardwareEthernetPacket);
|
||||
const std::vector<uint8_t>::const_iterator dataend = databegin + packet->Length - fcsSize;
|
||||
message.data.insert(message.data.begin(), databegin, dataend);
|
||||
|
||||
if(fcsSize) {
|
||||
uint32_t& fcs = message.fcs.emplace();
|
||||
std::copy(dataend, dataend + fcsSize, (uint8_t*)&fcs);
|
||||
}
|
||||
|
||||
return messagePtr;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -30,10 +30,10 @@ bool HardwareISO9141Packet::EncodeFromMessage(const ISO9141Message& message, std
|
|||
currentSize = (uint8_t)(bytesToSend - currentStart);
|
||||
|
||||
packet.insert(packet.begin(), {
|
||||
(uint8_t)_icsneo_netid_t::icsneo_netid_red, // 0x0C for long message
|
||||
(uint8_t)Network::NetID::RED, // 0x0C for long message
|
||||
(uint8_t)0, // Size, little endian 16-bit, filled later
|
||||
(uint8_t)0,
|
||||
(uint8_t)message.network.getNetID(), // _icsneo_netid_t, little endian 16-bit
|
||||
(uint8_t)message.network.getNetID(), // NetID, little endian 16-bit
|
||||
(uint8_t)(uint16_t(message.network.getNetID()) >> 8)
|
||||
});
|
||||
packet.push_back(uint8_t(message.network.getNetID()) + uint8_t((currentSize + (firstPacket ? 6 : 3)) << 4));
|
||||
|
|
|
|||
|
|
@ -113,7 +113,7 @@ bool HardwareLiveDataPacket::EncodeFromMessage(LiveDataMessage& message, std::ve
|
|||
return false;
|
||||
}
|
||||
|
||||
header->netid = static_cast<uint8_t>(_icsneo_netid_t::icsneo_netid_main51);
|
||||
header->netid = static_cast<uint8_t>(Network::NetID::Main51);
|
||||
header->fullLength = fullSize;
|
||||
header->command = static_cast<uint8_t>(Command::Extended);
|
||||
header->extendedCommand = static_cast<uint16_t>(ExtendedCommand::LiveData);
|
||||
|
|
|
|||
|
|
@ -54,7 +54,7 @@ bool Packetizer::input(RingBuffer& bytes) {
|
|||
if(packetLength == 0) {
|
||||
state = ReadState::ParseLongStylePacketHeader;
|
||||
break;
|
||||
} else if(packetLength == 0xA && packet.network == _icsneo_netid_t::icsneo_netid_disk_data) {
|
||||
} else if(packetLength == 0xA && packet.network == Network::NetID::DiskData) {
|
||||
state = ReadState::ParseDiskDataHeader;
|
||||
break;
|
||||
}
|
||||
|
|
@ -159,7 +159,7 @@ bool Packetizer::input(RingBuffer& bytes) {
|
|||
processedPackets.push_back(std::make_shared<Packet>(packet));
|
||||
bytes.pop(packetLength);
|
||||
|
||||
if(packet.network == _icsneo_netid_t::icsneo_netid_disk_data && (packetLength - headerSize) % 2 == 0) {
|
||||
if(packet.network == Network::NetID::DiskData && (packetLength - headerSize) % 2 == 0) {
|
||||
bytes.pop_front();
|
||||
}
|
||||
} else {
|
||||
|
|
|
|||
|
|
@ -218,8 +218,7 @@ bool Device::open(OpenFlags flags, OpenStatusHandler handler) {
|
|||
if(block) // Extensions say no
|
||||
return false;
|
||||
|
||||
// Get component versions *after* the extension "onDeviceOpen" hooks (e.g. device reflashes)
|
||||
|
||||
// Get component versions again *after* the extension "onDeviceOpen" hooks (e.g. device reflashes)
|
||||
if(supportsComponentVersions()) {
|
||||
if(auto compVersions = com->getComponentVersionsSync())
|
||||
componentVersions = std::move(*compVersions);
|
||||
|
|
@ -348,6 +347,15 @@ APIEvent::Type Device::attemptToBeginCommunication() {
|
|||
else
|
||||
versions = std::move(*maybeVersions);
|
||||
|
||||
|
||||
// Get component versions before the extension "onDeviceOpen" hooks so that we can properly check verisons
|
||||
if(supportsComponentVersions()) {
|
||||
if(auto compVersions = com->getComponentVersionsSync())
|
||||
componentVersions = std::move(*compVersions);
|
||||
else
|
||||
return getCommunicationNotEstablishedError();
|
||||
}
|
||||
|
||||
return APIEvent::Type::NoErrorFound;
|
||||
}
|
||||
|
||||
|
|
@ -389,7 +397,7 @@ bool Device::goOnline() {
|
|||
|
||||
updateLEDState();
|
||||
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_reset_status);
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Reset_Status);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
// Wait until communication is enabled or 5 seconds, whichever comes first
|
||||
|
|
@ -432,7 +440,7 @@ bool Device::goOffline() {
|
|||
|
||||
updateLEDState();
|
||||
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_reset_status);
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Reset_Status);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
// Wait until communication is disabled or 5 seconds, whichever comes first
|
||||
|
|
@ -457,7 +465,7 @@ int8_t Device::prepareScriptLoad() {
|
|||
return false;
|
||||
}
|
||||
|
||||
static std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_coremini_preload);
|
||||
static std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::CoreMiniPreLoad);
|
||||
|
||||
if(!com->sendCommand(Command::CoreMiniPreload))
|
||||
return false;
|
||||
|
|
@ -488,7 +496,7 @@ bool Device::startScript(Disk::MemoryType memType)
|
|||
|
||||
uint8_t location = static_cast<uint8_t>(memType);
|
||||
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_device);
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Device);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
const auto response = com->waitForMessageSync([&]() {
|
||||
|
|
@ -510,7 +518,7 @@ bool Device::stopScript()
|
|||
return false;
|
||||
}
|
||||
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_device);
|
||||
std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::Device);
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
const auto response = com->waitForMessageSync([&]() {
|
||||
|
|
@ -597,7 +605,7 @@ bool Device::uploadCoremini(std::istream& stream, Disk::MemoryType memType) {
|
|||
}
|
||||
|
||||
bool Device::eraseScriptMemory(Disk::MemoryType memType, uint64_t amount) {
|
||||
static std::shared_ptr<MessageFilter> NeoEraseDone = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_neo_memory_write_done);
|
||||
static std::shared_ptr<MessageFilter> NeoEraseDone = std::make_shared<MessageFilter>(Network::NetID::NeoMemoryWriteDone);
|
||||
|
||||
if(!supportsEraseMemory()) {
|
||||
return true;
|
||||
|
|
@ -780,7 +788,7 @@ void Device::setWriteBlocks(bool blocks) {
|
|||
com->setWriteBlocks(blocks);
|
||||
}
|
||||
|
||||
size_t Device::getNetworkCountByType(icsneo_msg_bus_type_t type) const {
|
||||
size_t Device::getNetworkCountByType(Network::Type type) const {
|
||||
size_t count = 0;
|
||||
for(const auto& net : getSupportedRXNetworks())
|
||||
if(net.getType() == type)
|
||||
|
|
@ -789,7 +797,7 @@ size_t Device::getNetworkCountByType(icsneo_msg_bus_type_t type) const {
|
|||
}
|
||||
|
||||
// Indexed starting at one
|
||||
Network Device::getNetworkByNumber(icsneo_msg_bus_type_t type, size_t index) const {
|
||||
Network Device::getNetworkByNumber(Network::Type type, size_t index) const {
|
||||
size_t count = 0;
|
||||
for(const auto& net : getSupportedRXNetworks()) {
|
||||
if(net.getType() == type) {
|
||||
|
|
@ -798,7 +806,7 @@ Network Device::getNetworkByNumber(icsneo_msg_bus_type_t type, size_t index) con
|
|||
return net;
|
||||
}
|
||||
}
|
||||
return _icsneo_netid_t::icsneo_netid_invalid;
|
||||
return Network::NetID::Invalid;
|
||||
}
|
||||
|
||||
std::shared_ptr<HardwareInfo> Device::getHardwareInfo(std::chrono::milliseconds timeout) {
|
||||
|
|
@ -806,12 +814,7 @@ std::shared_ptr<HardwareInfo> Device::getHardwareInfo(std::chrono::milliseconds
|
|||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
if(!isOnline()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>(Message::Type::HardwareInfo);
|
||||
|
||||
auto response = com->waitForMessageSync([this]() {
|
||||
|
|
@ -1721,16 +1724,7 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
|||
case Message::Type::InternalMessage: {
|
||||
auto rawMessage = std::static_pointer_cast<InternalMessage>(message);
|
||||
switch(rawMessage->network.getNetID()) {
|
||||
case _icsneo_netid_t::icsneo_netid_device: {
|
||||
// Device is not guaranteed to be a CANMessage, it might be a InternalMessage
|
||||
// if it couldn't be decoded to a CANMessage. We only care about the
|
||||
// CANMessage decoding right now.
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
case _icsneo_netid_t::icsneo_netid_device_status:
|
||||
case Network::NetID::DeviceStatus:
|
||||
// Device Status format is unique per device, so the devices need to decode it themselves
|
||||
handleDeviceStatus(rawMessage);
|
||||
break;
|
||||
|
|
@ -1739,6 +1733,15 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
|||
}
|
||||
break;
|
||||
}
|
||||
case Message::Type::BusMessage: {
|
||||
// Device is not guaranteed to be a CANMessage, it might be a InternalMessage
|
||||
// if it couldn't be decoded to a CANMessage. We only care about the
|
||||
// CANMessage decoding right now.
|
||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||
if(canmsg)
|
||||
handleNeoVIMessage(std::move(canmsg));
|
||||
break;
|
||||
}
|
||||
default: break;
|
||||
}
|
||||
forEachExtension([&](const std::shared_ptr<DeviceExtension>& ext) {
|
||||
|
|
@ -1817,7 +1820,7 @@ std::optional<EthPhyMessage> Device::sendEthPhyMsg(const EthPhyMessage& message,
|
|||
HardwareEthernetPhyRegisterPacket::EncodeFromMessage(message, bytes, report);
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this, bytes](){ return com->sendCommand(Command::PHYControlRegisters, bytes); },
|
||||
std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_eth_phy_control), timeout);
|
||||
std::make_shared<MessageFilter>(Network::NetID::EthPHYControl), timeout);
|
||||
|
||||
if(!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
|
|
@ -1888,7 +1891,7 @@ std::optional<bool> Device::SetRootDirectoryEntryFlags(uint8_t mask, uint8_t val
|
|||
|
||||
std::optional<std::chrono::time_point<std::chrono::system_clock>> Device::getRTC()
|
||||
{
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_red_get_rtc);
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(Network::NetID::RED_GET_RTC);
|
||||
std::shared_ptr<Message> generic = com->waitForMessageSync([this]() {
|
||||
return com->sendCommand(Command::GetRTC);
|
||||
}, filter, std::chrono::milliseconds(3000));
|
||||
|
|
@ -2023,7 +2026,7 @@ bool Device::readBinaryFile(std::ostream& stream, uint16_t binaryIndex) {
|
|||
std::vector<uint8_t> arguments(sizeof(ExtendedDataMessage::ExtendedDataHeader));
|
||||
ExtendedDataMessage::ExtendedDataHeader& parameters = *reinterpret_cast<ExtendedDataMessage::ExtendedDataHeader*>(arguments.data());
|
||||
|
||||
auto filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_extended_data);
|
||||
auto filter = std::make_shared<MessageFilter>(Network::NetID::ExtendedData);
|
||||
|
||||
for(size_t offset = 0; offset < *size; offset+=ExtendedDataMessage::MaxExtendedDataBufferSize) {
|
||||
parameters.subCommand = ExtendedDataSubCommand::GenericBinaryRead;
|
||||
|
|
@ -3260,13 +3263,13 @@ std::optional<uint64_t> Device::getVSADiskSize() {
|
|||
return diskSize;
|
||||
}
|
||||
|
||||
bool Device::requestTC10Wake(_icsneo_netid_t network) {
|
||||
bool Device::requestTC10Wake(Network::NetID network) {
|
||||
if(!supportsTC10()) {
|
||||
report(APIEvent::Type::NotSupported, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> args(sizeof(network));
|
||||
*(_icsneo_netid_t*)args.data() = network;
|
||||
*(Network::NetID*)args.data() = network;
|
||||
auto msg = com->waitForMessageSync([&] {
|
||||
return com->sendCommand(ExtendedCommand::RequestTC10Wake, args);
|
||||
}, std::make_shared<MessageFilter>(Message::Type::ExtendedResponse), std::chrono::milliseconds(1000));
|
||||
|
|
@ -3285,13 +3288,13 @@ bool Device::requestTC10Wake(_icsneo_netid_t network) {
|
|||
return resp->response == ExtendedResponse::OK;
|
||||
}
|
||||
|
||||
bool Device::requestTC10Sleep(_icsneo_netid_t network) {
|
||||
bool Device::requestTC10Sleep(Network::NetID network) {
|
||||
if(!supportsTC10()) {
|
||||
report(APIEvent::Type::NotSupported, APIEvent::Severity::Error);
|
||||
return false;
|
||||
}
|
||||
std::vector<uint8_t> args(sizeof(network));
|
||||
*(_icsneo_netid_t*)args.data() = network;
|
||||
*(Network::NetID*)args.data() = network;
|
||||
auto msg = com->waitForMessageSync([&] {
|
||||
return com->sendCommand(ExtendedCommand::RequestTC10Sleep, args);
|
||||
}, std::make_shared<MessageFilter>(Message::Type::ExtendedResponse), std::chrono::milliseconds(1000));
|
||||
|
|
@ -3310,13 +3313,13 @@ bool Device::requestTC10Sleep(_icsneo_netid_t network) {
|
|||
return typed->response == ExtendedResponse::OK;
|
||||
}
|
||||
|
||||
std::optional<TC10StatusMessage> Device::getTC10Status(_icsneo_netid_t network) {
|
||||
std::optional<TC10StatusMessage> Device::getTC10Status(Network::NetID network) {
|
||||
if(!supportsTC10()) {
|
||||
report(APIEvent::Type::NotSupported, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
std::vector<uint8_t> args(sizeof(network));
|
||||
*(_icsneo_netid_t*)args.data() = network;
|
||||
*(Network::NetID*)args.data() = network;
|
||||
auto msg = com->waitForMessageSync([&] {
|
||||
return com->sendCommand(ExtendedCommand::GetTC10Status, args);
|
||||
}, std::make_shared<MessageFilter>(Message::Type::TC10Status), std::chrono::milliseconds(1000));
|
||||
|
|
@ -3335,3 +3338,34 @@ std::optional<TC10StatusMessage> Device::getTC10Status(_icsneo_netid_t network)
|
|||
|
||||
return *typed;
|
||||
}
|
||||
|
||||
std::optional<GPTPStatus> Device::getGPTPStatus(std::chrono::milliseconds timeout) {
|
||||
if(!supportsGPTP()) {
|
||||
report(APIEvent::Type::GPTPNotSupported, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::shared_ptr<Message> response = com->waitForMessageSync(
|
||||
[this](){
|
||||
return com->sendCommand(ExtendedCommand::GetGPTPStatus, {});
|
||||
},
|
||||
std::make_shared<MessageFilter>(Message::Type::GPTPStatus),
|
||||
timeout
|
||||
);
|
||||
|
||||
if(!response) {
|
||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
auto retMsg = std::static_pointer_cast<GPTPStatus>(response);
|
||||
if(!retMsg) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
return *retMsg;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,6 +1,5 @@
|
|||
#include "icsneo/device/extensions/flexray/controller.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/icsneotypes.h"
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
|
|
@ -611,7 +610,7 @@ uint16_t FlexRay::Controller::CalculateCycleFilter(uint8_t baseCycle, uint8_t cy
|
|||
}
|
||||
|
||||
std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const {
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_flexray_control);
|
||||
static const std::shared_ptr<MessageFilter> filter = std::make_shared<MessageFilter>(icsneo::Network::NetID::FlexRayControl);
|
||||
if(timeout.count() <= 20)
|
||||
return {false, 0}; // Out of time!
|
||||
|
||||
|
|
|
|||
|
|
@ -2,9 +2,6 @@
|
|||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||
|
||||
#include <chrono>
|
||||
#include <memory>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
FlexRay::Extension::Extension(Device& device, const std::vector<Network>& controllerNetworks) : DeviceExtension(device) {
|
||||
|
|
@ -49,7 +46,7 @@ void FlexRay::Extension::handleMessage(const std::shared_ptr<Message>& message)
|
|||
}
|
||||
|
||||
bool FlexRay::Extension::transmitHook(const std::shared_ptr<BusMessage>& frame, bool& success) {
|
||||
if(!frame || frame->network.getType() != icsneo_msg_bus_type_flexray)
|
||||
if(!frame || frame->network.getType() != Network::Type::FlexRay)
|
||||
return true; // Don't hook non-FlexRay messages
|
||||
|
||||
success = false;
|
||||
|
|
|
|||
|
|
@ -403,7 +403,7 @@ int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_can: {
|
||||
case Network::Type::CAN: {
|
||||
const CAN_SETTINGS* cfg = getCANSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::CANSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -417,7 +417,7 @@ int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
|||
}
|
||||
return baudrate;
|
||||
}
|
||||
case icsneo_msg_bus_type_swcan: {
|
||||
case Network::Type::SWCAN: {
|
||||
const SWCAN_SETTINGS* cfg = getSWCANSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -431,7 +431,7 @@ int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
|||
}
|
||||
return baudrate;
|
||||
}
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
case Network::Type::LSFTCAN: {
|
||||
const CAN_SETTINGS* cfg = getLSFTCANSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LSFTCANSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -445,7 +445,7 @@ int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
|||
}
|
||||
return baudrate;
|
||||
}
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -477,7 +477,7 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_can: {
|
||||
case Network::Type::CAN: {
|
||||
if(baudrate > 1000000) { // This is an FD baudrate. Use setFDBaudrateFor instead.
|
||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -499,7 +499,7 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
case Network::Type::LSFTCAN: {
|
||||
CAN_SETTINGS* cfg = getMutableLSFTCANSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LSFTCANSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -516,7 +516,7 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_swcan: {
|
||||
case Network::Type::SWCAN: {
|
||||
SWCAN_SETTINGS* cfg = getMutableSWCANSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -533,7 +533,7 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
return true;
|
||||
}
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -566,7 +566,7 @@ int64_t IDeviceSettings::getFDBaudrateFor(Network net) const {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_can: {
|
||||
case Network::Type::CAN: {
|
||||
const CANFD_SETTINGS* cfg = getCANFDSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -604,7 +604,7 @@ bool IDeviceSettings::setFDBaudrateFor(Network net, int64_t baudrate) {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_can: {
|
||||
case Network::Type::CAN: {
|
||||
CANFD_SETTINGS* cfg = getMutableCANFDSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -771,7 +771,7 @@ std::optional<bool> IDeviceSettings::isCommanderResistorEnabledFor(Network net)
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -803,7 +803,7 @@ bool IDeviceSettings::setCommanderResistorFor(Network net, bool resistor_on) {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -831,7 +831,7 @@ std::optional<LINMode> IDeviceSettings::getLINModeFor(Network net) const {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -863,7 +863,7 @@ bool IDeviceSettings::setLINModeFor(Network net, LINMode mode) {
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -891,7 +891,7 @@ std::optional<uint8_t> IDeviceSettings::getLINCommanderResponseTimeFor(Network n
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
const LIN_SETTINGS* cfg = getLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
@ -923,7 +923,7 @@ bool IDeviceSettings::setLINCommanderResponseTimeFor(Network net, uint8_t bits)
|
|||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case icsneo_msg_bus_type_lin: {
|
||||
case Network::Type::LIN: {
|
||||
LIN_SETTINGS* cfg = getMutableLINSettingsFor(net);
|
||||
if(cfg == nullptr) {
|
||||
report(APIEvent::Type::LINSettingsNotAvailable, APIEvent::Severity::Error);
|
||||
|
|
|
|||
|
|
@ -6,7 +6,7 @@ neodevice_t::neodevice_t() : device(nullptr), handle(0), type(0) {
|
|||
memset(serial, 0, sizeof(serial));
|
||||
}
|
||||
|
||||
neodevice_t::neodevice_t(const icsneo::FoundDevice& found, icsneo_devicetype_t inType)
|
||||
neodevice_t::neodevice_t(const icsneo::FoundDevice& found, devicetype_t inType)
|
||||
: device(nullptr), handle(found.handle), type(inType) {
|
||||
static_assert(sizeof(found.serial) == sizeof(serial), "Serial sizes should match!");
|
||||
memcpy(serial, found.serial, sizeof(serial));
|
||||
|
|
|
|||
|
|
@ -34,7 +34,7 @@ std::optional<uint64_t> ExtExtractorDiskReadDriver::readLogicalDiskAligned(Commu
|
|||
|
||||
std::optional<uint64_t> ExtExtractorDiskReadDriver::attemptReadLogicalDiskAligned(Communication& com, device_eventhandler_t report,
|
||||
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType) {
|
||||
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_neo_memory_sdread);
|
||||
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead);
|
||||
|
||||
uint64_t sector = pos / SectorSize;
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ std::optional<uint64_t> ExtExtractorDiskReadDriver::attemptReadLogicalDiskAligne
|
|||
cv.notify_all();
|
||||
}
|
||||
}
|
||||
}, std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_disk_data)));
|
||||
}, std::make_shared<MessageFilter>(Network::NetID::DiskData)));
|
||||
|
||||
if(!com.sendCommand(ExtendedCommand::Extract, {
|
||||
uint8_t(sector & 0xff),
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@ using namespace icsneo::Disk;
|
|||
|
||||
std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report,
|
||||
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) {
|
||||
const auto filter = std::make_shared<MessageFilter>((memType == MemoryType::SD ? _icsneo_netid_t::icsneo_netid_neo_memory_sdread : _icsneo_netid_t::icsneo_netid_red_int_memoryread));
|
||||
const auto filter = std::make_shared<MessageFilter>((memType == MemoryType::SD ? Network::NetID::NeoMemorySDRead : Network::NetID::RED_INT_MEMORYREAD));
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
if(pos % SectorSize != 0)
|
||||
|
|
@ -61,7 +61,7 @@ std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio
|
|||
std::optional<uint64_t> NeoMemoryDiskDriver::writeLogicalDiskAligned(Communication& com, device_eventhandler_t report,
|
||||
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>(_icsneo_netid_t::icsneo_netid_neo_memory_write_done);
|
||||
static std::shared_ptr<MessageFilter> NeoMemoryDone = std::make_shared<MessageFilter>(Network::NetID::NeoMemoryWriteDone);
|
||||
|
||||
if(pos % SectorSize != 0)
|
||||
return std::nullopt;
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@ using namespace icsneo::Disk;
|
|||
|
||||
std::optional<uint64_t> PlasionDiskReadDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report,
|
||||
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType) {
|
||||
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(_icsneo_netid_t::icsneo_netid_neo_memory_sdread);
|
||||
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead);
|
||||
|
||||
if(amount > getBlockSizeBounds().second)
|
||||
return std::nullopt;
|
||||
|
|
|
|||
|
|
@ -22,7 +22,7 @@ void VSAExtendedMessage::appendPacket(std::shared_ptr<Packet> packet) const
|
|||
{
|
||||
packet->data.insert(packet->data.end(), payload.begin(), payload.end());
|
||||
// Set the network if not already set (Happens in AA0F records)
|
||||
if(packet->network.getNetID() == _icsneo_netid_t::icsneo_netid_invalid) {
|
||||
if(packet->network.getNetID() == Network::NetID::Invalid) {
|
||||
packet->network = network;
|
||||
}
|
||||
}
|
||||
|
|
@ -31,7 +31,7 @@ void VSAExtendedMessage::truncatePacket(std::shared_ptr<Packet> packet)
|
|||
{
|
||||
static constexpr auto EthernetLengthOffset = 26u;
|
||||
switch(packet->network.getType()) {
|
||||
case icsneo_msg_bus_type_ethernet:
|
||||
case Network::Type::Ethernet:
|
||||
{
|
||||
const auto& packetLength = *reinterpret_cast<uint16_t*>(packet->data.data() + EthernetLengthOffset);
|
||||
const size_t ethernetFrameSize = packetLength - (sizeof(uint16_t) * 2);
|
||||
|
|
|
|||
|
|
@ -7,13 +7,12 @@ import subprocess
|
|||
|
||||
subprocess.call('cd ..; doxygen docs/icsneocpp/Doxyfile', shell=True)
|
||||
subprocess.call('cd ..; doxygen docs/icsneoc/Doxyfile', shell=True)
|
||||
subprocess.call('cd ..; doxygen docs/icsneo/Doxyfile', shell=True)
|
||||
|
||||
# -- Project information -----------------------------------------------------
|
||||
# https://www.sphinx-doc.org/en/master/usage/configuration.html#project-information
|
||||
|
||||
project = 'libicsneo'
|
||||
copyright = '2024, Intrepid Control Systems, Inc.'
|
||||
copyright = '2024-2025, Intrepid Control Systems, Inc.'
|
||||
author = 'Intrepid Control Systems, Inc.'
|
||||
|
||||
# -- General configuration ---------------------------------------------------
|
||||
|
|
@ -27,7 +26,6 @@ exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']
|
|||
breathe_projects = {
|
||||
'icsneocpp': 'icsneocpp/doxygen/xml',
|
||||
'icsneoc': 'icsneoc/doxygen/xml',
|
||||
'icsneo': 'icsneoc/doxygen/xml',
|
||||
}
|
||||
|
||||
breathe_default_project = 'icsneocpp'
|
||||
|
|
|
|||
2862
docs/icsneo/Doxyfile
2862
docs/icsneo/Doxyfile
File diff suppressed because it is too large
Load Diff
|
|
@ -1,8 +0,0 @@
|
|||
=====
|
||||
C API
|
||||
=====
|
||||
|
||||
.. doxygenfile:: icsneo.h
|
||||
:project: icsneo
|
||||
.. doxygenfile:: icsneotypes.h
|
||||
:project: icsneo
|
||||
|
|
@ -1,43 +0,0 @@
|
|||
==========
|
||||
C Examples
|
||||
==========
|
||||
|
||||
A variety of examples can be found within ``examples/c``, see below for an
|
||||
example that uses the polling API to receive CAN frames.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
size_t deviceCount = 10; // Pre-set to the size of your buffer before the icsneo_findAllDevices() call
|
||||
neodevice_t devices[10];
|
||||
icsneo_findAllDevices(devices, &deviceCount);
|
||||
printf("We found %ull devices\n", deviceCount);
|
||||
for(size_t i = 0; i < deviceCount; i++) {
|
||||
neodevice_t* myDevice = &devices[i];
|
||||
char desc[ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION];
|
||||
size_t sz = ICSNEO_DEVICETYPE_LONGEST_DESCRIPTION;
|
||||
icsneo_describeDevice(myDevice, desc, &sz);
|
||||
printf("Found %s\n", desc); // "Found neoVI FIRE 2 CY2345"
|
||||
}
|
||||
neodevice_t* myDevice = &devices[0];
|
||||
if(!icsneo_openDevice(myDevice)) {
|
||||
neoevent_t error;
|
||||
if(icsneo_getLastError(&error))
|
||||
printf("Error! %s\n", error.description);
|
||||
}
|
||||
icsneo_goOnline(myDevice); // Start receiving messages
|
||||
icsneo_enableMessagePolling(myDevice); // Allow the use of icsneo_getMessages() later
|
||||
sleep(5);
|
||||
neomessage_t messages[50];
|
||||
size_t messageCount = 50;
|
||||
icsneo_getMessages(myDevice, messages, &messageCount, 0 /* non-blocking */);
|
||||
printf("We got %ull messages!\n", messageCount);
|
||||
for(size_t i = 0; i < messageCount; i++) {
|
||||
if(messages[i].type == ICSNEO_NETWORK_TYPE_CAN) {
|
||||
// A message of type CAN should be interperated a neomessage_can_t, so we can cast safely
|
||||
neomessage_can_t* canmsg = (neomessage_can_t*)&messages[i];
|
||||
// canmsg->arbid is valid here
|
||||
// canmsg->data is an uint8_t*, you can check canmsg->length for the length of the payload
|
||||
// canmsg->timestamp is the time recorded by the hardware in nanoseconds since (1/1/2007 12:00:00 GMT)
|
||||
}
|
||||
}
|
||||
icsneo_closeDevice(myDevice);
|
||||
|
|
@ -1,9 +0,0 @@
|
|||
icsneo
|
||||
=======
|
||||
|
||||
.. toctree::
|
||||
:maxdepth: 2
|
||||
|
||||
installation
|
||||
examples
|
||||
api
|
||||
|
|
@ -1,7 +0,0 @@
|
|||
============
|
||||
Installation
|
||||
============
|
||||
|
||||
The installation steps for the C API are the same as the C++ API as the C API is
|
||||
a wrapper for the C++ library. The ``LIBICSNEO_BUILD_ICSNEO`` CMake option is
|
||||
default ``ON`` but note that the C API depends on this flag to build.
|
||||
|
|
@ -36,9 +36,9 @@ the arbitration ID.
|
|||
std::cout << "We got " << messages.size() << " messages!" << std::endl;
|
||||
for(auto& msg : messages) {
|
||||
switch(msg->network.getType()) {
|
||||
case icsneo_msg_bus_type_can:
|
||||
case icsneo_msg_bus_type_swcan:
|
||||
case icsneo_msg_bus_type_lsftcan: {
|
||||
case icsneo::Network::Type::CAN:
|
||||
case icsneo::Network::Type::SWCAN:
|
||||
case icsneo::Network::Type::LSFTCAN: {
|
||||
// A message of type CAN is guaranteed to be a CANMessage, so we can static cast safely
|
||||
auto canmsg = std::static_pointer_cast<icsneo::CANMessage>(msg);
|
||||
// canmsg->arbid is valid here
|
||||
|
|
|
|||
|
|
@ -6,4 +6,5 @@ Python API
|
|||
:members:
|
||||
:undoc-members:
|
||||
:show-inheritance:
|
||||
:imported-members:
|
||||
:special-members: __init__
|
||||
|
|
|
|||
|
|
@ -50,3 +50,41 @@ Receive CAN frames on HSCAN
|
|||
|
||||
# rx for 10s
|
||||
time.sleep(10)
|
||||
|
||||
|
||||
Monitor Ethernet Status
|
||||
=======================
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import icsneopy
|
||||
import time
|
||||
|
||||
def main():
|
||||
devices = icsneopy.find_all_devices()
|
||||
if len(devices) == 0:
|
||||
print("error: no devices found")
|
||||
return False
|
||||
|
||||
device = devices[0]
|
||||
print(f"info: monitoring Ethernet status on {device}")
|
||||
|
||||
def on_message(message):
|
||||
print(f"info: network: {message.network}, state: {message.state}, speed: {message.speed}, duplex: {message.duplex}, mode: {message.mode}")
|
||||
|
||||
filter = icsneopy.MessageFilter(icsneopy.Message.Type.EthernetStatus)
|
||||
callback = icsneopy.MessageCallback(on_message, filter)
|
||||
device.add_message_callback(callback)
|
||||
|
||||
if not device.open():
|
||||
print("error: unable to open device")
|
||||
return False
|
||||
|
||||
if not device.go_online():
|
||||
print("error: unable to go online")
|
||||
return False
|
||||
|
||||
while True:
|
||||
time.sleep(1)
|
||||
|
||||
main()
|
||||
|
|
|
|||
|
|
@ -13,4 +13,3 @@ communication library. The source code for libicsneo can be found on GitHub:
|
|||
icsneocpp/index
|
||||
icsneopy/index
|
||||
icsneoc/index
|
||||
icsneo/index
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
option(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE "Build the command-line interactive C example." ON)
|
||||
option(LIBICSNEO_BUILD_C_SIMPLE_EXAMPLE "Build the command-line simple C example." ON)
|
||||
option(LIBICSNEO_BUILD_C_OLD_INTERACTIVE_EXAMPLE "Build the command-line interactive C example." ON)
|
||||
option(LIBICSNEO_BUILD_C_OLD_SIMPLE_EXAMPLE "Build the command-line simple C example." ON)
|
||||
option(LIBICSNEO_BUILD_C_LEGACY_EXAMPLE "Build the command-line simple C example." ON)
|
||||
option(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE "Build the command-line simple C example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE "Build the simple C++ example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_INTERACTIVE_EXAMPLE "Build the command-line interactive C++ example." ON)
|
||||
option(LIBICSNEO_BUILD_CPP_A2B_EXAMPLE "Build the A2B example." ON)
|
||||
|
|
@ -16,20 +16,20 @@ option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the app error example." ON)
|
|||
# option(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE "Build the command-line interactive C# example." OFF)
|
||||
# option(LIBICSNEO_BUILD_JAVA_INTERACTIVE_EXAMPLE "Build the command-line interactive Java example." OFF)
|
||||
|
||||
if(LIBICSNEO_BUILD_C_INTERACTIVE_EXAMPLE)
|
||||
add_subdirectory(c/interactive)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_C_SIMPLE_EXAMPLE)
|
||||
add_subdirectory(c/simple)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_C_OLD_INTERACTIVE_EXAMPLE)
|
||||
add_subdirectory(c_old/interactive)
|
||||
if(LIBICSNEO_BUILD_C_LEGACY_EXAMPLE)
|
||||
add_subdirectory(c/legacy)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_C_OLD_SIMPLE_EXAMPLE)
|
||||
add_subdirectory(c_old/simple)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_C_OLD_LEGACY_EXAMPLE)
|
||||
add_subdirectory(c_old/legacy)
|
||||
if(LIBICSNEO_BUILD_C2_SIMPLE_EXAMPLE)
|
||||
add_subdirectory(c2/simple)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_CPP_SIMPLE_EXAMPLE)
|
||||
|
|
|
|||
|
|
@ -1,2 +1,5 @@
|
|||
add_executable(libicsneo-simple-example src/main.c)
|
||||
target_link_libraries(libicsneo-simple-example icsneo)
|
||||
add_executable(libicsneoc-simple-lin-example lin/main.c)
|
||||
if(UNIX)
|
||||
target_link_libraries(libicsneoc-simple-lin-example ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
target_link_libraries(libicsneoc-simple-lin-example icsneoc)
|
||||
|
|
@ -1,424 +0,0 @@
|
|||
#include <icsneo/icsneo.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sleeps for a specified number of milliseconds.
|
||||
*
|
||||
* Sleeps for a specified number of milliseconds using Sleep() on Windows and sleep() on *nix.
|
||||
*
|
||||
* @param ms The number of milliseconds to sleep.
|
||||
*/
|
||||
void sleep_ms(uint32_t ms) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Sleep(ms);
|
||||
#else
|
||||
sleep(ms / 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints an error message with the given string and error code.
|
||||
*
|
||||
* If the error code is not icsneo_error_success, prints the error string for the given error code
|
||||
* and returns the error code.
|
||||
*
|
||||
* @param message The message to print.
|
||||
* @param error The error code to print.
|
||||
* @return error as int
|
||||
*/
|
||||
int print_error_code(const char* message, icsneo_error_t error) {
|
||||
char error_str[256] = {0};
|
||||
uint32_t error_length = 256;
|
||||
icsneo_error_t res = icsneo_get_error_code(error, error_str, &error_length);
|
||||
if (res != icsneo_error_success) {
|
||||
printf("%s: Failed to get string for error code %d with error code %d\n", message, error, res);
|
||||
return res;
|
||||
}
|
||||
printf("%s: \"%s\" (%u)\n", message, error_str, error);
|
||||
return (int)error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes a list of messages from a device.
|
||||
*
|
||||
* This function iterates over a given array of messages received from a specified device.
|
||||
* For each message in the array, it retrieves and prints the message type and bus type.
|
||||
* If an error occurs while retrieving these details, an error message is printed.
|
||||
*
|
||||
* @param device A pointer to the icsneo_device_t structure representing the device.
|
||||
* @param messages An array of pointers to icsneo_message_t structures containing the messages to process.
|
||||
* @param messages_count The number of messages in the messages array.
|
||||
*
|
||||
* @return An icsneo_error_t value indicating success or failure of the message processing.
|
||||
*/
|
||||
int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint32_t messages_count);
|
||||
|
||||
/**
|
||||
* @brief Prints device and global events for a given device.
|
||||
*
|
||||
* This function retrieves and prints all current events associated with the specified device,
|
||||
* as well as any global events not tied to a specific device. For each event, it retrieves
|
||||
* and prints a description. If retrieving events or their descriptions fails, an error
|
||||
* message is printed. The function also prints a summary of the count of device-specific
|
||||
* and global events processed.
|
||||
*
|
||||
* @param device A pointer to the icsneo_device_t structure representing the device to get events from.
|
||||
* @param device_description A description of the device used in the output.
|
||||
*/
|
||||
void print_device_events(icsneo_device_t* device, const char* device_description);
|
||||
|
||||
/**
|
||||
* @brief Transmits a series of CAN messages from a device.
|
||||
*
|
||||
* This function creates and transmits 100 CAN messages with incrementing payload data.
|
||||
* Each message is configured with specific attributes such as network ID, arbitration
|
||||
* ID, CANFD status, extended status, and baudrate switch. After successfully transmitting
|
||||
* each message, it is freed from memory.
|
||||
*
|
||||
* @param device A pointer to the icsneo_device_t structure representing the device to transmit messages from.
|
||||
*
|
||||
* @return An icsneo_error_t value indicating success or failure of the message transmission process.
|
||||
*/
|
||||
int transmit_can_messages(icsneo_device_t* device);
|
||||
|
||||
/**
|
||||
* @brief Get the RTC (Real time clock) of a device and print it.
|
||||
*
|
||||
* @param[in] device The device to get the RTC of.
|
||||
* @param[in] description A description of the device for printing purpose.
|
||||
*
|
||||
* @return icsneo_error_t icsneo_error_success if successful, icsneo_error_invalid_parameters otherwise.
|
||||
*/
|
||||
icsneo_error_t get_and_print_rtc(icsneo_device_t* device, const char* description);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
icsneo_device_t* devices[255] = {0};
|
||||
uint32_t devices_count = 255;
|
||||
|
||||
icsneo_error_t res = icsneo_device_find_all(devices, &devices_count, NULL);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to find devices", res);
|
||||
};
|
||||
|
||||
printf("Found %u devices\n", devices_count);
|
||||
// Loop over each device
|
||||
for (uint32_t i = 0; i < devices_count; i++) {
|
||||
icsneo_device_t* device = devices[i];
|
||||
// Get description of the device
|
||||
const char description[255] = {0};
|
||||
uint32_t description_length = 255;
|
||||
res = icsneo_device_get_description(device, description, &description_length);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to get device description", res);
|
||||
};
|
||||
// Get timestamp resolution of the device
|
||||
uint32_t timestamp_resolution = 0;
|
||||
res = icsneo_device_get_timestamp_resolution(device, ×tamp_resolution);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to get timestamp resolution", res);
|
||||
}
|
||||
printf("%s timestamp resolution: %uns\n", description, timestamp_resolution);
|
||||
// Get/Set open options
|
||||
icsneo_open_options_t options = icsneo_open_options_none;
|
||||
res = icsneo_device_get_open_options(device, &options);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to get open options", res);
|
||||
}
|
||||
// Disable Syncing RTC
|
||||
options &= ~icsneo_open_options_sync_rtc;
|
||||
res = icsneo_device_set_open_options(device, options);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to set open options", res);
|
||||
}
|
||||
// Open the device
|
||||
printf("Opening device: %s...\n", description);
|
||||
res = icsneo_device_open(device);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to open device", res);
|
||||
};
|
||||
// Get RTC
|
||||
res = get_and_print_rtc(device, description);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to get RTC", res);
|
||||
}
|
||||
// Set RTC
|
||||
time_t current_time = time(NULL);
|
||||
res = icsneo_device_set_rtc(device, (int64_t*)¤t_time);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to set RTC", res);
|
||||
}
|
||||
// Get RTC
|
||||
res = get_and_print_rtc(device, description);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to get RTC", res);
|
||||
}
|
||||
// Get/Set baudrate for HSCAN
|
||||
uint64_t baudrate = 0;
|
||||
res = icsneo_device_get_baudrate(device, icsneo_netid_hscan, &baudrate);
|
||||
res += icsneo_device_set_baudrate(device, icsneo_netid_hscan, baudrate, true);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to transmit CAN messages", res);
|
||||
};
|
||||
printf("HSCAN baudrate: %llu\n", baudrate);
|
||||
// Get/Set CAN FD baudrate for HSCAN
|
||||
res = icsneo_device_get_canfd_baudrate(device, icsneo_netid_hscan, &baudrate);
|
||||
res += icsneo_device_set_canfd_baudrate(device, icsneo_netid_hscan, baudrate, true);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to transmit CAN messages", res);
|
||||
};
|
||||
printf("HSCAN CANFD baudrate: %llu\n", baudrate);
|
||||
|
||||
// Transmit CAN messages
|
||||
res = transmit_can_messages(device);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to transmit CAN messages", res);
|
||||
}
|
||||
// Wait for the bus to collect some messages, requires an active bus to get messages
|
||||
printf("Waiting 1 second for messages...\n");
|
||||
sleep_ms(1000);
|
||||
// Get the messages
|
||||
icsneo_message_t* messages[20000] = {0};
|
||||
uint32_t message_count = 20000;
|
||||
printf("Getting messages from device with timeout of 3000ms on %s...\n", description);
|
||||
res = icsneo_device_get_messages(device, messages, &message_count, 3000);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to get messages from device", res);
|
||||
};
|
||||
// Process the messages
|
||||
res = process_messages(device, messages, message_count);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to process messages", res);
|
||||
}
|
||||
// Finally, close the device.
|
||||
printf("Closing device: %s...\n", description);
|
||||
res = icsneo_device_close(device);
|
||||
if (res != icsneo_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("Failed to close device", res);
|
||||
};
|
||||
// Print device events
|
||||
print_device_events(device, description);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
icsneo_error_t get_and_print_rtc(icsneo_device_t* device, const char* description) {
|
||||
time_t unix_epoch = 0;
|
||||
icsneo_error_t res = icsneo_device_get_rtc(device, &unix_epoch);
|
||||
if (res != icsneo_error_success) {
|
||||
return res;
|
||||
}
|
||||
char rtc_time[32] = {0};
|
||||
strftime(rtc_time, sizeof(rtc_time), "%Y-%m-%d %H:%M:%S", localtime(&unix_epoch));
|
||||
printf("RTC: %lld %s\n", unix_epoch, rtc_time);
|
||||
|
||||
return icsneo_error_success;
|
||||
}
|
||||
|
||||
void print_device_events(icsneo_device_t* device, const char* device_description) {
|
||||
// Get device events
|
||||
icsneo_event_t* events[1024] = {0};
|
||||
uint32_t events_count = 1024;
|
||||
icsneo_error_t res = icsneo_device_get_events(device, events, &events_count);
|
||||
if (res != icsneo_error_success) {
|
||||
(void)print_error_code("Failed to get device events", res);
|
||||
return;
|
||||
}
|
||||
// Loop over each event and describe it.
|
||||
for (uint32_t i = 0; i < events_count; i++) {
|
||||
const char event_description[255] = {0};
|
||||
uint32_t event_description_length = 255;
|
||||
res = icsneo_event_get_description(events[i], event_description, &event_description_length);
|
||||
if (res != icsneo_error_success) {
|
||||
print_error_code("Failed to get event description", res);
|
||||
continue;
|
||||
}
|
||||
printf("\t%s: Event %u: %s\n", device_description, i, event_description);
|
||||
}
|
||||
|
||||
// Get global events
|
||||
icsneo_event_t* global_events[1024] = {0};
|
||||
uint32_t global_events_count = 1024;
|
||||
res = icsneo_get_events(global_events, &global_events_count);
|
||||
if (res != icsneo_error_success) {
|
||||
(void)print_error_code("Failed to get global events", res);
|
||||
return;
|
||||
}
|
||||
// Loop over each event and describe it.
|
||||
for (uint32_t i = 0; i < global_events_count; i++) {
|
||||
const char event_description[255] = {0};
|
||||
uint32_t event_description_length = 255;
|
||||
res = icsneo_event_get_description(global_events[i], event_description, &event_description_length);
|
||||
if (res != icsneo_error_success) {
|
||||
print_error_code("Failed to get global event description", res);
|
||||
continue;
|
||||
}
|
||||
printf("\t%s: Global Event %u: %s\n", device_description, i, event_description);
|
||||
}
|
||||
printf("%s: Received %u events and %u global events\n", device_description, events_count, global_events_count);
|
||||
}
|
||||
|
||||
int process_messages(icsneo_device_t* device, icsneo_message_t** messages, uint32_t messages_count) {
|
||||
// Print the type and bus type of each message
|
||||
uint32_t tx_count = 0;
|
||||
for (uint32_t i = 0; i < messages_count; i++) {
|
||||
icsneo_message_t* message = messages[i];
|
||||
// Get the message type
|
||||
icsneo_msg_type_t msg_type = 0;
|
||||
icsneo_error_t res = icsneo_message_get_type(device, message, &msg_type);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message type", res);
|
||||
}
|
||||
// Get the message type name
|
||||
char msg_type_name[128] = {0};
|
||||
uint32_t msg_type_name_length = 128;
|
||||
res = icsneo_message_get_type_name(msg_type, msg_type_name, &msg_type_name_length);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message type name", res);
|
||||
}
|
||||
// Check if the message is a bus message, ignore otherwise
|
||||
if (msg_type != icsneo_msg_type_bus) {
|
||||
printf("Ignoring message type: %u (%s)\n", msg_type, msg_type_name);
|
||||
continue;
|
||||
}
|
||||
icsneo_msg_bus_type_t bus_type = 0;
|
||||
res = icsneo_message_get_bus_type(device, message, &bus_type);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message bus type", res);
|
||||
}
|
||||
const char bus_name[128] = {0};
|
||||
uint32_t bus_name_length = 128;
|
||||
res = icsneo_get_bus_type_name(&bus_type, bus_name, &bus_name_length);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message bus type name", res);
|
||||
}
|
||||
bool is_tx = false;
|
||||
res = icsneo_message_is_transmit(device, message, &is_tx);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to get message is transmit", res);
|
||||
}
|
||||
if (is_tx) {
|
||||
tx_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\t%d) Message type: %u bus type: %s (%u)\n", i, msg_type, bus_name, bus_type);
|
||||
if (bus_type == icsneo_msg_bus_type_can) {
|
||||
uint32_t arbid = 0;
|
||||
int32_t dlc = 0;
|
||||
icsneo_netid_t netid = 0;
|
||||
bool is_remote = false;
|
||||
bool is_canfd = false;
|
||||
bool is_extended = false;
|
||||
bool is_tx = false;
|
||||
uint8_t data[64] = {0};
|
||||
uint32_t data_length = 64;
|
||||
const char netid_name[128] = {0};
|
||||
uint32_t netid_name_length = 128;
|
||||
uint32_t result = icsneo_message_get_netid(device, message, &netid);
|
||||
result += icsneo_get_netid_name(netid, netid_name, &netid_name_length);
|
||||
result += icsneo_can_message_get_arbid(device, message, &arbid);
|
||||
result += icsneo_can_message_get_dlc(device, message, &dlc);
|
||||
result += icsneo_can_message_is_remote(device, message, &is_remote);
|
||||
result += icsneo_can_message_is_canfd(device, message, &is_canfd);
|
||||
result += icsneo_can_message_is_extended(device, message, &is_extended);
|
||||
result += icsneo_message_get_data(device, message, data, &data_length);
|
||||
result += icsneo_message_is_transmit(device, message, &is_tx);
|
||||
if (result != icsneo_error_success) {
|
||||
printf("\tFailed get get CAN parameters (error: %u) for index %u\n", result, i);
|
||||
continue;
|
||||
}
|
||||
printf("\t NetID: %s (0x%x)\tArbID: 0x%x\t DLC: %u\t TX: %d\t Remote: %d\t CANFD: %d\t Extended: %d\t Data length: %u\n", netid_name, netid, arbid, dlc, is_tx, is_remote, is_canfd, is_extended, data_length);
|
||||
printf("\t Data: [");
|
||||
for (uint32_t x = 0; x < data_length; x++) {
|
||||
printf(" 0x%x", data[x]);
|
||||
}
|
||||
printf(" ]\n");
|
||||
// Lets transmit the message back with an Arbitration ID 1 higher than the original.
|
||||
result = icsneo_can_message_set_arbid(device, message, arbid + 1);
|
||||
if (result != icsneo_error_success) {
|
||||
printf("\tFailed to set CAN Arbitration ID (error: %u) for index %u\n", result, i);
|
||||
continue;
|
||||
}
|
||||
uint32_t tx_msg_count = 1;
|
||||
result = icsneo_device_transmit_messages(device, &message, &tx_msg_count);
|
||||
if (result != icsneo_error_success) {
|
||||
printf("\tFailed to transmit CAN message (error: %u) for index %u\n", result, i);
|
||||
continue;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
}
|
||||
printf("Received %u messages total, %u were TX messages\n", messages_count, tx_count);
|
||||
|
||||
return icsneo_error_success;
|
||||
}
|
||||
|
||||
int transmit_can_messages(icsneo_device_t* device) {
|
||||
uint64_t counter = 0;
|
||||
|
||||
for (uint32_t i = 0; i < 100; i++) {
|
||||
// Create the message
|
||||
icsneo_message_t* message = NULL;
|
||||
uint32_t message_count = 1;
|
||||
icsneo_error_t res = icsneo_can_messages_create(device, &message, message_count);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to create messages", res);
|
||||
}
|
||||
// Set the message attributes
|
||||
res = icsneo_message_set_netid(device, message, icsneo_netid_hscan);
|
||||
res += icsneo_can_message_set_arbid(device, message, 0x10);
|
||||
res += icsneo_can_message_set_canfd(device, message, true);
|
||||
res += icsneo_can_message_set_extended(device, message, true);
|
||||
res += icsneo_can_message_set_baudrate_switch(device, message, true);
|
||||
// Create the payload
|
||||
uint8_t data[8] = {0};
|
||||
data[0] = (uint8_t)(counter >> 56);
|
||||
data[1] = (uint8_t)(counter >> 48);
|
||||
data[2] = (uint8_t)(counter >> 40);
|
||||
data[3] = (uint8_t)(counter >> 32);
|
||||
data[4] = (uint8_t)(counter >> 24);
|
||||
data[5] = (uint8_t)(counter >> 16);
|
||||
data[6] = (uint8_t)(counter >> 8);
|
||||
data[7] = (uint8_t)(counter >> 0);
|
||||
res += icsneo_message_set_data(device, message, data, sizeof(data));
|
||||
res += icsneo_can_message_set_dlc(device, message, -1);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to modify message", res);
|
||||
}
|
||||
res = icsneo_device_transmit_messages(device, &message, &message_count);
|
||||
res += icsneo_can_message_free(device, message);
|
||||
if (res != icsneo_error_success) {
|
||||
return print_error_code("Failed to transmit messages", res);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
return icsneo_error_success;
|
||||
}
|
||||
|
|
@ -0,0 +1,2 @@
|
|||
add_executable(libicsneo-simple-example src/main.c)
|
||||
target_link_libraries(libicsneo-simple-example icsneoc2)
|
||||
|
|
@ -0,0 +1,454 @@
|
|||
#include <icsneo/icsneoc2.h>
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
#include <windows.h>
|
||||
#else
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
||||
|
||||
/**
|
||||
* @brief Sleeps for a specified number of milliseconds.
|
||||
*
|
||||
* Sleeps for a specified number of milliseconds using Sleep() on Windows and sleep() on *nix.
|
||||
*
|
||||
* @param ms The number of milliseconds to sleep.
|
||||
*/
|
||||
void sleep_ms(uint32_t ms) {
|
||||
#if defined(_WIN32) || defined(_WIN64)
|
||||
Sleep(ms);
|
||||
#else
|
||||
sleep(ms / 1000);
|
||||
#endif
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Prints an error message with the given string and error code.
|
||||
*
|
||||
* If the error code is not icsneoc2_error_success, prints the error string for the given error code
|
||||
* and returns the error code.
|
||||
*
|
||||
* @param message The message to print.
|
||||
* @param error The error code to print.
|
||||
* @return error as int
|
||||
*/
|
||||
int print_error_code(const char* message, icsneoc2_error_t error) {
|
||||
char error_str[256] = {0};
|
||||
uint32_t error_length = 256;
|
||||
icsneoc2_error_t res = icsneoc2_error_code_get(error, error_str, &error_length);
|
||||
if (res != icsneoc2_error_success) {
|
||||
printf("%s: Failed to get string for error code %d with error code %d\n", message, error, res);
|
||||
return res;
|
||||
}
|
||||
printf("%s: \"%s\" (%u)\n", message, error_str, error);
|
||||
return (int)error;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Processes a list of messages from a device.
|
||||
*
|
||||
* This function iterates over a given array of messages received from a specified device.
|
||||
* For each message in the array, it retrieves and prints the message type and bus type.
|
||||
* If an error occurs while retrieving these details, an error message is printed.
|
||||
*
|
||||
* @param device A pointer to the icsneoc2_device_t structure representing the device.
|
||||
* @param messages An array of pointers to icsneoc2_message_t structures containing the messages to process.
|
||||
* @param messages_count The number of messages in the messages array.
|
||||
*
|
||||
* @return An icsneoc2_error_t value indicating success or failure of the message processing.
|
||||
*/
|
||||
int process_messages(icsneoc2_device_t* device, icsneoc2_message_t** messages, uint32_t messages_count);
|
||||
|
||||
/**
|
||||
* @brief Prints device and global events for a given device.
|
||||
*
|
||||
* This function retrieves and prints all current events associated with the specified device,
|
||||
* as well as any global events not tied to a specific device. For each event, it retrieves
|
||||
* and prints a description. If retrieving events or their descriptions fails, an error
|
||||
* message is printed. The function also prints a summary of the count of device-specific
|
||||
* and global events processed.
|
||||
*
|
||||
* @param device A pointer to the icsneoc2_device_t structure representing the device to get events from.
|
||||
* @param device_description A description of the device used in the output.
|
||||
*/
|
||||
void print_device_events(icsneoc2_device_t* device, const char* device_description);
|
||||
|
||||
/**
|
||||
* @brief Transmits a series of CAN messages from a device.
|
||||
*
|
||||
* This function creates and transmits 100 CAN messages with incrementing payload data.
|
||||
* Each message is configured with specific attributes such as network ID, arbitration
|
||||
* ID, CANFD status, extended status, and baudrate switch. After successfully transmitting
|
||||
* each message, it is freed from memory.
|
||||
*
|
||||
* @param device A pointer to the icsneoc2_device_t structure representing the device to transmit messages from.
|
||||
*
|
||||
* @return An icsneoc2_error_t value indicating success or failure of the message transmission process.
|
||||
*/
|
||||
int transmit_can_messages(icsneoc2_device_t* device);
|
||||
|
||||
/**
|
||||
* @brief Get the RTC (Real time clock) of a device and print it.
|
||||
*
|
||||
* @param[in] device The device to get the RTC of.
|
||||
* @param[in] description A description of the device for printing purpose.
|
||||
*
|
||||
* @return icsneoc2_error_t icsneoc2_error_success if successful, icsneoc2_error_invalid_parameters otherwise.
|
||||
*/
|
||||
icsneoc2_error_t get_and_print_rtc(icsneoc2_device_t* device, const char* description);
|
||||
|
||||
int main(int argc, char* argv[]) {
|
||||
(void)argc;
|
||||
(void)argv;
|
||||
|
||||
icsneoc2_device_t* devices[255] = {0};
|
||||
uint32_t devices_count = 255;
|
||||
|
||||
printf("Finding devices...\n");
|
||||
icsneoc2_error_t res = icsneoc2_device_find_all(devices, &devices_count, NULL);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to find devices", res);
|
||||
};
|
||||
printf("OK, %u device%s found\n", devices_count, devices_count == 1 ? "" : "s");
|
||||
// List off the devices
|
||||
for (uint32_t i = 0; i < devices_count; i++) {
|
||||
icsneoc2_device_t* device = devices[i];
|
||||
// Get description of the device
|
||||
const char description[255] = {0};
|
||||
uint32_t description_length = 255;
|
||||
res = icsneoc2_device_description_get(device, description, &description_length);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get device description", res);
|
||||
};
|
||||
printf("%.*s @ Handle %p\n", description_length, description, device);
|
||||
// Get/Set open options
|
||||
icsneoc2_open_options_t options = icsneoc2_open_options_none;
|
||||
res = icsneoc2_device_open_options_get(device, &options);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get open options", res);
|
||||
}
|
||||
// Disable Syncing RTC and going online
|
||||
options &= ~icsneoc2_open_options_sync_rtc;
|
||||
options &= ~icsneoc2_open_options_go_online;
|
||||
printf("\tDevice open options: 0x%x\n", options);
|
||||
res = icsneoc2_device_open_options_set(device, options);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to set open options", res);
|
||||
}
|
||||
// Open the device
|
||||
printf("\tOpening device: %s...\n", description);
|
||||
res = icsneoc2_device_open(device);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to open device", res);
|
||||
};
|
||||
// Get timestamp resolution of the device
|
||||
printf("\tGetting timestamp resolution... ");
|
||||
uint32_t timestamp_resolution = 0;
|
||||
res = icsneoc2_device_timestamp_resolution_get(device, ×tamp_resolution);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get timestamp resolution", res);
|
||||
}
|
||||
printf("%uns\n", timestamp_resolution);
|
||||
// Get baudrates for HSCAN
|
||||
printf("\tGetting HSCAN Baudrate... ");
|
||||
uint64_t baudrate = 0;
|
||||
res = icsneoc2_device_baudrate_get(device, icsneoc2_netid_hscan, &baudrate);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get baudrate", res);
|
||||
};
|
||||
printf("%llumbit/s\n", baudrate);
|
||||
// Get FDbaudrates for HSCAN
|
||||
printf("\tGetting FD HSCAN Baudrate... ");
|
||||
uint64_t fd_baudrate = 0;
|
||||
res = icsneoc2_device_canfd_baudrate_get(device, icsneoc2_netid_hscan, &fd_baudrate);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get FD baudrate", res);
|
||||
};
|
||||
printf("%llumbit/s\n", fd_baudrate);
|
||||
// Set baudrates for HSCAN
|
||||
// save_to_device: If this is set to true, the baudrate will be saved on the device
|
||||
// and will persist through a power cycle
|
||||
bool save_to_device = false;
|
||||
printf("\tSetting HSCAN Baudrate... ");
|
||||
res = icsneoc2_device_baudrate_set(device, icsneoc2_netid_hscan, baudrate, save_to_device);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to set baudrate", res);
|
||||
};
|
||||
printf("Ok\n");
|
||||
// Set FDbaudrates for HSCAN
|
||||
printf("\tSetting FD HSCAN Baudrate... ");
|
||||
res = icsneoc2_device_canfd_baudrate_set(device, icsneoc2_netid_hscan, fd_baudrate, save_to_device);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to set FD baudrate", res);
|
||||
};
|
||||
printf("Ok\n");
|
||||
// Get RTC
|
||||
printf("\tGetting RTC... ");
|
||||
res = get_and_print_rtc(device, description);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get RTC", res);
|
||||
}
|
||||
// Set RTC
|
||||
printf("\tSetting RTC to current time... ");
|
||||
time_t current_time = time(NULL);
|
||||
res = icsneoc2_device_rtc_set(device, current_time);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to set RTC", res);
|
||||
}
|
||||
printf("Ok\n");
|
||||
// Get RTC
|
||||
printf("\tGetting RTC... ");
|
||||
res = get_and_print_rtc(device, description);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get RTC", res);
|
||||
}
|
||||
// Go online, start acking traffic
|
||||
printf("\tGoing online... ");
|
||||
res = icsneoc2_device_go_online(device, true);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to go online", res);
|
||||
}
|
||||
// Redundant check to show how to check if the device is online, if the previous
|
||||
// icsneoc2_device_go_online call was successful we can assume we are online already
|
||||
bool is_online = false;
|
||||
res = icsneoc2_device_is_online(device, &is_online);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to check if online", res);
|
||||
}
|
||||
printf("%s\n", is_online ? "Online" : "Offline");
|
||||
// Transmit CAN messages
|
||||
res = transmit_can_messages(device);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to transmit CAN messages", res);
|
||||
}
|
||||
// Wait for the bus to collect some messages, requires an active bus to get messages
|
||||
printf("\tWaiting 1 second for messages...\n");
|
||||
sleep_ms(1000);
|
||||
// Get the messages
|
||||
icsneoc2_message_t* messages[20000] = {0};
|
||||
uint32_t message_count = 20000;
|
||||
printf("\tGetting messages from device with timeout of 3000ms on %s...\n", description);
|
||||
res = icsneoc2_device_messages_get(device, messages, &message_count, 3000);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to get messages from device", res);
|
||||
};
|
||||
// Process the messages
|
||||
res = process_messages(device, messages, message_count);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to process messages", res);
|
||||
}
|
||||
// Finally, close the device.
|
||||
printf("\tClosing device: %s...\n", description);
|
||||
res = icsneoc2_device_close(device);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_device_events(device, description);
|
||||
return print_error_code("\tFailed to close device", res);
|
||||
};
|
||||
// Print device events
|
||||
print_device_events(device, description);
|
||||
|
||||
}
|
||||
printf("\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
icsneoc2_error_t get_and_print_rtc(icsneoc2_device_t* device, const char* description) {
|
||||
time_t unix_epoch = 0;
|
||||
icsneoc2_error_t res = icsneoc2_device_rtc_get(device, &unix_epoch);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return res;
|
||||
}
|
||||
char rtc_time[32] = {0};
|
||||
strftime(rtc_time, sizeof(rtc_time), "%Y-%m-%d %H:%M:%S", localtime(&unix_epoch));
|
||||
printf("RTC: %lld %s\n", unix_epoch, rtc_time);
|
||||
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
||||
void print_device_events(icsneoc2_device_t* device, const char* device_description) {
|
||||
// Get device events
|
||||
icsneoc2_event_t* events[1024] = {0};
|
||||
uint32_t events_count = 1024;
|
||||
icsneoc2_error_t res = icsneoc2_device_events_get(device, events, &events_count);
|
||||
if (res != icsneoc2_error_success) {
|
||||
(void)print_error_code("\tFailed to get device events", res);
|
||||
return;
|
||||
}
|
||||
// Loop over each event and describe it.
|
||||
for (uint32_t i = 0; i < events_count; i++) {
|
||||
const char event_description[255] = {0};
|
||||
uint32_t event_description_length = 255;
|
||||
res = icsneoc2_event_description_get(events[i], event_description, &event_description_length);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to get event description", res);
|
||||
continue;
|
||||
}
|
||||
printf("\t%s: Event %u: %s\n", device_description, i, event_description);
|
||||
}
|
||||
|
||||
// Get global events
|
||||
icsneoc2_event_t* global_events[1024] = {0};
|
||||
uint32_t global_events_count = 1024;
|
||||
res = icsneoc2_events_get(global_events, &global_events_count);
|
||||
if (res != icsneoc2_error_success) {
|
||||
(void)print_error_code("\tFailed to get global events", res);
|
||||
return;
|
||||
}
|
||||
// Loop over each event and describe it.
|
||||
for (uint32_t i = 0; i < global_events_count; i++) {
|
||||
const char event_description[255] = {0};
|
||||
uint32_t event_description_length = 255;
|
||||
res = icsneoc2_event_description_get(global_events[i], event_description, &event_description_length);
|
||||
if (res != icsneoc2_error_success) {
|
||||
print_error_code("\tFailed to get global event description", res);
|
||||
continue;
|
||||
}
|
||||
printf("\t%s: Global Event %u: %s\n", device_description, i, event_description);
|
||||
}
|
||||
printf("\t%s: Received %u events and %u global events\n", device_description, events_count, global_events_count);
|
||||
}
|
||||
|
||||
int process_messages(icsneoc2_device_t* device, icsneoc2_message_t** messages, uint32_t messages_count) {
|
||||
// Print the type and bus type of each message
|
||||
uint32_t tx_count = 0;
|
||||
for (uint32_t i = 0; i < messages_count; i++) {
|
||||
icsneoc2_message_t* message = messages[i];
|
||||
// Get the message type
|
||||
icsneoc2_msg_type_t msg_type = 0;
|
||||
icsneoc2_error_t res = icsneoc2_message_type_get(device, message, &msg_type);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to get message type", res);
|
||||
}
|
||||
// Get the message type name
|
||||
char msg_type_name[128] = {0};
|
||||
uint32_t msg_type_name_length = 128;
|
||||
res = icsneoc2_message_type_name_get(msg_type, msg_type_name, &msg_type_name_length);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to get message type name", res);
|
||||
}
|
||||
// Check if the message is a bus message, ignore otherwise
|
||||
if (msg_type != icsneoc2_msg_type_bus) {
|
||||
printf("Ignoring message type: %u (%s)\n", msg_type, msg_type_name);
|
||||
continue;
|
||||
}
|
||||
icsneoc2_msg_bus_type_t bus_type = 0;
|
||||
res = icsneoc2_message_bus_type_get(device, message, &bus_type);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to get message bus type", res);
|
||||
}
|
||||
const char bus_name[128] = {0};
|
||||
uint32_t bus_name_length = 128;
|
||||
res = icsneoc2_bus_type_name_get(bus_type, bus_name, &bus_name_length);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to get message bus type name", res);
|
||||
}
|
||||
bool is_tx = false;
|
||||
res = icsneoc2_message_is_transmit(device, message, &is_tx);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to get message is transmit", res);
|
||||
}
|
||||
if (is_tx) {
|
||||
tx_count++;
|
||||
continue;
|
||||
}
|
||||
|
||||
printf("\t%d) Message type: %u bus type: %s (%u)\n", i, msg_type, bus_name, bus_type);
|
||||
if (bus_type == icsneoc2_msg_bus_type_can) {
|
||||
uint32_t arbid = 0;
|
||||
int32_t dlc = 0;
|
||||
icsneoc2_netid_t netid = 0;
|
||||
bool is_remote = false;
|
||||
bool is_canfd = false;
|
||||
bool is_extended = false;
|
||||
uint8_t data[64] = {0};
|
||||
uint32_t data_length = 64;
|
||||
const char netid_name[128] = {0};
|
||||
uint32_t netid_name_length = 128;
|
||||
uint32_t result = icsneoc2_message_netid_get(device, message, &netid);
|
||||
result += icsneoc2_netid_name_get(netid, netid_name, &netid_name_length);
|
||||
result += icsneoc2_message_can_arbid_get(device, message, &arbid);
|
||||
result += icsneoc2_message_can_dlc_get(device, message, &dlc);
|
||||
result += icsneoc2_message_can_is_remote(device, message, &is_remote);
|
||||
result += icsneoc2_message_can_is_canfd(device, message, &is_canfd);
|
||||
result += icsneoc2_message_can_is_extended(device, message, &is_extended);
|
||||
result += icsneoc2_message_data_get(device, message, data, &data_length);
|
||||
if (result != icsneoc2_error_success) {
|
||||
printf("\tFailed get get CAN parameters (error: %u) for index %u\n", result, i);
|
||||
continue;
|
||||
}
|
||||
printf("\t NetID: %s (0x%x)\tArbID: 0x%x\t DLC: %u\t Remote: %d\t CANFD: %d\t Extended: %d\t Data length: %u\n", netid_name, netid, arbid, dlc, is_remote, is_canfd, is_extended, data_length);
|
||||
printf("\t Data: [");
|
||||
for (uint32_t x = 0; x < data_length; x++) {
|
||||
printf(" 0x%x", data[x]);
|
||||
}
|
||||
printf(" ]\n");
|
||||
}
|
||||
}
|
||||
printf("\tReceived %u messages total, %u were TX messages\n", messages_count, tx_count);
|
||||
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
||||
int transmit_can_messages(icsneoc2_device_t* device) {
|
||||
uint64_t counter = 0;
|
||||
const uint32_t msg_count = 100;
|
||||
printf("\tTransmitting %d messages...\n", msg_count);
|
||||
for (uint32_t i = 0; i < msg_count; i++) {
|
||||
// Create the message
|
||||
icsneoc2_message_t* message = NULL;
|
||||
uint32_t message_count = 1;
|
||||
icsneoc2_error_t res = icsneoc2_message_can_create(device, &message, message_count);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to create messages", res);
|
||||
}
|
||||
// Set the message attributes
|
||||
res = icsneoc2_message_netid_set(device, message, icsneoc2_netid_hscan);
|
||||
res += icsneoc2_message_can_arbid_set(device, message, 0x10);
|
||||
res += icsneoc2_message_can_canfd_set(device, message, true);
|
||||
res += icsneoc2_message_can_extended_set(device, message, true);
|
||||
res += icsneoc2_message_can_baudrate_switch_set(device, message, true);
|
||||
// Create the payload
|
||||
uint8_t data[8] = {0};
|
||||
data[0] = (uint8_t)(counter >> 56);
|
||||
data[1] = (uint8_t)(counter >> 48);
|
||||
data[2] = (uint8_t)(counter >> 40);
|
||||
data[3] = (uint8_t)(counter >> 32);
|
||||
data[4] = (uint8_t)(counter >> 24);
|
||||
data[5] = (uint8_t)(counter >> 16);
|
||||
data[6] = (uint8_t)(counter >> 8);
|
||||
data[7] = (uint8_t)(counter >> 0);
|
||||
res += icsneoc2_message_data_set(device, message, data, sizeof(data));
|
||||
res += icsneoc2_message_can_dlc_set(device, message, -1);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to modify message", res);
|
||||
}
|
||||
res = icsneoc2_device_messages_transmit(device, &message, &message_count);
|
||||
res += icsneoc2_message_can_free(device, message);
|
||||
if (res != icsneoc2_error_success) {
|
||||
return print_error_code("\tFailed to transmit messages", res);
|
||||
}
|
||||
counter++;
|
||||
}
|
||||
|
||||
return icsneoc2_error_success;
|
||||
}
|
||||
|
|
@ -1,5 +0,0 @@
|
|||
add_executable(libicsneoc-simple-lin-example lin/main.c)
|
||||
if(UNIX)
|
||||
target_link_libraries(libicsneoc-simple-lin-example ${CMAKE_DL_LIBS})
|
||||
endif()
|
||||
target_link_libraries(libicsneoc-simple-lin-example icsneoc)
|
||||
|
|
@ -79,7 +79,7 @@ void example0(const std::shared_ptr<icsneo::Device>& rada2b) {
|
|||
true /* true if we want 16 bit channels in the message, false for 32 bit. This should match the RAD-A2B device setting */
|
||||
);
|
||||
msg->txmsg = true;
|
||||
msg->network = icsneo::Network(_icsneo_netid_t::icsneo_netid_a2b2);
|
||||
msg->network = icsneo::Network(icsneo::Network::NetID::A2B2);
|
||||
|
||||
// Load the WAV audio data into the desired channel, break if we fail to load
|
||||
if(!msg->loadAudioBuffer(wavStream, channelMap)) {
|
||||
|
|
@ -192,7 +192,7 @@ void example3(const std::shared_ptr<icsneo::Device>& rada2b) {
|
|||
std::shared_ptr<icsneo::A2BMessage> a2bmsgPtr = std::make_shared<icsneo::A2BMessage>(numFrames, icsneo::A2BMessage::TDMMode::TDM4, true);
|
||||
|
||||
icsneo::A2BMessage& a2bmsg = *a2bmsgPtr.get();
|
||||
a2bmsg.network = icsneo::Network(_icsneo_netid_t::icsneo_netid_a2b2);
|
||||
a2bmsg.network = icsneo::Network(icsneo::Network::NetID::A2B2);
|
||||
a2bmsg.txmsg = true;
|
||||
|
||||
for(size_t frame = 0; frame < a2bmsg.getNumFrames(); frame++) {
|
||||
|
|
@ -245,9 +245,9 @@ void example3(const std::shared_ptr<icsneo::Device>& rada2b) {
|
|||
*/
|
||||
void example4(const std::shared_ptr<icsneo::Device>& rada2b) {
|
||||
std::shared_ptr<icsneo::I2CMessage> msg = std::make_shared<icsneo::I2CMessage>();
|
||||
std::shared_ptr<icsneo::MessageFilter> msgFilter = std::make_shared<icsneo::MessageFilter>(_icsneo_netid_t::icsneo_netid_i2c2);
|
||||
std::shared_ptr<icsneo::MessageFilter> msgFilter = std::make_shared<icsneo::MessageFilter>(icsneo::Network::NetID::I2C2);
|
||||
|
||||
msg->network = icsneo::Network(_icsneo_netid_t::icsneo_netid_i2c2);
|
||||
msg->network = icsneo::Network(icsneo::Network::NetID::I2C2);
|
||||
msg->controlBytes.resize(1);
|
||||
msg->controlBytes[0] = static_cast<uint8_t>(0x17u); // Register address for A2B INTTYPE
|
||||
msg->dataBytes.resize(1, 0);
|
||||
|
|
@ -261,7 +261,7 @@ void example4(const std::shared_ptr<icsneo::Device>& rada2b) {
|
|||
|
||||
if(newMsg->type == icsneo::Message::Type::BusMessage) {
|
||||
const auto& frame = std::dynamic_pointer_cast<icsneo::BusMessage>(newMsg);
|
||||
if(frame && frame->network.getNetID() == _icsneo_netid_t::icsneo_netid_i2c2) {
|
||||
if(frame && frame->network.getNetID() == icsneo::Network::NetID::I2C2) {
|
||||
const auto& i2cMessage = std::dynamic_pointer_cast<icsneo::I2CMessage>(frame);
|
||||
|
||||
if(!i2cMessage) {
|
||||
|
|
@ -392,11 +392,11 @@ int main(int argc, char** argv) {
|
|||
const auto& txNetworks = dev->getSupportedTXNetworks();
|
||||
const auto& rxNetworks = dev->getSupportedRXNetworks();
|
||||
|
||||
if(std::none_of(txNetworks.begin(), txNetworks.end(), [](const icsneo::Network& net) { return net.getType() == icsneo_msg_bus_type_a2b; })) {
|
||||
if(std::none_of(txNetworks.begin(), txNetworks.end(), [](const icsneo::Network& net) { return net.getType() == icsneo::Network::Type::A2B; })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if(std::none_of(rxNetworks.begin(), rxNetworks.end(), [](const icsneo::Network& net) { return net.getType() == icsneo_msg_bus_type_a2b; })) {
|
||||
if(std::none_of(rxNetworks.begin(), rxNetworks.end(), [](const icsneo::Network& net) { return net.getType() == icsneo::Network::Type::A2B; })) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -40,7 +40,7 @@ int main() {
|
|||
// Add your error handling here
|
||||
auto handler = device->addMessageCallback(std::make_shared<icsneo::MessageCallback>(filter, [](std::shared_ptr<icsneo::Message> message) {
|
||||
auto msg = std::static_pointer_cast<icsneo::AppErrorMessage>(message);
|
||||
if(_icsneo_netid_t::icsneo_netid_red_app_error == msg->network.getNetID()) {
|
||||
if(icsneo::Network::NetID::RED_App_Error == msg->network.getNetID()) {
|
||||
std::cout << std::endl << "App error reported:" << std::endl;
|
||||
std::cout << msg->getAppErrorString() << std::endl << std::endl;
|
||||
}
|
||||
|
|
@ -58,7 +58,7 @@ int main() {
|
|||
// Prepare a CAN message
|
||||
std::cout << std::endl << "Transmitting a CAN frame... ";
|
||||
auto txMessage = std::make_shared<icsneo::CANMessage>();
|
||||
txMessage->network = _icsneo_netid_t::icsneo_netid_hscan;
|
||||
txMessage->network = icsneo::Network::NetID::HSCAN;
|
||||
txMessage->arbid = 0x22;
|
||||
txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc});
|
||||
// The DLC will come from the length of the data vector
|
||||
|
|
|
|||
|
|
@ -185,10 +185,10 @@ std::shared_ptr<icsneo::Device> selectDevice(const std::vector<std::shared_ptr<i
|
|||
void printMessage(const std::shared_ptr<icsneo::Message>& message) {
|
||||
switch(message->type) {
|
||||
case icsneo::Message::Type::BusMessage: {
|
||||
// A message of type BusMessage is guaranteed to be a BusMessage, so we can static cast safely
|
||||
// A message of type Frame is guaranteed to be a Frame, so we can static cast safely
|
||||
auto frame = std::static_pointer_cast<icsneo::BusMessage>(message);
|
||||
switch(frame->network.getType()) {
|
||||
case icsneo_msg_bus_type_can: {
|
||||
case icsneo::Network::Type::CAN: {
|
||||
// A message of type CAN is guaranteed to be a CANMessage, so we can static cast safely
|
||||
auto canMessage = std::static_pointer_cast<icsneo::CANMessage>(message);
|
||||
|
||||
|
|
@ -214,10 +214,10 @@ void printMessage(const std::shared_ptr<icsneo::Message>& message) {
|
|||
std::cout << std::dec << '(' << canMessage->timestamp << " ns since 1/1/2007)\n";
|
||||
break;
|
||||
}
|
||||
case icsneo_msg_bus_type_ethernet: {
|
||||
case icsneo::Network::Type::Ethernet: {
|
||||
auto ethMessage = std::static_pointer_cast<icsneo::EthernetMessage>(message);
|
||||
|
||||
std::cout << "\t\t" << ethMessage->network << " BusMessage - " << std::dec
|
||||
std::cout << "\t\t" << ethMessage->network << " Frame - " << std::dec
|
||||
<< ethMessage->data.size() << " bytes on wire\n";
|
||||
std::cout << "\t\t Timestamped:\t"<< ethMessage->timestamp << " ns since 1/1/2007\n";
|
||||
|
||||
|
|
@ -235,7 +235,7 @@ void printMessage(const std::shared_ptr<icsneo::Message>& message) {
|
|||
std::cout << std::dec << std::endl;
|
||||
break;
|
||||
}
|
||||
case icsneo_msg_bus_type_iso9141: {
|
||||
case icsneo::Network::Type::ISO9141: {
|
||||
// Note that the default settings on some devices have ISO9141 disabled by default in favor of LIN
|
||||
// and that this example loads the device defaults at the very end.
|
||||
// A message of type ISO9414 is guaranteed to be an ISO9141Message, so we can static cast safely
|
||||
|
|
@ -267,7 +267,7 @@ void printMessage(const std::shared_ptr<icsneo::Message>& message) {
|
|||
} // end of icsneo::Message::Type::BusMessage
|
||||
case icsneo::Message::Type::CANErrorCount: {
|
||||
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
|
||||
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << cec->receiveErrorCount
|
||||
<< " TEC=" << cec->transmitErrorCount << " (" << (cec->busOff ? "" : "Not ") << "Bus Off)" << std::endl;
|
||||
break;
|
||||
|
|
@ -508,7 +508,7 @@ int main() {
|
|||
|
||||
std::cout << "Transmitting a normal CAN frame..." << std::endl;
|
||||
auto msg = std::make_shared<icsneo::CANMessage>();
|
||||
msg->network = _icsneo_netid_t::icsneo_netid_hscan;
|
||||
msg->network = icsneo::Network::NetID::HSCAN;
|
||||
msg->arbid = 0x120;
|
||||
msg->data.insert(msg->data.end(), {0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff});
|
||||
msg->isExtended = false;
|
||||
|
|
@ -525,7 +525,7 @@ int main() {
|
|||
/** Example of CAN FD
|
||||
std::cout << "Transmitting an extended CAN FD frame... " << std::endl;
|
||||
auto txMessage = std::make_shared<icsneo::CANMessage>();
|
||||
txMessage->network = icsneo_netid_hscan;
|
||||
txMessage->network = icsneo::Network::NetID::HSCAN;
|
||||
txMessage->arbid = 0x1C5001C5;
|
||||
txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc});
|
||||
// The DLC will come from the length of the data vector
|
||||
|
|
@ -565,7 +565,7 @@ int main() {
|
|||
selectedDevice = selectDevice(devices);
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(selectedDevice->settings->setBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan, 250000) && selectedDevice->settings->apply()) {
|
||||
if(selectedDevice->settings->setBaudrateFor(icsneo::Network::NetID::HSCAN, 250000) && selectedDevice->settings->apply()) {
|
||||
std::cout << "Successfully set HS CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed to set HS CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl << std::endl;
|
||||
|
|
@ -586,7 +586,7 @@ int main() {
|
|||
selectedDevice = selectDevice(devices);
|
||||
|
||||
// Attempt to set baudrate and apply settings
|
||||
if(selectedDevice->settings->setBaudrateFor(_icsneo_netid_t::icsneo_netid_lsftcan, 250000) && selectedDevice->settings->apply()) {
|
||||
if(selectedDevice->settings->setBaudrateFor(icsneo::Network::NetID::LSFTCAN, 250000) && selectedDevice->settings->apply()) {
|
||||
std::cout << "Successfully set LSFT CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed to set LSFT CAN baudrate for " << selectedDevice->describe() << " to 250k!" << std::endl << std::endl;
|
||||
|
|
@ -790,7 +790,7 @@ int main() {
|
|||
selectedDevice = selectDevice(devices);
|
||||
|
||||
std::cout << "Termination is ";
|
||||
const auto val = selectedDevice->settings->isTerminationEnabledFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
const auto val = selectedDevice->settings->isTerminationEnabledFor(icsneo::Network::NetID::HSCAN);
|
||||
if(!val.has_value()) {
|
||||
std::cout << "not available at this time: " << icsneo::GetLastError() << std::endl << std::endl;
|
||||
break;
|
||||
|
|
@ -807,7 +807,7 @@ int main() {
|
|||
}
|
||||
|
||||
// Attempt to set termination and apply settings
|
||||
if(selectedDevice->settings->setTerminationFor(_icsneo_netid_t::icsneo_netid_hscan, selection2 == '1') && selectedDevice->settings->apply()) {
|
||||
if(selectedDevice->settings->setTerminationFor(icsneo::Network::NetID::HSCAN, selection2 == '1') && selectedDevice->settings->apply()) {
|
||||
std::cout << "Successfully set HS CAN termination for " << selectedDevice->describe() << std::endl;
|
||||
} else {
|
||||
std::cout << "Failed to set HS CAN termination for " << selectedDevice->describe() << std::endl;
|
||||
|
|
|
|||
|
|
@ -33,27 +33,27 @@ int main() {
|
|||
int64_t baud = 19200;
|
||||
|
||||
std::cout << "Enable LIN commander resistor... ";
|
||||
ret = device->settings->setCommanderResistorFor(_icsneo_netid_t::icsneo_netid_lin, true);
|
||||
ret = device->settings->setCommanderResistorFor(icsneo::Network::NetID::LIN, true);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Disable LIN2 commander resistor... ";
|
||||
ret = device->settings->setCommanderResistorFor(_icsneo_netid_t::icsneo_netid_lin2, false);
|
||||
ret = device->settings->setCommanderResistorFor(icsneo::Network::NetID::LIN2, false);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN to operate at " << baud << "bit/s... ";
|
||||
ret = device->settings->setBaudrateFor(_icsneo_netid_t::icsneo_netid_lin, baud);
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::LIN, baud);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN2 to operate at " << baud << "bit/s... ";
|
||||
ret = device->settings->setBaudrateFor(_icsneo_netid_t::icsneo_netid_lin2, baud);
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::LIN2, baud);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN mode to NORMAL... ";
|
||||
ret = device->settings->setLINModeFor(_icsneo_netid_t::icsneo_netid_lin, NORMAL_MODE);
|
||||
ret = device->settings->setLINModeFor(icsneo::Network::NetID::LIN, NORMAL_MODE);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Setting LIN2 mode to NORMAL... ";
|
||||
ret = device->settings->setLINModeFor(_icsneo_netid_t::icsneo_netid_lin2, NORMAL_MODE);
|
||||
ret = device->settings->setLINModeFor(icsneo::Network::NetID::LIN2, NORMAL_MODE);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Applying settings... ";
|
||||
|
|
@ -61,14 +61,14 @@ int main() {
|
|||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "Getting LIN Baudrate... ";
|
||||
int64_t readBaud = device->settings->getBaudrateFor(_icsneo_netid_t::icsneo_netid_lin);
|
||||
int64_t readBaud = device->settings->getBaudrateFor(icsneo::Network::NetID::LIN);
|
||||
if(readBaud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
std::cout << "OK, " << (readBaud) << "bit/s" << std::endl;
|
||||
|
||||
std::cout << "Getting LIN2 Baudrate... ";
|
||||
readBaud = device->settings->getBaudrateFor(_icsneo_netid_t::icsneo_netid_lin2);
|
||||
readBaud = device->settings->getBaudrateFor(icsneo::Network::NetID::LIN2);
|
||||
if(readBaud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
|
|
@ -98,7 +98,7 @@ int main() {
|
|||
auto handler = device->addMessageCallback(std::make_shared<icsneo::MessageCallback>([&](std::shared_ptr<icsneo::Message> message) {
|
||||
if(icsneo::Message::Type::BusMessage == message->type) {
|
||||
auto frame = std::static_pointer_cast<icsneo::BusMessage>(message);
|
||||
if(icsneo_msg_bus_type_lin == frame->network.getType()) {
|
||||
if(icsneo::Network::Type::LIN == frame->network.getType()) {
|
||||
auto msg = std::static_pointer_cast<icsneo::LINMessage>(message);
|
||||
std::cout << msg->network << " RX frame | ID: 0x" << std::hex << static_cast<int>(msg->ID) << " | ";
|
||||
std::cout << "Protected ID: 0x" << static_cast<int>(msg->protectedID) << "\n" << "Data: ";
|
||||
|
|
@ -115,7 +115,7 @@ int main() {
|
|||
// We can transmit messages
|
||||
std::cout << "Transmitting a LIN responder data frame... ";
|
||||
auto lin_r = std::make_shared<icsneo::LINMessage>();
|
||||
lin_r->network = _icsneo_netid_t::icsneo_netid_lin2;
|
||||
lin_r->network = icsneo::Network::NetID::LIN2;
|
||||
lin_r->ID = 0x11;
|
||||
lin_r->linMsgType = icsneo::LINMessage::Type::LIN_UPDATE_RESPONDER;
|
||||
lin_r->data = {0xaa, 0xbb, 0xcc, 0xdd, 0x11, 0x22, 0x33, 0x44};
|
||||
|
|
@ -124,7 +124,7 @@ int main() {
|
|||
|
||||
std::cout << "Transmitting a LIN commander header... ";
|
||||
auto lin_c = std::make_shared<icsneo::LINMessage>();
|
||||
lin_c->network = _icsneo_netid_t::icsneo_netid_lin;
|
||||
lin_c->network = icsneo::Network::NetID::LIN;
|
||||
lin_c->ID = 0x11;
|
||||
lin_c->linMsgType = icsneo::LINMessage::Type::LIN_HEADER_ONLY;
|
||||
ret = device->transmit(lin_c);
|
||||
|
|
@ -134,7 +134,7 @@ int main() {
|
|||
|
||||
std::cout << "Transmitting a LIN commander frame with responder data... ";
|
||||
auto lin_d = std::make_shared<icsneo::LINMessage>();
|
||||
lin_d->network = _icsneo_netid_t::icsneo_netid_lin;
|
||||
lin_d->network = icsneo::Network::NetID::LIN;
|
||||
lin_d->ID = 0x22;
|
||||
lin_d->isEnhancedChecksum = true;
|
||||
lin_d->linMsgType = icsneo::LINMessage::Type::LIN_COMMANDER_MSG;
|
||||
|
|
|
|||
|
|
@ -94,7 +94,7 @@ int main()
|
|||
{
|
||||
if(icsneo::Message::Type::BusMessage == message->type) {
|
||||
auto frame = std::static_pointer_cast<icsneo::BusMessage>(message);
|
||||
if(icsneo_msg_bus_type_mdio == frame->network.getType()) {
|
||||
if(icsneo::Network::Type::MDIO == frame->network.getType()) {
|
||||
auto msg = std::static_pointer_cast<icsneo::MDIOMessage>(message);
|
||||
std::cout << msg->network << " " << ((msg->isTXMsg)? "TX" : "RX") << " frame\n";
|
||||
std::cout << "Clause: " << ((msg->clause == icsneo::MDIOMessage::Clause::Clause22) ? "22" : "45") << "\n";
|
||||
|
|
@ -117,7 +117,7 @@ int main()
|
|||
// We can transmit messages to read the PHY ID of BCM89810 PHY
|
||||
std::cout << "\tTransmitting a MDIO request to read ID on BCM89810...\n";
|
||||
auto mdio_r = std::make_shared<icsneo::MDIOMessage>();
|
||||
mdio_r->network = _icsneo_netid_t::icsneo_netid_mdio1;
|
||||
mdio_r->network = icsneo::Network::NetID::MDIO1;
|
||||
mdio_r->phyAddress = 0x00u;
|
||||
mdio_r->regAddress = 0x02u;
|
||||
mdio_r->direction = icsneo::MDIOMessage::Direction::Read;
|
||||
|
|
@ -128,7 +128,7 @@ int main()
|
|||
// We can transmit messages to write to arbitrary register
|
||||
std::cout << "\tTransmitting a MDIO request to write register on BCM89810...\n";
|
||||
mdio_r = std::make_shared<icsneo::MDIOMessage>();
|
||||
mdio_r->network = _icsneo_netid_t::icsneo_netid_mdio1;
|
||||
mdio_r->network = icsneo::Network::NetID::MDIO1;
|
||||
mdio_r->phyAddress = 0x00u;
|
||||
mdio_r->regAddress = 0x1Bu;
|
||||
mdio_r->data = {0xAA, 0xAF};
|
||||
|
|
@ -140,7 +140,7 @@ int main()
|
|||
// We can transmit messages to read back to arbitrary register
|
||||
std::cout << "\tTransmitting a MDIO request to read register on BCM89810...\n";
|
||||
mdio_r = std::make_shared<icsneo::MDIOMessage>();
|
||||
mdio_r->network = _icsneo_netid_t::icsneo_netid_mdio1;
|
||||
mdio_r->network = icsneo::Network::NetID::MDIO1;
|
||||
mdio_r->phyAddress = 0x00u;
|
||||
mdio_r->regAddress = 0x1Bu;
|
||||
mdio_r->direction = icsneo::MDIOMessage::Direction::Read;
|
||||
|
|
@ -154,7 +154,7 @@ int main()
|
|||
// We can transmit messages to read the PHY ID of BCM89810 PHY
|
||||
std::cout << "\tTransmitting a MDIO request to read ID on 88Q2112...\n";
|
||||
mdio_r = std::make_shared<icsneo::MDIOMessage>();
|
||||
mdio_r->network = _icsneo_netid_t::icsneo_netid_mdio1;
|
||||
mdio_r->network = icsneo::Network::NetID::MDIO1;
|
||||
mdio_r->phyAddress = 0x06u;
|
||||
mdio_r->devAddress = 0x01u;
|
||||
mdio_r->regAddress = 0x0002u;
|
||||
|
|
@ -166,7 +166,7 @@ int main()
|
|||
// We can transmit messages to write to arbitrary register
|
||||
std::cout << "\tTransmitting a MDIO request to write register on 88Q2112...\n";
|
||||
mdio_r = std::make_shared<icsneo::MDIOMessage>();
|
||||
mdio_r->network = _icsneo_netid_t::icsneo_netid_mdio1;
|
||||
mdio_r->network = icsneo::Network::NetID::MDIO1;
|
||||
mdio_r->phyAddress = 0x06u;
|
||||
mdio_r->devAddress = 0x01u;
|
||||
mdio_r->regAddress = 0x0902u;
|
||||
|
|
@ -179,7 +179,7 @@ int main()
|
|||
// We can transmit messages to read back to arbitrary register
|
||||
std::cout << "\tTransmitting a MDIO request to read register on 88Q2112...\n";
|
||||
mdio_r = std::make_shared<icsneo::MDIOMessage>();
|
||||
mdio_r->network = _icsneo_netid_t::icsneo_netid_mdio1;
|
||||
mdio_r->network = icsneo::Network::NetID::MDIO1;
|
||||
mdio_r->phyAddress = 0x06u;
|
||||
mdio_r->devAddress = 0x01u;
|
||||
mdio_r->regAddress = 0x0902u;
|
||||
|
|
|
|||
|
|
@ -15,7 +15,7 @@ int main() {
|
|||
|
||||
std::cout<< "Supported devices:" << std::endl;
|
||||
for(auto& dev : icsneo::GetSupportedDevices())
|
||||
std::cout << '\t' << dev.getProductName() << std::endl;
|
||||
std::cout << '\t' << dev.getGenericProductName() << std::endl;
|
||||
|
||||
std::cout << "\nFinding devices... " << std::flush;
|
||||
auto devices = icsneo::FindAllDevices(); // This is type std::vector<std::shared_ptr<icsneo::Device>>
|
||||
|
|
@ -38,38 +38,38 @@ int main() {
|
|||
std::cout << "OK" << std::endl;
|
||||
|
||||
std::cout << "\tGetting HSCAN Baudrate... ";
|
||||
int64_t baud = device->settings->getBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
int64_t baud = device->settings->getBaudrateFor(icsneo::Network::NetID::HSCAN);
|
||||
if(baud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
std::cout << "OK, " << (baud/1000) << "kbit/s" << std::endl;
|
||||
|
||||
std::cout << "\tSetting HSCAN to operate at 125kbit/s... ";
|
||||
ret = device->settings->setBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan, 125000);
|
||||
ret = device->settings->setBaudrateFor(icsneo::Network::NetID::HSCAN, 125000);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
// Changes to the settings do not take affect until you call settings->apply()!
|
||||
// When you get the baudrate here, you're reading what the device is currently operating on
|
||||
std::cout << "\tGetting HSCAN Baudrate... (expected to be unchanged) ";
|
||||
baud = device->settings->getBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
baud = device->settings->getBaudrateFor(icsneo::Network::NetID::HSCAN);
|
||||
if(baud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
std::cout << "OK, " << (baud/1000) << "kbit/s" << std::endl;
|
||||
|
||||
std::cout << "\tGetting HSCANFD Baudrate... ";
|
||||
baud = device->settings->getFDBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
baud = device->settings->getFDBaudrateFor(icsneo::Network::NetID::HSCAN);
|
||||
if(baud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
std::cout << "OK, " << (baud/1000) << "kbit/s" << std::endl;
|
||||
|
||||
std::cout << "\tSetting HSCANFD to operate at 8Mbit/s... ";
|
||||
ret = device->settings->setFDBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan, 8000000);
|
||||
ret = device->settings->setFDBaudrateFor(icsneo::Network::NetID::HSCAN, 8000000);
|
||||
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||
|
||||
std::cout << "\tGetting HSCANFD Baudrate... (expected to be unchanged) ";
|
||||
baud = device->settings->getFDBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
baud = device->settings->getFDBaudrateFor(icsneo::Network::NetID::HSCAN);
|
||||
if(baud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
|
|
@ -84,14 +84,14 @@ int main() {
|
|||
|
||||
// Now that we have applied, we expect that our operating baudrates have changed
|
||||
std::cout << "\tGetting HSCAN Baudrate... ";
|
||||
baud = device->settings->getBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
baud = device->settings->getBaudrateFor(icsneo::Network::NetID::HSCAN);
|
||||
if(baud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
std::cout << "OK, " << (baud/1000) << "kbit/s" << std::endl;
|
||||
|
||||
std::cout << "\tGetting HSCANFD Baudrate... ";
|
||||
baud = device->settings->getFDBaudrateFor(_icsneo_netid_t::icsneo_netid_hscan);
|
||||
baud = device->settings->getFDBaudrateFor(icsneo::Network::NetID::HSCAN);
|
||||
if(baud < 0)
|
||||
std::cout << "FAIL" << std::endl;
|
||||
else
|
||||
|
|
@ -155,7 +155,7 @@ int main() {
|
|||
// We can transmit messages
|
||||
std::cout << "\n\tTransmitting an extended CAN FD frame... ";
|
||||
auto txMessage5 = std::make_shared<icsneo::CANMessage>();
|
||||
txMessage5->network = _icsneo_netid_t::icsneo_netid_hscan;
|
||||
txMessage5->network = icsneo::Network::NetID::HSCAN;
|
||||
txMessage5->arbid = 0x1C5001C5;
|
||||
txMessage5->data.insert(txMessage5->data.end(), {0xaa, 0xbb, 0xcc});
|
||||
// The DLC will come from the length of the data vector
|
||||
|
|
@ -173,7 +173,7 @@ int main() {
|
|||
// A message of type BusMessage is guaranteed to be a BusMessage, so we can static cast safely
|
||||
auto frame = std::static_pointer_cast<icsneo::BusMessage>(message);
|
||||
switch(frame->network.getType()) {
|
||||
case icsneo_msg_bus_type_can: {
|
||||
case icsneo::Network::Type::CAN: {
|
||||
// A message of type CAN is guaranteed to be a CANMessage, so we can static cast safely
|
||||
auto canMessage = std::static_pointer_cast<icsneo::CANMessage>(message);
|
||||
|
||||
|
|
@ -199,7 +199,7 @@ int main() {
|
|||
std::cout << std::dec << '(' << canMessage->timestamp << " ns since 1/1/2007)\n";
|
||||
break;
|
||||
}
|
||||
case icsneo_msg_bus_type_ethernet: {
|
||||
case icsneo::Network::Type::Ethernet: {
|
||||
auto ethMessage = std::static_pointer_cast<icsneo::EthernetMessage>(message);
|
||||
|
||||
std::cout << "\t\t" << ethMessage->network << " BusMessage - " << std::dec
|
||||
|
|
@ -220,7 +220,7 @@ int main() {
|
|||
std::cout << std::dec << std::endl;
|
||||
break;
|
||||
}
|
||||
case icsneo_msg_bus_type_iso9141: {
|
||||
case icsneo::Network::Type::ISO9141: {
|
||||
// Note that the default settings on some devices have ISO9141 disabled by default in favor of LIN
|
||||
// and that this example loads the device defaults at the very end.
|
||||
// A message of type ISO9414 is guaranteed to be an ISO9141Message, so we can static cast safely
|
||||
|
|
@ -252,7 +252,7 @@ int main() {
|
|||
} // end of icsneo::Message::Type::BusMessage
|
||||
case icsneo::Message::Type::CANErrorCount: {
|
||||
// A message of type CANErrorCount is guaranteed to be a CANErrorCount, so we can static cast safely
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorCountMessage>(message);
|
||||
auto cec = std::static_pointer_cast<icsneo::CANErrorMessage>(message);
|
||||
|
||||
// Print the error counts
|
||||
std::cout << "\t\t" << cec->network << " error counts changed, REC=" << std::to_string(cec->receiveErrorCount)
|
||||
|
|
@ -290,7 +290,7 @@ int main() {
|
|||
// We can transmit messages
|
||||
std::cout << "\tTransmitting an extended CAN FD frame... ";
|
||||
auto txMessage = std::make_shared<icsneo::CANMessage>();
|
||||
txMessage->network = _icsneo_netid_t::icsneo_netid_hscan;
|
||||
txMessage->network = icsneo::Network::NetID::HSCAN;
|
||||
txMessage->arbid = 0x1C5001C5;
|
||||
txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc});
|
||||
// The DLC will come from the length of the data vector
|
||||
|
|
@ -301,7 +301,7 @@ int main() {
|
|||
|
||||
std::cout << "\tTransmitting an ethernet frame on OP (BR) Ethernet 2... ";
|
||||
auto ethTxMessage = std::make_shared<icsneo::EthernetMessage>();
|
||||
ethTxMessage->network = _icsneo_netid_t::icsneo_netid_op_ethernet2;
|
||||
ethTxMessage->network = icsneo::Network::NetID::OP_Ethernet2;
|
||||
ethTxMessage->data.insert(ethTxMessage->data.end(), {
|
||||
0x00, 0xFC, 0x70, 0x00, 0x01, 0x02, /* Destination MAC */
|
||||
0x00, 0xFC, 0x70, 0x00, 0x01, 0x01, /* Source MAC */
|
||||
|
|
|
|||
|
|
@ -36,7 +36,7 @@ std::vector<std::shared_ptr<icsneo::BusMessage>> constructRandomFrames(size_t fr
|
|||
// Short Ethernet
|
||||
{
|
||||
auto frame = std::make_shared<icsneo::EthernetMessage>();
|
||||
frame->network = _icsneo_netid_t::icsneo_netid_ethernet;
|
||||
frame->network = icsneo::Network::NetID::Ethernet;
|
||||
frames.push_back(frame);
|
||||
frame->data.resize(ShortEthSize);
|
||||
std::generate(frame->data.begin(), frame->data.end(), randByteGen);
|
||||
|
|
@ -46,7 +46,7 @@ std::vector<std::shared_ptr<icsneo::BusMessage>> constructRandomFrames(size_t fr
|
|||
// Long Ethernet
|
||||
{
|
||||
auto frame = std::make_shared<icsneo::EthernetMessage>();
|
||||
frame->network = _icsneo_netid_t::icsneo_netid_ethernet;
|
||||
frame->network = icsneo::Network::NetID::Ethernet;
|
||||
frames.push_back(frame);
|
||||
frame->data.resize(LongEthSize);
|
||||
std::generate(frame->data.begin(), frame->data.end(), randByteGen);
|
||||
|
|
@ -56,7 +56,7 @@ std::vector<std::shared_ptr<icsneo::BusMessage>> constructRandomFrames(size_t fr
|
|||
// Classic CAN
|
||||
{
|
||||
auto frame = std::make_shared<icsneo::CANMessage>();
|
||||
frame->network = _icsneo_netid_t::icsneo_netid_hscan2;
|
||||
frame->network = icsneo::Network::NetID::HSCAN2;
|
||||
frames.push_back(frame);
|
||||
frame->data.resize(ClassicCANSize);
|
||||
|
||||
|
|
@ -67,7 +67,7 @@ std::vector<std::shared_ptr<icsneo::BusMessage>> constructRandomFrames(size_t fr
|
|||
// CAN FD
|
||||
{
|
||||
auto frame = std::make_shared<icsneo::CANMessage>();
|
||||
frame->network = _icsneo_netid_t::icsneo_netid_hscan3;
|
||||
frame->network = icsneo::Network::NetID::HSCAN3;
|
||||
frames.push_back(frame);
|
||||
frame->data.resize(CANFDSize);
|
||||
std::generate(frame->data.begin(), frame->data.end(), randByteGen);
|
||||
|
|
@ -170,9 +170,9 @@ int main(int argc, char* argv[]) {
|
|||
return;
|
||||
}
|
||||
const auto frame = std::static_pointer_cast<icsneo::BusMessage>(msg);
|
||||
if(frame->network.getType() == icsneo_msg_bus_type_can) {
|
||||
if(frame->network.getType() == icsneo::Network::Type::CAN) {
|
||||
++canFrameCount;
|
||||
} else if(frame->network.getType() == icsneo_msg_bus_type_ethernet) {
|
||||
} else if(frame->network.getType() == icsneo::Network::Type::Ethernet) {
|
||||
++ethFrameCount;
|
||||
}
|
||||
}));
|
||||
|
|
|
|||
|
|
@ -0,0 +1,19 @@
|
|||
libicsneoc2 simple Go example
|
||||
====
|
||||
|
||||
This is a mirror of the icsneoc2 C simple example, written in Go.
|
||||
|
||||
Windows
|
||||
====
|
||||
|
||||
- Install [msys64](https://www.msys2.org/) with gcc (`pacman -S mingw-w64-ucrt-x86_64-gcc`)
|
||||
- Setup environment variables:
|
||||
- add `C:\msys64\ucrt64\bin` to `PATH`
|
||||
- Powershell: `$env:PATH += ";C:\msys64\ucrt64\bin"`
|
||||
- `gcc --version` should return a version now
|
||||
- enable cgo: `CGO_ENABLED = 1`
|
||||
- Powershell: `$env:CGO_ENABLED=1`
|
||||
- Set compiler to gcc
|
||||
- Powershell: `$env:CC="gcc"`
|
||||
- `icsneoc2.dll` should be in path (or inside this directory)
|
||||
- `go run simple`
|
||||
|
|
@ -0,0 +1,354 @@
|
|||
package main
|
||||
|
||||
// #cgo CFLAGS: -I../../../include
|
||||
// #cgo LDFLAGS: -L../../../build -licsneoc2
|
||||
// #include "icsneo/icsneoc2.h"
|
||||
// #include "stdint.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"time"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
// Find devices connected to host.
|
||||
devices := [255]*C.icsneoc2_device_t{nil}
|
||||
devicesCount := 255
|
||||
print("Finding devices... ")
|
||||
if res := C.icsneoc2_device_find_all(&devices[0], (*C.uint)(unsafe.Pointer(&devicesCount)), nil); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("OK, %d device(s) found\n", devicesCount)
|
||||
// List off the devices
|
||||
for _, device := range devices[:devicesCount] {
|
||||
// Get description of the device
|
||||
description := make([]byte, 255)
|
||||
descriptionLength := 255
|
||||
if res := C.icsneoc2_device_description_get(device, (*C.char)(unsafe.Pointer(&description[0])), (*C.uint)(unsafe.Pointer(&descriptionLength))); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("%s @ Handle %p\n", description, device)
|
||||
// Get/Set open options
|
||||
options := C.icsneoc2_open_options_none
|
||||
if res := C.icsneoc2_device_open_options_get(device, (*C.icsneoc2_open_options_t)(unsafe.Pointer(&options))); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
options &= ^C.icsneoc2_open_options_sync_rtc
|
||||
options &= ^C.icsneoc2_open_options_go_online
|
||||
fmt.Printf("\tDevice open options: 0x%X\n", options)
|
||||
if res := C.icsneoc2_device_open_options_set(device, (C.icsneoc2_open_options_t)(options)); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
// Open the device
|
||||
fmt.Printf("\tOpening device: %s...\n", description)
|
||||
if res := C.icsneoc2_device_open(device); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
defer func() {
|
||||
if !printDeviceEvents(device, string(description)) {
|
||||
println("\tFailed to print events...")
|
||||
}
|
||||
fmt.Printf("\tClosing device: %s...\n", description)
|
||||
if res := C.icsneoc2_device_close(device); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
}()
|
||||
// Get timestamp resolution of the device
|
||||
fmt.Printf("\tGetting timestamp resolution... ")
|
||||
var timestampResolution C.uint = 0
|
||||
if res := C.icsneoc2_device_timestamp_resolution_get(device, ×tampResolution); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%dns\n", timestampResolution)
|
||||
// Get baudrates for HSCAN
|
||||
fmt.Printf("\tGetting HSCAN Baudrate... ")
|
||||
var baudrate uint64 = 0
|
||||
if res := C.icsneoc2_device_baudrate_get(device, (C.icsneoc2_netid_t)(C.icsneoc2_netid_hscan), (*C.uint64_t)(unsafe.Pointer(&baudrate))); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%dmbit/s\n", baudrate)
|
||||
// Get FD baudrates for HSCAN
|
||||
fmt.Printf("\tGetting FD HSCAN Baudrate... ")
|
||||
var fdBaudrate uint64 = 0
|
||||
if res := C.icsneoc2_device_canfd_baudrate_get(device, (C.icsneoc2_netid_t)(C.icsneoc2_netid_hscan), (*C.uint64_t)(unsafe.Pointer(&fdBaudrate))); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("%dmbit/s\n", fdBaudrate)
|
||||
// Set baudrates for HSCAN
|
||||
// saveToDevice: If this is set to true, the baudrate will be saved on the device
|
||||
// and will persist through a power cycle
|
||||
var saveToDevice C.bool = false
|
||||
fmt.Printf("\tSetting HSCAN Baudrate... ")
|
||||
if res := C.icsneoc2_device_baudrate_set(device, (C.icsneoc2_netid_t)(C.icsneoc2_netid_hscan), (C.uint64_t)(baudrate), saveToDevice); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("OK\n")
|
||||
// Set FD baudrates for HSCAN
|
||||
fmt.Printf("\tSetting FD HSCAN Baudrate... ")
|
||||
if res := C.icsneoc2_device_canfd_baudrate_set(device, (C.icsneoc2_netid_t)(C.icsneoc2_netid_hscan), (C.uint64_t)(fdBaudrate), saveToDevice); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("OK\n")
|
||||
// Get RTC
|
||||
fmt.Printf("\tGetting RTC... ")
|
||||
var unix_epoch C.int64_t = 0
|
||||
if res := C.icsneoc2_device_rtc_get(device, (*C.int64_t)(unsafe.Pointer(&unix_epoch))); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
currentRTC := time.Unix(int64(unix_epoch), 0)
|
||||
fmt.Printf("%d %s\n", currentRTC.Unix(), currentRTC)
|
||||
// Set RTC
|
||||
fmt.Printf("\tSetting RTC... ")
|
||||
unix_epoch = (C.int64_t)(time.Now().Unix())
|
||||
if res := C.icsneoc2_device_rtc_set(device, unix_epoch); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
fmt.Printf("OK\n")
|
||||
// Get RTC
|
||||
fmt.Printf("\tGetting RTC... ")
|
||||
if res := C.icsneoc2_device_rtc_get(device, (*C.int64_t)(unsafe.Pointer(&unix_epoch))); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
currentRTC = time.Unix(int64(unix_epoch), 0)
|
||||
fmt.Printf("%d %s\n", currentRTC.Unix(), currentRTC)
|
||||
// Go online, start acking traffic
|
||||
fmt.Printf("\tGoing online... ")
|
||||
if res := C.icsneoc2_device_go_online(device, true); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
// Redundant check to show how to check if the device is online, if the previous
|
||||
// icsneoc2_device_go_online call was successful we can assume we are online already
|
||||
var isOnline C.bool = false
|
||||
if res := C.icsneoc2_device_is_online(device, &isOnline); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
if isOnline {
|
||||
println("Online")
|
||||
} else {
|
||||
println("Offline")
|
||||
}
|
||||
// Transmit CAN messages
|
||||
if !transmitCANMessages(device) {
|
||||
return
|
||||
}
|
||||
// Wait for the bus to collect some messages, requires an active bus to get messages
|
||||
println("\tWaiting 1 second for messages...")
|
||||
time.Sleep(1 * time.Second)
|
||||
// Get the messages
|
||||
messages := [20000]*C.icsneoc2_message_t{nil}
|
||||
var messagesCount C.uint32_t = 20000
|
||||
if res := C.icsneoc2_device_messages_get(device, &messages[0], &messagesCount, 3000); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
// Process the messages
|
||||
if !processMessages(device, messages[0:messagesCount]) {
|
||||
return
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func printError(err C.icsneoc2_error_t) C.icsneoc2_error_t {
|
||||
buffer := make([]byte, 255)
|
||||
bufferLength := 255
|
||||
res := C.icsneoc2_error_code_get(err, (*C.char)(unsafe.Pointer(&buffer[0])), (*C.uint)(unsafe.Pointer(&bufferLength)))
|
||||
if res != C.icsneoc2_error_success {
|
||||
println("\ticsneoc2_get_error_code failed, original error:", err)
|
||||
return res
|
||||
}
|
||||
println("\tError:", string(buffer[:bufferLength]))
|
||||
return res
|
||||
}
|
||||
|
||||
func printDeviceEvents(device *C.icsneoc2_device_t, deviceDescription string) bool {
|
||||
// Get device events
|
||||
events := [1024]*C.icsneoc2_event_t{nil}
|
||||
var eventsCount C.uint32_t = 1024
|
||||
if res := C.icsneoc2_device_events_get(device, &events[0], &eventsCount); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
for i, event := range events[:eventsCount] {
|
||||
eventDescription := make([]byte, 255)
|
||||
var eventDescriptionLength C.uint32_t = 255
|
||||
if res := C.icsneoc2_event_description_get(event, (*C.char)(unsafe.Pointer(&eventDescription[0])), &eventDescriptionLength); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("\t%s: Event %d: %s\n", deviceDescription, i, eventDescription)
|
||||
}
|
||||
// Get global events
|
||||
globalEvents := [1024]*C.icsneoc2_event_t{nil}
|
||||
var globalEventsCount C.uint32_t = 1024
|
||||
if res := C.icsneoc2_events_get(&globalEvents[0], &globalEventsCount); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
for i, event := range globalEvents[:globalEventsCount] {
|
||||
globalEventsDescription := make([]byte, 255)
|
||||
var globalEventsDescriptionLength C.uint32_t = 255
|
||||
if res := C.icsneoc2_event_description_get(event, (*C.char)(unsafe.Pointer(&globalEventsDescription[0])), &globalEventsDescriptionLength); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("\t%s: Global Event %d: %s\n", deviceDescription, i, globalEventsDescription)
|
||||
}
|
||||
fmt.Printf("\t%s: Received %d events and %d global events\n", deviceDescription, eventsCount, globalEventsCount)
|
||||
|
||||
return true
|
||||
}
|
||||
|
||||
func transmitCANMessages(device *C.icsneoc2_device_t) bool {
|
||||
var counter uint32 = 0
|
||||
const msgCount int = 100
|
||||
fmt.Printf("\tTransmitting %d messages...\n", msgCount)
|
||||
for range msgCount {
|
||||
// Create the message
|
||||
var message *C.icsneoc2_message_t = nil
|
||||
if res := C.icsneoc2_message_can_create(device, &message, 1); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
defer func() {
|
||||
if res := C.icsneoc2_message_can_free(device, message); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
}
|
||||
}()
|
||||
// Set the message attributes
|
||||
res := C.icsneoc2_message_netid_set(device, message, C.icsneoc2_netid_hscan)
|
||||
res += C.icsneoc2_message_can_arbid_set(device, message, 0x10)
|
||||
res += C.icsneoc2_message_can_canfd_set(device, message, true)
|
||||
res += C.icsneoc2_message_can_extended_set(device, message, true)
|
||||
res += C.icsneoc2_message_can_baudrate_switch_set(device, message, true)
|
||||
// Create the payload
|
||||
data := [...]C.uint8_t{
|
||||
(C.uint8_t)(counter >> 56),
|
||||
(C.uint8_t)(counter >> 48),
|
||||
(C.uint8_t)(counter >> 40),
|
||||
(C.uint8_t)(counter >> 32),
|
||||
(C.uint8_t)(counter >> 24),
|
||||
(C.uint8_t)(counter >> 16),
|
||||
(C.uint8_t)(counter >> 8),
|
||||
(C.uint8_t)(counter >> 0),
|
||||
}
|
||||
res += C.icsneoc2_message_data_set(device, message, &data[0], (C.uint32_t)(len(data)))
|
||||
res += C.icsneoc2_message_can_dlc_set(device, message, -1)
|
||||
if res != C.icsneoc2_error_success {
|
||||
fmt.Printf("\tFailed to modify message: %d\n", res)
|
||||
return false
|
||||
}
|
||||
var messageCount C.uint32_t = 1
|
||||
if res := C.icsneoc2_device_messages_transmit(device, &message, &messageCount); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
counter += 1
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
func processMessages(device *C.icsneoc2_device_t, messages []*C.icsneoc2_message_t) bool {
|
||||
txCount := 0
|
||||
for i, message := range messages {
|
||||
// Get the message type
|
||||
var msgType C.icsneoc2_msg_type_t = 0
|
||||
if res := C.icsneoc2_message_type_get(device, message, &msgType); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
// Get the message type name
|
||||
msgTypeName := make([]byte, 128)
|
||||
var msgTypeNameLength C.uint32_t = 128
|
||||
if res := C.icsneoc2_message_type_name_get(msgType, (*C.char)(unsafe.Pointer(&msgTypeName[0])), &msgTypeNameLength); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
// Check if the message is a bus message, ignore otherwise
|
||||
if msgType != C.icsneoc2_msg_type_bus {
|
||||
fmt.Print("\tIgnoring message type: %d (%s)\n", msgType, msgTypeName)
|
||||
continue
|
||||
}
|
||||
// Get the message bus type
|
||||
var msgBusType C.icsneoc2_msg_bus_type_t = 0
|
||||
if res := C.icsneoc2_message_bus_type_get(device, message, &msgBusType); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
// Get the bus message type name
|
||||
msgBusTypeName := make([]byte, 128)
|
||||
var msgBusTypeNameLength C.uint32_t = 128
|
||||
if res := C.icsneoc2_bus_type_name_get(msgBusType, (*C.char)(unsafe.Pointer(&msgBusTypeName[0])), &msgBusTypeNameLength); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
// Check if the message is a transmit message
|
||||
var isTransmit C.bool = false
|
||||
if res := C.icsneoc2_message_is_transmit(device, message, &isTransmit); res != C.icsneoc2_error_success {
|
||||
printError(res)
|
||||
return false
|
||||
}
|
||||
if isTransmit {
|
||||
txCount += 1
|
||||
continue
|
||||
}
|
||||
fmt.Printf("\t%d) Message type: %d bus type: %s (%d)\n", i, msgType, msgBusTypeName, msgBusType)
|
||||
if msgBusType == C.icsneoc2_msg_bus_type_can {
|
||||
var arbid C.uint32_t = 0
|
||||
var dlc C.int32_t = 0
|
||||
var netid C.icsneoc2_netid_t = 0
|
||||
var isRemote C.bool = false
|
||||
var isCanfd C.bool = false
|
||||
var isExtended C.bool = false
|
||||
data := make([]byte, 64)
|
||||
var dataLength C.uint32_t = 64
|
||||
netidName := make([]byte, 128)
|
||||
var netidNameLength C.uint32_t = 128
|
||||
var res C.icsneoc2_error_t = C.icsneoc2_error_success
|
||||
res = C.icsneoc2_message_netid_get(device, message, &netid)
|
||||
res += C.icsneoc2_netid_name_get(netid, (*C.char)(unsafe.Pointer(&netidName)), &netidNameLength)
|
||||
res += C.icsneoc2_message_can_arbid_get(device, message, &arbid)
|
||||
res += C.icsneoc2_message_can_dlc_get(device, message, &dlc)
|
||||
res += C.icsneoc2_message_can_is_remote(device, message, &isRemote)
|
||||
res += C.icsneoc2_message_can_is_canfd(device, message, &isCanfd)
|
||||
res += C.icsneoc2_message_can_is_extended(device, message, &isExtended)
|
||||
res += C.icsneoc2_message_data_get(device, message, (*C.uint8_t)(unsafe.Pointer(&data[0])), &dataLength)
|
||||
// We really should check the error message for all of these since we can't tell the exact error if something
|
||||
// bad happens but for an example this should be okay.
|
||||
if res != C.icsneoc2_error_success {
|
||||
fmt.Printf("\tFailed to get CAN parameters (error: %d) for index %d\n", res, i)
|
||||
continue
|
||||
}
|
||||
// Finally lets print the RX message
|
||||
fmt.Printf("\t NetID: %s (0x%X)\tArbID: 0x%X\t DLC: %d\t Remote: %t\t CANFD: %t\t Extended: %t\t Data length: %d\n", netidName, netid, arbid, dlc, isRemote, isCanfd, isExtended, dataLength)
|
||||
fmt.Printf("\t Data: [")
|
||||
for _, d := range data[:dataLength] {
|
||||
fmt.Printf(" 0x%X", d)
|
||||
}
|
||||
println(" ]")
|
||||
continue
|
||||
} else {
|
||||
fmt.Printf("\tIgnoring bus message type: %d (%s)\n", msgBusType, msgBusTypeName)
|
||||
continue
|
||||
}
|
||||
|
||||
}
|
||||
fmt.Printf("\tReceived %d messages total, %d were TX messages\n", len(messages), txCount)
|
||||
return true
|
||||
}
|
||||
|
|
@ -1,49 +0,0 @@
|
|||
package main
|
||||
|
||||
// #cgo CFLAGS: -I../../../../include
|
||||
// #cgo LDFLAGS: -L../../../../build -licsneo -lstdc++
|
||||
// #include "icsneo/icsneo.h"
|
||||
import "C"
|
||||
import (
|
||||
"fmt"
|
||||
"unsafe"
|
||||
)
|
||||
|
||||
func main() {
|
||||
findDevices()
|
||||
}
|
||||
|
||||
func findDevices() {
|
||||
// Get all devices attached to host
|
||||
devices := [255]*C.icsneo_device_t{nil}
|
||||
devicesCount := 255
|
||||
res := C.icsneo_device_find_all(&devices[0], (*C.uint)(unsafe.Pointer(&devicesCount)), nil)
|
||||
if res != C.icsneo_error_success {
|
||||
printError(res)
|
||||
return
|
||||
}
|
||||
println("Found", devicesCount, "device(s):")
|
||||
// Iterate through all the devices
|
||||
for i, device := range devices[:devicesCount] {
|
||||
description := make([]byte, 255)
|
||||
descriptionLength := 255
|
||||
res := C.icsneo_device_get_description(device, (*C.char)(unsafe.Pointer(&description[0])), (*C.uint)(unsafe.Pointer(&descriptionLength)))
|
||||
if res != C.icsneo_error_success {
|
||||
printError(res)
|
||||
continue
|
||||
}
|
||||
fmt.Printf("\t%d. %s\n", i+1, string(description[:descriptionLength]))
|
||||
}
|
||||
}
|
||||
|
||||
func printError(err C.icsneo_error_t) C.icsneo_error_t {
|
||||
buffer := make([]byte, 255)
|
||||
bufferLength := 255
|
||||
res := C.icsneo_get_error_code(err, (*C.char)(unsafe.Pointer(&buffer[0])), (*C.uint)(unsafe.Pointer(&bufferLength)))
|
||||
if res != C.icsneo_error_success {
|
||||
println("icsneo_get_error_code failed, original error:", err)
|
||||
return res
|
||||
}
|
||||
println("Error:", string(buffer[:bufferLength]))
|
||||
return res
|
||||
}
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
const std = @import("std");
|
||||
const print = @import("std").debug.print;
|
||||
|
||||
const ics = @cImport({
|
||||
@cInclude("icsneo/icsneo.h");
|
||||
});
|
||||
|
||||
pub fn find_all() !void {
|
||||
// Find devices connected to host.
|
||||
const MAX_DEVICE_COUNT: u32 = 255;
|
||||
var device_buffer: [MAX_DEVICE_COUNT]?*ics.icsneo_device_t = undefined;
|
||||
var devices_count: u32 = MAX_DEVICE_COUNT;
|
||||
var res: ics.icsneo_error_t = ics.icsneo_device_find_all(&device_buffer, &devices_count, null);
|
||||
if (res != ics.icsneo_error_success) {
|
||||
print("Failed to find device(s) with error: {}\n", .{res});
|
||||
}
|
||||
// Lets just take a slice of the entire device buffer
|
||||
const devices = device_buffer[0..devices_count];
|
||||
print("Found {} devices!\n", .{devices.len});
|
||||
// Lets display all the devices we found.
|
||||
for (devices, 1..) |device, i| {
|
||||
var description: [128]u8 = [_:0]u8{'a'} ** 128;
|
||||
var description_length: u32 = 128;
|
||||
res = ics.icsneo_device_get_description(device, &description, &description_length);
|
||||
if (res != ics.icsneo_error_success) {
|
||||
print("Failed to find devices with error: {}\n", .{res});
|
||||
}
|
||||
print("\t{}. {s}\n", .{ i, description });
|
||||
}
|
||||
}
|
||||
|
||||
pub fn main() !void {
|
||||
try find_all();
|
||||
}
|
||||
|
|
@ -1,13 +0,0 @@
|
|||
//! By convention, root.zig is the root source file when making a library. If
|
||||
//! you are making an executable, the convention is to delete this file and
|
||||
//! start with main.zig instead.
|
||||
const std = @import("std");
|
||||
const testing = std.testing;
|
||||
|
||||
export fn add(a: i32, b: i32) i32 {
|
||||
return a + b;
|
||||
}
|
||||
|
||||
test "basic add functionality" {
|
||||
try testing.expect(add(3, 7) == 10);
|
||||
}
|
||||
|
|
@ -15,20 +15,6 @@ pub fn build(b: *std.Build) void {
|
|||
// set a preferred release mode, allowing the user to decide how to optimize.
|
||||
const optimize = b.standardOptimizeOption(.{});
|
||||
|
||||
const lib = b.addStaticLibrary(.{
|
||||
.name = "simple",
|
||||
// In this case the main source file is merely a path, however, in more
|
||||
// complicated build scripts, this could be a generated file.
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// This declares intent for the library to be installed into the standard
|
||||
// location when the user invokes the "install" step (the default step when
|
||||
// running `zig build`).
|
||||
b.installArtifact(lib);
|
||||
|
||||
const exe = b.addExecutable(.{
|
||||
.name = "simple",
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
|
|
@ -36,11 +22,11 @@ pub fn build(b: *std.Build) void {
|
|||
.optimize = optimize,
|
||||
});
|
||||
|
||||
// Add support for icsneo
|
||||
exe.linkLibC();
|
||||
exe.addIncludePath(b.path("../../../../include"));
|
||||
exe.addLibraryPath(b.path("../../../../build"));
|
||||
exe.linkSystemLibrary("icsneo");
|
||||
// Add support for icsneoc2
|
||||
exe.addIncludePath(b.path("../../../include"));
|
||||
exe.addLibraryPath(b.path("../../../build"));
|
||||
exe.linkSystemLibrary("icsneoc2");
|
||||
|
||||
// This declares intent for the executable to be installed into the
|
||||
// standard location when the user invokes the "install" step (the default
|
||||
|
|
@ -70,16 +56,6 @@ pub fn build(b: *std.Build) void {
|
|||
const run_step = b.step("run", "Run the app");
|
||||
run_step.dependOn(&run_cmd.step);
|
||||
|
||||
// Creates a step for unit testing. This only builds the test executable
|
||||
// but does not run it.
|
||||
const lib_unit_tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/root.zig"),
|
||||
.target = target,
|
||||
.optimize = optimize,
|
||||
});
|
||||
|
||||
const run_lib_unit_tests = b.addRunArtifact(lib_unit_tests);
|
||||
|
||||
const exe_unit_tests = b.addTest(.{
|
||||
.root_source_file = b.path("src/main.zig"),
|
||||
.target = target,
|
||||
|
|
@ -92,6 +68,5 @@ pub fn build(b: *std.Build) void {
|
|||
// the `zig build --help` menu, providing a way for the user to request
|
||||
// running the unit tests.
|
||||
const test_step = b.step("test", "Run unit tests");
|
||||
test_step.dependOn(&run_lib_unit_tests.step);
|
||||
test_step.dependOn(&run_exe_unit_tests.step);
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue