mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-09-20 16:08:37 +02:00
Compare commits
6
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
d017d26795 | ||
|
|
eb43465c2a | ||
|
|
4e0ed09d71 | ||
|
|
ea8e6e6316 | ||
|
|
bead22bc36 | ||
|
|
3aaccaad74 |
@@ -1,11 +1,8 @@
|
|||||||
_build/
|
|
||||||
build/
|
build/
|
||||||
build*/
|
build*/
|
||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
CMakeSettings.json
|
|
||||||
.vscode
|
.vscode
|
||||||
third-party/concurrentqueue/benchmarks
|
third-party/concurrentqueue/benchmarks
|
||||||
third-party/concurrentqueue/tests
|
third-party/concurrentqueue/tests
|
||||||
*.bak
|
*.bak
|
||||||
.vs
|
|
||||||
+84
-133
@@ -1,11 +1,5 @@
|
|||||||
cmake_minimum_required(VERSION 3.2)
|
cmake_minimum_required(VERSION 3.2)
|
||||||
project(libicsneo VERSION 0.2.0)
|
project(libicsneo VERSION 0.1.0)
|
||||||
|
|
||||||
option(LIBICSNEO_BUILD_TESTS "Build all tests." OFF)
|
|
||||||
option(LIBICSNEO_BUILD_DOCS "Build documentation. Don't use in Visual Studio." OFF)
|
|
||||||
option(LIBICSNEO_BUILD_ICSNEOC "Build dynamic C library" ON)
|
|
||||||
option(LIBICSNEO_BUILD_ICSNEOC_STATIC "Build static C library" ON)
|
|
||||||
option(LIBICSNEO_BUILD_ICSNEOLEGACY "Build icsnVC40 compatibility library" ON)
|
|
||||||
|
|
||||||
set(CMAKE_CXX_STANDARD 11)
|
set(CMAKE_CXX_STANDARD 11)
|
||||||
|
|
||||||
@@ -13,6 +7,11 @@ include(GNUInstallDirs)
|
|||||||
|
|
||||||
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
set(CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake")
|
||||||
|
|
||||||
|
# macOS Homebrew Boost Fix
|
||||||
|
if(NOT MSVC)
|
||||||
|
include_directories(AFTER /usr/local/include)
|
||||||
|
endif()
|
||||||
|
|
||||||
# Enable Warnings
|
# Enable Warnings
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# Force to always compile with W4
|
# Force to always compile with W4
|
||||||
@@ -22,65 +21,62 @@ if(MSVC)
|
|||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} /W4")
|
||||||
endif()
|
endif()
|
||||||
else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
else() #if(CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
|
||||||
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-switch -Wno-unknown-pragmas")
|
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wno-switch -Wno-nested-anon-types -Wno-gnu-anonymous-struct -Wno-unknown-pragmas -Wno-zero-length-array")
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# doxygen
|
# doxygen
|
||||||
find_package(Doxygen)
|
find_package(Doxygen)
|
||||||
if(DOXYGEN_FOUND)
|
if(DOXYGEN_FOUND)
|
||||||
set(DOXYGEN_OUT ${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile)
|
set(DOXYGEN_OUT ${CMAKE_CURRENT_SOURCE_DIR}/generated/Doxyfile)
|
||||||
set(ICSNEO_DOCS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs)
|
set(ICSNEO_DOCS_DIR ${CMAKE_CURRENT_SOURCE_DIR}/docs)
|
||||||
if(NOT EXISTS "${DOXYGEN_OUT}")
|
if(NOT EXISTS "${DOXYGEN_OUT}")
|
||||||
set(DOXYGEN_FOUND FALSE)
|
set(DOXYGEN_FOUND FALSE)
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
if(LIBICSNEO_BUILD_DOCS)
|
if(DOXYGEN_FOUND)
|
||||||
if(DOXYGEN_FOUND)
|
message("Will build Doxygen based documentation")
|
||||||
message("Will build Doxygen based documentation")
|
|
||||||
|
|
||||||
add_custom_target(libicsneo_doxygen ALL
|
add_custom_target(libicsneo_doxygen ALL
|
||||||
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXYGEN_OUT}
|
||||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
|
||||||
COMMENT "Generating API documentation with Doxygen"
|
COMMENT "Generating API documentation with Doxygen"
|
||||||
VERBATIM
|
VERBATIM
|
||||||
|
DEPENDS icsneocpp icsneoc icsneolegacy)
|
||||||
|
|
||||||
|
# sphinx
|
||||||
|
find_package(Sphinx)
|
||||||
|
if(SPHINX_EXECUTABLE)
|
||||||
|
message("Will build Sphinx based documentation")
|
||||||
|
|
||||||
|
set(SPHINX_OUT ${ICSNEO_DOCS_DIR}/build/sphinx)
|
||||||
|
|
||||||
|
# configured documentation tools and intermediate build results
|
||||||
|
set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/_build)
|
||||||
|
|
||||||
|
# Sphinx cache with pickled ReST documents
|
||||||
|
set(SPHINX_CACHE_DIR ${CMAKE_CURRENT_BINARY_DIR}/_doctrees)
|
||||||
|
|
||||||
|
# HTML output directory
|
||||||
|
set(SPHINX_HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx)
|
||||||
|
|
||||||
|
configure_file(
|
||||||
|
"${ICSNEO_DOCS_DIR}/conf.py.template"
|
||||||
|
"${ICSNEO_DOCS_DIR}/conf.py"
|
||||||
|
@ONLY)
|
||||||
|
|
||||||
|
add_custom_target(libicsneo_sphinx ALL
|
||||||
|
${SPHINX_EXECUTABLE}
|
||||||
|
-q -b html
|
||||||
|
-c "${ICSNEO_DOCS_DIR}"
|
||||||
|
-d "${SPHINX_CACHE_DIR}"
|
||||||
|
"${ICSNEO_DOCS_DIR}"
|
||||||
|
"${SPHINX_HTML_DIR}"
|
||||||
|
COMMENT "Building HTML documentation with Sphinx"
|
||||||
DEPENDS icsneocpp icsneoc icsneolegacy)
|
DEPENDS icsneocpp icsneoc icsneolegacy)
|
||||||
|
|
||||||
# sphinx
|
|
||||||
find_package(Sphinx)
|
|
||||||
if(SPHINX_EXECUTABLE)
|
|
||||||
message("Will build Sphinx based documentation")
|
|
||||||
|
|
||||||
set(SPHINX_OUT ${ICSNEO_DOCS_DIR}/build/sphinx)
|
|
||||||
|
|
||||||
# configured documentation tools and intermediate build results
|
|
||||||
set(SPHINX_BUILD_DIR ${CMAKE_CURRENT_BINARY_DIR}/_build)
|
|
||||||
|
|
||||||
# Sphinx cache with pickled ReST documents
|
|
||||||
set(SPHINX_CACHE_DIR ${CMAKE_CURRENT_BINARY_DIR}/_doctrees)
|
|
||||||
|
|
||||||
# HTML output directory
|
|
||||||
set(SPHINX_HTML_DIR ${CMAKE_CURRENT_BINARY_DIR}/doc_sphinx)
|
|
||||||
|
|
||||||
configure_file(
|
|
||||||
"${ICSNEO_DOCS_DIR}/conf.py.template"
|
|
||||||
"${ICSNEO_DOCS_DIR}/conf.py"
|
|
||||||
@ONLY)
|
|
||||||
|
|
||||||
add_custom_target(libicsneo_sphinx
|
|
||||||
${SPHINX_EXECUTABLE}
|
|
||||||
-q -b html
|
|
||||||
-c "${ICSNEO_DOCS_DIR}"
|
|
||||||
-d "${SPHINX_CACHE_DIR}"
|
|
||||||
"${ICSNEO_DOCS_DIR}"
|
|
||||||
"${SPHINX_HTML_DIR}"
|
|
||||||
COMMENT "Building HTML documentation with Sphinx"
|
|
||||||
DEPENDS icsneocpp icsneoc icsneolegacy)
|
|
||||||
endif()
|
|
||||||
endif()
|
endif()
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
|
||||||
if(WIN32)
|
if(WIN32)
|
||||||
file(GLOB PLATFORM_SRC_EXTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/platform/windows/*.cpp)
|
file(GLOB PLATFORM_SRC_EXTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/platform/windows/*.cpp)
|
||||||
file(GLOB PLATFORM_SRC_INTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/platform/windows/internal/*.cpp)
|
file(GLOB PLATFORM_SRC_INTERNAL ${CMAKE_CURRENT_SOURCE_DIR}/platform/windows/internal/*.cpp)
|
||||||
@@ -90,9 +86,7 @@ else()
|
|||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(COMMON_SRC
|
set(COMMON_SRC
|
||||||
communication/message/flexray/control/flexraycontrolmessage.cpp
|
|
||||||
communication/message/neomessage.cpp
|
communication/message/neomessage.cpp
|
||||||
communication/packet/flexraypacket.cpp
|
|
||||||
communication/packet/canpacket.cpp
|
communication/packet/canpacket.cpp
|
||||||
communication/packet/ethernetpacket.cpp
|
communication/packet/ethernetpacket.cpp
|
||||||
communication/decoder.cpp
|
communication/decoder.cpp
|
||||||
@@ -101,8 +95,6 @@ set(COMMON_SRC
|
|||||||
communication/multichannelcommunication.cpp
|
communication/multichannelcommunication.cpp
|
||||||
communication/communication.cpp
|
communication/communication.cpp
|
||||||
communication/icommunication.cpp
|
communication/icommunication.cpp
|
||||||
device/extensions/flexray/extension.cpp
|
|
||||||
device/extensions/flexray/controller.cpp
|
|
||||||
device/idevicesettings.cpp
|
device/idevicesettings.cpp
|
||||||
device/devicefinder.cpp
|
device/devicefinder.cpp
|
||||||
device/device.cpp
|
device/device.cpp
|
||||||
@@ -124,25 +116,13 @@ execute_process(
|
|||||||
ERROR_VARIABLE GIT_DESCRIBE
|
ERROR_VARIABLE GIT_DESCRIBE
|
||||||
OUTPUT_STRIP_TRAILING_WHITESPACE
|
OUTPUT_STRIP_TRAILING_WHITESPACE
|
||||||
)
|
)
|
||||||
if(${BUILD_METADATA})
|
|
||||||
set(BUILD_METADATA_PLUS +${BUILD_METADATA})
|
|
||||||
endif()
|
|
||||||
if(NOT ${GIT_BRANCH} STREQUAL "master")
|
|
||||||
set(BUILD_GIT_INFO "${GIT_BRANCH} @ ")
|
|
||||||
endif()
|
|
||||||
string(SUBSTRING GIT_DESCRIBE 0 1 GIT_DESCRIBE_FIRST)
|
|
||||||
if(NOT ${GIT_DESCRIBE_FIRST} STREQUAL "v")
|
|
||||||
string(APPEND BUILD_GIT_INFO "${GIT_DESCRIBE}")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
configure_file(api/icsneocpp/buildinfo.h.template ${CMAKE_CURRENT_BINARY_DIR}/generated/buildinfo.h)
|
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)
|
|
||||||
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR})
|
||||||
|
|
||||||
add_library(icsneocpp
|
add_library(icsneocpp
|
||||||
api/icsneocpp/icsneocpp.cpp
|
api/icsneocpp/icsneocpp.cpp
|
||||||
api/icsneocpp/event.cpp
|
api/icsneocpp/error.cpp
|
||||||
api/icsneocpp/eventmanager.cpp
|
api/icsneocpp/errormanager.cpp
|
||||||
api/icsneocpp/version.cpp
|
api/icsneocpp/version.cpp
|
||||||
${SRC_FILES}
|
${SRC_FILES}
|
||||||
)
|
)
|
||||||
@@ -154,7 +134,6 @@ target_include_directories(icsneocpp
|
|||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
)
|
)
|
||||||
set_property(TARGET icsneocpp PROPERTY POSITION_INDEPENDENT_CODE ON)
|
set_property(TARGET icsneocpp PROPERTY POSITION_INDEPENDENT_CODE ON)
|
||||||
target_compile_features(icsneocpp PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
|
||||||
|
|
||||||
# libftdi
|
# libftdi
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
@@ -175,48 +154,44 @@ if(WIN32)
|
|||||||
add_definitions(-DWPCAP -DHAVE_REMOTE -DWIN32_LEAN_AND_MEAN)
|
add_definitions(-DWPCAP -DHAVE_REMOTE -DWIN32_LEAN_AND_MEAN)
|
||||||
endif(WIN32)
|
endif(WIN32)
|
||||||
|
|
||||||
if(LIBICSNEO_BUILD_ICSNEOC)
|
add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp)
|
||||||
add_library(icsneoc SHARED api/icsneoc/icsneoc.cpp ${CMAKE_CURRENT_BINARY_DIR}/generated/icsneoc/version.rc)
|
target_include_directories(icsneoc
|
||||||
target_include_directories(icsneoc
|
PUBLIC
|
||||||
PUBLIC
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<INSTALL_INTERFACE:>
|
||||||
$<INSTALL_INTERFACE:>
|
PRIVATE
|
||||||
PRIVATE
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
)
|
||||||
)
|
target_link_libraries(icsneoc PRIVATE icsneocpp)
|
||||||
target_link_libraries(icsneoc PRIVATE icsneocpp)
|
|
||||||
target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(LIBICSNEO_BUILD_ICSNEOC_STATIC)
|
add_library(icsneoc-static STATIC api/icsneoc/icsneoc.cpp)
|
||||||
add_library(icsneoc-static STATIC api/icsneoc/icsneoc.cpp)
|
target_include_directories(icsneoc-static
|
||||||
target_include_directories(icsneoc-static
|
PUBLIC
|
||||||
PUBLIC
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<INSTALL_INTERFACE:>
|
||||||
$<INSTALL_INTERFACE:>
|
PRIVATE
|
||||||
PRIVATE
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
)
|
||||||
)
|
target_link_libraries(icsneoc-static PUBLIC icsneocpp)
|
||||||
target_link_libraries(icsneoc-static PUBLIC icsneocpp)
|
|
||||||
target_compile_features(icsneoc-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
if(LIBICSNEO_BUILD_ICSNEOLEGACY)
|
add_library(icsneolegacy SHARED
|
||||||
add_library(icsneolegacy SHARED
|
api/icsneolegacy/icsneolegacy.cpp
|
||||||
api/icsneolegacy/icsneolegacy.cpp
|
api/icsneolegacy/icsneolegacyextra.cpp
|
||||||
api/icsneolegacy/icsneolegacyextra.cpp
|
api/icsneoc/icsneoc.cpp
|
||||||
api/icsneoc/icsneoc.cpp
|
)
|
||||||
)
|
target_include_directories(icsneolegacy
|
||||||
target_include_directories(icsneolegacy
|
PUBLIC
|
||||||
PUBLIC
|
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
||||||
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
|
$<INSTALL_INTERFACE:>
|
||||||
$<INSTALL_INTERFACE:>
|
PRIVATE
|
||||||
PRIVATE
|
${CMAKE_CURRENT_SOURCE_DIR}/include
|
||||||
${CMAKE_CURRENT_SOURCE_DIR}/include
|
)
|
||||||
)
|
target_link_libraries(icsneolegacy PRIVATE icsneocpp)
|
||||||
target_link_libraries(icsneolegacy PRIVATE icsneocpp)
|
|
||||||
target_compile_features(icsneolegacy PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
target_compile_features(icsneocpp PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||||
endif()
|
target_compile_features(icsneoc PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||||
|
target_compile_features(icsneoc-static PUBLIC cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||||
|
target_compile_features(icsneolegacy PRIVATE cxx_auto_type cxx_constexpr cxx_lambdas cxx_nullptr cxx_range_for cxx_rvalue_references cxx_sizeof_member cxx_strong_enums)
|
||||||
|
|
||||||
# libftdi
|
# libftdi
|
||||||
if(NOT WIN32)
|
if(NOT WIN32)
|
||||||
@@ -228,30 +203,6 @@ if(NOT WIN32)
|
|||||||
target_link_libraries(icsneocpp PUBLIC ${PCAP_LIBRARY})
|
target_link_libraries(icsneocpp PUBLIC ${PCAP_LIBRARY})
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
# googletest
|
|
||||||
if(LIBICSNEO_BUILD_TESTS)
|
|
||||||
if(WIN32)
|
|
||||||
set(gtest_force_shared_crt ON CACHE BOOL "" FORCE)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_subdirectory(third-party/googletest-master)
|
|
||||||
|
|
||||||
if (CMAKE_VERSION VERSION_LESS 2.8.11)
|
|
||||||
include_directories("${gtest_SOURCE_DIR}/include")
|
|
||||||
endif()
|
|
||||||
|
|
||||||
add_executable(runTests test/main.cpp test/eventmanagertest.cpp)
|
|
||||||
|
|
||||||
target_link_libraries(runTests gtest gtest_main)
|
|
||||||
target_link_libraries(runTests icsneocpp)
|
|
||||||
|
|
||||||
target_include_directories(runTests PUBLIC ${gtest_SOURCE_DIR}/include ${gtest_SOURCE_DIR})
|
|
||||||
|
|
||||||
enable_testing()
|
|
||||||
|
|
||||||
add_test(NAME testSuite COMMAND runTests)
|
|
||||||
endif()
|
|
||||||
|
|
||||||
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
set(CPACK_PROJECT_NAME ${PROJECT_NAME})
|
||||||
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
set(CPACK_PROJECT_VERSION ${PROJECT_VERSION})
|
||||||
include(CPack)
|
include(CPack)
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
Copyright 2019-2020 Intrepid Control Systems, Inc.
|
Copyright 2018-2019 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,5 +1,5 @@
|
|||||||
# libicsneo
|
# libicsneo
|
||||||
### The Intrepid Control Systems Open Source Cross-Platform Device Communication API
|
### The Intrepid Control Systems Open Cross-Platform Device Communication API
|
||||||
|
|
||||||
An open source solution to integrate Intrepid Control Systems vehicle networking hardware with your application.
|
An open source solution to integrate Intrepid Control Systems vehicle networking hardware with your application.
|
||||||
|
|
||||||
@@ -38,10 +38,11 @@ std::cout << devices.size() << " found!" << std::endl;
|
|||||||
for(auto& device : devices)
|
for(auto& device : devices)
|
||||||
std::cout << "Found " << device->describe() << std::endl; // "Found neoVI FIRE 2 CY2345"
|
std::cout << "Found " << device->describe() << std::endl; // "Found neoVI FIRE 2 CY2345"
|
||||||
std::shared_ptr<icsneo::Device> myDevice = devices[0];
|
std::shared_ptr<icsneo::Device> myDevice = devices[0];
|
||||||
|
if(!myDevice->open()) {
|
||||||
if(!myDevice->open()) // Device tried and failed to open, print the last error
|
// There was an error while attempting to open the device, print the error details
|
||||||
std::cout << icsneo::GetLastError() << std::endl;
|
for(auto& error : icsneo::getErrors())
|
||||||
|
std::cout << error << std::endl;
|
||||||
|
}
|
||||||
myDevice->goOnline(); // Start receiving messages
|
myDevice->goOnline(); // Start receiving messages
|
||||||
myDevice->enableMessagePolling(); // Allow the use of myDevice->getMessages() later
|
myDevice->enableMessagePolling(); // Allow the use of myDevice->getMessages() later
|
||||||
// Alternatively, assign a callback for new messages
|
// Alternatively, assign a callback for new messages
|
||||||
@@ -87,7 +88,7 @@ for(size_t i = 0; i < deviceCount; i++) {
|
|||||||
|
|
||||||
neodevice_t* myDevice = &devices[0];
|
neodevice_t* myDevice = &devices[0];
|
||||||
if(!icsneo_openDevice(myDevice)) {
|
if(!icsneo_openDevice(myDevice)) {
|
||||||
neoevent_t error;
|
neoerror_t error;
|
||||||
if(icsneo_getLastError(&error))
|
if(icsneo_getLastError(&error))
|
||||||
printf("Error! %s\n", error.description);
|
printf("Error! %s\n", error.description);
|
||||||
}
|
}
|
||||||
@@ -112,7 +113,7 @@ icsneo_closeDevice(myDevice);
|
|||||||
|
|
||||||
## Building from Source
|
## Building from Source
|
||||||
### Windows
|
### Windows
|
||||||
Building will require Microsoft Visual Studio 2017+ and CMake to be installed.
|
Building will require Microsoft Visual Studio 2017 and CMake to be installed.
|
||||||
### macOS
|
### macOS
|
||||||
Getting the dependencies is easiest with the Homebrew package manager. You will also need XCode installed. You can then install CMake, an up-to-date version of GCC or Clang, and `libusb-1.0`.
|
Getting the dependencies is easiest with the Homebrew package manager. You will also need XCode installed. You can then install CMake, an up-to-date version of GCC or Clang, and `libusb-1.0`.
|
||||||
### Linux
|
### Linux
|
||||||
@@ -120,7 +121,6 @@ The dependencies are as follows
|
|||||||
- CMake 3.2 or above
|
- CMake 3.2 or above
|
||||||
- GCC 4.7 or above, 4.8+ recommended
|
- GCC 4.7 or above, 4.8+ recommended
|
||||||
- `libusb-1.0-0-dev`
|
- `libusb-1.0-0-dev`
|
||||||
- `libpcap0.8-dev`
|
|
||||||
- `build-essential` is recommended
|
- `build-essential` is recommended
|
||||||
|
|
||||||
If you'd like to be able to run programs that use this library without being root, consider using the included udev rules
|
If you'd like to be able to run programs that use this library without being root, consider using the included udev rules
|
||||||
|
|||||||
+142
-148
@@ -7,10 +7,9 @@
|
|||||||
#include "icsneo/icsneoc.h"
|
#include "icsneo/icsneoc.h"
|
||||||
#include "icsneo/icsneocpp.h"
|
#include "icsneo/icsneocpp.h"
|
||||||
#include "icsneo/platform/dynamiclib.h"
|
#include "icsneo/platform/dynamiclib.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
#include "icsneo/device/devicefinder.h"
|
#include "icsneo/device/devicefinder.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <functional>
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
@@ -29,7 +28,7 @@ void icsneo_findAllDevices(neodevice_t* devices, size_t* count) {
|
|||||||
std::vector<std::shared_ptr<Device>> foundDevices = icsneo::FindAllDevices();
|
std::vector<std::shared_ptr<Device>> foundDevices = icsneo::FindAllDevices();
|
||||||
|
|
||||||
if(count == nullptr) {
|
if(count == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -44,7 +43,7 @@ void icsneo_findAllDevices(neodevice_t* devices, size_t* count) {
|
|||||||
*count = foundDevices.size();
|
*count = foundDevices.size();
|
||||||
size_t outputSize = *count;
|
size_t outputSize = *count;
|
||||||
if(outputSize > inputSize) {
|
if(outputSize > inputSize) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
outputSize = inputSize;
|
outputSize = inputSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -61,7 +60,7 @@ void icsneo_freeUnconnectedDevices() {
|
|||||||
bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) {
|
bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) {
|
||||||
// TAG String copy function
|
// TAG String copy function
|
||||||
if(count == nullptr) {
|
if(count == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -74,7 +73,7 @@ bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) {
|
|||||||
|
|
||||||
if(*count < result.length()) {
|
if(*count < result.length()) {
|
||||||
*count = result.length() + 1; // This is how big of a buffer we need
|
*count = result.length() + 1; // This is how big of a buffer we need
|
||||||
EventManager::GetInstance().add(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::BufferInsufficient);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -88,11 +87,6 @@ uint32_t icsneo_serialStringToNum(const char* str) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_isValidNeoDevice(const neodevice_t* device) {
|
bool icsneo_isValidNeoDevice(const neodevice_t* device) {
|
||||||
// return false on nullptr
|
|
||||||
if(!device) {
|
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// If this neodevice_t was returned by a previous search, it will no longer be valid (as the underlying icsneo::Device is freed)
|
// If this neodevice_t was returned by a previous search, it will no longer be valid (as the underlying icsneo::Device is freed)
|
||||||
for(auto& dev : connectedDevices) {
|
for(auto& dev : connectedDevices) {
|
||||||
if(dev.get() == device->device)
|
if(dev.get() == device->device)
|
||||||
@@ -102,14 +96,14 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) {
|
|||||||
if(dev.get() == device->device)
|
if(dev.get() == device->device)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
EventManager::GetInstance().add(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_openDevice(const neodevice_t* device) {
|
bool icsneo_openDevice(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!device->device->open())
|
if(!device->device->open())
|
||||||
return false;
|
return false;
|
||||||
@@ -129,8 +123,10 @@ bool icsneo_openDevice(const neodevice_t* device) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_closeDevice(const neodevice_t* device) {
|
bool icsneo_closeDevice(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(!device->device->close())
|
if(!device->device->close())
|
||||||
return false;
|
return false;
|
||||||
@@ -147,61 +143,60 @@ bool icsneo_closeDevice(const neodevice_t* device) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_isOpen(const neodevice_t* device) {
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return device->device->isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_goOnline(const neodevice_t* device) {
|
bool icsneo_goOnline(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->goOnline();
|
return device->device->goOnline();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_goOffline(const neodevice_t* device) {
|
bool icsneo_goOffline(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->goOffline();
|
return device->device->goOffline();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_isOnline(const neodevice_t* device) {
|
bool icsneo_isOnline(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->isOnline();
|
return device->device->isOnline();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_enableMessagePolling(const neodevice_t* device) {
|
bool icsneo_enableMessagePolling(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->enableMessagePolling();
|
device->device->enableMessagePolling();
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_disableMessagePolling(const neodevice_t* device) {
|
bool icsneo_disableMessagePolling(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->disableMessagePolling();
|
return device->device->disableMessagePolling();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_isMessagePollingEnabled(const neodevice_t* device) {
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return device->device->isMessagePollingEnabled();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_t* items, uint64_t timeout) {
|
bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_t* items, uint64_t timeout) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(items == nullptr) {
|
if(items == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,49 +223,36 @@ bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneo_getPollingMessageLimit(const neodevice_t* device) {
|
size_t icsneo_getPollingMessageLimit(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
return -1;
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
return (int)device->device->getPollingMessageLimit();
|
return device->device->getPollingMessageLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit) {
|
bool icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
device->device->setPollingMessageLimit(newLimit);
|
device->device->setPollingMessageLimit(newLimit);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneo_addMessageCallback(const neodevice_t* device, void (*callback)(neomessage_t), void*) {
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
return device->device->addMessageCallback(
|
|
||||||
MessageCallback(
|
|
||||||
[=](std::shared_ptr<icsneo::Message> msg) {
|
|
||||||
return callback(CreateNeoMessage(msg));
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_removeMessageCallback(const neodevice_t* device, int id) {
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
|
||||||
return false;
|
|
||||||
return device->device->removeMessageCallback(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength) {
|
bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength) {
|
||||||
// TAG String copy function
|
// TAG String copy function
|
||||||
if(maxLength == nullptr) {
|
if(maxLength == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string output = device->device->getType().toString();
|
std::string output = device->device->getType().toString();
|
||||||
|
|
||||||
@@ -283,7 +265,7 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng
|
|||||||
str[*maxLength] = '\0';
|
str[*maxLength] = '\0';
|
||||||
|
|
||||||
if(output.length() > *maxLength)
|
if(output.length() > *maxLength)
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -291,7 +273,7 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng
|
|||||||
bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength) {
|
bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength) {
|
||||||
// TAG String copy function
|
// TAG String copy function
|
||||||
if(maxLength == nullptr) {
|
if(maxLength == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -306,64 +288,76 @@ bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLengt
|
|||||||
str[*maxLength] = '\0';
|
str[*maxLength] = '\0';
|
||||||
|
|
||||||
if(output.length() > *maxLength)
|
if(output.length() > *maxLength)
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_settingsRefresh(const neodevice_t* device) {
|
bool icsneo_settingsRefresh(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->refresh();
|
return device->device->settings->refresh();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_settingsApply(const neodevice_t* device) {
|
bool icsneo_settingsApply(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->apply();
|
return device->device->settings->apply();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_settingsApplyTemporary(const neodevice_t* device) {
|
bool icsneo_settingsApplyTemporary(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->apply(true);
|
return device->device->settings->apply(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_settingsApplyDefaults(const neodevice_t* device) {
|
bool icsneo_settingsApplyDefaults(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->applyDefaults();
|
return device->device->settings->applyDefaults();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_settingsApplyDefaultsTemporary(const neodevice_t* device) {
|
bool icsneo_settingsApplyDefaultsTemporary(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->applyDefaults(true);
|
return device->device->settings->applyDefaults(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneo_settingsReadStructure(const neodevice_t* device, void* structure, size_t structureSize) {
|
size_t icsneo_settingsReadStructure(const neodevice_t* device, void* structure, size_t structureSize) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
return -1;
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
size_t readSize = device->device->settings->getSize();
|
size_t readSize = device->device->settings->getSize();
|
||||||
if(structure == nullptr) // Structure size request
|
if(structure == nullptr) // Structure size request
|
||||||
return (int)readSize;
|
return readSize;
|
||||||
if(readSize > structureSize) {
|
if(readSize > structureSize) {
|
||||||
// Client application has a smaller structure than we do
|
// Client application has a smaller structure than we do
|
||||||
// It is probably built against an older version of the API
|
// It is probably built against an older version of the API
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
readSize = structureSize;
|
readSize = structureSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
const void* deviceStructure = device->device->settings->getRawStructurePointer();
|
const void* deviceStructure = device->device->settings->getRawStructurePointer();
|
||||||
if(deviceStructure == nullptr) {
|
if(deviceStructure == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::SettingsNotAvailable);
|
||||||
return -1;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
memcpy(structure, deviceStructure, readSize);
|
memcpy(structure, deviceStructure, readSize);
|
||||||
@@ -371,28 +365,30 @@ int icsneo_settingsReadStructure(const neodevice_t* device, void* structure, siz
|
|||||||
if(readSize < structureSize) // Client application is attempting to read more than we have
|
if(readSize < structureSize) // Client application is attempting to read more than we have
|
||||||
memset((uint8_t*)structure + readSize, 0, structureSize - readSize);
|
memset((uint8_t*)structure + readSize, 0, structureSize - readSize);
|
||||||
|
|
||||||
return (int)readSize;
|
return readSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Not exported
|
// Not exported
|
||||||
static bool icsneo_settingsWriteStructure(const neodevice_t* device, const void* structure, size_t structureSize) {
|
static bool icsneo_settingsWriteStructure(const neodevice_t* device, const void* structure, size_t structureSize) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(structure == nullptr) {
|
if(structure == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t writeSize = device->device->settings->getSize();
|
size_t writeSize = device->device->settings->getSize();
|
||||||
if(writeSize < structureSize) {
|
if(writeSize < structureSize) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
structureSize = writeSize;
|
structureSize = writeSize;
|
||||||
}
|
}
|
||||||
|
|
||||||
void* deviceStructure = device->device->settings->getMutableRawStructurePointer();
|
void* deviceStructure = device->device->settings->getMutableRawStructurePointer();
|
||||||
if(deviceStructure == nullptr) {
|
if(deviceStructure == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::SettingsNotAvailable);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -413,36 +409,46 @@ bool icsneo_settingsApplyStructureTemporary(const neodevice_t* device, const voi
|
|||||||
}
|
}
|
||||||
|
|
||||||
int64_t icsneo_getBaudrate(const neodevice_t* device, uint16_t netid) {
|
int64_t icsneo_getBaudrate(const neodevice_t* device, uint16_t netid) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->getBaudrateFor(netid);
|
return device->device->settings->getBaudrateFor(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_setBaudrate(const neodevice_t* device, uint16_t netid, int64_t newBaudrate) {
|
bool icsneo_setBaudrate(const neodevice_t* device, uint16_t netid, int64_t newBaudrate) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->setBaudrateFor(netid, newBaudrate);
|
return device->device->settings->setBaudrateFor(netid, newBaudrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t icsneo_getFDBaudrate(const neodevice_t* device, uint16_t netid) {
|
int64_t icsneo_getFDBaudrate(const neodevice_t* device, uint16_t netid) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return -1;
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->getFDBaudrateFor(netid);
|
return device->device->settings->getFDBaudrateFor(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_setFDBaudrate(const neodevice_t* device, uint16_t netid, int64_t newBaudrate) {
|
bool icsneo_setFDBaudrate(const neodevice_t* device, uint16_t netid, int64_t newBaudrate) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->settings->setFDBaudrateFor(netid, newBaudrate);
|
return device->device->settings->setFDBaudrateFor(netid, newBaudrate);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_transmit(const neodevice_t* device, const neomessage_t* message) {
|
bool icsneo_transmit(const neodevice_t* device, const neomessage_t* message) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
return device->device->transmit(CreateMessageFromNeoMessage(message));
|
return device->device->transmit(CreateMessageFromNeoMessage(message));
|
||||||
}
|
}
|
||||||
@@ -457,22 +463,17 @@ bool icsneo_transmitMessages(const neodevice_t* device, const neomessage_t* mess
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo_setWriteBlocks(const neodevice_t* device, bool blocks) {
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
|
||||||
return;
|
|
||||||
|
|
||||||
device->device->setWriteBlocks(blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength) {
|
bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength) {
|
||||||
// TAG String copy function
|
// TAG String copy function
|
||||||
if(maxLength == nullptr) {
|
if(maxLength == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
std::string output = device->device->describe();
|
std::string output = device->device->describe();
|
||||||
|
|
||||||
@@ -480,7 +481,7 @@ bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLeng
|
|||||||
str[*maxLength] = '\0';
|
str[*maxLength] = '\0';
|
||||||
|
|
||||||
if(output.length() > *maxLength)
|
if(output.length() > *maxLength)
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -489,102 +490,92 @@ neoversion_t icsneo_getVersion(void) {
|
|||||||
return icsneo::GetVersion();
|
return icsneo::GetVersion();
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneo_addEventCallback(void (*callback)(neoevent_t), void*) {
|
bool icsneo_getErrors(neoerror_t* errors, size_t* size) {
|
||||||
return EventManager::GetInstance().addEventCallback(
|
|
||||||
EventCallback(
|
|
||||||
[=](std::shared_ptr<icsneo::APIEvent> evt) {
|
|
||||||
return callback(*(evt->getNeoEvent()));
|
|
||||||
}
|
|
||||||
)
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_removeEventCallback(int id) {
|
|
||||||
return EventManager::GetInstance().removeEventCallback(id);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool icsneo_getEvents(neoevent_t* events, size_t* size) {
|
|
||||||
if(size == nullptr) {
|
if(size == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(events == nullptr) {
|
if(errors == nullptr) {
|
||||||
*size = icsneo::EventCount();
|
*size = icsneo::ErrorCount();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cppErrors = icsneo::GetEvents(*size);
|
auto cppErrors = icsneo::GetErrors(*size);
|
||||||
for(size_t i = 0; i < cppErrors.size(); i++)
|
for(size_t i = 0; i < cppErrors.size(); i++)
|
||||||
memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t));
|
memcpy(&errors[i], cppErrors[i].getNeoError(), sizeof(neoerror_t));
|
||||||
*size = cppErrors.size();
|
*size = cppErrors.size();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_getDeviceEvents(const neodevice_t* device, neoevent_t* events, size_t* size) {
|
bool icsneo_getDeviceErrors(const neodevice_t* device, neoerror_t* errors, size_t* size) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(device != nullptr && !icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(size == nullptr) {
|
if(size == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Creating the filter will nullptr is okay! It will find any events not associated with a device.
|
// Creating the filter will nullptr is okay! It will find any errors not associated with a device.
|
||||||
EventFilter filter = (device != nullptr ? device->device : nullptr);
|
ErrorFilter filter = (device != nullptr ? device->device : nullptr);
|
||||||
|
|
||||||
if(events == nullptr) {
|
if(errors == nullptr) {
|
||||||
*size = icsneo::EventCount(filter);
|
*size = icsneo::ErrorCount(filter);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto cppErrors = icsneo::GetEvents(*size, filter);
|
auto cppErrors = icsneo::GetErrors(*size, filter);
|
||||||
for(size_t i = 0; i < cppErrors.size(); i++)
|
for(size_t i = 0; i < cppErrors.size(); i++)
|
||||||
memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t));
|
memcpy(&errors[i], cppErrors[i].getNeoError(), sizeof(neoerror_t));
|
||||||
*size = cppErrors.size();
|
*size = cppErrors.size();
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_getLastError(neoevent_t* error) {
|
bool icsneo_getLastError(neoerror_t* error) {
|
||||||
if(error == nullptr) {
|
if(error == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
APIEvent cppErr = icsneo::GetLastError();
|
APIError cppErr;
|
||||||
if(cppErr.getType() == icsneo::APIEvent::Type::NoErrorFound)
|
if(!icsneo::GetLastError(cppErr))
|
||||||
return false;
|
return false;
|
||||||
memcpy(error, cppErr.getNeoEvent(), sizeof(neoevent_t));
|
memcpy(error, cppErr.getNeoError(), sizeof(neoerror_t));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo_discardAllEvents(void) {
|
void icsneo_discardAllErrors(void) {
|
||||||
icsneo::DiscardEvents();
|
icsneo::DiscardErrors();
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo_discardDeviceEvents(const neodevice_t* device) {
|
void icsneo_discardDeviceErrors(const neodevice_t* device) {
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
if(device != nullptr && !icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
if(device == nullptr)
|
if(device == nullptr)
|
||||||
icsneo::DiscardEvents(nullptr); // Discard events not associated with a device
|
icsneo::DiscardErrors(nullptr); // Discard errors not associated with a device
|
||||||
else
|
else
|
||||||
icsneo::DiscardEvents(device->device);
|
icsneo::DiscardErrors(device->device);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo_setEventLimit(size_t newLimit) {
|
void icsneo_setErrorLimit(size_t newLimit) {
|
||||||
icsneo::SetEventLimit(newLimit);
|
icsneo::SetErrorLimit(newLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t icsneo_getEventLimit(void) {
|
size_t icsneo_getErrorLimit(void) {
|
||||||
return icsneo::GetEventLimit();
|
return icsneo::GetErrorLimit();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) {
|
bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) {
|
||||||
if(count == nullptr) {
|
if(count == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -598,7 +589,7 @@ bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) {
|
|||||||
|
|
||||||
if(*count < len) {
|
if(*count < len) {
|
||||||
len = *count;
|
len = *count;
|
||||||
EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning);
|
ErrorManager::GetInstance().add(APIError::OutputTruncated);
|
||||||
}
|
}
|
||||||
|
|
||||||
for(size_t i = 0; i < len; i++)
|
for(size_t i = 0; i < len; i++)
|
||||||
@@ -608,12 +599,15 @@ bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern bool DLLExport icsneo_getTimestampResolution(const neodevice_t* device, uint16_t* resolution) {
|
extern bool DLLExport icsneo_getTimestampResolution(const neodevice_t* device, uint16_t* resolution)
|
||||||
if(!icsneo_isValidNeoDevice(device))
|
{
|
||||||
|
if (!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
if(resolution == nullptr) {
|
if (resolution == nullptr) {
|
||||||
EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error);
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,51 +0,0 @@
|
|||||||
#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", "icsneoc.dll"
|
|
||||||
VALUE "LegalCopyright", "Intrepid Control Systems, Inc. (C) 2018-2019"
|
|
||||||
VALUE "OriginalFilename", "icsneoc.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
|
|
||||||
@@ -0,0 +1,183 @@
|
|||||||
|
#include "icsneo/api/error.h"
|
||||||
|
#include "icsneo/device/device.h"
|
||||||
|
#include <sstream>
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
APIError::APIError(ErrorType error) : errorStruct({}) {
|
||||||
|
init(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
APIError::APIError(ErrorType error, const Device* forDevice) : errorStruct({}) {
|
||||||
|
device = forDevice;
|
||||||
|
serial = device->getSerial();
|
||||||
|
errorStruct.serial[serial.copy(errorStruct.serial, sizeof(errorStruct.serial))] = '\0';
|
||||||
|
|
||||||
|
init(error);
|
||||||
|
}
|
||||||
|
|
||||||
|
void APIError::init(ErrorType error) {
|
||||||
|
timepoint = ErrorClock::now();
|
||||||
|
errorStruct.description = DescriptionForType(error);
|
||||||
|
errorStruct.errorNumber = (uint32_t)error;
|
||||||
|
errorStruct.severity = (uint8_t)SeverityForType(error);
|
||||||
|
errorStruct.timestamp = ErrorClock::to_time_t(timepoint);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string APIError::describe() const noexcept {
|
||||||
|
std::stringstream ss;
|
||||||
|
if(device)
|
||||||
|
ss << *device; // Makes use of device.describe()
|
||||||
|
else
|
||||||
|
ss << "API";
|
||||||
|
ss << " Error: ";
|
||||||
|
ss << getDescription();
|
||||||
|
return ss.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool APIError::isForDevice(std::string filterSerial) const noexcept {
|
||||||
|
if(!device || filterSerial.length() == 0)
|
||||||
|
return false;
|
||||||
|
return device->getSerial() == filterSerial;
|
||||||
|
}
|
||||||
|
|
||||||
|
// API Errors
|
||||||
|
static constexpr const char* ERROR_INVALID_NEODEVICE = "The provided neodevice_t object was invalid.";
|
||||||
|
static constexpr const char* ERROR_REQUIRED_PARAMETER_NULL = "A required parameter was NULL.";
|
||||||
|
static constexpr const char* ERROR_BUFFER_INSUFFICIENT = "The provided buffer was insufficient. No data was written.";
|
||||||
|
static constexpr const char* ERROR_OUTPUT_TRUNCATED = "The output was too large for the provided buffer and has been truncated.";
|
||||||
|
static constexpr const char* ERROR_PARAMETER_OUT_OF_RANGE = "A parameter was out of range.";
|
||||||
|
|
||||||
|
// Device Errors
|
||||||
|
static constexpr const char* ERROR_POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!";
|
||||||
|
static constexpr const char* ERROR_NO_SERIAL_NUMBER = "Communication could not be established with the device. Perhaps it is not powered with 12 volts?";
|
||||||
|
static constexpr const char* ERROR_INCORRECT_SERIAL_NUMBER = "The device did not return the expected serial number!";
|
||||||
|
static constexpr const char* ERROR_SETTINGS_READ = "The device settings could not be read.";
|
||||||
|
static constexpr const char* ERROR_SETTINGS_VERSION = "The settings version is incorrect, please update your firmware with neoVI Explorer.";
|
||||||
|
static constexpr const char* ERROR_SETTINGS_LENGTH = "The settings length is incorrect, please update your firmware with neoVI Explorer.";
|
||||||
|
static constexpr const char* ERROR_SETTINGS_CHECKSUM = "The settings checksum is incorrect, attempting to set defaults may remedy this issue.";
|
||||||
|
static constexpr const char* ERROR_SETTINGS_NOT_AVAILABLE = "Settings are not available for this device.";
|
||||||
|
|
||||||
|
// Transport Errors
|
||||||
|
static constexpr const char* ERROR_FAILED_TO_READ = "A read operation failed.";
|
||||||
|
static constexpr const char* ERROR_FAILED_TO_WRITE = "A write operation failed.";
|
||||||
|
static constexpr const char* ERROR_DRIVER_FAILED_TO_OPEN = "The device driver encountered a low-level error while opening the device.";
|
||||||
|
static constexpr const char* ERROR_PACKET_CHECKSUM_ERROR = "There was a checksum error while decoding a packet. The packet was dropped.";
|
||||||
|
static constexpr const char* ERROR_TRANSMIT_BUFFER_FULL = "The transmit buffer is full and the device is set to non-blocking.";
|
||||||
|
static constexpr const char* ERROR_PCAP_COULD_NOT_START = "The PCAP driver could not be started. Ethernet devices will not be found.";
|
||||||
|
static constexpr const char* ERROR_PCAP_COULD_NOT_FIND_DEVICES = "The PCAP driver failed to find devices. Ethernet devices will not be found.";
|
||||||
|
|
||||||
|
static constexpr const char* ERROR_TOO_MANY_ERRORS = "Too many errors have occurred. The list has been truncated.";
|
||||||
|
static constexpr const char* ERROR_UNKNOWN = "An unknown internal error occurred.";
|
||||||
|
static constexpr const char* ERROR_INVALID = "An invalid internal error occurred.";
|
||||||
|
const char* APIError::DescriptionForType(ErrorType type) {
|
||||||
|
switch(type) {
|
||||||
|
// API Errors
|
||||||
|
case InvalidNeoDevice:
|
||||||
|
return ERROR_INVALID_NEODEVICE;
|
||||||
|
case RequiredParameterNull:
|
||||||
|
return ERROR_REQUIRED_PARAMETER_NULL;
|
||||||
|
case BufferInsufficient:
|
||||||
|
return ERROR_BUFFER_INSUFFICIENT;
|
||||||
|
case OutputTruncated:
|
||||||
|
return ERROR_OUTPUT_TRUNCATED;
|
||||||
|
case ParameterOutOfRange:
|
||||||
|
return ERROR_PARAMETER_OUT_OF_RANGE;
|
||||||
|
|
||||||
|
// Device Errors
|
||||||
|
case PollingMessageOverflow:
|
||||||
|
return ERROR_POLLING_MESSAGE_OVERFLOW;
|
||||||
|
case NoSerialNumber:
|
||||||
|
return ERROR_NO_SERIAL_NUMBER;
|
||||||
|
case IncorrectSerialNumber:
|
||||||
|
return ERROR_INCORRECT_SERIAL_NUMBER;
|
||||||
|
case SettingsReadError:
|
||||||
|
return ERROR_SETTINGS_READ;
|
||||||
|
case SettingsVersionError:
|
||||||
|
return ERROR_SETTINGS_VERSION;
|
||||||
|
case SettingsLengthError:
|
||||||
|
return ERROR_SETTINGS_LENGTH;
|
||||||
|
case SettingsChecksumError:
|
||||||
|
return ERROR_SETTINGS_CHECKSUM;
|
||||||
|
case SettingsNotAvailable:
|
||||||
|
return ERROR_SETTINGS_NOT_AVAILABLE;
|
||||||
|
|
||||||
|
// Transport Errors
|
||||||
|
case FailedToRead:
|
||||||
|
return ERROR_FAILED_TO_READ;
|
||||||
|
case FailedToWrite:
|
||||||
|
return ERROR_FAILED_TO_WRITE;
|
||||||
|
case DriverFailedToOpen:
|
||||||
|
return ERROR_DRIVER_FAILED_TO_OPEN;
|
||||||
|
case PacketChecksumError:
|
||||||
|
return ERROR_PACKET_CHECKSUM_ERROR;
|
||||||
|
case TransmitBufferFull:
|
||||||
|
return ERROR_TRANSMIT_BUFFER_FULL;
|
||||||
|
case PCAPCouldNotStart:
|
||||||
|
return ERROR_PCAP_COULD_NOT_START;
|
||||||
|
case PCAPCouldNotFindDevices:
|
||||||
|
return ERROR_PCAP_COULD_NOT_FIND_DEVICES;
|
||||||
|
|
||||||
|
// Other Errors
|
||||||
|
case TooManyErrors:
|
||||||
|
return ERROR_TOO_MANY_ERRORS;
|
||||||
|
case Unknown:
|
||||||
|
return ERROR_UNKNOWN;
|
||||||
|
default:
|
||||||
|
return ERROR_INVALID;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
APIError::Severity APIError::SeverityForType(ErrorType type) {
|
||||||
|
switch(type) {
|
||||||
|
// API Warnings
|
||||||
|
case OutputTruncated:
|
||||||
|
// Device Warnings
|
||||||
|
case PollingMessageOverflow:
|
||||||
|
// Transport Warnings
|
||||||
|
case PCAPCouldNotStart:
|
||||||
|
case PCAPCouldNotFindDevices:
|
||||||
|
return Severity::Warning;
|
||||||
|
|
||||||
|
// API Errors
|
||||||
|
case InvalidNeoDevice:
|
||||||
|
case RequiredParameterNull:
|
||||||
|
case BufferInsufficient:
|
||||||
|
case ParameterOutOfRange:
|
||||||
|
// Device Errors
|
||||||
|
case NoSerialNumber:
|
||||||
|
case IncorrectSerialNumber:
|
||||||
|
case SettingsReadError:
|
||||||
|
case SettingsVersionError:
|
||||||
|
case SettingsLengthError:
|
||||||
|
case SettingsChecksumError:
|
||||||
|
case SettingsNotAvailable:
|
||||||
|
// Transport Errors
|
||||||
|
case FailedToRead:
|
||||||
|
case FailedToWrite:
|
||||||
|
case DriverFailedToOpen:
|
||||||
|
case PacketChecksumError:
|
||||||
|
case TransmitBufferFull:
|
||||||
|
// Other Errors
|
||||||
|
case TooManyErrors:
|
||||||
|
case Unknown:
|
||||||
|
default:
|
||||||
|
return Severity::Error;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ErrorFilter::match(const APIError& error) const noexcept {
|
||||||
|
if(type != APIError::Any && type != error.getType())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(matchOnDevicePtr && !error.isForDevice(device))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(severity != APIError::Severity::Any && severity != error.getSeverity())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
if(serial.length() != 0 && !error.isForDevice(serial))
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
@@ -0,0 +1,146 @@
|
|||||||
|
#include "icsneo/api/errormanager.h"
|
||||||
|
#include <memory>
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
static std::unique_ptr<ErrorManager> singleton;
|
||||||
|
|
||||||
|
ErrorManager& ErrorManager::GetInstance() {
|
||||||
|
if(!singleton)
|
||||||
|
singleton = std::unique_ptr<ErrorManager>(new ErrorManager());
|
||||||
|
return *singleton.get();
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorManager::get(std::vector<APIError>& errorOutput, size_t max, ErrorFilter filter) {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
|
||||||
|
if(max == 0) // A limit of 0 indicates no limit
|
||||||
|
max = (size_t)-1;
|
||||||
|
|
||||||
|
size_t count = 0;
|
||||||
|
errorOutput.clear();
|
||||||
|
auto it = errors.begin();
|
||||||
|
while(it != errors.end()) {
|
||||||
|
if(filter.match(*it)) {
|
||||||
|
errorOutput.push_back(*it);
|
||||||
|
errors.erase(it++);
|
||||||
|
if(count++ >= max)
|
||||||
|
break; // We now have as many written to output as we can
|
||||||
|
} else {
|
||||||
|
std::advance(it, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ErrorManager::getLastError(APIError& errorOutput, ErrorFilter filter) {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
|
||||||
|
auto it = errors.rbegin();
|
||||||
|
while(it != errors.rend()) {
|
||||||
|
if(filter.match(*it)) {
|
||||||
|
errorOutput = *it;
|
||||||
|
errors.erase(std::next(it).base());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::advance(it, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorManager::discard(ErrorFilter filter) {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
errors.remove_if([&filter](const APIError& error) {
|
||||||
|
return filter.match(error);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t ErrorManager::count_internal(ErrorFilter filter) const {
|
||||||
|
size_t ret = 0;
|
||||||
|
for(auto& error : errors)
|
||||||
|
if(filter.match(error))
|
||||||
|
ret++;
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ErrorManager::beforeAddCheck(APIError::ErrorType type) {
|
||||||
|
if(enforceLimit()) { // The enforceLimit will add the "TooManyErrors" error for us if necessary
|
||||||
|
// We need to decide whether to add this error or drop it
|
||||||
|
// We would have to remove something if we added this error
|
||||||
|
if(APIError::SeverityForType(type) < lowestCurrentSeverity())
|
||||||
|
return false; // Don't add this one, we are already full of higher priority items
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool ErrorManager::enforceLimit() {
|
||||||
|
if(errors.size() + 1 < errorLimit)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
bool hasTooManyWarningAlready = count_internal(ErrorFilter(APIError::TooManyErrors)) != 0;
|
||||||
|
size_t amountToRemove = (errors.size() + (hasTooManyWarningAlready ? 1 : 2)) - errorLimit;
|
||||||
|
|
||||||
|
discardLeastSevere(amountToRemove);
|
||||||
|
if(!hasTooManyWarningAlready)
|
||||||
|
errors.emplace_back(APIError::TooManyErrors);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
APIError::Severity ErrorManager::lowestCurrentSeverity() {
|
||||||
|
if(errors.empty())
|
||||||
|
return APIError::Severity(0);
|
||||||
|
|
||||||
|
APIError::Severity lowest = APIError::Severity::Error;
|
||||||
|
auto it = errors.begin();
|
||||||
|
while(it != errors.end()) {
|
||||||
|
if((*it).getSeverity() < lowest)
|
||||||
|
lowest = (*it).getSeverity();
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
return lowest;
|
||||||
|
}
|
||||||
|
|
||||||
|
void ErrorManager::discardLeastSevere(size_t count) {
|
||||||
|
if(count == 0)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ErrorFilter infoFilter(APIError::Severity::Info);
|
||||||
|
auto it = errors.begin();
|
||||||
|
while(it != errors.end()) {
|
||||||
|
if(infoFilter.match(*it)) {
|
||||||
|
errors.erase(it++);
|
||||||
|
if(--count == 0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count != 0) {
|
||||||
|
ErrorFilter warningFilter(APIError::Severity::Warning);
|
||||||
|
it = errors.begin();
|
||||||
|
while(it != errors.end()) {
|
||||||
|
if(warningFilter.match(*it)) {
|
||||||
|
errors.erase(it++);
|
||||||
|
if(--count == 0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(count != 0) {
|
||||||
|
ErrorFilter errorFilter(APIError::Severity::Error);
|
||||||
|
it = errors.begin();
|
||||||
|
while(it != errors.end()) {
|
||||||
|
if(errorFilter.match(*it)) {
|
||||||
|
errors.erase(it++);
|
||||||
|
if(--count == 0)
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
it++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,231 +0,0 @@
|
|||||||
#include "icsneo/api/event.h"
|
|
||||||
#include "icsneo/device/device.h"
|
|
||||||
#include <sstream>
|
|
||||||
|
|
||||||
using namespace icsneo;
|
|
||||||
|
|
||||||
APIEvent::APIEvent(Type type, APIEvent::Severity severity, const Device* device) : eventStruct({}) {
|
|
||||||
this->device = device;
|
|
||||||
if(device) {
|
|
||||||
serial = device->getSerial();
|
|
||||||
eventStruct.serial[serial.copy(eventStruct.serial, sizeof(eventStruct.serial))] = '\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
init(type, severity);
|
|
||||||
}
|
|
||||||
|
|
||||||
void APIEvent::init(Type event, APIEvent::Severity severity) {
|
|
||||||
timepoint = EventClock::now();
|
|
||||||
eventStruct.description = DescriptionForType(event);
|
|
||||||
eventStruct.eventNumber = (uint32_t)event;
|
|
||||||
eventStruct.severity = (uint8_t) severity;
|
|
||||||
eventStruct.timestamp = EventClock::to_time_t(timepoint);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::string APIEvent::describe() const noexcept {
|
|
||||||
std::stringstream ss;
|
|
||||||
if(device)
|
|
||||||
ss << *device; // Makes use of device.describe()
|
|
||||||
else
|
|
||||||
ss << "API";
|
|
||||||
|
|
||||||
Severity severity = getSeverity();
|
|
||||||
if(severity == Severity::EventInfo) {
|
|
||||||
ss << " Info: ";
|
|
||||||
} else if(severity == Severity::EventWarning) {
|
|
||||||
ss << " Warning: ";
|
|
||||||
} else if(severity == Severity::Error) {
|
|
||||||
ss << " Error: ";
|
|
||||||
} else {
|
|
||||||
// Should never get here, since Severity::Any should only be used for filtering
|
|
||||||
ss << " Any: ";
|
|
||||||
}
|
|
||||||
|
|
||||||
ss << getDescription();
|
|
||||||
return ss.str();
|
|
||||||
}
|
|
||||||
|
|
||||||
void APIEvent::downgradeFromError() noexcept {
|
|
||||||
eventStruct.severity = (uint8_t) APIEvent::Severity::EventWarning;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool APIEvent::isForDevice(std::string filterSerial) const noexcept {
|
|
||||||
if(!device || filterSerial.length() == 0)
|
|
||||||
return false;
|
|
||||||
return device->getSerial() == filterSerial;
|
|
||||||
}
|
|
||||||
|
|
||||||
// API Errors
|
|
||||||
static constexpr const char* INVALID_NEODEVICE = "The provided neodevice_t object was invalid.";
|
|
||||||
static constexpr const char* REQUIRED_PARAMETER_NULL = "A required parameter was NULL.";
|
|
||||||
static constexpr const char* OUTPUT_TRUNCATED = "The output was too large for the provided buffer and has been truncated.";
|
|
||||||
static constexpr const char* BUFFER_INSUFFICIENT = "The provided buffer was insufficient. No data was written.";
|
|
||||||
static constexpr const char* PARAMETER_OUT_OF_RANGE = "A parameter was out of range.";
|
|
||||||
static constexpr const char* DEVICE_CURRENTLY_OPEN = "The device is currently open.";
|
|
||||||
static constexpr const char* DEVICE_CURRENTLY_CLOSED = "The device is currently closed.";
|
|
||||||
static constexpr const char* DEVICE_CURRENTLY_ONLINE = "The device is currently online.";
|
|
||||||
static constexpr const char* DEVICE_CURRENTLY_OFFLINE = "The device is currently offline.";
|
|
||||||
static constexpr const char* DEVICE_CURRENTLY_POLLING = "The device is currently polling for messages.";
|
|
||||||
static constexpr const char* DEVICE_NOT_CURRENTLY_POLLING = "The device is not currently polling for messages.";
|
|
||||||
static constexpr const char* UNSUPPORTED_TX_NETWORK = "Message network is not a supported TX network.";
|
|
||||||
static constexpr const char* MESSAGE_MAX_LENGTH_EXCEEDED = "The message was too long.";
|
|
||||||
|
|
||||||
// Device Errors
|
|
||||||
static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!";
|
|
||||||
static constexpr const char* NO_SERIAL_NUMBER = "Communication could not be established with the device. Perhaps it is not powered with 12 volts?";
|
|
||||||
static constexpr const char* INCORRECT_SERIAL_NUMBER = "The device did not return the expected serial number!";
|
|
||||||
static constexpr const char* SETTINGS_READ = "The device settings could not be read.";
|
|
||||||
static constexpr const char* SETTINGS_VERSION = "The settings version is incorrect, please update your firmware with neoVI Explorer.";
|
|
||||||
static constexpr const char* SETTINGS_LENGTH = "The settings length is incorrect, please update your firmware with neoVI Explorer.";
|
|
||||||
static constexpr const char* SETTINGS_CHECKSUM = "The settings checksum is incorrect, attempting to set defaults may remedy this issue.";
|
|
||||||
static constexpr const char* SETTINGS_NOT_AVAILABLE = "Settings are not available for this device.";
|
|
||||||
static constexpr const char* SETTINGS_READONLY = "Settings are read-only for this device.";
|
|
||||||
static constexpr const char* CAN_SETTINGS_NOT_AVAILABLE = "CAN settings are not available for this device.";
|
|
||||||
static constexpr const char* CANFD_SETTINGS_NOT_AVAILABLE = "CANFD settings are not available for this device.";
|
|
||||||
static constexpr const char* LSFTCAN_SETTINGS_NOT_AVAILABLE = "LSFTCAN settings are not available for this device.";
|
|
||||||
static constexpr const char* SWCAN_SETTINGS_NOT_AVAILABLE = "SWCAN settings are not available for this device.";
|
|
||||||
static constexpr const char* BAUDRATE_NOT_FOUND = "The baudrate was not found.";
|
|
||||||
static constexpr const char* UNEXPECTED_NETWORK_TYPE = "The network type was not found.";
|
|
||||||
static constexpr const char* DEVICE_FIRMWARE_OUT_OF_DATE = "The device firmware is out of date. New API functionality may not be supported.";
|
|
||||||
static constexpr const char* SETTINGS_STRUCTURE_MISMATCH = "Unexpected settings structure for this device.";
|
|
||||||
static constexpr const char* SETTINGS_STRUCTURE_TRUNCATED = "Settings structure is longer than the device supports and will be truncated.";
|
|
||||||
static constexpr const char* NO_DEVICE_RESPONSE = "Expected a response from the device but none were found.";
|
|
||||||
static constexpr const char* MESSAGE_FORMATTING = "The message was not properly formed.";
|
|
||||||
static constexpr const char* CANFD_NOT_SUPPORTED = "This device does not support CANFD.";
|
|
||||||
static constexpr const char* RTR_NOT_SUPPORTED = "RTR is not supported with CANFD.";
|
|
||||||
|
|
||||||
// Transport Errors
|
|
||||||
static constexpr const char* FAILED_TO_READ = "A read operation failed.";
|
|
||||||
static constexpr const char* FAILED_TO_WRITE = "A write operation failed.";
|
|
||||||
static constexpr const char* DRIVER_FAILED_TO_OPEN = "The device driver encountered a low-level error while opening the device.";
|
|
||||||
static constexpr const char* DRIVER_FAILED_TO_CLOSE = "The device driver encountered a low-level error while closing the device.";
|
|
||||||
static constexpr const char* PACKET_CHECKSUM_ERROR = "There was a checksum error while decoding a packet. The packet was dropped.";
|
|
||||||
static constexpr const char* TRANSMIT_BUFFER_FULL = "The transmit buffer is full and the device is set to non-blocking.";
|
|
||||||
static constexpr const char* PCAP_COULD_NOT_START = "The PCAP driver could not be started. Ethernet devices will not be found.";
|
|
||||||
static constexpr const char* PCAP_COULD_NOT_FIND_DEVICES = "The PCAP driver failed to find devices. Ethernet devices will not be found.";
|
|
||||||
static constexpr const char* PACKET_DECODING = "The packet could not be decoded.";
|
|
||||||
|
|
||||||
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
|
|
||||||
case Type::InvalidNeoDevice:
|
|
||||||
return INVALID_NEODEVICE;
|
|
||||||
case Type::RequiredParameterNull:
|
|
||||||
return REQUIRED_PARAMETER_NULL;
|
|
||||||
case Type::BufferInsufficient:
|
|
||||||
return BUFFER_INSUFFICIENT;
|
|
||||||
case Type::OutputTruncated:
|
|
||||||
return OUTPUT_TRUNCATED;
|
|
||||||
case Type::ParameterOutOfRange:
|
|
||||||
return PARAMETER_OUT_OF_RANGE;
|
|
||||||
case Type::DeviceCurrentlyOpen:
|
|
||||||
return DEVICE_CURRENTLY_OPEN;
|
|
||||||
case Type::DeviceCurrentlyClosed:
|
|
||||||
return DEVICE_CURRENTLY_CLOSED;
|
|
||||||
case Type::DeviceCurrentlyOnline:
|
|
||||||
return DEVICE_CURRENTLY_ONLINE;
|
|
||||||
case Type::DeviceCurrentlyOffline:
|
|
||||||
return DEVICE_CURRENTLY_OFFLINE;
|
|
||||||
case Type::DeviceCurrentlyPolling:
|
|
||||||
return DEVICE_CURRENTLY_POLLING;
|
|
||||||
case Type::DeviceNotCurrentlyPolling:
|
|
||||||
return DEVICE_NOT_CURRENTLY_POLLING;
|
|
||||||
case Type::UnsupportedTXNetwork:
|
|
||||||
return UNSUPPORTED_TX_NETWORK;
|
|
||||||
case Type::MessageMaxLengthExceeded:
|
|
||||||
return MESSAGE_MAX_LENGTH_EXCEEDED;
|
|
||||||
|
|
||||||
// Device Errors
|
|
||||||
case Type::PollingMessageOverflow:
|
|
||||||
return POLLING_MESSAGE_OVERFLOW;
|
|
||||||
case Type::NoSerialNumber:
|
|
||||||
return NO_SERIAL_NUMBER;
|
|
||||||
case Type::IncorrectSerialNumber:
|
|
||||||
return INCORRECT_SERIAL_NUMBER;
|
|
||||||
case Type::SettingsReadError:
|
|
||||||
return SETTINGS_READ;
|
|
||||||
case Type::SettingsVersionError:
|
|
||||||
return SETTINGS_VERSION;
|
|
||||||
case Type::SettingsLengthError:
|
|
||||||
return SETTINGS_LENGTH;
|
|
||||||
case Type::SettingsChecksumError:
|
|
||||||
return SETTINGS_CHECKSUM;
|
|
||||||
case Type::SettingsNotAvailable:
|
|
||||||
return SETTINGS_NOT_AVAILABLE;
|
|
||||||
case Type::SettingsReadOnly:
|
|
||||||
return SETTINGS_READONLY;
|
|
||||||
case Type::CANSettingsNotAvailable:
|
|
||||||
return CAN_SETTINGS_NOT_AVAILABLE;
|
|
||||||
case Type::CANFDSettingsNotAvailable:
|
|
||||||
return CANFD_SETTINGS_NOT_AVAILABLE;
|
|
||||||
case Type::LSFTCANSettingsNotAvailable:
|
|
||||||
return LSFTCAN_SETTINGS_NOT_AVAILABLE;
|
|
||||||
case Type::SWCANSettingsNotAvailable:
|
|
||||||
return SWCAN_SETTINGS_NOT_AVAILABLE;
|
|
||||||
case Type::BaudrateNotFound:
|
|
||||||
return BAUDRATE_NOT_FOUND;
|
|
||||||
case Type::UnexpectedNetworkType:
|
|
||||||
return UNEXPECTED_NETWORK_TYPE;
|
|
||||||
case Type::DeviceFirmwareOutOfDate:
|
|
||||||
return DEVICE_FIRMWARE_OUT_OF_DATE;
|
|
||||||
case Type::SettingsStructureMismatch:
|
|
||||||
return SETTINGS_STRUCTURE_MISMATCH;
|
|
||||||
case Type::SettingsStructureTruncated:
|
|
||||||
return SETTINGS_STRUCTURE_TRUNCATED;
|
|
||||||
case Type::NoDeviceResponse:
|
|
||||||
return NO_DEVICE_RESPONSE;
|
|
||||||
case Type::MessageFormattingError:
|
|
||||||
return MESSAGE_FORMATTING;
|
|
||||||
case Type::CANFDNotSupported:
|
|
||||||
return CANFD_NOT_SUPPORTED;
|
|
||||||
case Type::RTRNotSupported:
|
|
||||||
return RTR_NOT_SUPPORTED;
|
|
||||||
|
|
||||||
// Transport Errors
|
|
||||||
case Type::FailedToRead:
|
|
||||||
return FAILED_TO_READ;
|
|
||||||
case Type::FailedToWrite:
|
|
||||||
return FAILED_TO_WRITE;
|
|
||||||
case Type::DriverFailedToOpen:
|
|
||||||
return DRIVER_FAILED_TO_OPEN;
|
|
||||||
case Type::DriverFailedToClose:
|
|
||||||
return DRIVER_FAILED_TO_CLOSE;
|
|
||||||
case Type::PacketChecksumError:
|
|
||||||
return PACKET_CHECKSUM_ERROR;
|
|
||||||
case Type::TransmitBufferFull:
|
|
||||||
return TRANSMIT_BUFFER_FULL;
|
|
||||||
case Type::PCAPCouldNotStart:
|
|
||||||
return PCAP_COULD_NOT_START;
|
|
||||||
case Type::PCAPCouldNotFindDevices:
|
|
||||||
return PCAP_COULD_NOT_FIND_DEVICES;
|
|
||||||
case Type::PacketDecodingError:
|
|
||||||
return PACKET_DECODING;
|
|
||||||
|
|
||||||
// Other Errors
|
|
||||||
case Type::TooManyEvents:
|
|
||||||
return TOO_MANY_EVENTS;
|
|
||||||
case Type::Unknown:
|
|
||||||
return UNKNOWN;
|
|
||||||
default:
|
|
||||||
return INVALID;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventFilter::match(const APIEvent& event) const noexcept {
|
|
||||||
if(type != APIEvent::Type::Any && type != event.getType())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(matchOnDevicePtr && !event.isForDevice(device))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(severity != APIEvent::Severity::Any && severity != event.getSeverity())
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if(serial.length() != 0 && !event.isForDevice(serial))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
@@ -1,142 +0,0 @@
|
|||||||
#include "icsneo/api/eventmanager.h"
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
using namespace icsneo;
|
|
||||||
|
|
||||||
EventManager& EventManager::GetInstance() {
|
|
||||||
static EventManager inst;
|
|
||||||
return inst;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::ResetInstance() {
|
|
||||||
std::lock_guard<std::mutex> eventsLock(eventsMutex);
|
|
||||||
std::lock_guard<std::mutex> errorsLock(errorsMutex);
|
|
||||||
std::lock_guard<std::mutex> downgradedThreadsLock(downgradedThreadsMutex);
|
|
||||||
std::lock_guard<std::mutex> callbacksLock(callbacksMutex);
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> callbackIDLock(callbackIDMutex);
|
|
||||||
std::lock_guard<std::mutex> eventLimitLock(eventLimitMutex);
|
|
||||||
|
|
||||||
events.clear();
|
|
||||||
lastUserErrors.clear();
|
|
||||||
downgradedThreads.clear();
|
|
||||||
callbacks.clear();
|
|
||||||
|
|
||||||
callbackID = 0;
|
|
||||||
eventLimit = 10000;
|
|
||||||
}
|
|
||||||
|
|
||||||
int EventManager::addEventCallback(const EventCallback &cb) {
|
|
||||||
std::lock_guard<std::mutex> callbacksLock(callbacksMutex);
|
|
||||||
std::lock_guard<std::mutex> callbackIDLock(callbackIDMutex);
|
|
||||||
callbacks.insert({callbackID, cb});
|
|
||||||
return callbackID++;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventManager::removeEventCallback(int id) {
|
|
||||||
std::lock_guard<std::mutex> lk(callbacksMutex);
|
|
||||||
|
|
||||||
auto iter = callbacks.find(id);
|
|
||||||
|
|
||||||
if(iter != callbacks.end()) {
|
|
||||||
callbacks.erase(iter);
|
|
||||||
return true;
|
|
||||||
} else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool EventManager::isDowngradingErrorsOnCurrentThread() const {
|
|
||||||
auto i = downgradedThreads.find(std::this_thread::get_id());
|
|
||||||
if(i != downgradedThreads.end()) {
|
|
||||||
return i->second;
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::get(std::vector<APIEvent>& eventOutput, size_t max, EventFilter filter) {
|
|
||||||
std::lock_guard<std::mutex> lk(eventsMutex);
|
|
||||||
|
|
||||||
if(max == 0) // A limit of 0 indicates no limit
|
|
||||||
max = (size_t)-1;
|
|
||||||
|
|
||||||
size_t count = 0;
|
|
||||||
eventOutput.clear();
|
|
||||||
auto it = events.begin();
|
|
||||||
while(it != events.end()) {
|
|
||||||
if(filter.match(*it)) {
|
|
||||||
eventOutput.push_back(*it);
|
|
||||||
it = events.erase(it);
|
|
||||||
if(++count >= max)
|
|
||||||
break; // We now have as many written to output as we can
|
|
||||||
} else {
|
|
||||||
it++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Removes the returned error from the map
|
|
||||||
* If no error was found, return a NoErrorFound Info event
|
|
||||||
*/
|
|
||||||
APIEvent EventManager::getLastError() {
|
|
||||||
std::lock_guard<std::mutex> lk(errorsMutex);
|
|
||||||
|
|
||||||
auto it = lastUserErrors.find(std::this_thread::get_id());
|
|
||||||
if(it == lastUserErrors.end()) {
|
|
||||||
return APIEvent(APIEvent::Type::NoErrorFound, APIEvent::Severity::EventInfo);
|
|
||||||
} else {
|
|
||||||
APIEvent ret = it->second;
|
|
||||||
it = lastUserErrors.erase(it);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::discard(EventFilter filter) {
|
|
||||||
std::lock_guard<std::mutex> lk(eventsMutex);
|
|
||||||
events.remove_if([&filter](const APIEvent& event) {
|
|
||||||
return filter.match(event);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t EventManager::count_internal(EventFilter filter) const {
|
|
||||||
size_t ret = 0;
|
|
||||||
for(auto& event : events)
|
|
||||||
if(filter.match(event))
|
|
||||||
ret++;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Ensures events is always at most eventLimit - 1 in size.
|
|
||||||
* Returns true if any events were removed in the process of doing so.
|
|
||||||
*/
|
|
||||||
bool EventManager::enforceLimit() {
|
|
||||||
// Remove all TooManyEvents from the end before checking
|
|
||||||
auto filter = EventFilter(APIEvent::Type::TooManyEvents);
|
|
||||||
auto it = events.rbegin();
|
|
||||||
while(it != events.rend() && filter.match(*it)) {
|
|
||||||
it = decltype(it){events.erase( std::next(it).base() )};
|
|
||||||
}
|
|
||||||
|
|
||||||
// We are not overflowing
|
|
||||||
if(events.size() < eventLimit)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
size_t amountToRemove = events.size() + 1 - eventLimit;
|
|
||||||
|
|
||||||
discardOldest(amountToRemove);
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
void EventManager::discardOldest(size_t count) {
|
|
||||||
if(count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
auto it = events.begin();
|
|
||||||
while(it != events.end()) {
|
|
||||||
it = events.erase(it);
|
|
||||||
if(--count == 0)
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+18
-18
@@ -11,38 +11,38 @@ std::vector<DeviceType> icsneo::GetSupportedDevices() {
|
|||||||
return DeviceFinder::GetSupportedDevices();
|
return DeviceFinder::GetSupportedDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t icsneo::EventCount(EventFilter filter) {
|
size_t icsneo::ErrorCount(ErrorFilter filter) {
|
||||||
return EventManager::GetInstance().eventCount(filter);
|
return ErrorManager::GetInstance().count(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<APIEvent> icsneo::GetEvents(EventFilter filter, size_t max) {
|
std::vector<APIError> icsneo::GetErrors(ErrorFilter filter, size_t max) {
|
||||||
return EventManager::GetInstance().get(filter, max);
|
return ErrorManager::GetInstance().get(filter, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<APIEvent> icsneo::GetEvents(size_t max, EventFilter filter) {
|
std::vector<APIError> icsneo::GetErrors(size_t max, ErrorFilter filter) {
|
||||||
return EventManager::GetInstance().get(max, filter);
|
return ErrorManager::GetInstance().get(max, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max) {
|
void icsneo::GetErrors(std::vector<APIError>& errors, ErrorFilter filter, size_t max) {
|
||||||
EventManager::GetInstance().get(events, filter, max);
|
ErrorManager::GetInstance().get(errors, filter, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::GetEvents(std::vector<APIEvent>& events, size_t max, EventFilter filter) {
|
void icsneo::GetErrors(std::vector<APIError>& errors, size_t max, ErrorFilter filter) {
|
||||||
EventManager::GetInstance().get(events, max, filter);
|
ErrorManager::GetInstance().get(errors, max, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
APIEvent icsneo::GetLastError() {
|
bool icsneo::GetLastError(APIError& error, ErrorFilter filter) {
|
||||||
return EventManager::GetInstance().getLastError();
|
return ErrorManager::GetInstance().getLastError(error, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::DiscardEvents(EventFilter filter) {
|
void icsneo::DiscardErrors(ErrorFilter filter) {
|
||||||
EventManager::GetInstance().discard(filter);
|
ErrorManager::GetInstance().discard(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::SetEventLimit(size_t newLimit) {
|
void icsneo::SetErrorLimit(size_t newLimit) {
|
||||||
EventManager::GetInstance().setEventLimit(newLimit);
|
ErrorManager::GetInstance().setErrorLimit(newLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t icsneo::GetEventLimit() {
|
size_t icsneo::GetErrorLimit() {
|
||||||
return EventManager::GetInstance().getEventLimit();
|
return ErrorManager::GetInstance().getErrorLimit();
|
||||||
}
|
}
|
||||||
@@ -163,8 +163,9 @@ int icsneoOpenNeoDevice(NeoDevice* pNeoDevice, void** hObject, unsigned char* bN
|
|||||||
*hObject = device;
|
*hObject = device;
|
||||||
if(!icsneo_openDevice(device))
|
if(!icsneo_openDevice(device))
|
||||||
return false;
|
return false;
|
||||||
|
icsneo_setPollingMessageLimit(device, 20000);
|
||||||
return icsneo_setPollingMessageLimit(device, 20000) && icsneo_enableMessagePolling(device) && icsneo_goOnline(device);
|
icsneo_enableMessagePolling(device);
|
||||||
|
return icsneo_goOnline(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoClosePort(void* hObject, int* pNumberOfErrors) {
|
int icsneoClosePort(void* hObject, int* pNumberOfErrors) {
|
||||||
@@ -292,7 +293,7 @@ int icsneoGetFireSettings(void* hObject, SFireSettings* pSettings, int iNumBytes
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetFireSettings(void* hObject, SFireSettings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetFireSettings(void* hObject, SFireSettings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
@@ -308,7 +309,7 @@ int icsneoGetVCAN3Settings(void* hObject, SVCAN3Settings* pSettings, int iNumByt
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetVCAN3Settings(void* hObject, SVCAN3Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetVCAN3Settings(void* hObject, SVCAN3Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
@@ -324,7 +325,7 @@ int icsneoGetFire2Settings(void* hObject, SFire2Settings* pSettings, int iNumByt
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetFire2Settings(void* hObject, SFire2Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetFire2Settings(void* hObject, SFire2Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
@@ -340,7 +341,7 @@ int icsneoGetVCANRFSettings(void* hObject, SVCANRFSettings* pSettings, int iNumB
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetVCANRFSettings(void* hObject, SVCANRFSettings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetVCANRFSettings(void* hObject, SVCANRFSettings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
@@ -356,7 +357,7 @@ int icsneoGetVCAN412Settings(void* hObject, SVCAN412Settings* pSettings, int iNu
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetVCAN412Settings(void* hObject, SVCAN412Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetVCAN412Settings(void* hObject, SVCAN412Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
@@ -372,7 +373,7 @@ int icsneoGetRADGalaxySettings(void* hObject, SRADGalaxySettings* pSettings, int
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetRADGalaxySettings(void* hObject, SRADGalaxySettings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetRADGalaxySettings(void* hObject, SRADGalaxySettings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
@@ -388,7 +389,7 @@ int icsneoGetRADStar2Settings(void* hObject, SRADStar2Settings* pSettings, int i
|
|||||||
if(!icsneoValidateHObject(hObject))
|
if(!icsneoValidateHObject(hObject))
|
||||||
return false;
|
return false;
|
||||||
neodevice_t* device = (neodevice_t*)hObject;
|
neodevice_t* device = (neodevice_t*)hObject;
|
||||||
return !!(icsneo_settingsReadStructure(device, pSettings, iNumBytes) + 1);
|
return !!icsneo_settingsReadStructure(device, pSettings, iNumBytes);
|
||||||
}
|
}
|
||||||
|
|
||||||
int icsneoSetRADStar2Settings(void* hObject, SRADStar2Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
int icsneoSetRADStar2Settings(void* hObject, SRADStar2Settings* pSettings, int iNumBytes, int bSaveToEEPROM) {
|
||||||
|
|||||||
@@ -18,12 +18,11 @@ using namespace icsneo;
|
|||||||
int Communication::messageCallbackIDCounter = 1;
|
int Communication::messageCallbackIDCounter = 1;
|
||||||
|
|
||||||
bool Communication::open() {
|
bool Communication::open() {
|
||||||
if(isOpen()) {
|
if(isOpen)
|
||||||
report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error);
|
return true;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
spawnThreads();
|
spawnThreads();
|
||||||
|
isOpen = true;
|
||||||
return impl->open();
|
return impl->open();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -39,20 +38,15 @@ void Communication::joinThreads() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool Communication::close() {
|
bool Communication::close() {
|
||||||
if(!isOpen()) {
|
if(!isOpen)
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
|
isOpen = false;
|
||||||
joinThreads();
|
joinThreads();
|
||||||
|
|
||||||
return impl->close();
|
return impl->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Communication::isOpen() {
|
|
||||||
return impl->isOpen();
|
|
||||||
}
|
|
||||||
|
|
||||||
bool Communication::sendPacket(std::vector<uint8_t>& bytes) {
|
bool Communication::sendPacket(std::vector<uint8_t>& bytes) {
|
||||||
// This is here so that other communication types (like multichannel) can override it
|
// This is here so that other communication types (like multichannel) can override it
|
||||||
return rawWrite(bytes);
|
return rawWrite(bytes);
|
||||||
@@ -73,16 +67,12 @@ bool Communication::getSettingsSync(std::vector<uint8_t>& data, std::chrono::mil
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
std::shared_ptr<ReadSettingsMessage> gsmsg = std::dynamic_pointer_cast<ReadSettingsMessage>(msg);
|
std::shared_ptr<ReadSettingsMessage> gsmsg = std::dynamic_pointer_cast<ReadSettingsMessage>(msg);
|
||||||
if(!gsmsg) {
|
if(!gsmsg)
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(gsmsg->response != ReadSettingsMessage::Response::OK) {
|
if(gsmsg->response != ReadSettingsMessage::Response::OK)
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
data = std::move(msg->data);
|
data = std::move(msg->data);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@@ -101,18 +91,15 @@ std::shared_ptr<SerialNumberMessage> Communication::getSerialNumberSync(std::chr
|
|||||||
}
|
}
|
||||||
|
|
||||||
int Communication::addMessageCallback(const MessageCallback& cb) {
|
int Communication::addMessageCallback(const MessageCallback& cb) {
|
||||||
std::lock_guard<std::mutex> lk(messageCallbacksLock);
|
|
||||||
messageCallbacks.insert(std::make_pair(messageCallbackIDCounter, cb));
|
messageCallbacks.insert(std::make_pair(messageCallbackIDCounter, cb));
|
||||||
return messageCallbackIDCounter++;
|
return messageCallbackIDCounter++;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Communication::removeMessageCallback(int id) {
|
bool Communication::removeMessageCallback(int id) {
|
||||||
std::lock_guard<std::mutex> lk(messageCallbacksLock);
|
|
||||||
try {
|
try {
|
||||||
messageCallbacks.erase(id);
|
messageCallbacks.erase(id);
|
||||||
return true;
|
return true;
|
||||||
} catch(...) {
|
} catch(...) {
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -131,8 +118,7 @@ std::shared_ptr<Message> Communication::waitForMessageSync(std::shared_ptr<Messa
|
|||||||
|
|
||||||
// We have now added the callback, wait for it to return from the other thread
|
// We have now added the callback, wait for it to return from the other thread
|
||||||
std::unique_lock<std::mutex> lk(m);
|
std::unique_lock<std::mutex> lk(m);
|
||||||
cv.wait_for(lk, timeout, [&returnedMessage] { return !!returnedMessage; }); // `!!shared_ptr` checks if the ptr has a value
|
cv.wait_for(lk, timeout, [&returnedMessage]{ return !!returnedMessage; }); // `!!shared_ptr` checks if the ptr has a value
|
||||||
lk.unlock();
|
|
||||||
|
|
||||||
// We don't actually check that we got a message, because either way we want to remove the callback (since it should only happen once)
|
// We don't actually check that we got a message, because either way we want to remove the callback (since it should only happen once)
|
||||||
removeMessageCallback(cb);
|
removeMessageCallback(cb);
|
||||||
@@ -141,37 +127,25 @@ std::shared_ptr<Message> Communication::waitForMessageSync(std::shared_ptr<Messa
|
|||||||
return returnedMessage;
|
return returnedMessage;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Communication::dispatchMessage(const std::shared_ptr<Message>& msg) {
|
|
||||||
std::lock_guard<std::mutex> lk(messageCallbacksLock);
|
|
||||||
|
|
||||||
// We want callbacks to be able to access errors
|
|
||||||
const bool downgrade = EventManager::GetInstance().isDowngradingErrorsOnCurrentThread();
|
|
||||||
if(downgrade)
|
|
||||||
EventManager::GetInstance().cancelErrorDowngradingOnCurrentThread();
|
|
||||||
for(auto& cb : messageCallbacks) {
|
|
||||||
if(!closing) { // We might have closed while reading or processing
|
|
||||||
cb.second.callIfMatch(msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(downgrade)
|
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
|
||||||
}
|
|
||||||
|
|
||||||
void Communication::readTask() {
|
void Communication::readTask() {
|
||||||
std::vector<uint8_t> readBytes;
|
std::vector<uint8_t> readBytes;
|
||||||
|
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
|
||||||
|
|
||||||
while(!closing) {
|
while(!closing) {
|
||||||
readBytes.clear();
|
readBytes.clear();
|
||||||
if(impl->readWait(readBytes)) {
|
if(impl->readWait(readBytes)) {
|
||||||
if(packetizer->input(readBytes)) {
|
if(packetizer->input(readBytes)) {
|
||||||
for(auto& packet : packetizer->output()) {
|
for(auto& packet : packetizer->output()) {
|
||||||
std::shared_ptr<Message> msg;
|
std::shared_ptr<Message> msg;
|
||||||
if(!decoder->decode(msg, packet))
|
if(!decoder->decode(msg, packet)) {
|
||||||
|
err(APIError::Unknown); // TODO Use specific error
|
||||||
continue;
|
continue;
|
||||||
|
}
|
||||||
dispatchMessage(msg);
|
|
||||||
|
for(auto& cb : messageCallbacks) {
|
||||||
|
if(!closing) { // We might have closed while reading or processing
|
||||||
|
cb.second.callIfMatch(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,12 +3,10 @@
|
|||||||
#include "icsneo/communication/message/serialnumbermessage.h"
|
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||||
#include "icsneo/communication/message/resetstatusmessage.h"
|
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||||
#include "icsneo/communication/message/readsettingsmessage.h"
|
#include "icsneo/communication/message/readsettingsmessage.h"
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
|
||||||
#include "icsneo/communication/command.h"
|
#include "icsneo/communication/command.h"
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/communication/packet/canpacket.h"
|
#include "icsneo/communication/packet/canpacket.h"
|
||||||
#include "icsneo/communication/packet/ethernetpacket.h"
|
#include "icsneo/communication/packet/ethernetpacket.h"
|
||||||
#include "icsneo/communication/packet/flexraypacket.h"
|
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
@@ -24,10 +22,8 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||||||
switch(packet->network.getType()) {
|
switch(packet->network.getType()) {
|
||||||
case Network::Type::Ethernet:
|
case Network::Type::Ethernet:
|
||||||
result = HardwareEthernetPacket::DecodeToMessage(packet->data);
|
result = HardwareEthernetPacket::DecodeToMessage(packet->data);
|
||||||
if(!result) {
|
if(!result)
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false; // A nullptr was returned, the packet was not long enough to decode
|
return false; // A nullptr was returned, the packet was not long enough to decode
|
||||||
}
|
|
||||||
|
|
||||||
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
||||||
// The resolution depends on the device
|
// The resolution depends on the device
|
||||||
@@ -37,33 +33,13 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||||||
case Network::Type::CAN:
|
case Network::Type::CAN:
|
||||||
case Network::Type::SWCAN:
|
case Network::Type::SWCAN:
|
||||||
case Network::Type::LSFTCAN: {
|
case Network::Type::LSFTCAN: {
|
||||||
if(packet->data.size() < 24) {
|
if(packet->data.size() < 24)
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
result = HardwareCANPacket::DecodeToMessage(packet->data);
|
||||||
if(!result) {
|
if(!result)
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false; // A nullptr was returned, the packet was malformed
|
return false; // A nullptr was returned, the packet was malformed
|
||||||
}
|
|
||||||
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
|
||||||
// The resolution depends on the device
|
|
||||||
result->timestamp *= timestampResolution;
|
|
||||||
result->network = packet->network;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
case Network::Type::FlexRay: {
|
|
||||||
if(packet->data.size() < 24) {
|
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
result = HardwareFlexRayPacket::DecodeToMessage(packet->data);
|
|
||||||
if(!result) {
|
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false; // A nullptr was returned, the packet was malformed
|
|
||||||
}
|
|
||||||
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
// Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000
|
||||||
// The resolution depends on the device
|
// The resolution depends on the device
|
||||||
result->timestamp *= timestampResolution;
|
result->timestamp *= timestampResolution;
|
||||||
@@ -73,10 +49,8 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||||||
case Network::Type::Internal: {
|
case Network::Type::Internal: {
|
||||||
switch(packet->network.getNetID()) {
|
switch(packet->network.getNetID()) {
|
||||||
case Network::NetID::Reset_Status: {
|
case Network::NetID::Reset_Status: {
|
||||||
if(packet->data.size() < sizeof(HardwareResetStatusPacket)) {
|
if(packet->data.size() < sizeof(HardwareResetStatusPacket))
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
HardwareResetStatusPacket* data = (HardwareResetStatusPacket*)packet->data.data();
|
HardwareResetStatusPacket* data = (HardwareResetStatusPacket*)packet->data.data();
|
||||||
auto msg = std::make_shared<ResetStatusMessage>();
|
auto msg = std::make_shared<ResetStatusMessage>();
|
||||||
@@ -101,15 +75,6 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||||||
result = msg;
|
result = msg;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
case Network::NetID::FlexRayControl: {
|
|
||||||
auto frResult = std::make_shared<FlexRayControlMessage>(*packet);
|
|
||||||
if(!frResult->decoded) {
|
|
||||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
result = frResult;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
default:
|
default:
|
||||||
break;//return false;
|
break;//return false;
|
||||||
}
|
}
|
||||||
@@ -146,7 +111,7 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||||||
/* So-called "old format" messages are a "new style, long format" wrapper around the old short messages.
|
/* 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
|
* 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
|
* with no checksum. The upper-nibble length of the combo byte should be ignored completely, using the
|
||||||
* length from the first two bytes in its place. Ideally, we never actually send the oldformat messages
|
* length from the first two bytes in it's place. Ideally, we never actually send the oldformat messages
|
||||||
* out to the rest of the application as they can recursively get decoded to another message type here.
|
* out to the rest of the application as they can recursively get decoded to another message type here.
|
||||||
* Feed the result back into the decoder in case we do something special with the resultant netid.
|
* Feed the result back into the decoder in case we do something special with the resultant netid.
|
||||||
*/
|
*/
|
||||||
|
|||||||
+10
-35
@@ -13,13 +13,11 @@ bool Encoder::encode(std::vector<uint8_t>& result, const std::shared_ptr<Message
|
|||||||
switch(message->network.getType()) {
|
switch(message->network.getType()) {
|
||||||
case Network::Type::Ethernet: {
|
case Network::Type::Ethernet: {
|
||||||
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(message);
|
auto ethmsg = std::dynamic_pointer_cast<EthernetMessage>(message);
|
||||||
if(!ethmsg) {
|
if(!ethmsg)
|
||||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
|
||||||
return false; // The message was not a properly formed EthernetMessage
|
return false; // The message was not a properly formed EthernetMessage
|
||||||
}
|
|
||||||
|
|
||||||
useResultAsBuffer = true;
|
useResultAsBuffer = true;
|
||||||
if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, report))
|
if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -28,18 +26,14 @@ bool Encoder::encode(std::vector<uint8_t>& result, const std::shared_ptr<Message
|
|||||||
case Network::Type::SWCAN:
|
case Network::Type::SWCAN:
|
||||||
case Network::Type::LSFTCAN: {
|
case Network::Type::LSFTCAN: {
|
||||||
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
auto canmsg = std::dynamic_pointer_cast<CANMessage>(message);
|
||||||
if(!canmsg) {
|
if(!canmsg)
|
||||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
|
||||||
return false; // The message was not a properly formed CANMessage
|
return false; // The message was not a properly formed CANMessage
|
||||||
}
|
|
||||||
|
|
||||||
if(!supportCANFD && canmsg->isCANFD) {
|
if(!supportCANFD && canmsg->isCANFD)
|
||||||
report(APIEvent::Type::CANFDNotSupported, APIEvent::Severity::Error);
|
|
||||||
return false; // This device does not support CAN FD
|
return false; // This device does not support CAN FD
|
||||||
}
|
|
||||||
|
|
||||||
useResultAsBuffer = true;
|
useResultAsBuffer = true;
|
||||||
if(!HardwareCANPacket::EncodeFromMessage(*canmsg, result, report))
|
if(!HardwareCANPacket::EncodeFromMessage(*canmsg, result))
|
||||||
return false; // The CANMessage was malformed
|
return false; // The CANMessage was malformed
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -75,7 +69,6 @@ bool Encoder::encode(std::vector<uint8_t>& result, const std::shared_ptr<Message
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -103,27 +96,9 @@ bool Encoder::encode(std::vector<uint8_t>& result, const std::shared_ptr<Message
|
|||||||
|
|
||||||
bool Encoder::encode(std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments) {
|
bool Encoder::encode(std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments) {
|
||||||
auto msg = std::make_shared<Message>();
|
auto msg = std::make_shared<Message>();
|
||||||
if(cmd == Command::UpdateLEDState) {
|
msg->network = Network::NetID::Main51;
|
||||||
/* NetID::Device is a super old command type.
|
msg->data.reserve(arguments.size() + 1);
|
||||||
* It has a leading 0x00 byte, a byte for command, and a byte for an argument.
|
msg->data.push_back((uint8_t)cmd);
|
||||||
* In this case, command 0x06 is SetLEDState.
|
msg->data.insert(msg->data.end(), std::make_move_iterator(arguments.begin()), std::make_move_iterator(arguments.end()));
|
||||||
* This old command type is not really used anywhere else.
|
|
||||||
*/
|
|
||||||
if (arguments.empty()) {
|
|
||||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
msg->network = Network::NetID::Device;
|
|
||||||
msg->data.reserve(3);
|
|
||||||
msg->data.push_back(0x00);
|
|
||||||
msg->data.push_back(0x06); // SetLEDState
|
|
||||||
msg->data.push_back(arguments.at(0)); // See Device::LEDState
|
|
||||||
} else {
|
|
||||||
msg->network = Network::NetID::Main51;
|
|
||||||
msg->data.reserve(arguments.size() + 1);
|
|
||||||
msg->data.push_back((uint8_t)cmd);
|
|
||||||
msg->data.insert(msg->data.end(), std::make_move_iterator(arguments.begin()), std::make_move_iterator(arguments.end()));
|
|
||||||
}
|
|
||||||
|
|
||||||
return encode(result, msg);
|
return encode(result, msg);
|
||||||
}
|
}
|
||||||
@@ -39,25 +39,16 @@ bool ICommunication::readWait(std::vector<uint8_t>& bytes, std::chrono::millisec
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool ICommunication::write(const std::vector<uint8_t>& bytes) {
|
bool ICommunication::write(const std::vector<uint8_t>& bytes) {
|
||||||
if(!isOpen()) {
|
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(writeBlocks) {
|
if(writeBlocks) {
|
||||||
std::unique_lock<std::mutex> lk(writeMutex);
|
std::unique_lock<std::mutex> lk(writeMutex);
|
||||||
if(writeQueue.size_approx() > writeQueueSize)
|
if(writeQueue.size_approx() > writeQueueSize) {
|
||||||
writeCV.wait(lk);
|
writeCV.wait(lk);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
if(writeQueue.size_approx() > writeQueueSize) {
|
if(writeQueue.size_approx() > writeQueueSize) {
|
||||||
report(APIEvent::Type::TransmitBufferFull, APIEvent::Severity::Error);
|
err(APIError::TransmitBufferFull);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return writeQueue.enqueue(WriteOperation(bytes));
|
||||||
bool ret = writeQueue.enqueue(WriteOperation(bytes));
|
|
||||||
if(!ret)
|
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
|
||||||
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
@@ -1,72 +0,0 @@
|
|||||||
#include <icsneo/communication/message/flexray/control/flexraycontrolmessage.h>
|
|
||||||
#include <cstring> // memcpy
|
|
||||||
#include <limits>
|
|
||||||
#include <algorithm>
|
|
||||||
|
|
||||||
using namespace icsneo;
|
|
||||||
|
|
||||||
std::vector<uint8_t> FlexRayControlMessage::BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, std::initializer_list<uint8_t> args) {
|
|
||||||
std::vector<uint8_t> ret;
|
|
||||||
ret.reserve(args.size() + 4);
|
|
||||||
ret.push_back(controller);
|
|
||||||
const uint16_t size = uint16_t((std::min)(args.size() + 1, size_t(std::numeric_limits<uint16_t>::max()))); // Add 1 for the opcode
|
|
||||||
ret.push_back(uint8_t(size));
|
|
||||||
ret.push_back(uint8_t(size >> 8));
|
|
||||||
ret.push_back(uint8_t(op));
|
|
||||||
ret.insert(ret.end(), args.begin(), args.end());
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> FlexRayControlMessage::BuildReadCCRegsArgs(uint8_t controller, uint16_t startAddress, uint8_t numRegisters) {
|
|
||||||
startAddress /= 4;
|
|
||||||
return BuildBaseControlArgs(controller, FlexRay::Opcode::ReadCCRegs, {
|
|
||||||
uint8_t(startAddress),
|
|
||||||
uint8_t(startAddress >> 8),
|
|
||||||
numRegisters
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> FlexRayControlMessage::BuildWriteCCRegArgs(uint8_t controller, uint16_t address, uint32_t value) {
|
|
||||||
address /= 4;
|
|
||||||
return BuildBaseControlArgs(controller, FlexRay::Opcode::ReadCCRegs, {
|
|
||||||
uint8_t(address),
|
|
||||||
uint8_t(address >> 8),
|
|
||||||
uint8_t(value),
|
|
||||||
uint8_t(value >> 8),
|
|
||||||
uint8_t(value >> 16),
|
|
||||||
uint8_t(value >> 24)
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
FlexRayControlMessage::FlexRayControlMessage(const Packet& packet) : Message() {
|
|
||||||
if(packet.data.size() < 2)
|
|
||||||
return; // huh?
|
|
||||||
controller = packet.data[0];
|
|
||||||
if(controller < 2)
|
|
||||||
return; // Invalid controller
|
|
||||||
|
|
||||||
// Opcode is only ReadCCStatus or ReadCCRegs for the moment
|
|
||||||
opcode = FlexRay::Opcode(packet.data[1]);
|
|
||||||
if(opcode != FlexRay::Opcode::ReadCCRegs && opcode != FlexRay::Opcode::ReadCCStatus)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Read out registers
|
|
||||||
size_t bytes = packet.data.size() - 2;
|
|
||||||
const size_t count = bytes / sizeof(uint32_t);
|
|
||||||
bytes -= bytes % sizeof(uint32_t); // trim off any trailing bytes
|
|
||||||
registers.resize(count);
|
|
||||||
memcpy(registers.data(), packet.data.data() + 2, bytes);
|
|
||||||
|
|
||||||
// If it was a status message, we should decode these registers into their components
|
|
||||||
if(opcode == FlexRay::Opcode::ReadCCStatus) {
|
|
||||||
if(count < 8)
|
|
||||||
return;
|
|
||||||
pocStatus = FlexRay::POCStatus(registers[0] & 0x0000003F);
|
|
||||||
slotCounterA = registers[4] & 0x0000FFFF;
|
|
||||||
slotCounterB = (registers[4] & 0xFFFF0000) >> 16;
|
|
||||||
rateCorrection = registers[6];
|
|
||||||
offsetCorrection = registers[7];
|
|
||||||
}
|
|
||||||
|
|
||||||
decoded = true;
|
|
||||||
}
|
|
||||||
@@ -25,13 +25,10 @@ bool MultiChannelCommunication::sendPacket(std::vector<uint8_t>& bytes) {
|
|||||||
|
|
||||||
void MultiChannelCommunication::readTask() {
|
void MultiChannelCommunication::readTask() {
|
||||||
bool readMore = true;
|
bool readMore = true;
|
||||||
bool gotPacket = false; // Have we got the first valid packet (don't flag errors otherwise)
|
|
||||||
std::deque<uint8_t> usbReadFifo;
|
std::deque<uint8_t> usbReadFifo;
|
||||||
std::vector<uint8_t> readBytes;
|
std::vector<uint8_t> readBytes;
|
||||||
std::vector<uint8_t> payloadBytes;
|
std::vector<uint8_t> payloadBytes;
|
||||||
|
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
|
||||||
|
|
||||||
while(!closing) {
|
while(!closing) {
|
||||||
if(readMore) {
|
if(readMore) {
|
||||||
readBytes.clear();
|
readBytes.clear();
|
||||||
@@ -50,8 +47,8 @@ void MultiChannelCommunication::readTask() {
|
|||||||
currentCommandType = (CommandType)usbReadFifo[0];
|
currentCommandType = (CommandType)usbReadFifo[0];
|
||||||
|
|
||||||
if(!CommandTypeIsValid(currentCommandType)) {
|
if(!CommandTypeIsValid(currentCommandType)) {
|
||||||
// Device to host bytes discarded
|
// TODO Flag error? Device to host bytes discarded
|
||||||
EventManager::GetInstance().add(APIEvent(APIEvent::Type::FailedToRead, APIEvent::Severity::Error));
|
//std::cout << "cnv" << std::hex << (int)currentCommandType << ' ' << std::dec;
|
||||||
usbReadFifo.pop_front();
|
usbReadFifo.pop_front();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -109,11 +106,16 @@ void MultiChannelCommunication::readTask() {
|
|||||||
if(packetizer->input(payloadBytes)) {
|
if(packetizer->input(payloadBytes)) {
|
||||||
for(auto& packet : packetizer->output()) {
|
for(auto& packet : packetizer->output()) {
|
||||||
std::shared_ptr<Message> msg;
|
std::shared_ptr<Message> msg;
|
||||||
if(!decoder->decode(msg, packet))
|
if(!decoder->decode(msg, packet)) {
|
||||||
continue; // Error will have been reported from within decoder
|
err(APIError::Unknown); // TODO Use specific error
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
gotPacket = true;
|
for(auto& cb : messageCallbacks) { // We might have closed while reading or processing
|
||||||
dispatchMessage(msg);
|
if(!closing) {
|
||||||
|
cb.second.callIfMatch(msg);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -79,17 +79,13 @@ std::shared_ptr<CANMessage> HardwareCANPacket::DecodeToMessage(const std::vector
|
|||||||
return msg;
|
return msg;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector<uint8_t>& result, const device_eventhandler_t& report) {
|
bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector<uint8_t>& result) {
|
||||||
if(message.isCANFD && message.isRemote) {
|
if(message.isCANFD && message.isRemote)
|
||||||
report(APIEvent::Type::RTRNotSupported, APIEvent::Severity::Error);
|
|
||||||
return false; // RTR frames can not be used with CAN FD
|
return false; // RTR frames can not be used with CAN FD
|
||||||
}
|
|
||||||
|
|
||||||
const size_t dataSize = message.data.size();
|
const size_t dataSize = message.data.size();
|
||||||
if(dataSize > 64 || (dataSize > 8 && !message.isCANFD)) {
|
if(dataSize > 64 || (dataSize > 8 && !message.isCANFD))
|
||||||
report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error);
|
|
||||||
return false; // Too much data for the protocol
|
return false; // Too much data for the protocol
|
||||||
}
|
|
||||||
|
|
||||||
uint8_t lengthNibble = uint8_t(message.data.size());
|
uint8_t lengthNibble = uint8_t(message.data.size());
|
||||||
uint8_t paddingBytes = 0;
|
uint8_t paddingBytes = 0;
|
||||||
@@ -166,7 +162,6 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector
|
|||||||
lengthNibble = 0xF;
|
lengthNibble = 0xF;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error);
|
|
||||||
return false; // CAN FD frame may have had an incorrect byte count
|
return false; // CAN FD frame may have had an incorrect byte count
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -181,10 +176,8 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector
|
|||||||
|
|
||||||
// Next 2-4 bytes are ArbID
|
// Next 2-4 bytes are ArbID
|
||||||
if(message.isExtended) {
|
if(message.isExtended) {
|
||||||
if(message.arbid >= 0x20000000) {// Extended messages use 29-bit arb IDs
|
if(message.arbid >= 0x20000000) // Extended messages use 29-bit arb IDs
|
||||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
result.insert(result.end(), {
|
result.insert(result.end(), {
|
||||||
(uint8_t)(message.arbid >> 21),
|
(uint8_t)(message.arbid >> 21),
|
||||||
@@ -193,10 +186,8 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector
|
|||||||
(uint8_t)message.arbid
|
(uint8_t)message.arbid
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
if(message.arbid >= 0x800) {// Standard messages use 11-bit arb IDs
|
if(message.arbid >= 0x800) // Standard messages use 11-bit arb IDs
|
||||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
result.insert(result.end(), {
|
result.insert(result.end(), {
|
||||||
(uint8_t)(message.arbid >> 3),
|
(uint8_t)(message.arbid >> 3),
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ std::shared_ptr<EthernetMessage> HardwareEthernetPacket::DecodeToMessage(const s
|
|||||||
return messagePtr;
|
return messagePtr;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t&) {
|
bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream) {
|
||||||
const size_t unpaddedSize = message.data.size();
|
const size_t unpaddedSize = message.data.size();
|
||||||
size_t paddedSize = unpaddedSize;
|
size_t paddedSize = unpaddedSize;
|
||||||
|
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#include "icsneo/communication/packet/flexraypacket.h"
|
|
||||||
|
|
||||||
using namespace icsneo;
|
|
||||||
|
|
||||||
std::shared_ptr<FlexRayMessage> HardwareFlexRayPacket::DecodeToMessage(const std::vector<uint8_t>& bytestream) {
|
|
||||||
const HardwareFlexRayPacket* data = (const HardwareFlexRayPacket*)bytestream.data();
|
|
||||||
if(!data->timestamp.IsExtended) // We can only process "extended" frames here
|
|
||||||
return nullptr;
|
|
||||||
|
|
||||||
auto msg = std::make_shared<FlexRayMessage>();
|
|
||||||
|
|
||||||
// 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;
|
|
||||||
|
|
||||||
// Always get the frame length, even for a symbol
|
|
||||||
msg->framelen = data->frame_length_12_5ns * 12.5e-9;
|
|
||||||
|
|
||||||
if(data->tss_length_12_5ns == 0xffff) {// Flag value meaning this is a symbol
|
|
||||||
msg->symbol = FlexRay::Symbol::Unknown; // We can't know the symbol yet because this will depend on the baudrate
|
|
||||||
// Eventually we'll have to get this from the framelen
|
|
||||||
} else {
|
|
||||||
msg->tsslen = data->tss_length_12_5ns * 12.5e-9;
|
|
||||||
msg->channelB = data->statusBits.bits.chb;
|
|
||||||
|
|
||||||
if(data->statusBits.bits.bytesRxed >= 5) {
|
|
||||||
if(data->statusBits.bits.hcrc_error)
|
|
||||||
msg->headerCRCStatus = FlexRay::CRCStatus::Error;
|
|
||||||
} else {
|
|
||||||
msg->headerCRCStatus = FlexRay::CRCStatus::NoCRC;
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t numBytes = data->payload_len * 2;
|
|
||||||
if(int64_t(numBytes) >= int64_t(data->Length) - 4) {
|
|
||||||
if(data->statusBits.bits.fcrc_error)
|
|
||||||
msg->crcStatus = FlexRay::CRCStatus::Error;
|
|
||||||
} else {
|
|
||||||
msg->crcStatus = FlexRay::CRCStatus::NoCRC;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(data->statusBits.bits.bytesRxed >= 5) { // Received entire header
|
|
||||||
msg->headerCRC = (data->hdr_crc_10 << 10) | data->hdr_crc_9_0;
|
|
||||||
if(msg->headerCRCStatus != FlexRay::CRCStatus::Error) {
|
|
||||||
msg->reserved0was1 = data->reserved_0;
|
|
||||||
msg->payloadPreamble = data->payload_preamble;
|
|
||||||
msg->nullFrame = data->null_frame;
|
|
||||||
msg->sync = data->sync;
|
|
||||||
msg->startup = data->startup;
|
|
||||||
msg->slotid = data->slotid;
|
|
||||||
if(int64_t(numBytes) != int64_t(data->Length) - 4) {
|
|
||||||
|
|
||||||
} else {
|
|
||||||
// This is an error, probably need to flag it
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool HardwareFlexRayPacket::EncodeFromMessage(const FlexRayMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) {
|
|
||||||
(void)message;
|
|
||||||
(void)bytestream;
|
|
||||||
(void)report;
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
@@ -41,7 +41,6 @@ bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
|
|||||||
state = ReadState::ParseHeader;
|
state = ReadState::ParseHeader;
|
||||||
currentIndex = 1;
|
currentIndex = 1;
|
||||||
} else {
|
} else {
|
||||||
std::cerr << "Discarding byte " << std::hex << std::setw(2) << std::setfill('0') << int(bytes.front()) << std::endl;
|
|
||||||
bytes.pop_front(); // Discard
|
bytes.pop_front(); // Discard
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -82,23 +81,8 @@ bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
|
|||||||
* payload, and not the header or checksum.
|
* payload, and not the header or checksum.
|
||||||
*/
|
*/
|
||||||
if(packetLength < 4 || packetLength > 4000) {
|
if(packetLength < 4 || packetLength > 4000) {
|
||||||
std::cerr << "====================================\n";
|
|
||||||
std::cerr << "An improper packet has occurred!\n";
|
|
||||||
std::cerr << "Packet: (" << std::dec << packetLength << ")\n";
|
|
||||||
std::cerr << '\t';
|
|
||||||
for(auto i = 0; i < std::min(packetLength, 16); i++)
|
|
||||||
std::cerr << std::hex << std::setw(2) << std::setfill('0') << int(bytes[i]) << ' ';
|
|
||||||
std::cerr << std::endl;
|
|
||||||
std::cerr << "Previous: (" << std::dec << previousPacket.data.size() << ") " << previousPacket.network << '\n';
|
|
||||||
for(auto i = 0; i < previousPacket.data.size(); i += 16) {
|
|
||||||
std::cerr << '\t';
|
|
||||||
for(auto j = 0; j < 16 && (i + j) < previousPacket.data.size(); j++)
|
|
||||||
std::cerr << std::hex << std::setw(2) << std::setfill('0') << int(previousPacket.data[i+j]) << ' ';
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
std::cerr << "====================================\n";
|
|
||||||
bytes.pop_front();
|
bytes.pop_front();
|
||||||
EventManager::GetInstance().add(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
//std::cout << "skipping long packet with length " << packetLength << std::endl;
|
||||||
state = ReadState::SearchForHeader;
|
state = ReadState::SearchForHeader;
|
||||||
} else {
|
} else {
|
||||||
state = ReadState::GetData;
|
state = ReadState::GetData;
|
||||||
@@ -127,29 +111,9 @@ bool Packetizer::input(const std::vector<uint8_t>& inputBytes) {
|
|||||||
bytes.pop_front();
|
bytes.pop_front();
|
||||||
} else {
|
} else {
|
||||||
if(gotGoodPackets) // Don't complain unless we've already gotten a good packet, in case we started in the middle of a stream
|
if(gotGoodPackets) // Don't complain unless we've already gotten a good packet, in case we started in the middle of a stream
|
||||||
report(APIEvent::Type::PacketChecksumError, APIEvent::Severity::Error);
|
err(APIError::PacketChecksumError);
|
||||||
|
|
||||||
std::cerr << "====================================\n";
|
|
||||||
std::cerr << "A checksum error has occurred!\n";
|
|
||||||
std::cerr << "Packet: (" << std::dec << packet.data.size() << ") " << packet.network << '\n';
|
|
||||||
for(auto i = 0; i < packet.data.size(); i += 16) {
|
|
||||||
std::cerr << '\t';
|
|
||||||
for(auto j = 0; j < 16 && (i + j) < packet.data.size(); j++)
|
|
||||||
std::cerr << std::hex << std::setw(2) << std::setfill('0') << int(packet.data[i+j]) << ' ';
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
std::cerr << "Previous: (" << std::dec << previousPacket.data.size() << ") " << previousPacket.network << '\n';
|
|
||||||
for(auto i = 0; i < previousPacket.data.size(); i += 16) {
|
|
||||||
std::cerr << '\t';
|
|
||||||
for(auto j = 0; j < 16 && (i + j) < previousPacket.data.size(); j++)
|
|
||||||
std::cerr << std::hex << std::setw(2) << std::setfill('0') << int(previousPacket.data[i+j]) << ' ';
|
|
||||||
std::cerr << std::endl;
|
|
||||||
}
|
|
||||||
std::cerr << "====================================\n";
|
|
||||||
|
|
||||||
bytes.pop_front(); // Drop the first byte so it doesn't get picked up again
|
bytes.pop_front(); // Drop the first byte so it doesn't get picked up again
|
||||||
}
|
}
|
||||||
previousPacket = packet;
|
|
||||||
|
|
||||||
// Reset for the next packet
|
// Reset for the next packet
|
||||||
currentIndex = 0;
|
currentIndex = 0;
|
||||||
|
|||||||
+28
-122
@@ -1,11 +1,9 @@
|
|||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/communication/message/callback/messagecallback.h"
|
#include "icsneo/communication/message/callback/messagecallback.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
|
||||||
#include "icsneo/communication/command.h"
|
#include "icsneo/communication/command.h"
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <chrono>
|
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
@@ -79,55 +77,33 @@ std::string Device::describe() const {
|
|||||||
return ss.str();
|
return ss.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::enableMessagePolling() {
|
void Device::enableMessagePolling() {
|
||||||
if(isMessagePollingEnabled()) {// We are already polling
|
if(messagePollingCallbackID != 0) // We are already polling
|
||||||
report(APIEvent::Type::DeviceCurrentlyPolling, APIEvent::Severity::Error);
|
return;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
messagePollingCallbackID = com->addMessageCallback(MessageCallback([this](std::shared_ptr<Message> message) {
|
messagePollingCallbackID = com->addMessageCallback(MessageCallback([this](std::shared_ptr<Message> message) {
|
||||||
pollingContainer.enqueue(message);
|
pollingContainer.enqueue(message);
|
||||||
enforcePollingMessageLimit();
|
enforcePollingMessageLimit();
|
||||||
}));
|
}));
|
||||||
return true;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::disableMessagePolling() {
|
bool Device::disableMessagePolling() {
|
||||||
if(!isMessagePollingEnabled()) {
|
if(messagePollingCallbackID == 0)
|
||||||
report(APIEvent::Type::DeviceNotCurrentlyPolling, APIEvent::Severity::Error);
|
return true; // Not currently polling
|
||||||
return false; // Not currently polling
|
|
||||||
}
|
|
||||||
auto ret = com->removeMessageCallback(messagePollingCallbackID);
|
auto ret = com->removeMessageCallback(messagePollingCallbackID);
|
||||||
getMessages(); // Flush any messages still in the container
|
getMessages(); // Flush any messages still in the container
|
||||||
messagePollingCallbackID = 0;
|
messagePollingCallbackID = 0;
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns a pair of {vector, bool}, where the vector contains shared_ptrs to the returned msgs and the bool is whether or not the call was successful.
|
std::vector<std::shared_ptr<Message>> Device::getMessages() {
|
||||||
std::pair<std::vector<std::shared_ptr<Message>>, bool> Device::getMessages() {
|
|
||||||
std::vector<std::shared_ptr<Message>> ret;
|
std::vector<std::shared_ptr<Message>> ret;
|
||||||
bool retBool = getMessages(ret);
|
getMessages(ret);
|
||||||
return std::make_pair(ret, retBool);
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::getMessages(std::vector<std::shared_ptr<Message>>& container, size_t limit, std::chrono::milliseconds timeout) {
|
bool Device::getMessages(std::vector<std::shared_ptr<Message>>& container, size_t limit, std::chrono::milliseconds timeout) {
|
||||||
// not open
|
|
||||||
if(!isOpen()) {
|
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not online
|
|
||||||
if(!isOnline()) {
|
|
||||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// not currently polling, throw error
|
|
||||||
if(!isMessagePollingEnabled()) {
|
|
||||||
report(APIEvent::Type::DeviceNotCurrentlyPolling, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// A limit of zero indicates no limit
|
// A limit of zero indicates no limit
|
||||||
if(limit == 0)
|
if(limit == 0)
|
||||||
limit = (size_t)-1;
|
limit = (size_t)-1;
|
||||||
@@ -154,19 +130,18 @@ void Device::enforcePollingMessageLimit() {
|
|||||||
while(pollingContainer.size_approx() > pollingMessageLimit) {
|
while(pollingContainer.size_approx() > pollingMessageLimit) {
|
||||||
std::shared_ptr<Message> throwAway;
|
std::shared_ptr<Message> throwAway;
|
||||||
pollingContainer.try_dequeue(throwAway);
|
pollingContainer.try_dequeue(throwAway);
|
||||||
report(APIEvent::Type::PollingMessageOverflow, APIEvent::Severity::EventWarning);
|
err(APIError::PollingMessageOverflow);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::open() {
|
bool Device::open() {
|
||||||
if(!com) {
|
if(!com) {
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
err(APIError::Unknown);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!com->open()) {
|
if(!com->open())
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
auto serial = com->getSerialNumberSync();
|
auto serial = com->getSerialNumberSync();
|
||||||
int i = 0;
|
int i = 0;
|
||||||
@@ -176,24 +151,20 @@ bool Device::open() {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(!serial) {
|
if(!serial) {
|
||||||
report(APIEvent::Type::NoSerialNumber, APIEvent::Severity::Error); // Communication could not be established with the device. Perhaps it is not powered with 12 volts?
|
err(APIError::NoSerialNumber);
|
||||||
com->close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string currentSerial = getNeoDevice().serial;
|
std::string currentSerial = getNeoDevice().serial;
|
||||||
if(currentSerial != serial->deviceSerial) {
|
if(currentSerial != serial->deviceSerial) {
|
||||||
report(APIEvent::Type::IncorrectSerialNumber, APIEvent::Severity::Error);
|
err(APIError::IncorrectSerialNumber);
|
||||||
com->close();
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!settings->disabled)
|
if(!settings->disabled)
|
||||||
settings->refresh();
|
settings->refresh();
|
||||||
|
|
||||||
MessageFilter filter;
|
internalHandlerCallbackID = com->addMessageCallback(MessageCallback(MessageFilter(Network::Type::Internal), [this](std::shared_ptr<Message> message) {
|
||||||
filter.includeInternalInAny = true;
|
|
||||||
internalHandlerCallbackID = com->addMessageCallback(MessageCallback(filter, [this](std::shared_ptr<Message> message) {
|
|
||||||
handleInternalMessage(message);
|
handleInternalMessage(message);
|
||||||
}));
|
}));
|
||||||
|
|
||||||
@@ -202,18 +173,14 @@ bool Device::open() {
|
|||||||
|
|
||||||
bool Device::close() {
|
bool Device::close() {
|
||||||
if(!com) {
|
if(!com) {
|
||||||
report(APIEvent::Type::Unknown, APIEvent::Severity::Error);
|
err(APIError::Unknown);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(isOnline())
|
|
||||||
goOffline();
|
|
||||||
|
|
||||||
if(internalHandlerCallbackID)
|
if(internalHandlerCallbackID)
|
||||||
com->removeMessageCallback(internalHandlerCallbackID);
|
com->removeMessageCallback(internalHandlerCallbackID);
|
||||||
|
|
||||||
internalHandlerCallbackID = 0;
|
goOffline();
|
||||||
|
|
||||||
return com->close();
|
return com->close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -221,28 +188,10 @@ bool Device::goOnline() {
|
|||||||
if(!com->sendCommand(Command::EnableNetworkCommunication, true))
|
if(!com->sendCommand(Command::EnableNetworkCommunication, true))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto startTime = std::chrono::system_clock::now();
|
|
||||||
|
|
||||||
ledState = LEDState::Online;
|
ledState = LEDState::Online;
|
||||||
|
|
||||||
updateLEDState();
|
updateLEDState();
|
||||||
|
|
||||||
MessageFilter filter(Network::NetID::Reset_Status);
|
|
||||||
filter.includeInternalInAny = true;
|
|
||||||
|
|
||||||
// Wait until communication is enabled or 5 seconds, whichever comes first
|
|
||||||
while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) {
|
|
||||||
if(latestResetStatus && latestResetStatus->comEnabled)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!com->sendCommand(Command::RequestStatusUpdate))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
com->waitForMessageSync(filter, std::chrono::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
online = true;
|
online = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -250,48 +199,16 @@ bool Device::goOffline() {
|
|||||||
if(!com->sendCommand(Command::EnableNetworkCommunication, false))
|
if(!com->sendCommand(Command::EnableNetworkCommunication, false))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
auto startTime = std::chrono::system_clock::now();
|
|
||||||
|
|
||||||
ledState = (latestResetStatus && latestResetStatus->cmRunning) ? LEDState::CoreMiniRunning : LEDState::Offline;
|
ledState = (latestResetStatus && latestResetStatus->cmRunning) ? LEDState::CoreMiniRunning : LEDState::Offline;
|
||||||
|
|
||||||
updateLEDState();
|
updateLEDState();
|
||||||
|
|
||||||
MessageFilter filter(Network::NetID::Reset_Status);
|
|
||||||
filter.includeInternalInAny = true;
|
|
||||||
|
|
||||||
// wait until communication is disabled or 10 seconds, whichever comes first
|
|
||||||
while((std::chrono::system_clock::now() - startTime) < std::chrono::seconds(5)) {
|
|
||||||
if(latestResetStatus && !latestResetStatus->comEnabled)
|
|
||||||
break;
|
|
||||||
|
|
||||||
if(!com->sendCommand(Command::RequestStatusUpdate))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
com->waitForMessageSync(filter, std::chrono::milliseconds(100));
|
|
||||||
}
|
|
||||||
|
|
||||||
online = false;
|
online = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Device::transmit(std::shared_ptr<Message> message) {
|
bool Device::transmit(std::shared_ptr<Message> message) {
|
||||||
// not open
|
if(!isSupportedTXNetwork(message->network))
|
||||||
if(!isOpen()) {
|
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
// not online
|
|
||||||
if(!isOnline()) {
|
|
||||||
report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!isSupportedTXNetwork(message->network)) {
|
|
||||||
report(APIEvent::Type::UnsupportedTXNetwork, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> packet;
|
std::vector<uint8_t> packet;
|
||||||
if(!com->encoder->encode(packet, message))
|
if(!com->encoder->encode(packet, message))
|
||||||
@@ -308,10 +225,6 @@ bool Device::transmit(std::vector<std::shared_ptr<Message>> messages) {
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::setWriteBlocks(bool blocks) {
|
|
||||||
com->setWriteBlocks(blocks);
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t Device::getNetworkCountByType(Network::Type type) const {
|
size_t Device::getNetworkCountByType(Network::Type type) const {
|
||||||
size_t count = 0;
|
size_t count = 0;
|
||||||
for(const auto& net : getSupportedRXNetworks())
|
for(const auto& net : getSupportedRXNetworks())
|
||||||
@@ -333,17 +246,6 @@ Network Device::getNetworkByNumber(Network::Type type, size_t index) const {
|
|||||||
return Network::NetID::Invalid;
|
return Network::NetID::Invalid;
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::addExtension(std::shared_ptr<DeviceExtension>&& extension) {
|
|
||||||
std::lock_guard<std::mutex> lk(extensionsLock);
|
|
||||||
extensions.push_back(extension);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::forEachExtension(std::function<void(const std::shared_ptr<DeviceExtension>&)> fn) {
|
|
||||||
std::lock_guard<std::mutex> lk(extensionsLock);
|
|
||||||
for(const auto& ext : extensions)
|
|
||||||
fn(ext);
|
|
||||||
}
|
|
||||||
|
|
||||||
void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
||||||
switch(message->network.getNetID()) {
|
switch(message->network.getNetID()) {
|
||||||
case Network::NetID::Reset_Status:
|
case Network::NetID::Reset_Status:
|
||||||
@@ -352,12 +254,16 @@ void Device::handleInternalMessage(std::shared_ptr<Message> message) {
|
|||||||
default:
|
default:
|
||||||
break; //std::cout << "HandleInternalMessage got a message from " << message->network << " and it was unhandled!" << std::endl;
|
break; //std::cout << "HandleInternalMessage got a message from " << message->network << " and it was unhandled!" << std::endl;
|
||||||
}
|
}
|
||||||
forEachExtension([&](const std::shared_ptr<DeviceExtension>& ext) {
|
|
||||||
ext->handleMessage(message);
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void Device::updateLEDState() {
|
void Device::updateLEDState() {
|
||||||
std::vector<uint8_t> args {(uint8_t) ledState};
|
/* NetID::Device is a super old command type.
|
||||||
com->sendCommand(Command::UpdateLEDState, args);
|
* 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 msg = std::make_shared<Message>();
|
||||||
|
msg->network = Network::NetID::Device;
|
||||||
|
msg->data = {0x00, 0x06, uint8_t(ledState)};
|
||||||
|
transmit(msg);
|
||||||
}
|
}
|
||||||
@@ -38,10 +38,6 @@ static std::vector<DeviceType> supportedDevices = {
|
|||||||
RADGalaxy::DEVICE_TYPE,
|
RADGalaxy::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADPLUTOUSB_H_
|
|
||||||
RADPlutoUSB::DEVICE_TYPE,
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __RADSTAR2ETH_H_
|
#ifdef __RADSTAR2ETH_H_
|
||||||
RADStar2ETH::DEVICE_TYPE,
|
RADStar2ETH::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
@@ -116,10 +112,6 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
|||||||
findResults.push_back(RADGalaxy::Find());
|
findResults.push_back(RADGalaxy::Find());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADPLUTOUSB_H_
|
|
||||||
findResults.push_back(RADPlutoUSB::Find());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef __RADSTAR2ETH_H_
|
#ifdef __RADSTAR2ETH_H_
|
||||||
findResults.push_back(RADStar2ETH::Find());
|
findResults.push_back(RADStar2ETH::Find());
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -1,120 +0,0 @@
|
|||||||
#include "icsneo/device/extensions/flexray/controller.h"
|
|
||||||
#include "icsneo/device/device.h"
|
|
||||||
|
|
||||||
using namespace icsneo;
|
|
||||||
|
|
||||||
std::shared_ptr<FlexRayControlMessage> FlexRay::Controller::getStatus() const {
|
|
||||||
std::lock_guard<std::mutex> lk(statusLock);
|
|
||||||
return status;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlexRay::Controller::_setStatus(std::shared_ptr<FlexRayControlMessage> msg) {
|
|
||||||
std::lock_guard<std::mutex> lk(statusLock);
|
|
||||||
status = msg;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlexRay::Controller::getReady() {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlexRay::Controller::start() {
|
|
||||||
if(true) // TODO something
|
|
||||||
getReady();
|
|
||||||
if(wakeupBeforeStart)
|
|
||||||
setCurrentPOCCommand(FlexRay::POCCommand::Wakeup);
|
|
||||||
if(allowColdstart)
|
|
||||||
setCurrentPOCCommand(FlexRay::POCCommand::AllowColdstart);
|
|
||||||
setCurrentPOCCommand(FlexRay::POCCommand::Run);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<bool, FlexRay::POCCommand> FlexRay::Controller::getCurrentPOCCommand(std::chrono::milliseconds timeout) const {
|
|
||||||
const auto val = readRegister(ERAYRegister::SUCC1, timeout);
|
|
||||||
return {val.first, FlexRay::POCCommand(val.second & 0x0000000F)};
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlexRay::Controller::setCurrentPOCCommand(FlexRay::POCCommand cmd, bool checkForSuccess, std::chrono::milliseconds timeout) {
|
|
||||||
const auto beforeWrite = std::chrono::steady_clock::now();
|
|
||||||
|
|
||||||
if(!writeRegister(ERAYRegister::SUCC1, uint32_t(cmd), true, timeout))
|
|
||||||
return false;
|
|
||||||
if(!checkForSuccess)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
const auto writeDuration = std::chrono::steady_clock::now() - beforeWrite;
|
|
||||||
timeout = std::chrono::duration_cast<std::chrono::milliseconds>(writeDuration - timeout);
|
|
||||||
if(timeout.count() <= 0)
|
|
||||||
return false; // Out of time!
|
|
||||||
|
|
||||||
return wasCommandSuccessful(timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlexRay::Controller::wasCommandSuccessful(std::chrono::milliseconds timeout) const {
|
|
||||||
const auto val = getCurrentPOCCommand(timeout);
|
|
||||||
return val.first && val.second != FlexRay::POCCommand::CommandNotAccepted;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::pair<bool, uint32_t> FlexRay::Controller::readRegister(ERAYRegister reg, std::chrono::milliseconds timeout) const {
|
|
||||||
std::lock_guard<std::mutex> lk(readRegisterLock);
|
|
||||||
device.com->sendCommand(Command::FlexRayControl, FlexRayControlMessage::BuildReadCCRegsArgs(index, uint16_t(reg)));
|
|
||||||
std::shared_ptr<FlexRayControlMessage> resp;
|
|
||||||
const auto start = std::chrono::steady_clock::now();
|
|
||||||
while(!resp && (std::chrono::steady_clock::now() - start) < timeout) {
|
|
||||||
auto msg = device.com->waitForMessageSync(MessageFilter(icsneo::Network::NetID::FlexRayControl), timeout);
|
|
||||||
if(auto frmsg = std::dynamic_pointer_cast<FlexRayControlMessage>(msg)) {
|
|
||||||
if(frmsg->decoded && frmsg->controller == index && frmsg->opcode == FlexRay::Opcode::ReadCCRegs)
|
|
||||||
resp = frmsg;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if(resp)
|
|
||||||
return {true, resp->registers[0]};
|
|
||||||
else
|
|
||||||
return {false, 0};
|
|
||||||
}
|
|
||||||
|
|
||||||
uint32_t FlexRay::Controller::readRegisterOr(ERAYRegister reg, uint32_t defaultValue, std::chrono::milliseconds timeout) const {
|
|
||||||
auto ret = readRegister(reg, timeout);
|
|
||||||
return ret.first ? ret.second : defaultValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlexRay::Controller::writeRegister(
|
|
||||||
ERAYRegister reg,
|
|
||||||
uint32_t value,
|
|
||||||
uint32_t mask,
|
|
||||||
bool waitForPOCReady,
|
|
||||||
std::chrono::milliseconds timeout) {
|
|
||||||
|
|
||||||
if(mask != 0xffffffff) {
|
|
||||||
const auto beforeRead = std::chrono::steady_clock::now();
|
|
||||||
auto pair = readRegister(reg, timeout);
|
|
||||||
if(!pair.first)
|
|
||||||
return false; // Couldn't read, so we don't want to try to write anything
|
|
||||||
auto readDuration = std::chrono::duration_cast<std::chrono::milliseconds>(std::chrono::steady_clock::now() - beforeRead);
|
|
||||||
timeout = readDuration - timeout;
|
|
||||||
if(timeout.count() <= 0)
|
|
||||||
return false; // Out of time!
|
|
||||||
pair.second &= ~mask;
|
|
||||||
pair.second |= value & mask;
|
|
||||||
value = pair.second;
|
|
||||||
}
|
|
||||||
return writeRegister(reg, value, waitForPOCReady, timeout);
|
|
||||||
}
|
|
||||||
|
|
||||||
bool FlexRay::Controller::writeRegister(
|
|
||||||
ERAYRegister reg,
|
|
||||||
uint32_t value,
|
|
||||||
bool waitForPOCReady,
|
|
||||||
std::chrono::milliseconds timeout) {
|
|
||||||
|
|
||||||
if(waitForPOCReady) {
|
|
||||||
const auto start = std::chrono::steady_clock::now();
|
|
||||||
bool pocBusy = isPOCBusy();
|
|
||||||
while(pocBusy && (std::chrono::steady_clock::now() - start) < timeout) {
|
|
||||||
pocBusy = isPOCBusy();
|
|
||||||
}
|
|
||||||
if(pocBusy) // timeout
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
device.com->sendCommand(Command::FlexRayControl, FlexRayControlMessage::BuildWriteCCRegArgs(index, uint16_t(reg), value));
|
|
||||||
return true; // Does the device send anything back to tell us this actually happened?
|
|
||||||
}
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#include "icsneo/device/extensions/flexray/extension.h"
|
|
||||||
#include "icsneo/device/device.h"
|
|
||||||
|
|
||||||
using namespace icsneo;
|
|
||||||
|
|
||||||
FlexRay::Extension::Extension(Device& device, uint8_t controllerCount) : DeviceExtension(device) {
|
|
||||||
for(uint8_t i = 0; i < controllerCount; i++)
|
|
||||||
controllers.emplace_back(std::make_shared<FlexRay::Controller>(device, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
void FlexRay::Extension::handleMessage(const std::shared_ptr<Message>& message) {
|
|
||||||
switch(message->network.getNetID()) {
|
|
||||||
case Network::NetID::FlexRayControl: {
|
|
||||||
auto msg = std::dynamic_pointer_cast<FlexRayControlMessage>(message);
|
|
||||||
if(!msg || !msg->decoded)
|
|
||||||
return;
|
|
||||||
switch(msg->opcode) {
|
|
||||||
case FlexRay::Opcode::ReadCCStatus:
|
|
||||||
if(auto status = std::dynamic_pointer_cast<FlexRayControlMessage>(message)) { // TODO else report error?
|
|
||||||
if(status->controller >= controllers.size())
|
|
||||||
return; // TODO error
|
|
||||||
controllers[status->controller]->_setStatus(status);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
+45
-171
@@ -130,7 +130,7 @@ int64_t IDeviceSettings::GetBaudrateValueForEnum(CANBaudrate enumValue) {
|
|||||||
|
|
||||||
bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
||||||
if(disabled) {
|
if(disabled) {
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
err(APIError::SettingsNotAvailable);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,12 +140,12 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
|||||||
std::vector<uint8_t> rxSettings;
|
std::vector<uint8_t> rxSettings;
|
||||||
bool ret = com->getSettingsSync(rxSettings);
|
bool ret = com->getSettingsSync(rxSettings);
|
||||||
if(!ret) {
|
if(!ret) {
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
err(APIError::SettingsReadError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rxSettings.size() < 6) { // We need to at least have the header of GLOBAL_SETTINGS
|
if(rxSettings.size() < 6) { // We need to at least have the header of GLOBAL_SETTINGS
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
err(APIError::SettingsReadError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -158,17 +158,17 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
|||||||
rxSettings.erase(rxSettings.begin(), rxSettings.begin() + gs_size);
|
rxSettings.erase(rxSettings.begin(), rxSettings.begin() + gs_size);
|
||||||
|
|
||||||
if(gs_version != 5) {
|
if(gs_version != 5) {
|
||||||
report(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error);
|
err(APIError::SettingsVersionError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(rxLen != gs_len) {
|
if(rxLen != gs_len) {
|
||||||
report(APIEvent::Type::SettingsLengthError, APIEvent::Severity::Error);
|
err(APIError::SettingsLengthError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!ignoreChecksum && gs_chksum != CalculateGSChecksum(rxSettings)) {
|
if(!ignoreChecksum && gs_chksum != CalculateGSChecksum(rxSettings)) {
|
||||||
report(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error);
|
err(APIError::SettingsChecksumError);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -183,20 +183,8 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool IDeviceSettings::apply(bool temporary) {
|
bool IDeviceSettings::apply(bool temporary) {
|
||||||
if(readonly) {
|
if(!settingsLoaded || disabled || readonly)
|
||||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(disabled) {
|
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!settingsLoaded) {
|
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
std::vector<uint8_t> bytestream;
|
std::vector<uint8_t> bytestream;
|
||||||
bytestream.resize(7 + settings.size());
|
bytestream.resize(7 + settings.size());
|
||||||
@@ -214,11 +202,7 @@ bool IDeviceSettings::apply(bool temporary) {
|
|||||||
std::shared_ptr<Message> msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
std::shared_ptr<Message> msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
||||||
|
|
||||||
if(!msg || msg->data[0] != 1) { // We did not receive a response
|
if(!msg || msg->data[0] != 1) { // We did not receive a response
|
||||||
// Attempt to get the settings from the device so we're up to date if possible
|
refresh(); // Attempt to get the settings from the device so we're up to date if possible
|
||||||
if(refresh()) {
|
|
||||||
// refresh succeeded but previously there was an error
|
|
||||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -233,11 +217,7 @@ bool IDeviceSettings::apply(bool temporary) {
|
|||||||
com->sendCommand(Command::SetSettings, bytestream);
|
com->sendCommand(Command::SetSettings, bytestream);
|
||||||
msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
||||||
if(!msg || msg->data[0] != 1) {
|
if(!msg || msg->data[0] != 1) {
|
||||||
// Attempt to get the settings from the device so we're up to date if possible
|
refresh();
|
||||||
if(refresh()) {
|
|
||||||
// refresh succeeded but previously there was an error
|
|
||||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -248,32 +228,17 @@ bool IDeviceSettings::apply(bool temporary) {
|
|||||||
|
|
||||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||||
|
|
||||||
bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
return (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||||
if(!ret) {
|
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDeviceSettings::applyDefaults(bool temporary) {
|
bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||||
if(disabled) {
|
if(disabled || readonly)
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(readonly) {
|
|
||||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
com->sendCommand(Command::SetDefaultSettings);
|
com->sendCommand(Command::SetDefaultSettings);
|
||||||
std::shared_ptr<Message> msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetDefaultSettings), std::chrono::milliseconds(1000));
|
std::shared_ptr<Message> msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetDefaultSettings), std::chrono::milliseconds(1000));
|
||||||
if(!msg || msg->data[0] != 1) {
|
if(!msg || msg->data[0] != 1) {
|
||||||
// Attempt to get the settings from the device so we're up to date if possible
|
refresh();
|
||||||
if(refresh()) {
|
|
||||||
// refresh succeeded but previously there was an error
|
|
||||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -298,11 +263,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
|||||||
com->sendCommand(Command::SetSettings, bytestream);
|
com->sendCommand(Command::SetSettings, bytestream);
|
||||||
msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
||||||
if(!msg || msg->data[0] != 1) {
|
if(!msg || msg->data[0] != 1) {
|
||||||
// Attempt to get the settings from the device so we're up to date if possible
|
refresh();
|
||||||
if(refresh()) {
|
|
||||||
// refresh succeeded but previously there was an error
|
|
||||||
report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -313,79 +274,45 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
|||||||
|
|
||||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||||
|
|
||||||
bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
return (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||||
if(!ret) {
|
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
||||||
if(disabled) {
|
if(!settingsLoaded || disabled)
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
if(!settingsLoaded) {
|
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(net.getType()) {
|
switch(net.getType()) {
|
||||||
case Network::Type::CAN: {
|
case Network::Type::CAN: {
|
||||||
const CAN_SETTINGS* cfg = getCANSettingsFor(net);
|
const CAN_SETTINGS* cfg = getCANSettingsFor(net);
|
||||||
if(cfg == nullptr) {
|
if(cfg == nullptr)
|
||||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->Baudrate);
|
int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->Baudrate);
|
||||||
if(baudrate == -1) {
|
if(baudrate == -1)
|
||||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
return baudrate;
|
return baudrate;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
||||||
if(disabled) {
|
if(!settingsLoaded || disabled || readonly)
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(!settingsLoaded) {
|
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(readonly) {
|
|
||||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(net.getType()) {
|
switch(net.getType()) {
|
||||||
case Network::Type::CAN: {
|
case Network::Type::CAN: {
|
||||||
if(baudrate > 1000000) { // This is an FD baudrate. Use setFDBaudrateFor instead.
|
if(baudrate > 1000000) // This is an FD baudrate. Use setFDBaudrateFor instead.
|
||||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
CAN_SETTINGS* cfg = getMutableCANSettingsFor(net);
|
CAN_SETTINGS* cfg = getMutableCANSettingsFor(net);
|
||||||
if(cfg == nullptr) {
|
if(cfg == nullptr)
|
||||||
report(APIEvent::Type::CANSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||||
if(newBaud == (CANBaudrate)-1) {
|
if(newBaud == (CANBaudrate)-1)
|
||||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
cfg->Baudrate = (uint8_t)newBaud;
|
cfg->Baudrate = (uint8_t)newBaud;
|
||||||
cfg->auto_baud = false;
|
cfg->auto_baud = false;
|
||||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||||
@@ -393,16 +320,12 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||||||
}
|
}
|
||||||
case Network::Type::LSFTCAN: {
|
case Network::Type::LSFTCAN: {
|
||||||
CAN_SETTINGS* cfg = getMutableLSFTCANSettingsFor(net);
|
CAN_SETTINGS* cfg = getMutableLSFTCANSettingsFor(net);
|
||||||
if(cfg == nullptr) {
|
if(cfg == nullptr)
|
||||||
report(APIEvent::Type::LSFTCANSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||||
if(newBaud == (CANBaudrate)-1) {
|
if(newBaud == (CANBaudrate)-1)
|
||||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
cfg->Baudrate = (uint8_t)newBaud;
|
cfg->Baudrate = (uint8_t)newBaud;
|
||||||
cfg->auto_baud = false;
|
cfg->auto_baud = false;
|
||||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||||
@@ -410,127 +333,78 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||||||
}
|
}
|
||||||
case Network::Type::SWCAN: {
|
case Network::Type::SWCAN: {
|
||||||
SWCAN_SETTINGS* cfg = getMutableSWCANSettingsFor(net);
|
SWCAN_SETTINGS* cfg = getMutableSWCANSettingsFor(net);
|
||||||
if(cfg == nullptr) {
|
if(cfg == nullptr)
|
||||||
report(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||||
if(newBaud == (CANBaudrate)-1) {
|
if(newBaud == (CANBaudrate)-1)
|
||||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
cfg->Baudrate = (uint8_t)newBaud;
|
cfg->Baudrate = (uint8_t)newBaud;
|
||||||
cfg->auto_baud = false;
|
cfg->auto_baud = false;
|
||||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int64_t IDeviceSettings::getFDBaudrateFor(Network net) const {
|
int64_t IDeviceSettings::getFDBaudrateFor(Network net) const {
|
||||||
if(disabled) {
|
if(!settingsLoaded || disabled)
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
}
|
|
||||||
|
|
||||||
if(!settingsLoaded) {
|
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
switch(net.getType()) {
|
switch(net.getType()) {
|
||||||
case Network::Type::CAN: {
|
case Network::Type::CAN: {
|
||||||
const CANFD_SETTINGS* cfg = getCANFDSettingsFor(net);
|
const CANFD_SETTINGS* cfg = getCANFDSettingsFor(net);
|
||||||
if(cfg == nullptr) {
|
if(cfg == nullptr)
|
||||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->FDBaudrate);
|
int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->FDBaudrate);
|
||||||
if(baudrate == -1) {
|
if(baudrate == -1)
|
||||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
|
||||||
|
|
||||||
return baudrate;
|
return baudrate;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool IDeviceSettings::setFDBaudrateFor(Network net, int64_t baudrate) {
|
bool IDeviceSettings::setFDBaudrateFor(Network net, int64_t baudrate) {
|
||||||
if(!settingsLoaded) {
|
if(!settingsLoaded || disabled || readonly)
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(disabled) {
|
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(readonly) {
|
|
||||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
switch(net.getType()) {
|
switch(net.getType()) {
|
||||||
case Network::Type::CAN: {
|
case Network::Type::CAN: {
|
||||||
CANFD_SETTINGS* cfg = getMutableCANFDSettingsFor(net);
|
CANFD_SETTINGS* cfg = getMutableCANFDSettingsFor(net);
|
||||||
if(cfg == nullptr) {
|
if(cfg == nullptr)
|
||||||
report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||||
if(newBaud == (CANBaudrate)-1) {
|
if(newBaud == (CANBaudrate)-1)
|
||||||
report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
cfg->FDBaudrate = (uint8_t)newBaud;
|
cfg->FDBaudrate = (uint8_t)newBaud;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
default:
|
default:
|
||||||
report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T> bool IDeviceSettings::applyStructure(const T& newStructure) {
|
template<typename T> bool IDeviceSettings::applyStructure(const T& newStructure) {
|
||||||
if(!settingsLoaded) {
|
if(!settingsLoaded || disabled || readonly)
|
||||||
report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error);
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
if(disabled) {
|
|
||||||
report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
if(readonly) {
|
|
||||||
report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// This function is only called from C++ so the caller's structure size and ours should never differ
|
// This function is only called from C++ so the callers structure size and ours should never differ
|
||||||
if(sizeof(T) != structSize) {
|
if(sizeof(T) != structSize)
|
||||||
report(APIEvent::Type::SettingsStructureMismatch, APIEvent::Severity::Error);
|
|
||||||
return false; // The wrong structure was passed in for the current device
|
return false; // The wrong structure was passed in for the current device
|
||||||
}
|
|
||||||
size_t copySize = sizeof(T);
|
|
||||||
if(copySize > settings.size()) {
|
|
||||||
report(APIEvent::Type::SettingsStructureTruncated, APIEvent::Severity::EventWarning);
|
|
||||||
copySize = settings.size(); // TODO Warn user that their structure is truncated
|
|
||||||
}
|
|
||||||
// Warn user that the device firmware doesn't support all the settings in the current API
|
|
||||||
if(copySize < settings.size())
|
|
||||||
report(APIEvent::Type::DeviceFirmwareOutOfDate, APIEvent::Severity::EventWarning);
|
|
||||||
|
|
||||||
|
size_t copySize = sizeof(T);
|
||||||
|
if(copySize > settings.size())
|
||||||
|
copySize = settings.size(); // TODO Warn user that their structure is truncated
|
||||||
|
|
||||||
|
// TODO Warn user that the device firmware doesn't support all the settings in the current API
|
||||||
|
//if(copySize < settings.size())
|
||||||
|
|
||||||
memcpy(settings.data(), &newStructure, structSize);
|
memcpy(settings.data(), &newStructure, structSize);
|
||||||
return apply();
|
return apply();
|
||||||
}
|
}
|
||||||
-102
@@ -1,102 +0,0 @@
|
|||||||
****************
|
|
||||||
**API Usage**
|
|
||||||
****************
|
|
||||||
|
|
||||||
API Concepts
|
|
||||||
================
|
|
||||||
|
|
||||||
Overview
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Events convey information about the API's inner workings to the user. There are 3 severity levels: ``EventInfo``, ``EventWarning``, and ``Error``.
|
|
||||||
**However, the API treats events of severities** ``EventInfo`` **and** ``EventWarning`` **differently than those of severity** ``Error`` **.**
|
|
||||||
From here on out, when we (and the API functions) refer to "events", we refer exclusively to those of severities ``EventInfo`` and ``EventWarning``, which use the events_ system.
|
|
||||||
Those of severity ``Error`` are referred to as "errors", which use a separate errors_ system.
|
|
||||||
|
|
||||||
Events should periodically be read out in order to avoid overflowing, and the last error should be read out immediately after an API function fails.
|
|
||||||
|
|
||||||
Additionally, `event callbacks`_ can be registered, which may remove the need to periodically read events in some cases.
|
|
||||||
|
|
||||||
.. _events:
|
|
||||||
|
|
||||||
Events
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The API stores events in a single buffer that can has a default size of 10,000 events.
|
|
||||||
This limit includes 1 reserved slot at the end of the buffer for a potential Event of type ``TooManyEvents`` and severity ``EventWarning``, which is added when there are too many events for the buffer to hold.
|
|
||||||
This could occur if the events aren't read out by the user often enough, or if the user sets the size of the buffer to a value smaller than the number of existing events.
|
|
||||||
There will only ever be one of these ``TooManyEvents`` events, and it will always be located at the very end of the buffer if it exists.
|
|
||||||
Because of this reserved slot, the buffer by default is able to hold 9,999 events. If capacity is exceeded, the oldest events in the buffer are automatically discarded until the buffer is exactly at capacity again.
|
|
||||||
When events are read out by the user, they are removed from the buffer. If an event filter is used, only the filtered events will be removed from the buffer.
|
|
||||||
|
|
||||||
In a multithreaded environment, all threads will log their events to the same buffer. In this case, the order of events will largely be meaningless, although the behavior of ``TooManyEvents`` is still guaranteed to be as described above.
|
|
||||||
|
|
||||||
.. _event callbacks:
|
|
||||||
|
|
||||||
Event Callbacks
|
|
||||||
~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Users may register event callbacks, which are automatically called whenever a matching event is logged.
|
|
||||||
Message callbacks consist of a user-defined ``std::function< void( std::shared_ptr<APIEvent> ) >`` and optional EventFilter used for matching.
|
|
||||||
If no EventFilter is provided, the default-constructed one will be used, which matches any event.
|
|
||||||
Registering a callback returns an ``int`` representing the id of the callback, which should be stored by the user and later used to remove the callback when desired.
|
|
||||||
Note that this functionality is only available in C and C++. C does not currently support filters.
|
|
||||||
|
|
||||||
Event callbacks are run after the event has been added to the buffer of events. The buffer of events may be safely modified within the callback, such as getting (flushing) the type and severity of the triggering event.
|
|
||||||
Using event callbacks in this manner means that periodically reading events is unnecessary.
|
|
||||||
|
|
||||||
.. _errors:
|
|
||||||
|
|
||||||
Errors
|
|
||||||
~~~~~~~~~
|
|
||||||
|
|
||||||
The error system is threadsafe and separate from the events_ system.
|
|
||||||
Each thread keeps track of the last error logged on it, and getting the last error will return the last error from the calling thread, removing it in the process.
|
|
||||||
Trying to get the last error when there is none will return an event of type ``NoErrorFound`` and severity ``EventInfo``.
|
|
||||||
|
|
||||||
The API also contains some threads for internal use which may potentially log errors of their own and are inaccessible to the user.
|
|
||||||
These threads have been marked to downgrade any errors that occur on them to severity ``EventWarning`` and will log the corresponding event in the events_ system described above.
|
|
||||||
|
|
||||||
Device Concepts
|
|
||||||
================
|
|
||||||
|
|
||||||
Open/Close Status
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
In order to access device functionality, the device must first be opened, which begins communication between the API and the device.
|
|
||||||
The exception to this is setting the message polling status of the device.
|
|
||||||
Trying to open/close the device when the device is already open/closed will result in an error being logged on the calling thread.
|
|
||||||
|
|
||||||
Online/Offline Status
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
Going online begins communication between the device and the rest of the network. In order to be online, the device must also be open.
|
|
||||||
Trying to go online/offline when the device is already online/offline will result in an error being logged on the calling thread.
|
|
||||||
|
|
||||||
It is possible to have a device be both open and offline. In this situation, device settings such as the baudrate may still be read and changed.
|
|
||||||
This is useful for setting up your device properly before going online and joining the network.
|
|
||||||
|
|
||||||
Message Callbacks and Polling
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
In order to handle messages, users may register message callbacks, which are automatically called whenever a matching message is received.
|
|
||||||
Message callbacks consist of a user-defined ``std::function< void( std::shared_ptr<Message> ) >`` and optional message filter used for matching.
|
|
||||||
If no message filter is provided, the default-constructed one will be used, which matches any message.
|
|
||||||
Registering a callback returns an ``int`` representing the id of the callback, which should be stored by the user and later used to remove the callback when desired.
|
|
||||||
Note that this functionality is only available in C and C++. C does not currently support filters.
|
|
||||||
|
|
||||||
The default method of handling messages is to enable message polling, which is built upon message callbacks.
|
|
||||||
Enabling message polling will register a callback that stores each received message in a buffer for later retrieval.
|
|
||||||
The default limit of this buffer is 20,000 messages.
|
|
||||||
If the limit is exceeded, the oldest messages will be dropped until the buffer is at capacity, and an error will be logged on the calling thread.
|
|
||||||
To avoid exceeding the limit, try to get messages periodically, which will flush the buffer upon each call.
|
|
||||||
Attempting to read messages without first enabling message polling will result in an error being logged on the calling thread.
|
|
||||||
|
|
||||||
It is recommended to either enable message polling or manually register callbacks to handle messages, but not both.
|
|
||||||
|
|
||||||
Write Blocking Status
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
The write blocking status of the device determines the behavior of attempting to transmit to the device (likely via sending messages) with a large backlog of messages.
|
|
||||||
If write blocking is enabled, then the transmitting thread will wait for the entire buffer to be transmitted.
|
|
||||||
If write blocking is disabled, then the attempt to transmit will simply fail and an error will be logged on the calling thread.
|
|
||||||
+3
-3
@@ -64,7 +64,7 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'libicsneo'
|
project = 'libicsneo'
|
||||||
copyright = '2019, Intrepid Control Systems, Inc'
|
copyright = '2018, Intrepid Control Systems, Inc'
|
||||||
author = 'Intrepid Control Systems, Inc.'
|
author = 'Intrepid Control Systems, Inc.'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
@@ -72,9 +72,9 @@ author = 'Intrepid Control Systems, Inc.'
|
|||||||
# built documents.
|
# built documents.
|
||||||
#
|
#
|
||||||
# The short X.Y version.
|
# The short X.Y version.
|
||||||
version = '0.2.0'
|
version = '0.1.0'
|
||||||
# The full version, including alpha/beta/rc tags.
|
# The full version, including alpha/beta/rc tags.
|
||||||
release = '0.2.0 '
|
release = '0.1.0 '
|
||||||
|
|
||||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||||
# for a list of supported languages.
|
# for a list of supported languages.
|
||||||
|
|||||||
@@ -64,7 +64,7 @@ master_doc = 'index'
|
|||||||
|
|
||||||
# General information about the project.
|
# General information about the project.
|
||||||
project = 'libicsneo'
|
project = 'libicsneo'
|
||||||
copyright = '2019, Intrepid Control Systems, Inc'
|
copyright = '2018, Intrepid Control Systems, Inc'
|
||||||
author = 'Intrepid Control Systems, Inc.'
|
author = 'Intrepid Control Systems, Inc.'
|
||||||
|
|
||||||
# The version info for the project you're documenting, acts as replacement for
|
# The version info for the project you're documenting, acts as replacement for
|
||||||
|
|||||||
@@ -5,6 +5,5 @@ Welcome to libicsneo's documentation!
|
|||||||
:maxdepth: 3
|
:maxdepth: 3
|
||||||
:caption: Documentation
|
:caption: Documentation
|
||||||
|
|
||||||
Usage
|
|
||||||
icsneocpp
|
icsneocpp
|
||||||
icsneoc
|
icsneoc
|
||||||
|
|||||||
@@ -0,0 +1,127 @@
|
|||||||
|
#ifndef __ICSNEO_API_ERROR_H_
|
||||||
|
#define __ICSNEO_API_ERROR_H_
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
const char* description;
|
||||||
|
time_t timestamp;
|
||||||
|
uint32_t errorNumber;
|
||||||
|
uint8_t severity;
|
||||||
|
char serial[7];
|
||||||
|
uint8_t reserved[16];
|
||||||
|
} neoerror_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <chrono>
|
||||||
|
#include <string>
|
||||||
|
#include <ostream>
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
class Device;
|
||||||
|
|
||||||
|
class APIError {
|
||||||
|
public:
|
||||||
|
typedef std::chrono::system_clock ErrorClock;
|
||||||
|
typedef std::chrono::time_point<ErrorClock> ErrorTimePoint;
|
||||||
|
|
||||||
|
enum ErrorType : uint32_t {
|
||||||
|
Any = 0, // Used for filtering, should not appear in data
|
||||||
|
|
||||||
|
// API Errors
|
||||||
|
InvalidNeoDevice = 0x1000,
|
||||||
|
RequiredParameterNull = 0x1001,
|
||||||
|
BufferInsufficient = 0x1002,
|
||||||
|
OutputTruncated = 0x1003,
|
||||||
|
ParameterOutOfRange = 0x1004,
|
||||||
|
|
||||||
|
// Device Errors
|
||||||
|
PollingMessageOverflow = 0x2000,
|
||||||
|
NoSerialNumber = 0x2001,
|
||||||
|
IncorrectSerialNumber = 0x2002,
|
||||||
|
SettingsReadError = 0x2003,
|
||||||
|
SettingsVersionError = 0x2004,
|
||||||
|
SettingsLengthError = 0x2005,
|
||||||
|
SettingsChecksumError = 0x2006,
|
||||||
|
SettingsNotAvailable = 0x2007,
|
||||||
|
|
||||||
|
// Transport Errors
|
||||||
|
FailedToRead = 0x3000,
|
||||||
|
FailedToWrite = 0x3001,
|
||||||
|
DriverFailedToOpen = 0x3002,
|
||||||
|
PacketChecksumError = 0x3003,
|
||||||
|
TransmitBufferFull = 0x3004,
|
||||||
|
PCAPCouldNotStart = 0x3102,
|
||||||
|
PCAPCouldNotFindDevices = 0x3103,
|
||||||
|
|
||||||
|
TooManyErrors = 0xFFFFFFFE,
|
||||||
|
Unknown = 0xFFFFFFFF
|
||||||
|
};
|
||||||
|
enum class Severity : uint8_t {
|
||||||
|
Any = 0, // Used for filtering, should not appear in data
|
||||||
|
Info = 0x10,
|
||||||
|
Warning = 0x20,
|
||||||
|
Error = 0x30
|
||||||
|
};
|
||||||
|
|
||||||
|
APIError() : errorStruct({}), device(nullptr) {}
|
||||||
|
APIError(ErrorType error);
|
||||||
|
APIError(ErrorType error, const Device* device);
|
||||||
|
|
||||||
|
const neoerror_t* getNeoError() const noexcept { return &errorStruct; }
|
||||||
|
ErrorType getType() const noexcept { return ErrorType(errorStruct.errorNumber); }
|
||||||
|
Severity getSeverity() const noexcept { return Severity(errorStruct.severity); }
|
||||||
|
std::string getDescription() const noexcept { return std::string(errorStruct.description); }
|
||||||
|
const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide error
|
||||||
|
ErrorTimePoint getTimestamp() const noexcept { return timepoint; }
|
||||||
|
|
||||||
|
bool isForDevice(const Device* forDevice) const noexcept { return forDevice == device; }
|
||||||
|
bool isForDevice(std::string serial) const noexcept;
|
||||||
|
|
||||||
|
// As opposed to getDescription, this will also add text such as "neoVI FIRE 2 CY2468 Error: " to fully describe the problem
|
||||||
|
std::string describe() const noexcept;
|
||||||
|
friend std::ostream& operator<<(std::ostream& os, const APIError& error) {
|
||||||
|
os << error.describe();
|
||||||
|
return os;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const char* DescriptionForType(ErrorType type);
|
||||||
|
static Severity SeverityForType(ErrorType type);
|
||||||
|
|
||||||
|
private:
|
||||||
|
neoerror_t errorStruct;
|
||||||
|
std::string serial;
|
||||||
|
ErrorTimePoint timepoint;
|
||||||
|
const Device* device;
|
||||||
|
|
||||||
|
void init(ErrorType error);
|
||||||
|
};
|
||||||
|
|
||||||
|
class ErrorFilter {
|
||||||
|
public:
|
||||||
|
ErrorFilter() {} // Empty filter matches anything
|
||||||
|
ErrorFilter(APIError::ErrorType error) : type(error) {}
|
||||||
|
ErrorFilter(APIError::Severity severity) : severity(severity) {}
|
||||||
|
ErrorFilter(const Device* device, APIError::ErrorType error = APIError::Any) : type(error), matchOnDevicePtr(true), device(device) {}
|
||||||
|
ErrorFilter(const Device* device, APIError::Severity severity) : severity(severity), matchOnDevicePtr(true), device(device) {}
|
||||||
|
ErrorFilter(std::string serial, APIError::ErrorType error = APIError::Any) : type(error), serial(serial) {}
|
||||||
|
ErrorFilter(std::string serial, APIError::Severity severity) : severity(severity), serial(serial) {}
|
||||||
|
|
||||||
|
bool match(const APIError& error) const noexcept;
|
||||||
|
|
||||||
|
APIError::Severity severity = APIError::Severity::Any;
|
||||||
|
APIError::ErrorType type = APIError::Any;
|
||||||
|
bool matchOnDevicePtr = false;
|
||||||
|
const Device* device = nullptr; // nullptr will match on "no device, generic API error"
|
||||||
|
std::string serial; // Empty serial will match any, including no device. Not affected by matchOnDevicePtr
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -0,0 +1,98 @@
|
|||||||
|
#ifndef __ICSNEO_API_ERRORMANAGER_H_
|
||||||
|
#define __ICSNEO_API_ERRORMANAGER_H_
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <list>
|
||||||
|
#include <mutex>
|
||||||
|
#include <functional>
|
||||||
|
#include "icsneo/api/error.h"
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
typedef std::function<void (APIError::ErrorType)> device_errorhandler_t;
|
||||||
|
|
||||||
|
class ErrorManager {
|
||||||
|
public:
|
||||||
|
static ErrorManager& GetInstance();
|
||||||
|
|
||||||
|
size_t count(ErrorFilter filter = ErrorFilter()) const {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
return count_internal(filter);
|
||||||
|
};
|
||||||
|
|
||||||
|
std::vector<APIError> get(ErrorFilter filter, size_t max = 0) { return get(max, filter); }
|
||||||
|
std::vector<APIError> get(size_t max = 0, ErrorFilter filter = ErrorFilter()) {
|
||||||
|
std::vector<APIError> ret;
|
||||||
|
get(ret, filter, max);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
void get(std::vector<APIError>& outErrors, ErrorFilter filter, size_t max = 0) { get(outErrors, max, filter); }
|
||||||
|
void get(std::vector<APIError>& outErrors, size_t max = 0, ErrorFilter filter = ErrorFilter());
|
||||||
|
bool getLastError(APIError& outErrors, ErrorFilter filter = ErrorFilter());
|
||||||
|
|
||||||
|
void add(APIError error) {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
add_internal(error);
|
||||||
|
}
|
||||||
|
void add(APIError::ErrorType type) {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
add_internal(type);
|
||||||
|
}
|
||||||
|
void add(APIError::ErrorType type, const Device* forDevice) {
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
add_internal(type, forDevice);
|
||||||
|
}
|
||||||
|
|
||||||
|
void discard(ErrorFilter filter = ErrorFilter());
|
||||||
|
|
||||||
|
void setErrorLimit(size_t newLimit) {
|
||||||
|
if(newLimit < 10) {
|
||||||
|
add(APIError::ParameterOutOfRange);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
errorLimit = newLimit;
|
||||||
|
enforceLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t getErrorLimit() const { return errorLimit; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ErrorManager() {}
|
||||||
|
mutable std::mutex mutex;
|
||||||
|
std::list<APIError> errors;
|
||||||
|
size_t errorLimit = 10000;
|
||||||
|
|
||||||
|
size_t count_internal(ErrorFilter filter = ErrorFilter()) const;
|
||||||
|
|
||||||
|
void add_internal(APIError error) {
|
||||||
|
if(!beforeAddCheck(error.getType()))
|
||||||
|
return;
|
||||||
|
errors.push_back(error);
|
||||||
|
enforceLimit();
|
||||||
|
}
|
||||||
|
void add_internal(APIError::ErrorType type) {
|
||||||
|
if(!beforeAddCheck(type))
|
||||||
|
return;
|
||||||
|
errors.emplace_back(type);
|
||||||
|
enforceLimit();
|
||||||
|
}
|
||||||
|
void add_internal(APIError::ErrorType type, const Device* forDevice) {
|
||||||
|
if(!beforeAddCheck(type))
|
||||||
|
return;
|
||||||
|
errors.emplace_back(type, forDevice);
|
||||||
|
enforceLimit();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool beforeAddCheck(APIError::ErrorType type); // Returns whether the error should be added
|
||||||
|
|
||||||
|
bool enforceLimit(); // Returns whether the limit enforcement resulted in an overflow
|
||||||
|
|
||||||
|
APIError::Severity lowestCurrentSeverity();
|
||||||
|
void discardLeastSevere(size_t count = 1);
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -1,152 +0,0 @@
|
|||||||
#ifndef __ICSNEO_API_EVENT_H_
|
|
||||||
#define __ICSNEO_API_EVENT_H_
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
const char* description;
|
|
||||||
time_t timestamp;
|
|
||||||
uint32_t eventNumber;
|
|
||||||
uint8_t severity;
|
|
||||||
char serial[7];
|
|
||||||
uint8_t reserved[16];
|
|
||||||
} neoevent_t;
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <chrono>
|
|
||||||
#include <string>
|
|
||||||
#include <ostream>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class Device;
|
|
||||||
|
|
||||||
class APIEvent {
|
|
||||||
public:
|
|
||||||
typedef std::chrono::system_clock EventClock;
|
|
||||||
typedef std::chrono::time_point<EventClock> EventTimePoint;
|
|
||||||
|
|
||||||
enum class Type : uint32_t {
|
|
||||||
Any = 0, // Used for filtering, should not appear in data
|
|
||||||
|
|
||||||
// API Events
|
|
||||||
InvalidNeoDevice = 0x1000, // api
|
|
||||||
RequiredParameterNull = 0x1001,
|
|
||||||
BufferInsufficient = 0x1002,
|
|
||||||
OutputTruncated = 0x1003, // just a warning
|
|
||||||
ParameterOutOfRange = 0x1004,
|
|
||||||
DeviceCurrentlyOpen = 0x1005,
|
|
||||||
DeviceCurrentlyClosed = 0x1006,
|
|
||||||
DeviceCurrentlyOnline = 0x1007,
|
|
||||||
DeviceCurrentlyOffline = 0x1008,
|
|
||||||
DeviceCurrentlyPolling = 0x1009,
|
|
||||||
DeviceNotCurrentlyPolling = 0x1010,
|
|
||||||
UnsupportedTXNetwork = 0x1011,
|
|
||||||
MessageMaxLengthExceeded = 0x1012,
|
|
||||||
|
|
||||||
// Device Events
|
|
||||||
PollingMessageOverflow = 0x2000,
|
|
||||||
NoSerialNumber = 0x2001, // api
|
|
||||||
IncorrectSerialNumber = 0x2002, // api
|
|
||||||
SettingsReadError = 0x2003,
|
|
||||||
SettingsVersionError = 0x2004,
|
|
||||||
SettingsLengthError = 0x2005,
|
|
||||||
SettingsChecksumError = 0x2006,
|
|
||||||
SettingsNotAvailable = 0x2007,
|
|
||||||
SettingsReadOnly = 0x2008,
|
|
||||||
CANSettingsNotAvailable = 0x2009,
|
|
||||||
CANFDSettingsNotAvailable = 0x2010,
|
|
||||||
LSFTCANSettingsNotAvailable = 0x2011,
|
|
||||||
SWCANSettingsNotAvailable = 0x2012,
|
|
||||||
BaudrateNotFound = 0x2013,
|
|
||||||
UnexpectedNetworkType = 0x2014,
|
|
||||||
DeviceFirmwareOutOfDate = 0x2015,
|
|
||||||
SettingsStructureMismatch = 0x2016,
|
|
||||||
SettingsStructureTruncated = 0x2017,
|
|
||||||
NoDeviceResponse = 0x2018,
|
|
||||||
MessageFormattingError = 0x2019,
|
|
||||||
CANFDNotSupported = 0x2020,
|
|
||||||
RTRNotSupported = 0x2021,
|
|
||||||
|
|
||||||
// Transport Events
|
|
||||||
FailedToRead = 0x3000,
|
|
||||||
FailedToWrite = 0x3001,
|
|
||||||
DriverFailedToOpen = 0x3002,
|
|
||||||
DriverFailedToClose = 0x3003,
|
|
||||||
PacketChecksumError = 0x3004,
|
|
||||||
TransmitBufferFull = 0x3005,
|
|
||||||
PCAPCouldNotStart = 0x3102,
|
|
||||||
PCAPCouldNotFindDevices = 0x3103,
|
|
||||||
PacketDecodingError = 0x3104,
|
|
||||||
|
|
||||||
NoErrorFound = 0xFFFFFFFD,
|
|
||||||
TooManyEvents = 0xFFFFFFFE,
|
|
||||||
Unknown = 0xFFFFFFFF
|
|
||||||
};
|
|
||||||
enum class Severity : uint8_t {
|
|
||||||
Any = 0, // Used for filtering, should not appear in data
|
|
||||||
EventInfo = 0x10,
|
|
||||||
EventWarning = 0x20,
|
|
||||||
Error = 0x30
|
|
||||||
};
|
|
||||||
|
|
||||||
APIEvent() : eventStruct({}), serial(), timepoint(), device(nullptr) {}
|
|
||||||
APIEvent(APIEvent::Type event, APIEvent::Severity severity, const Device* device = nullptr);
|
|
||||||
|
|
||||||
const neoevent_t* getNeoEvent() const noexcept { return &eventStruct; }
|
|
||||||
Type getType() const noexcept { return Type(eventStruct.eventNumber); }
|
|
||||||
Severity getSeverity() const noexcept { return Severity(eventStruct.severity); }
|
|
||||||
std::string getDescription() const noexcept { return std::string(eventStruct.description); }
|
|
||||||
const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide event
|
|
||||||
EventTimePoint getTimestamp() const noexcept { return timepoint; }
|
|
||||||
|
|
||||||
void downgradeFromError() noexcept;
|
|
||||||
|
|
||||||
bool isForDevice(const Device* forDevice) const noexcept { return forDevice == device; }
|
|
||||||
bool isForDevice(std::string serial) const noexcept;
|
|
||||||
|
|
||||||
// As opposed to getDescription, this will also add text such as "neoVI FIRE 2 CY2468 Error: " to fully describe the problem
|
|
||||||
std::string describe() const noexcept;
|
|
||||||
friend std::ostream& operator<<(std::ostream& os, const APIEvent& event) {
|
|
||||||
os << event.describe();
|
|
||||||
return os;
|
|
||||||
}
|
|
||||||
|
|
||||||
static const char* DescriptionForType(Type type);
|
|
||||||
|
|
||||||
private:
|
|
||||||
neoevent_t eventStruct;
|
|
||||||
std::string serial;
|
|
||||||
EventTimePoint timepoint;
|
|
||||||
const Device* device;
|
|
||||||
|
|
||||||
void init(APIEvent::Type event, APIEvent::Severity);
|
|
||||||
};
|
|
||||||
|
|
||||||
class EventFilter {
|
|
||||||
public:
|
|
||||||
EventFilter() {} // Empty filter matches anything
|
|
||||||
EventFilter(APIEvent::Type type, APIEvent::Severity severity = APIEvent::Severity::Any) : type(type), severity(severity) {}
|
|
||||||
EventFilter(APIEvent::Severity severity) : severity(severity) {}
|
|
||||||
EventFilter(const Device* device, APIEvent::Type type = APIEvent::Type::Any, APIEvent::Severity severity = APIEvent::Severity::Any) : type(type), severity(severity), matchOnDevicePtr(true), device(device) {}
|
|
||||||
EventFilter(const Device* device, APIEvent::Severity severity) : severity(severity), matchOnDevicePtr(true), device(device) {}
|
|
||||||
EventFilter(std::string serial, APIEvent::Type type = APIEvent::Type::Any, APIEvent::Severity severity = APIEvent::Severity::Any) : type(type), severity(severity), serial(serial) {}
|
|
||||||
EventFilter(std::string serial, APIEvent::Severity severity) : severity(severity), serial(serial) {}
|
|
||||||
|
|
||||||
bool match(const APIEvent& event) const noexcept;
|
|
||||||
|
|
||||||
APIEvent::Type type = APIEvent::Type::Any;
|
|
||||||
APIEvent::Severity severity = APIEvent::Severity::Any;
|
|
||||||
bool matchOnDevicePtr = false;
|
|
||||||
const Device* device = nullptr; // nullptr will match on "no device, generic API event"
|
|
||||||
std::string serial; // Empty serial will match any, including no device. Not affected by matchOnDevicePtr
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif // __cplusplus
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,39 +0,0 @@
|
|||||||
#ifndef __EVENTCALLBACK_H_
|
|
||||||
#define __EVENTCALLBACK_H_
|
|
||||||
|
|
||||||
#include <functional>
|
|
||||||
#include <memory>
|
|
||||||
#include "event.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class EventCallback {
|
|
||||||
public:
|
|
||||||
typedef std::function< void( std::shared_ptr<APIEvent> ) > fn_eventCallback;
|
|
||||||
|
|
||||||
EventCallback(fn_eventCallback cb, std::shared_ptr<EventFilter> f) : callback(cb), filter(f) {}
|
|
||||||
EventCallback(fn_eventCallback cb, EventFilter f = EventFilter()) : callback(cb), filter(std::make_shared<EventFilter>(f)) {}
|
|
||||||
|
|
||||||
// Allow the filter to be placed first if the user wants (maybe in the case of a lambda)
|
|
||||||
EventCallback(std::shared_ptr<EventFilter> f, fn_eventCallback cb) : callback(cb), filter(f) {}
|
|
||||||
EventCallback(EventFilter f, fn_eventCallback cb) : callback(cb), filter(std::make_shared<EventFilter>(f)) {}
|
|
||||||
|
|
||||||
virtual bool callIfMatch(const std::shared_ptr<APIEvent>& event) const {
|
|
||||||
bool ret = filter->match(*event);
|
|
||||||
if(ret)
|
|
||||||
callback(event);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const EventFilter& getFilter() const { return *filter; }
|
|
||||||
const fn_eventCallback& getCallback() const { return callback; }
|
|
||||||
|
|
||||||
private:
|
|
||||||
fn_eventCallback callback;
|
|
||||||
std::shared_ptr<EventFilter> filter;
|
|
||||||
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,209 +0,0 @@
|
|||||||
#ifndef __ICSNEO_API_EVENTMANAGER_H_
|
|
||||||
#define __ICSNEO_API_EVENTMANAGER_H_
|
|
||||||
|
|
||||||
#include <vector>
|
|
||||||
#include <list>
|
|
||||||
#include <mutex>
|
|
||||||
#include <functional>
|
|
||||||
#include<map>
|
|
||||||
#include <thread>
|
|
||||||
#include <algorithm>
|
|
||||||
#include "icsneo/api/event.h"
|
|
||||||
#include "icsneo/api/eventcallback.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
typedef std::function<void (APIEvent::Type, APIEvent::Severity)> device_eventhandler_t;
|
|
||||||
|
|
||||||
class EventManager {
|
|
||||||
public:
|
|
||||||
~EventManager() {
|
|
||||||
destructing = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
static EventManager& GetInstance();
|
|
||||||
|
|
||||||
void ResetInstance();
|
|
||||||
|
|
||||||
// If this thread is not in the map, add it to be ignored
|
|
||||||
// If it is, set it to be ignored
|
|
||||||
void downgradeErrorsOnCurrentThread() {
|
|
||||||
if(destructing)
|
|
||||||
return;
|
|
||||||
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
|
||||||
auto i = downgradedThreads.find(std::this_thread::get_id());
|
|
||||||
if(i != downgradedThreads.end()) {
|
|
||||||
i->second = true;
|
|
||||||
} else {
|
|
||||||
downgradedThreads.insert({std::this_thread::get_id(), true});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If this thread exists in the map, turn off downgrading
|
|
||||||
void cancelErrorDowngradingOnCurrentThread() {
|
|
||||||
if(destructing)
|
|
||||||
return;
|
|
||||||
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
|
||||||
auto i = downgradedThreads.find(std::this_thread::get_id());
|
|
||||||
if(i != downgradedThreads.end()) {
|
|
||||||
i->second = false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool isDowngradingErrorsOnCurrentThread() const;
|
|
||||||
|
|
||||||
int addEventCallback(const EventCallback &cb);
|
|
||||||
bool removeEventCallback(int id);
|
|
||||||
|
|
||||||
size_t eventCount(EventFilter filter = EventFilter()) const {
|
|
||||||
std::lock_guard<std::mutex> lk(eventsMutex);
|
|
||||||
return count_internal(filter);
|
|
||||||
};
|
|
||||||
|
|
||||||
std::vector<APIEvent> get(EventFilter filter, size_t max = 0) { return get(max, filter); }
|
|
||||||
std::vector<APIEvent> get(size_t max = 0, EventFilter filter = EventFilter()) {
|
|
||||||
std::vector<APIEvent> ret;
|
|
||||||
get(ret, filter, max);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
void get(std::vector<APIEvent>& outEvents, EventFilter filter, size_t max = 0) { get(outEvents, max, filter); }
|
|
||||||
void get(std::vector<APIEvent>& outEvents, size_t max = 0, EventFilter filter = EventFilter());
|
|
||||||
|
|
||||||
APIEvent getLastError();
|
|
||||||
|
|
||||||
void add(APIEvent event) {
|
|
||||||
if(destructing)
|
|
||||||
return;
|
|
||||||
if(event.getSeverity() == APIEvent::Severity::Error) {
|
|
||||||
// if the error was added on a thread that downgrades errors (non-user thread)
|
|
||||||
std::lock_guard<std::mutex> lk(downgradedThreadsMutex);
|
|
||||||
auto i = downgradedThreads.find(std::this_thread::get_id());
|
|
||||||
if(i != downgradedThreads.end() && i->second) {
|
|
||||||
event.downgradeFromError();
|
|
||||||
std::unique_lock<std::mutex> eventsLock(eventsMutex);
|
|
||||||
add_internal_event(event);
|
|
||||||
// free the lock so that callbacks may modify events
|
|
||||||
eventsLock.unlock();
|
|
||||||
runCallbacks(event);
|
|
||||||
} else {
|
|
||||||
std::lock_guard<std::mutex> errorsLock(errorsMutex);
|
|
||||||
add_internal_error(event);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
std::unique_lock<std::mutex> eventsLock(eventsMutex);
|
|
||||||
add_internal_event(event);
|
|
||||||
// free the lock so that callbacks may modify events
|
|
||||||
eventsLock.unlock();
|
|
||||||
runCallbacks(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
void add(APIEvent::Type type, APIEvent::Severity severity, const Device* forDevice = nullptr) {
|
|
||||||
add(APIEvent(type, severity, forDevice));
|
|
||||||
}
|
|
||||||
|
|
||||||
void discard(EventFilter filter = EventFilter());
|
|
||||||
|
|
||||||
void setEventLimit(size_t newLimit) {
|
|
||||||
std::lock_guard<std::mutex> eventLimitLock(eventLimitMutex);
|
|
||||||
|
|
||||||
if(newLimit == eventLimit)
|
|
||||||
return;
|
|
||||||
|
|
||||||
if(newLimit < 10) {
|
|
||||||
add(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::Error);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
eventLimit = newLimit;
|
|
||||||
|
|
||||||
std::lock_guard<std::mutex> eventsLock(eventsMutex);
|
|
||||||
if(enforceLimit())
|
|
||||||
add_internal_event(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning));
|
|
||||||
}
|
|
||||||
|
|
||||||
size_t getEventLimit() const {
|
|
||||||
std::lock_guard<std::mutex> lk(eventLimitMutex);
|
|
||||||
return eventLimit;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
EventManager() : eventsMutex(), errorsMutex(), downgradedThreadsMutex(), callbacksMutex(), callbackIDMutex(), eventLimitMutex(), downgradedThreads(), callbacks(), events(), lastUserErrors(), eventLimit(10000) {}
|
|
||||||
EventManager(const EventManager &other);
|
|
||||||
EventManager& operator=(const EventManager &other);
|
|
||||||
|
|
||||||
// Used by functions for threadsafety
|
|
||||||
mutable std::mutex eventsMutex;
|
|
||||||
mutable std::mutex errorsMutex;
|
|
||||||
mutable std::mutex downgradedThreadsMutex;
|
|
||||||
mutable std::mutex callbacksMutex;
|
|
||||||
|
|
||||||
mutable std::mutex callbackIDMutex;
|
|
||||||
mutable std::mutex eventLimitMutex;
|
|
||||||
|
|
||||||
std::map<std::thread::id, bool> downgradedThreads;
|
|
||||||
|
|
||||||
std::map<int, EventCallback> callbacks;
|
|
||||||
|
|
||||||
int callbackID = 0;
|
|
||||||
|
|
||||||
bool destructing = false;
|
|
||||||
|
|
||||||
// Stores all events
|
|
||||||
std::list<APIEvent> events;
|
|
||||||
std::map<std::thread::id, APIEvent> lastUserErrors;
|
|
||||||
size_t eventLimit = 10000;
|
|
||||||
|
|
||||||
size_t count_internal(EventFilter filter = EventFilter()) const;
|
|
||||||
|
|
||||||
void runCallbacks(APIEvent event) {
|
|
||||||
std::lock_guard<std::mutex> lk(callbacksMutex);
|
|
||||||
for(auto &i : callbacks) {
|
|
||||||
i.second.callIfMatch(std::make_shared<APIEvent>(event));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Places a {id, event} pair into the lastUserErrors
|
|
||||||
* If the key id already exists in the map, replace the event of that pair with the new one
|
|
||||||
*/
|
|
||||||
void add_internal_error(APIEvent event) {
|
|
||||||
std::thread::id id = std::this_thread::get_id();
|
|
||||||
auto it = lastUserErrors.find(id);
|
|
||||||
if(it == lastUserErrors.end())
|
|
||||||
lastUserErrors.insert({id, event});
|
|
||||||
else
|
|
||||||
it->second = event;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* If events is not full, add the event at the end
|
|
||||||
* Otherwise, remove the oldest event, push the event to the back and push a APIEvent::TooManyEvents to the back (in that order)
|
|
||||||
*/
|
|
||||||
void add_internal_event(APIEvent event) {
|
|
||||||
// Ensure the event list is at most exactly full (size of eventLimit - 1, leaving room for a potential APIEvent::TooManyEvents)
|
|
||||||
// Removes any events of type TooManyEvents from the end before checking to avoid duplicates.
|
|
||||||
enforceLimit();
|
|
||||||
|
|
||||||
// We are exactly full, either because the list was truncated or because we were simply full before
|
|
||||||
if(events.size() == eventLimit - 1) {
|
|
||||||
// If the event is worth adding
|
|
||||||
if(event.getType() != APIEvent::Type::TooManyEvents) {
|
|
||||||
discardOldest(1);
|
|
||||||
events.push_back(event);
|
|
||||||
}
|
|
||||||
|
|
||||||
events.push_back(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning));
|
|
||||||
} else {
|
|
||||||
if (event.getType() != APIEvent::Type::TooManyEvents)
|
|
||||||
events.push_back(event);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool enforceLimit(); // Returns whether the limit enforcement resulted in an overflow
|
|
||||||
|
|
||||||
void discardOldest(size_t count = 1);
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -10,10 +10,7 @@ enum class Command : uint8_t {
|
|||||||
//GetSettings = 0xA5, // Previously known as RED_CMD_READ_BAUD_REQ, now unused
|
//GetSettings = 0xA5, // Previously known as RED_CMD_READ_BAUD_REQ, now unused
|
||||||
SaveSettings = 0xA6,
|
SaveSettings = 0xA6,
|
||||||
SetDefaultSettings = 0xA8, // Follow up with SaveSettings to write to EEPROM
|
SetDefaultSettings = 0xA8, // Follow up with SaveSettings to write to EEPROM
|
||||||
RequestStatusUpdate = 0xBC,
|
ReadSettings = 0xC7 // Previously known as 3G_READ_SETTINGS_EX
|
||||||
ReadSettings = 0xC7, // Previously known as 3G_READ_SETTINGS_EX
|
|
||||||
UpdateLEDState = 0xA7,
|
|
||||||
FlexRayControl = 0xF3
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,7 +7,7 @@
|
|||||||
#include "icsneo/communication/packet.h"
|
#include "icsneo/communication/packet.h"
|
||||||
#include "icsneo/communication/message/callback/messagecallback.h"
|
#include "icsneo/communication/message/callback/messagecallback.h"
|
||||||
#include "icsneo/communication/message/serialnumbermessage.h"
|
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
#include "icsneo/communication/packetizer.h"
|
#include "icsneo/communication/packetizer.h"
|
||||||
#include "icsneo/communication/encoder.h"
|
#include "icsneo/communication/encoder.h"
|
||||||
#include "icsneo/communication/decoder.h"
|
#include "icsneo/communication/decoder.h"
|
||||||
@@ -23,23 +23,20 @@ namespace icsneo {
|
|||||||
class Communication {
|
class Communication {
|
||||||
public:
|
public:
|
||||||
Communication(
|
Communication(
|
||||||
device_eventhandler_t report,
|
device_errorhandler_t err,
|
||||||
std::unique_ptr<ICommunication> com,
|
std::unique_ptr<ICommunication> com,
|
||||||
std::shared_ptr<Packetizer> p,
|
std::shared_ptr<Packetizer> p,
|
||||||
std::unique_ptr<Encoder> e,
|
std::unique_ptr<Encoder> e,
|
||||||
std::unique_ptr<Decoder> md) : packetizer(p), encoder(std::move(e)), decoder(std::move(md)), report(report), impl(std::move(com)) {}
|
std::unique_ptr<Decoder> md) : packetizer(p), encoder(std::move(e)), decoder(std::move(md)), err(err), impl(std::move(com)) {}
|
||||||
virtual ~Communication() { close(); }
|
virtual ~Communication() { close(); }
|
||||||
|
|
||||||
bool open();
|
bool open();
|
||||||
bool close();
|
bool close();
|
||||||
bool isOpen();
|
|
||||||
virtual void spawnThreads();
|
virtual void spawnThreads();
|
||||||
virtual void joinThreads();
|
virtual void joinThreads();
|
||||||
bool rawWrite(const std::vector<uint8_t>& bytes) { return impl->write(bytes); }
|
bool rawWrite(const std::vector<uint8_t>& bytes) { return impl->write(bytes); }
|
||||||
virtual bool sendPacket(std::vector<uint8_t>& bytes);
|
virtual bool sendPacket(std::vector<uint8_t>& bytes);
|
||||||
|
|
||||||
void setWriteBlocks(bool blocks) { impl->writeBlocks = blocks; }
|
|
||||||
|
|
||||||
virtual bool sendCommand(Command cmd, bool boolean) { return sendCommand(cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
virtual bool sendCommand(Command cmd, bool boolean) { return sendCommand(cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
||||||
virtual bool sendCommand(Command cmd, std::vector<uint8_t> arguments = {});
|
virtual bool sendCommand(Command cmd, std::vector<uint8_t> arguments = {});
|
||||||
bool getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
bool getSettingsSync(std::vector<uint8_t>& data, std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
||||||
@@ -55,18 +52,17 @@ public:
|
|||||||
std::shared_ptr<Packetizer> packetizer; // Ownership is shared with the encoder
|
std::shared_ptr<Packetizer> packetizer; // Ownership is shared with the encoder
|
||||||
std::unique_ptr<Encoder> encoder;
|
std::unique_ptr<Encoder> encoder;
|
||||||
std::unique_ptr<Decoder> decoder;
|
std::unique_ptr<Decoder> decoder;
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
std::unique_ptr<ICommunication> impl;
|
std::unique_ptr<ICommunication> impl;
|
||||||
static int messageCallbackIDCounter;
|
static int messageCallbackIDCounter;
|
||||||
std::mutex messageCallbacksLock;
|
|
||||||
std::map<int, MessageCallback> messageCallbacks;
|
std::map<int, MessageCallback> messageCallbacks;
|
||||||
std::atomic<bool> closing{false};
|
std::atomic<bool> closing{false};
|
||||||
|
|
||||||
void dispatchMessage(const std::shared_ptr<Message>& msg);
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
bool isOpen = false;
|
||||||
|
|
||||||
std::thread readTaskThread;
|
std::thread readTaskThread;
|
||||||
void readTask();
|
void readTask();
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -5,7 +5,7 @@
|
|||||||
#include "icsneo/communication/message/canmessage.h"
|
#include "icsneo/communication/message/canmessage.h"
|
||||||
#include "icsneo/communication/packet.h"
|
#include "icsneo/communication/packet.h"
|
||||||
#include "icsneo/communication/network.h"
|
#include "icsneo/communication/network.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -16,13 +16,13 @@ class Decoder {
|
|||||||
public:
|
public:
|
||||||
static uint64_t GetUInt64FromLEBytes(uint8_t* bytes);
|
static uint64_t GetUInt64FromLEBytes(uint8_t* bytes);
|
||||||
|
|
||||||
Decoder(device_eventhandler_t report) : report(report) {}
|
Decoder(device_errorhandler_t err) : err(err) {}
|
||||||
bool decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet);
|
bool decode(std::shared_ptr<Message>& result, const std::shared_ptr<Packet>& packet);
|
||||||
|
|
||||||
uint16_t timestampResolution = 25;
|
uint16_t timestampResolution = 25;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
|
|
||||||
#pragma pack(push, 1)
|
#pragma pack(push, 1)
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,7 @@ namespace icsneo {
|
|||||||
|
|
||||||
class Encoder {
|
class Encoder {
|
||||||
public:
|
public:
|
||||||
Encoder(device_eventhandler_t report, std::shared_ptr<Packetizer> p) : packetizer(p), report(report) {}
|
Encoder(device_errorhandler_t err, std::shared_ptr<Packetizer> p) : packetizer(p), err(err) {}
|
||||||
bool encode(std::vector<uint8_t>& result, const std::shared_ptr<Message>& message);
|
bool encode(std::vector<uint8_t>& result, const std::shared_ptr<Message>& message);
|
||||||
bool encode(std::vector<uint8_t>& result, Command cmd, bool boolean) { return encode(result, cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
bool encode(std::vector<uint8_t>& result, Command cmd, bool boolean) { return encode(result, cmd, std::vector<uint8_t>({ (uint8_t)boolean })); }
|
||||||
bool encode(std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments = {});
|
bool encode(std::vector<uint8_t>& result, Command cmd, std::vector<uint8_t> arguments = {});
|
||||||
@@ -23,7 +23,7 @@ public:
|
|||||||
bool supportCANFD = false;
|
bool supportCANFD = false;
|
||||||
private:
|
private:
|
||||||
std::shared_ptr<Packetizer> packetizer;
|
std::shared_ptr<Packetizer> packetizer;
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,14 +7,14 @@
|
|||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h"
|
#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ICommunication {
|
class ICommunication {
|
||||||
public:
|
public:
|
||||||
ICommunication(const device_eventhandler_t& handler) : report(handler) {}
|
ICommunication(const device_errorhandler_t& handler) : err(handler) {}
|
||||||
virtual ~ICommunication() {}
|
virtual ~ICommunication() {}
|
||||||
virtual bool open() = 0;
|
virtual bool open() = 0;
|
||||||
virtual bool isOpen() = 0;
|
virtual bool isOpen() = 0;
|
||||||
@@ -27,7 +27,7 @@ public:
|
|||||||
writeCV.notify_one();
|
writeCV.notify_one();
|
||||||
}
|
}
|
||||||
|
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
|
|
||||||
size_t writeQueueSize = 50;
|
size_t writeQueueSize = 50;
|
||||||
bool writeBlocks = true; // Otherwise it just fails when the queue is full
|
bool writeBlocks = true; // Otherwise it just fails when the queue is full
|
||||||
|
|||||||
@@ -1,35 +0,0 @@
|
|||||||
#ifndef __FLEXRAYCONTROLMESSAGE_H_
|
|
||||||
#define __FLEXRAYCONTROLMESSAGE_H_
|
|
||||||
|
|
||||||
#include "icsneo/communication/message/message.h"
|
|
||||||
#include "icsneo/communication/packet.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/opcode.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/pocstatus.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
// Internal message which gives us the state of the FlexRay Controllers
|
|
||||||
class FlexRayControlMessage : public Message {
|
|
||||||
public:
|
|
||||||
static std::vector<uint8_t> BuildBaseControlArgs(uint8_t controller, FlexRay::Opcode op, std::initializer_list<uint8_t> args);
|
|
||||||
static std::vector<uint8_t> BuildReadCCRegsArgs(uint8_t controller, uint16_t startAddress, uint8_t numRegisters = 1);
|
|
||||||
static std::vector<uint8_t> BuildWriteCCRegArgs(uint8_t controller, uint16_t address, uint32_t value);
|
|
||||||
|
|
||||||
FlexRayControlMessage(const Packet& packet);
|
|
||||||
virtual ~FlexRayControlMessage() = default;
|
|
||||||
bool decoded = false;
|
|
||||||
uint8_t controller = 0xff; // Controller index, either 0 or 1
|
|
||||||
FlexRay::Opcode opcode = FlexRay::Opcode::Unknown;
|
|
||||||
FlexRay::POCStatus pocStatus = FlexRay::POCStatus::Unknown;
|
|
||||||
uint16_t slotCounterA = 0;
|
|
||||||
uint16_t slotCounterB = 0;
|
|
||||||
uint16_t macroTick = 0;
|
|
||||||
uint16_t cycleCount = 0;
|
|
||||||
uint32_t rateCorrection = 0;
|
|
||||||
uint32_t offsetCorrection = 0;
|
|
||||||
std::vector<uint32_t> registers;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,32 +0,0 @@
|
|||||||
#ifndef __FLEXRAYMESSAGE_H_
|
|
||||||
#define __FLEXRAYMESSAGE_H_
|
|
||||||
|
|
||||||
#include "icsneo/communication/message/message.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/symbol.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/crcstatus.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class FlexRayMessage : public Message {
|
|
||||||
public:
|
|
||||||
uint16_t slotid = 0;
|
|
||||||
double tsslen = 0;
|
|
||||||
double framelen = 0;
|
|
||||||
FlexRay::Symbol symbol = FlexRay::Symbol::None;
|
|
||||||
FlexRay::CRCStatus headerCRCStatus = FlexRay::CRCStatus::OK;
|
|
||||||
uint16_t headerCRC = 0;
|
|
||||||
FlexRay::CRCStatus crcStatus = FlexRay::CRCStatus::OK;
|
|
||||||
uint32_t frameCRC = 0;
|
|
||||||
bool channelB = false;
|
|
||||||
bool nullFrame = false;
|
|
||||||
bool reserved0was1 = false;
|
|
||||||
bool payloadPreamble = false;
|
|
||||||
bool sync = false;
|
|
||||||
bool startup = false;
|
|
||||||
bool dynamic = false;
|
|
||||||
uint8_t cycle = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -11,7 +11,7 @@ namespace icsneo {
|
|||||||
class MultiChannelCommunication : public Communication {
|
class MultiChannelCommunication : public Communication {
|
||||||
public:
|
public:
|
||||||
MultiChannelCommunication(
|
MultiChannelCommunication(
|
||||||
device_eventhandler_t err,
|
device_errorhandler_t err,
|
||||||
std::unique_ptr<ICommunication> com,
|
std::unique_ptr<ICommunication> com,
|
||||||
std::shared_ptr<Packetizer> p,
|
std::shared_ptr<Packetizer> p,
|
||||||
std::unique_ptr<Encoder> e,
|
std::unique_ptr<Encoder> e,
|
||||||
@@ -44,62 +44,6 @@ private:
|
|||||||
HostPC_to_Microblaze = 0x80, // Host PC data to microblaze processor
|
HostPC_to_Microblaze = 0x80, // Host PC data to microblaze processor
|
||||||
Microblaze_to_HostPC = 0x81 // Microblaze processor data to host PC
|
Microblaze_to_HostPC = 0x81 // Microblaze processor data to host PC
|
||||||
};
|
};
|
||||||
|
|
||||||
static bool FixSlaveVNETPacketNetID(Packet& packet);
|
|
||||||
enum class CoreMiniNetwork : uint8_t {
|
|
||||||
HSCAN1 = (0),
|
|
||||||
MSCAN1 = (1),
|
|
||||||
LIN1 = (2),
|
|
||||||
LIN2 = (3),
|
|
||||||
VIRTUAL = (4),
|
|
||||||
HSCAN2 = (5),
|
|
||||||
LSFTCAN1 = (6),
|
|
||||||
SWCAN1 = (7),
|
|
||||||
HSCAN3 = (8),
|
|
||||||
GMCGI = (9),
|
|
||||||
J1850_VPW = (10),
|
|
||||||
LIN3 = (11),
|
|
||||||
LIN4 = (12),
|
|
||||||
J1708 = (13),
|
|
||||||
HSCAN4 = (14),
|
|
||||||
HSCAN5 = (15),
|
|
||||||
KLINE1 = (16),
|
|
||||||
KLINE2 = (17),
|
|
||||||
KLINE3 = (18),
|
|
||||||
KLINE4 = (19),
|
|
||||||
FLEXRAY_1A = (20),
|
|
||||||
UART = (21),
|
|
||||||
UART2 = (22),
|
|
||||||
LIN5 = (23),
|
|
||||||
MOST25 = (24),
|
|
||||||
MOST50 = (25),
|
|
||||||
FLEXRAY_1B = (26),
|
|
||||||
SWCAN2 = (27),
|
|
||||||
ETHERNET_DAQ = (28),
|
|
||||||
ETHERNET = (29),
|
|
||||||
FLEXRAY_2A = (30),
|
|
||||||
FLEXRAY_2B = (31),
|
|
||||||
HSCAN6 = (32),
|
|
||||||
HSCAN7 = (33),
|
|
||||||
LIN6 = (34),
|
|
||||||
LSFTCAN2 = (35),
|
|
||||||
OP_ETHERNET1 = (36),
|
|
||||||
OP_ETHERNET2 = (37),
|
|
||||||
OP_ETHERNET3 = (38),
|
|
||||||
OP_ETHERNET4 = (39),
|
|
||||||
OP_ETHERNET5 = (40),
|
|
||||||
OP_ETHERNET6 = (41),
|
|
||||||
OP_ETHERNET7 = (42),
|
|
||||||
OP_ETHERNET8 = (43),
|
|
||||||
OP_ETHERNET9 = (44),
|
|
||||||
OP_ETHERNET10 = (45),
|
|
||||||
OP_ETHERNET11 = (46),
|
|
||||||
OP_ETHERNET12 = (47),
|
|
||||||
KLINE5 = (48),
|
|
||||||
KLINE6 = (49),
|
|
||||||
FLEXRAY1 = (50),
|
|
||||||
FLEXRAY2 = (51)
|
|
||||||
};
|
|
||||||
static bool CommandTypeIsValid(CommandType cmd) {
|
static bool CommandTypeIsValid(CommandType cmd) {
|
||||||
switch(cmd) {
|
switch(cmd) {
|
||||||
case CommandType::PlasmaReadRequest:
|
case CommandType::PlasmaReadRequest:
|
||||||
|
|||||||
@@ -112,7 +112,6 @@ public:
|
|||||||
HSCAN7 = 97,
|
HSCAN7 = 97,
|
||||||
LIN6 = 98,
|
LIN6 = 98,
|
||||||
LSFTCAN2 = 99,
|
LSFTCAN2 = 99,
|
||||||
FlexRayControl = 243,
|
|
||||||
HW_COM_Latency_Test = 512,
|
HW_COM_Latency_Test = 512,
|
||||||
Device_Status = 513,
|
Device_Status = 513,
|
||||||
Any = 0xfffe, // Never actually set as type, but used as flag for filtering
|
Any = 0xfffe, // Never actually set as type, but used as flag for filtering
|
||||||
@@ -188,7 +187,6 @@ public:
|
|||||||
case NetID::RED:
|
case NetID::RED:
|
||||||
case NetID::Reset_Status:
|
case NetID::Reset_Status:
|
||||||
case NetID::Device_Status:
|
case NetID::Device_Status:
|
||||||
case NetID::FlexRayControl:
|
|
||||||
return Type::Internal;
|
return Type::Internal;
|
||||||
case NetID::Invalid:
|
case NetID::Invalid:
|
||||||
case NetID::Any:
|
case NetID::Any:
|
||||||
@@ -410,17 +408,14 @@ public:
|
|||||||
return "LIN 6";
|
return "LIN 6";
|
||||||
case NetID::LSFTCAN2:
|
case NetID::LSFTCAN2:
|
||||||
return "LSFTCAN 2";
|
return "LSFTCAN 2";
|
||||||
case NetID::FlexRayControl:
|
|
||||||
return "FlexRay Control";
|
|
||||||
case NetID::HW_COM_Latency_Test:
|
case NetID::HW_COM_Latency_Test:
|
||||||
return "HW COM Latency Test";
|
return "HW COM Latency Test";
|
||||||
case NetID::Device_Status:
|
case NetID::Device_Status:
|
||||||
return "Device Status";
|
return "Device Status";
|
||||||
case NetID::Any:
|
|
||||||
case NetID::Invalid:
|
case NetID::Invalid:
|
||||||
break;
|
default:
|
||||||
|
return "Invalid Network";
|
||||||
}
|
}
|
||||||
return "Invalid Network";
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Network() { setValue(NetID::Invalid); }
|
Network() { setValue(NetID::Invalid); }
|
||||||
@@ -448,121 +443,121 @@ private:
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __ICSNEOC_H_
|
#ifdef __ICSNEOC_H_
|
||||||
#define ICSNEO_NETID_DEVICE 0
|
#define ICSNEO_NETID_DEVICE ((uint16_t)0)
|
||||||
#define ICSNEO_NETID_HSCAN 1
|
#define ICSNEO_NETID_HSCAN ((uint16_t)1)
|
||||||
#define ICSNEO_NETID_MSCAN 2
|
#define ICSNEO_NETID_MSCAN ((uint16_t)2)
|
||||||
#define ICSNEO_NETID_SWCAN 3
|
#define ICSNEO_NETID_SWCAN ((uint16_t)3)
|
||||||
#define ICSNEO_NETID_LSFTCAN 4
|
#define ICSNEO_NETID_LSFTCAN ((uint16_t)4)
|
||||||
#define ICSNEO_NETID_FORDSCP 5
|
#define ICSNEO_NETID_FORDSCP ((uint16_t)5)
|
||||||
#define ICSNEO_NETID_J1708 6
|
#define ICSNEO_NETID_J1708 ((uint16_t)6)
|
||||||
#define ICSNEO_NETID_AUX 7
|
#define ICSNEO_NETID_AUX ((uint16_t)7)
|
||||||
#define ICSNEO_NETID_J1850VPW 8
|
#define ICSNEO_NETID_J1850VPW ((uint16_t)8)
|
||||||
#define ICSNEO_NETID_ISO 9
|
#define ICSNEO_NETID_ISO ((uint16_t)9)
|
||||||
#define ICSNEO_NETID_ISOPIC 10
|
#define ICSNEO_NETID_ISOPIC ((uint16_t)10)
|
||||||
#define ICSNEO_NETID_MAIN51 11
|
#define ICSNEO_NETID_MAIN51 ((uint16_t)11)
|
||||||
#define ICSNEO_NETID_RED 12
|
#define ICSNEO_NETID_RED ((uint16_t)12)
|
||||||
#define ICSNEO_NETID_SCI 13
|
#define ICSNEO_NETID_SCI ((uint16_t)13)
|
||||||
#define ICSNEO_NETID_ISO2 14
|
#define ICSNEO_NETID_ISO2 ((uint16_t)14)
|
||||||
#define ICSNEO_NETID_ISO14230 15
|
#define ICSNEO_NETID_ISO14230 ((uint16_t)15)
|
||||||
#define ICSNEO_NETID_LIN 16
|
#define ICSNEO_NETID_LIN ((uint16_t)16)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET1 17
|
#define ICSNEO_NETID_OP_ETHERNET1 ((uint16_t)17)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET2 18
|
#define ICSNEO_NETID_OP_ETHERNET2 ((uint16_t)18)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET3 19
|
#define ICSNEO_NETID_OP_ETHERNET3 ((uint16_t)19)
|
||||||
|
|
||||||
// START Device Command Returns
|
// START Device Command Returns
|
||||||
// When we send a command, the device returns on one of these, depending on command
|
// When we send a command, the device returns on one of these, depending on command
|
||||||
#define ICSNEO_NETID_RED_EXT_MEMORYREAD 20
|
#define ICSNEO_NETID_RED_EXT_MEMORYREAD ((uint16_t)20)
|
||||||
#define ICSNEO_NETID_RED_INT_MEMORYREAD 21
|
#define ICSNEO_NETID_RED_INT_MEMORYREAD ((uint16_t)21)
|
||||||
#define ICSNEO_NETID_RED_DFLASH_READ 22
|
#define ICSNEO_NETID_RED_DFLASH_READ ((uint16_t)22)
|
||||||
#define ICSNEO_NETID_RED_SDCARD_READ 23
|
#define ICSNEO_NETID_RED_SDCARD_READ ((uint16_t)23)
|
||||||
#define ICSNEO_NETID_CAN_ERRBITS 24
|
#define ICSNEO_NETID_CAN_ERRBITS ((uint16_t)24)
|
||||||
#define ICSNEO_NETID_RED_DFLASH_WRITE_DONE 25
|
#define ICSNEO_NETID_RED_DFLASH_WRITE_DONE ((uint16_t)25)
|
||||||
#define ICSNEO_NETID_RED_WAVE_CAN1_LOGICAL 26
|
#define ICSNEO_NETID_RED_WAVE_CAN1_LOGICAL ((uint16_t)26)
|
||||||
#define ICSNEO_NETID_RED_WAVE_CAN2_LOGICAL 27
|
#define ICSNEO_NETID_RED_WAVE_CAN2_LOGICAL ((uint16_t)27)
|
||||||
#define ICSNEO_NETID_RED_WAVE_LIN1_LOGICAL 28
|
#define ICSNEO_NETID_RED_WAVE_LIN1_LOGICAL ((uint16_t)28)
|
||||||
#define ICSNEO_NETID_RED_WAVE_LIN2_LOGICAL 29
|
#define ICSNEO_NETID_RED_WAVE_LIN2_LOGICAL ((uint16_t)29)
|
||||||
#define ICSNEO_NETID_RED_WAVE_LIN1_ANALOG 30
|
#define ICSNEO_NETID_RED_WAVE_LIN1_ANALOG ((uint16_t)30)
|
||||||
#define ICSNEO_NETID_RED_WAVE_LIN2_ANALOG 31
|
#define ICSNEO_NETID_RED_WAVE_LIN2_ANALOG ((uint16_t)31)
|
||||||
#define ICSNEO_NETID_RED_WAVE_MISC_ANALOG 32
|
#define ICSNEO_NETID_RED_WAVE_MISC_ANALOG ((uint16_t)32)
|
||||||
#define ICSNEO_NETID_RED_WAVE_MISCDIO2_LOGICAL 33
|
#define ICSNEO_NETID_RED_WAVE_MISCDIO2_LOGICAL ((uint16_t)33)
|
||||||
#define ICSNEO_NETID_RED_NETWORK_COM_ENABLE_EX 34
|
#define ICSNEO_NETID_RED_NETWORK_COM_ENABLE_EX ((uint16_t)34)
|
||||||
#define ICSNEO_NETID_RED_NEOVI_NETWORK 35
|
#define ICSNEO_NETID_RED_NEOVI_NETWORK ((uint16_t)35)
|
||||||
#define ICSNEO_NETID_RED_READ_BAUD_SETTINGS 36
|
#define ICSNEO_NETID_RED_READ_BAUD_SETTINGS ((uint16_t)36)
|
||||||
#define ICSNEO_NETID_RED_OLDFORMAT 37
|
#define ICSNEO_NETID_RED_OLDFORMAT ((uint16_t)37)
|
||||||
#define ICSNEO_NETID_RED_SCOPE_CAPTURE 38
|
#define ICSNEO_NETID_RED_SCOPE_CAPTURE ((uint16_t)38)
|
||||||
#define ICSNEO_NETID_RED_HARDWARE_EXCEP 39
|
#define ICSNEO_NETID_RED_HARDWARE_EXCEP ((uint16_t)39)
|
||||||
#define ICSNEO_NETID_RED_GET_RTC 40
|
#define ICSNEO_NETID_RED_GET_RTC ((uint16_t)40)
|
||||||
// END Device Command Returns
|
// END Device Command Returns
|
||||||
|
|
||||||
#define ICSNEO_NETID_ISO3 41
|
#define ICSNEO_NETID_ISO3 ((uint16_t)41)
|
||||||
#define ICSNEO_NETID_HSCAN2 42
|
#define ICSNEO_NETID_HSCAN2 ((uint16_t)42)
|
||||||
#define ICSNEO_NETID_HSCAN3 44
|
#define ICSNEO_NETID_HSCAN3 ((uint16_t)44)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET4 45
|
#define ICSNEO_NETID_OP_ETHERNET4 ((uint16_t)45)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET5 46
|
#define ICSNEO_NETID_OP_ETHERNET5 ((uint16_t)46)
|
||||||
#define ICSNEO_NETID_ISO4 47
|
#define ICSNEO_NETID_ISO4 ((uint16_t)47)
|
||||||
#define ICSNEO_NETID_LIN2 48
|
#define ICSNEO_NETID_LIN2 ((uint16_t)48)
|
||||||
#define ICSNEO_NETID_LIN3 49
|
#define ICSNEO_NETID_LIN3 ((uint16_t)49)
|
||||||
#define ICSNEO_NETID_LIN4 50
|
#define ICSNEO_NETID_LIN4 ((uint16_t)50)
|
||||||
//#define ICSNEO_NETID_MOST 51 Old and unused
|
//#define ICSNEO_NETID_MOST ((uint16_t)51) Old and unused
|
||||||
#define ICSNEO_NETID_RED_APP_ERROR 52
|
#define ICSNEO_NETID_RED_APP_ERROR ((uint16_t)52)
|
||||||
#define ICSNEO_NETID_CGI 53
|
#define ICSNEO_NETID_CGI ((uint16_t)53)
|
||||||
#define ICSNEO_NETID_RESET_STATUS 54
|
#define ICSNEO_NETID_RESET_STATUS ((uint16_t)54)
|
||||||
#define ICSNEO_NETID_FB_STATUS 55
|
#define ICSNEO_NETID_FB_STATUS ((uint16_t)55)
|
||||||
#define ICSNEO_NETID_APP_SIGNAL_STATUS 56
|
#define ICSNEO_NETID_APP_SIGNAL_STATUS ((uint16_t)56)
|
||||||
#define ICSNEO_NETID_READ_DATALINK_CM_TX_MSG 57
|
#define ICSNEO_NETID_READ_DATALINK_CM_TX_MSG ((uint16_t)57)
|
||||||
#define ICSNEO_NETID_READ_DATALINK_CM_RX_MSG 58
|
#define ICSNEO_NETID_READ_DATALINK_CM_RX_MSG ((uint16_t)58)
|
||||||
#define ICSNEO_NETID_LOGGING_OVERFLOW 59
|
#define ICSNEO_NETID_LOGGING_OVERFLOW ((uint16_t)59)
|
||||||
#define ICSNEO_NETID_READ_SETTINGS 60
|
#define ICSNEO_NETID_READ_SETTINGS ((uint16_t)60)
|
||||||
#define ICSNEO_NETID_HSCAN4 61
|
#define ICSNEO_NETID_HSCAN4 ((uint16_t)61)
|
||||||
#define ICSNEO_NETID_HSCAN5 62
|
#define ICSNEO_NETID_HSCAN5 ((uint16_t)62)
|
||||||
#define ICSNEO_NETID_RS232 63
|
#define ICSNEO_NETID_RS232 ((uint16_t)63)
|
||||||
#define ICSNEO_NETID_UART 64
|
#define ICSNEO_NETID_UART ((uint16_t)64)
|
||||||
#define ICSNEO_NETID_UART2 65
|
#define ICSNEO_NETID_UART2 ((uint16_t)65)
|
||||||
#define ICSNEO_NETID_UART3 66
|
#define ICSNEO_NETID_UART3 ((uint16_t)66)
|
||||||
#define ICSNEO_NETID_UART4 67
|
#define ICSNEO_NETID_UART4 ((uint16_t)67)
|
||||||
#define ICSNEO_NETID_SWCAN2 68
|
#define ICSNEO_NETID_SWCAN2 ((uint16_t)68)
|
||||||
#define ICSNEO_NETID_ETHERNET_DAQ 69
|
#define ICSNEO_NETID_ETHERNET_DAQ ((uint16_t)69)
|
||||||
#define ICSNEO_NETID_DATA_TO_HOST 70
|
#define ICSNEO_NETID_DATA_TO_HOST ((uint16_t)70)
|
||||||
#define ICSNEO_NETID_TEXTAPI_TO_HOST 71
|
#define ICSNEO_NETID_TEXTAPI_TO_HOST ((uint16_t)71)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET6 73
|
#define ICSNEO_NETID_OP_ETHERNET6 ((uint16_t)73)
|
||||||
#define ICSNEO_NETID_RED_VBAT 74
|
#define ICSNEO_NETID_RED_VBAT ((uint16_t)74)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET7 75
|
#define ICSNEO_NETID_OP_ETHERNET7 ((uint16_t)75)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET8 76
|
#define ICSNEO_NETID_OP_ETHERNET8 ((uint16_t)76)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET9 77
|
#define ICSNEO_NETID_OP_ETHERNET9 ((uint16_t)77)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET10 78
|
#define ICSNEO_NETID_OP_ETHERNET10 ((uint16_t)78)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET11 79
|
#define ICSNEO_NETID_OP_ETHERNET11 ((uint16_t)79)
|
||||||
#define ICSNEO_NETID_FLEXRAY1A 80
|
#define ICSNEO_NETID_FLEXRAY1A ((uint16_t)80)
|
||||||
#define ICSNEO_NETID_FLEXRAY1B 81
|
#define ICSNEO_NETID_FLEXRAY1B ((uint16_t)81)
|
||||||
#define ICSNEO_NETID_FLEXRAY2A 82
|
#define ICSNEO_NETID_FLEXRAY2A ((uint16_t)82)
|
||||||
#define ICSNEO_NETID_FLEXRAY2B 83
|
#define ICSNEO_NETID_FLEXRAY2B ((uint16_t)83)
|
||||||
#define ICSNEO_NETID_LIN5 84
|
#define ICSNEO_NETID_LIN5 ((uint16_t)84)
|
||||||
#define ICSNEO_NETID_FLEXRAY 85
|
#define ICSNEO_NETID_FLEXRAY ((uint16_t)85)
|
||||||
#define ICSNEO_NETID_FLEXRAY2 86
|
#define ICSNEO_NETID_FLEXRAY2 ((uint16_t)86)
|
||||||
#define ICSNEO_NETID_OP_ETHERNET12 87
|
#define ICSNEO_NETID_OP_ETHERNET12 ((uint16_t)87)
|
||||||
#define ICSNEO_NETID_MOST25 90
|
#define ICSNEO_NETID_MOST25 ((uint16_t)90)
|
||||||
#define ICSNEO_NETID_MOST50 91
|
#define ICSNEO_NETID_MOST50 ((uint16_t)91)
|
||||||
#define ICSNEO_NETID_MOST150 92
|
#define ICSNEO_NETID_MOST150 ((uint16_t)92)
|
||||||
#define ICSNEO_NETID_ETHERNET 93
|
#define ICSNEO_NETID_ETHERNET ((uint16_t)93)
|
||||||
#define ICSNEO_NETID_GMFSA 94
|
#define ICSNEO_NETID_GMFSA ((uint16_t)94)
|
||||||
#define ICSNEO_NETID_TCP 95
|
#define ICSNEO_NETID_TCP ((uint16_t)95)
|
||||||
#define ICSNEO_NETID_HSCAN6 96
|
#define ICSNEO_NETID_HSCAN6 ((uint16_t)96)
|
||||||
#define ICSNEO_NETID_HSCAN7 97
|
#define ICSNEO_NETID_HSCAN7 ((uint16_t)97)
|
||||||
#define ICSNEO_NETID_LIN6 98
|
#define ICSNEO_NETID_LIN6 ((uint16_t)98)
|
||||||
#define ICSNEO_NETID_LSFTCAN2 99
|
#define ICSNEO_NETID_LSFTCAN2 ((uint16_t)99)
|
||||||
#define ICSNEO_NETID_HW_COM_LATENCY_TEST 512
|
#define ICSNEO_NETID_HW_COM_LATENCY_TEST ((uint16_t)512)
|
||||||
#define ICSNEO_NETID_DEVICE_STATUS 513
|
#define ICSNEO_NETID_DEVICE_STATUS ((uint16_t)513)
|
||||||
#define ICSNEO_NETID_ANY 0xfffe // Never actually set as type, but used as flag for filtering
|
#define ICSNEO_NETID_ANY ((uint16_t)0xfffe) // Never actually set as type, but used as flag for filtering
|
||||||
#define ICSNEO_NETID_INVALID 0xffff
|
#define ICSNEO_NETID_INVALID ((uint16_t)0xffff)
|
||||||
|
|
||||||
#define ICSNEO_NETWORK_TYPE_INVALID 0
|
#define ICSNEO_NETWORK_TYPE_INVALID ((uint8_t)0)
|
||||||
#define ICSNEO_NETWORK_TYPE_INTERNAL 1 // Used for statuses that don't actually need to be transferred to the client application
|
#define ICSNEO_NETWORK_TYPE_INTERNAL ((uint8_t)1) // Used for statuses that don't actually need to be transferred to the client application
|
||||||
#define ICSNEO_NETWORK_TYPE_CAN 2
|
#define ICSNEO_NETWORK_TYPE_CAN ((uint8_t)2)
|
||||||
#define ICSNEO_NETWORK_TYPE_LIN 3
|
#define ICSNEO_NETWORK_TYPE_LIN ((uint8_t)3)
|
||||||
#define ICSNEO_NETWORK_TYPE_FLEXRAY 4
|
#define ICSNEO_NETWORK_TYPE_FLEXRAY ((uint8_t)4)
|
||||||
#define ICSNEO_NETWORK_TYPE_MOST 5
|
#define ICSNEO_NETWORK_TYPE_MOST ((uint8_t)5)
|
||||||
#define ICSNEO_NETWORK_TYPE_ETHERNET 6
|
#define ICSNEO_NETWORK_TYPE_ETHERNET ((uint8_t)6)
|
||||||
#define ICSNEO_NETWORK_TYPE_ANY 0xFE // Never actually set as type, but used as flag for filtering
|
#define ICSNEO_NETWORK_TYPE_ANY ((uint8_t)0xFE) // Never actually set as type, but used as flag for filtering
|
||||||
#define ICSNEO_NETWORK_TYPE_OTHER 0xFF
|
#define ICSNEO_NETWORK_TYPE_OTHER ((uint8_t)0xFF)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -2,7 +2,6 @@
|
|||||||
#define __CANPACKET_H__
|
#define __CANPACKET_H__
|
||||||
|
|
||||||
#include "icsneo/communication/message/canmessage.h"
|
#include "icsneo/communication/message/canmessage.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -12,7 +11,7 @@ typedef uint16_t icscm_bitfield;
|
|||||||
|
|
||||||
struct HardwareCANPacket {
|
struct HardwareCANPacket {
|
||||||
static std::shared_ptr<CANMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
static std::shared_ptr<CANMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||||
static bool EncodeFromMessage(const CANMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
static bool EncodeFromMessage(const CANMessage& message, std::vector<uint8_t>& bytestream);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
icscm_bitfield IDE : 1;
|
icscm_bitfield IDE : 1;
|
||||||
|
|||||||
@@ -2,7 +2,6 @@
|
|||||||
#define __ETHERNETPACKET_H__
|
#define __ETHERNETPACKET_H__
|
||||||
|
|
||||||
#include "icsneo/communication/message/ethernetmessage.h"
|
#include "icsneo/communication/message/ethernetmessage.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
|
||||||
#include <cstdint>
|
#include <cstdint>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
@@ -12,7 +11,7 @@ typedef uint16_t icscm_bitfield;
|
|||||||
|
|
||||||
struct HardwareEthernetPacket {
|
struct HardwareEthernetPacket {
|
||||||
static std::shared_ptr<EthernetMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
static std::shared_ptr<EthernetMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
||||||
static bool EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& err);
|
static bool EncodeFromMessage(const EthernetMessage& message, std::vector<uint8_t>& bytestream);
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
icscm_bitfield FCS_AVAIL : 1;
|
icscm_bitfield FCS_AVAIL : 1;
|
||||||
|
|||||||
@@ -1,66 +0,0 @@
|
|||||||
#ifndef __FLEXRAYPACKET_H__
|
|
||||||
#define __FLEXRAYPACKET_H__
|
|
||||||
|
|
||||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
|
||||||
#include "icsneo/api/eventmanager.h"
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
struct HardwareFlexRayPacket {
|
|
||||||
static std::shared_ptr<FlexRayMessage> DecodeToMessage(const std::vector<uint8_t>& bytestream);
|
|
||||||
static bool EncodeFromMessage(const FlexRayMessage& message, std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
|
||||||
|
|
||||||
//Word 0
|
|
||||||
uint16_t slotid : 11;
|
|
||||||
uint16_t startup : 1;
|
|
||||||
uint16_t sync : 1;
|
|
||||||
uint16_t null_frame : 1;
|
|
||||||
uint16_t payload_preamble : 1;
|
|
||||||
uint16_t reserved_0 : 1;
|
|
||||||
//Word 1
|
|
||||||
uint16_t hdr_crc_10 : 1;
|
|
||||||
uint16_t payload_len : 7;
|
|
||||||
uint16_t reserved_1 : 4;
|
|
||||||
uint16_t txmsg : 1;
|
|
||||||
uint16_t reserved_2 : 3;
|
|
||||||
//Word 2
|
|
||||||
uint16_t cycle : 6;
|
|
||||||
uint16_t hdr_crc_9_0 : 10;
|
|
||||||
//Word 3 (D0-D1)
|
|
||||||
union {
|
|
||||||
uint16_t word;
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
uint16_t bytesRxed : 9;
|
|
||||||
uint16_t dynamic : 1;
|
|
||||||
uint16_t chb : 1;
|
|
||||||
uint16_t hcrc_error : 1;
|
|
||||||
uint16_t fcrc_error : 1;
|
|
||||||
uint16_t reserved_3 : 3;
|
|
||||||
} bits;
|
|
||||||
} statusBits;
|
|
||||||
//Word 4 (D2-D3)
|
|
||||||
uint16_t tss_length_12_5ns;
|
|
||||||
//Word 5 (D4-D5)
|
|
||||||
uint16_t frame_length_12_5ns;
|
|
||||||
//Word 6 (D6-D7)
|
|
||||||
uint16_t extra;
|
|
||||||
//Word 7
|
|
||||||
uint16_t stat;
|
|
||||||
//Word 8-14 (Timestamp)
|
|
||||||
struct {
|
|
||||||
uint64_t TS : 60;
|
|
||||||
uint64_t : 3; // Reserved for future status bits
|
|
||||||
uint64_t IsExtended : 1;
|
|
||||||
} timestamp;
|
|
||||||
//Word 15 (From Extended Header)
|
|
||||||
uint16_t NetworkID;
|
|
||||||
//Word 16 (From Extended Header)
|
|
||||||
uint16_t Length;
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
#define __PACKETIZER_H_
|
#define __PACKETIZER_H_
|
||||||
|
|
||||||
#include "icsneo/communication/packet.h"
|
#include "icsneo/communication/packet.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
@@ -13,7 +13,7 @@ class Packetizer {
|
|||||||
public:
|
public:
|
||||||
static uint8_t ICSChecksum(const std::vector<uint8_t>& data);
|
static uint8_t ICSChecksum(const std::vector<uint8_t>& data);
|
||||||
|
|
||||||
Packetizer(device_eventhandler_t report) : report(report) {}
|
Packetizer(device_errorhandler_t err) : err(err) {}
|
||||||
|
|
||||||
std::vector<uint8_t>& packetWrap(std::vector<uint8_t>& data, bool shortFormat);
|
std::vector<uint8_t>& packetWrap(std::vector<uint8_t>& data, bool shortFormat);
|
||||||
|
|
||||||
@@ -37,12 +37,12 @@ private:
|
|||||||
int headerSize = 0;
|
int headerSize = 0;
|
||||||
bool checksum = false;
|
bool checksum = false;
|
||||||
bool gotGoodPackets = false; // Tracks whether we've ever gotten a good packet
|
bool gotGoodPackets = false; // Tracks whether we've ever gotten a good packet
|
||||||
Packet packet, previousPacket;
|
Packet packet;
|
||||||
std::deque<uint8_t> bytes;
|
std::deque<uint8_t> bytes;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Packet>> processedPackets;
|
std::vector<std::shared_ptr<Packet>> processedPackets;
|
||||||
|
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,21 +3,17 @@
|
|||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <utility>
|
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
#include "icsneo/device/neodevice.h"
|
#include "icsneo/device/neodevice.h"
|
||||||
#include "icsneo/device/idevicesettings.h"
|
#include "icsneo/device/idevicesettings.h"
|
||||||
#include "icsneo/device/nullsettings.h"
|
#include "icsneo/device/nullsettings.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/device/extensions/deviceextension.h"
|
|
||||||
#include "icsneo/communication/communication.h"
|
#include "icsneo/communication/communication.h"
|
||||||
#include "icsneo/communication/packetizer.h"
|
#include "icsneo/communication/packetizer.h"
|
||||||
#include "icsneo/communication/encoder.h"
|
#include "icsneo/communication/encoder.h"
|
||||||
#include "icsneo/communication/decoder.h"
|
#include "icsneo/communication/decoder.h"
|
||||||
#include "icsneo/communication/message/resetstatusmessage.h"
|
#include "icsneo/communication/message/resetstatusmessage.h"
|
||||||
#include "icsneo/device/extensions/flexray/controller.h"
|
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
|
||||||
#include "icsneo/third-party/concurrentqueue/concurrentqueue.h"
|
#include "icsneo/third-party/concurrentqueue/concurrentqueue.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -25,8 +21,7 @@ namespace icsneo {
|
|||||||
class Device {
|
class Device {
|
||||||
public:
|
public:
|
||||||
virtual ~Device() {
|
virtual ~Device() {
|
||||||
if(isMessagePollingEnabled())
|
disableMessagePolling();
|
||||||
disableMessagePolling();
|
|
||||||
close();
|
close();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,15 +44,13 @@ public:
|
|||||||
virtual bool open();
|
virtual bool open();
|
||||||
virtual bool close();
|
virtual bool close();
|
||||||
virtual bool isOnline() const { return online; }
|
virtual bool isOnline() const { return online; }
|
||||||
virtual bool isOpen() const { return com->isOpen(); }
|
|
||||||
virtual bool goOnline();
|
virtual bool goOnline();
|
||||||
virtual bool goOffline();
|
virtual bool goOffline();
|
||||||
|
|
||||||
// Message polling related functions
|
// Message polling related functions
|
||||||
bool enableMessagePolling();
|
void enableMessagePolling();
|
||||||
bool disableMessagePolling();
|
bool disableMessagePolling();
|
||||||
bool isMessagePollingEnabled() { return messagePollingCallbackID != 0; };
|
std::vector<std::shared_ptr<Message>> getMessages();
|
||||||
std::pair<std::vector<std::shared_ptr<Message>>, bool> getMessages();
|
|
||||||
bool getMessages(std::vector<std::shared_ptr<Message>>& container, size_t limit = 0, std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
|
bool getMessages(std::vector<std::shared_ptr<Message>>& container, size_t limit = 0, std::chrono::milliseconds timeout = std::chrono::milliseconds(0));
|
||||||
size_t getCurrentMessageCount() { return pollingContainer.size_approx(); }
|
size_t getCurrentMessageCount() { return pollingContainer.size_approx(); }
|
||||||
size_t getPollingMessageLimit() { return pollingMessageLimit; }
|
size_t getPollingMessageLimit() { return pollingMessageLimit; }
|
||||||
@@ -72,8 +65,6 @@ public:
|
|||||||
bool transmit(std::shared_ptr<Message> message);
|
bool transmit(std::shared_ptr<Message> message);
|
||||||
bool transmit(std::vector<std::shared_ptr<Message>> messages);
|
bool transmit(std::vector<std::shared_ptr<Message>> messages);
|
||||||
|
|
||||||
void setWriteBlocks(bool blocks);
|
|
||||||
|
|
||||||
const std::vector<Network>& getSupportedRXNetworks() const { return supportedRXNetworks; }
|
const std::vector<Network>& getSupportedRXNetworks() const { return supportedRXNetworks; }
|
||||||
const std::vector<Network>& getSupportedTXNetworks() const { return supportedTXNetworks; }
|
const std::vector<Network>& getSupportedTXNetworks() const { return supportedTXNetworks; }
|
||||||
virtual bool isSupportedRXNetwork(const Network& net) const {
|
virtual bool isSupportedRXNetwork(const Network& net) const {
|
||||||
@@ -86,10 +77,6 @@ public:
|
|||||||
virtual size_t getNetworkCountByType(Network::Type) const;
|
virtual size_t getNetworkCountByType(Network::Type) const;
|
||||||
virtual Network getNetworkByNumber(Network::Type, size_t) const;
|
virtual Network getNetworkByNumber(Network::Type, size_t) const;
|
||||||
|
|
||||||
virtual std::shared_ptr<FlexRay::Controller> getFlexRayControllerByNetwork(const Network&) const { return nullptr; }
|
|
||||||
|
|
||||||
const device_eventhandler_t& getEventHandler() const { return report; }
|
|
||||||
|
|
||||||
std::shared_ptr<Communication> com;
|
std::shared_ptr<Communication> com;
|
||||||
std::unique_ptr<IDeviceSettings> settings;
|
std::unique_ptr<IDeviceSettings> settings;
|
||||||
|
|
||||||
@@ -98,7 +85,7 @@ protected:
|
|||||||
bool online = false;
|
bool online = false;
|
||||||
int messagePollingCallbackID = 0;
|
int messagePollingCallbackID = 0;
|
||||||
int internalHandlerCallbackID = 0;
|
int internalHandlerCallbackID = 0;
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
|
|
||||||
// START Initialization Functions
|
// START Initialization Functions
|
||||||
Device(neodevice_t neodevice = { 0 }) {
|
Device(neodevice_t neodevice = { 0 }) {
|
||||||
@@ -108,7 +95,7 @@ protected:
|
|||||||
|
|
||||||
template<typename Transport, typename Settings = NullSettings>
|
template<typename Transport, typename Settings = NullSettings>
|
||||||
void initialize() {
|
void initialize() {
|
||||||
report = makeEventHandler();
|
err = makeErrorHandler();
|
||||||
auto transport = makeTransport<Transport>();
|
auto transport = makeTransport<Transport>();
|
||||||
setupTransport(*transport);
|
setupTransport(*transport);
|
||||||
auto packetizer = makePacketizer();
|
auto packetizer = makePacketizer();
|
||||||
@@ -123,33 +110,30 @@ protected:
|
|||||||
setupSettings(*settings);
|
setupSettings(*settings);
|
||||||
setupSupportedRXNetworks(supportedRXNetworks);
|
setupSupportedRXNetworks(supportedRXNetworks);
|
||||||
setupSupportedTXNetworks(supportedTXNetworks);
|
setupSupportedTXNetworks(supportedTXNetworks);
|
||||||
setupExtensions();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual device_eventhandler_t makeEventHandler() {
|
virtual device_errorhandler_t makeErrorHandler() {
|
||||||
return [this](APIEvent::Type type, APIEvent::Severity severity) {
|
return [this](APIError::ErrorType type) { ErrorManager::GetInstance().add(type, this); };
|
||||||
EventManager::GetInstance().add(type, severity, this);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename Transport>
|
template<typename Transport>
|
||||||
std::unique_ptr<ICommunication> makeTransport() { return std::unique_ptr<ICommunication>(new Transport(report, getWritableNeoDevice())); }
|
std::unique_ptr<ICommunication> makeTransport() { return std::unique_ptr<ICommunication>(new Transport(err, getWritableNeoDevice())); }
|
||||||
virtual void setupTransport(ICommunication&) {}
|
virtual void setupTransport(ICommunication&) {}
|
||||||
|
|
||||||
virtual std::shared_ptr<Packetizer> makePacketizer() { return std::make_shared<Packetizer>(report); }
|
virtual std::shared_ptr<Packetizer> makePacketizer() { return std::make_shared<Packetizer>(err); }
|
||||||
virtual void setupPacketizer(Packetizer&) {}
|
virtual void setupPacketizer(Packetizer&) {}
|
||||||
|
|
||||||
virtual std::unique_ptr<Encoder> makeEncoder(std::shared_ptr<Packetizer> p) { return std::unique_ptr<Encoder>(new Encoder(report, p)); }
|
virtual std::unique_ptr<Encoder> makeEncoder(std::shared_ptr<Packetizer> p) { return std::unique_ptr<Encoder>(new Encoder(err, p)); }
|
||||||
virtual void setupEncoder(Encoder&) {}
|
virtual void setupEncoder(Encoder&) {}
|
||||||
|
|
||||||
virtual std::unique_ptr<Decoder> makeDecoder() { return std::unique_ptr<Decoder>(new Decoder(report)); }
|
virtual std::unique_ptr<Decoder> makeDecoder() { return std::unique_ptr<Decoder>(new Decoder(err)); }
|
||||||
virtual void setupDecoder(Decoder&) {}
|
virtual void setupDecoder(Decoder&) {}
|
||||||
|
|
||||||
virtual std::shared_ptr<Communication> makeCommunication(
|
virtual std::shared_ptr<Communication> makeCommunication(
|
||||||
std::unique_ptr<ICommunication> t,
|
std::unique_ptr<ICommunication> t,
|
||||||
std::shared_ptr<Packetizer> p,
|
std::shared_ptr<Packetizer> p,
|
||||||
std::unique_ptr<Encoder> e,
|
std::unique_ptr<Encoder> e,
|
||||||
std::unique_ptr<Decoder> d) { return std::make_shared<Communication>(report, std::move(t), p, std::move(e), std::move(d)); }
|
std::unique_ptr<Decoder> d) { return std::make_shared<Communication>(err, std::move(t), p, std::move(e), std::move(d)); }
|
||||||
virtual void setupCommunication(Communication&) {}
|
virtual void setupCommunication(Communication&) {}
|
||||||
|
|
||||||
template<typename Settings>
|
template<typename Settings>
|
||||||
@@ -160,20 +144,6 @@ protected:
|
|||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>&) {}
|
virtual void setupSupportedRXNetworks(std::vector<Network>&) {}
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>&) {}
|
virtual void setupSupportedTXNetworks(std::vector<Network>&) {}
|
||||||
|
|
||||||
virtual void setupExtensions() {}
|
|
||||||
void addExtension(std::shared_ptr<DeviceExtension>&& extension);
|
|
||||||
|
|
||||||
template<typename Extension>
|
|
||||||
std::shared_ptr<Extension> getExtension() const {
|
|
||||||
std::shared_ptr<Extension> ret;
|
|
||||||
std::lock_guard<std::mutex> lk(extensionsLock);
|
|
||||||
for(auto& ext : extensions) {
|
|
||||||
if((ret = std::dynamic_pointer_cast<Extension>(ext)))
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
// END Initialization Functions
|
// END Initialization Functions
|
||||||
|
|
||||||
void handleInternalMessage(std::shared_ptr<Message> message);
|
void handleInternalMessage(std::shared_ptr<Message> message);
|
||||||
@@ -184,10 +154,6 @@ private:
|
|||||||
neodevice_t data;
|
neodevice_t data;
|
||||||
std::shared_ptr<ResetStatusMessage> latestResetStatus;
|
std::shared_ptr<ResetStatusMessage> latestResetStatus;
|
||||||
|
|
||||||
mutable std::mutex extensionsLock;
|
|
||||||
std::vector<std::shared_ptr<DeviceExtension>> extensions;
|
|
||||||
void forEachExtension(std::function<void(const std::shared_ptr<DeviceExtension>&)> fn);
|
|
||||||
|
|
||||||
std::vector<Network> supportedTXNetworks;
|
std::vector<Network> supportedTXNetworks;
|
||||||
std::vector<Network> supportedRXNetworks;
|
std::vector<Network> supportedRXNetworks;
|
||||||
|
|
||||||
|
|||||||
@@ -1,26 +0,0 @@
|
|||||||
#ifndef __DEVICEEXTENSION_H_
|
|
||||||
#define __DEVICEEXTENSION_H_
|
|
||||||
|
|
||||||
#include <memory>
|
|
||||||
#include "icsneo/communication/message/message.h"
|
|
||||||
#include "icsneo/api/eventmanager.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class Device;
|
|
||||||
|
|
||||||
class DeviceExtension {
|
|
||||||
public:
|
|
||||||
DeviceExtension(Device& device) : device(device) {}
|
|
||||||
virtual ~DeviceExtension() = default;
|
|
||||||
virtual const char* getName() const = 0;
|
|
||||||
virtual void handleMessage(const std::shared_ptr<Message>&) {}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
Device& device;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __DEVICEEXTENSION_H_
|
|
||||||
@@ -1,74 +0,0 @@
|
|||||||
#ifndef __FLEXRAYCONTROLLER_H_
|
|
||||||
#define __FLEXRAYCONTROLLER_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
#include <memory>
|
|
||||||
#include <chrono>
|
|
||||||
#include <mutex>
|
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/erayregister.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/poccommand.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class Device;
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
class Controller {
|
|
||||||
public:
|
|
||||||
Controller(Device& device, uint8_t index) : device(device), index(index) {}
|
|
||||||
std::shared_ptr<FlexRayControlMessage> getStatus() const;
|
|
||||||
void _setStatus(std::shared_ptr<FlexRayControlMessage> msg);
|
|
||||||
|
|
||||||
bool getAllowColdstart() const { return allowColdstart; }
|
|
||||||
void setAllowColdstart(bool enable) { allowColdstart = enable; }
|
|
||||||
|
|
||||||
bool getWakeupBeforeStart() const { return wakeupBeforeStart; }
|
|
||||||
void setWakeupBeforeStart(bool enable) { wakeupBeforeStart = enable; }
|
|
||||||
|
|
||||||
void getReady();
|
|
||||||
void start();
|
|
||||||
|
|
||||||
private:
|
|
||||||
bool isPOCBusy() const { return readRegisterOr(ERAYRegister::SUCC1, 0x00000080) & 0x00000080; }
|
|
||||||
std::pair<bool, FlexRay::POCCommand> getCurrentPOCCommand(std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
|
|
||||||
bool setCurrentPOCCommand(
|
|
||||||
FlexRay::POCCommand cmd,
|
|
||||||
bool checkForSuccess = true,
|
|
||||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
|
||||||
bool wasCommandSuccessful(std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
|
|
||||||
|
|
||||||
std::pair<bool, uint32_t> readRegister(
|
|
||||||
ERAYRegister reg,
|
|
||||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
|
|
||||||
uint32_t readRegisterOr(
|
|
||||||
ERAYRegister reg,
|
|
||||||
uint32_t defaultValue = 0,
|
|
||||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(50)) const;
|
|
||||||
bool writeRegister(
|
|
||||||
ERAYRegister reg,
|
|
||||||
uint32_t value,
|
|
||||||
uint32_t mask,
|
|
||||||
bool waitForPOCReady = true,
|
|
||||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
|
||||||
bool writeRegister(
|
|
||||||
ERAYRegister reg,
|
|
||||||
uint32_t value,
|
|
||||||
bool waitForPOCReady = true,
|
|
||||||
std::chrono::milliseconds timeout = std::chrono::milliseconds(50));
|
|
||||||
|
|
||||||
Device& device;
|
|
||||||
uint8_t index;
|
|
||||||
mutable std::mutex statusLock;
|
|
||||||
mutable std::mutex readRegisterLock;
|
|
||||||
std::shared_ptr<FlexRayControlMessage> status;
|
|
||||||
bool allowColdstart = false;
|
|
||||||
bool wakeupBeforeStart = false;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __FLEXRAYCONTROLLER_H_
|
|
||||||
@@ -1,20 +0,0 @@
|
|||||||
#ifndef __FLEXRAYCRCSTATUS_H_
|
|
||||||
#define __FLEXRAYCRCSTATUS_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
enum class CRCStatus {
|
|
||||||
OK = 0,
|
|
||||||
Error,
|
|
||||||
NoCRC
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __FLEXRAYCRCSTATUS_H_
|
|
||||||
@@ -1,116 +0,0 @@
|
|||||||
#ifndef __ERAYREGISTER_H_
|
|
||||||
#define __ERAYREGISTER_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
enum class ERAYRegister : uint32_t {
|
|
||||||
// Customer Registers : Not Part of ERAY, part of FUJITSU FlexRay ASSP MB88121C
|
|
||||||
VER = 0x0000,// Version Information Register reset = 0440_79FF Access = r
|
|
||||||
CCNT = 0x0004,// Clock Control Register reset = 0000_0000 Access = r/w
|
|
||||||
DBGS_DMAS = 0x0008,// Debug Support Register / DMA Support Register reset = 0000_0000 Acess = r/w
|
|
||||||
INT_REG = 0x000C,// Interrupt Register Register reset = 0000_0000 Acess = r/w
|
|
||||||
LCK = 0x001C,// Lock Register reset = 0000_0000 Acess = r/w
|
|
||||||
|
|
||||||
// Interrupt-Related Registers
|
|
||||||
EIR = 0x0020,// Error Interrupt Register reset=0000_0000 Access = r/w
|
|
||||||
SIR = 0x0024,// Status Interrupt Register 0000_0000 r/w
|
|
||||||
EILS = 0x0028,// Error Interrupt Line Select Register 0000_0000 r/w
|
|
||||||
SILS = 0x002C,// Status Interrupt Line Select Register 0303_FFFF r/w
|
|
||||||
EIES = 0x0030,// Error Interrupt Enable Register (set) 0000_0000 r/w
|
|
||||||
EIER = 0x0034,// Error Interrupt Enable Register (reset) 0000_0000 r/w
|
|
||||||
SIES = 0x0038,// Status Interrupt Enable Register (set) 0000_0000 r/w
|
|
||||||
SIER = 0x003C,// Status Interrupt Enable Register (reset) 0000_0000 r/w
|
|
||||||
ILE = 0x0040,// Interrupt Line Enable Register 0000_0000 r/w
|
|
||||||
T0C = 0x0044,// Timer 0 Configuration Register 0 0000_0000 r/w
|
|
||||||
T1C = 0x0048,// Timer 0 Configuration Register 1 0002_0000 r/w
|
|
||||||
STPW1 = 0x004C,// Stop Watch Register 1 0000_0000 r/w
|
|
||||||
STPW2 = 0x0050,// Stop Watch Register 2 0000_0000 r
|
|
||||||
//0x0054�0x007C- reserved(11) 0000_0000 r
|
|
||||||
|
|
||||||
// System Universal Control (SUC)
|
|
||||||
// The system universal control controls the following functions.
|
|
||||||
//� Configuration
|
|
||||||
//� Wakeup
|
|
||||||
//� Startup
|
|
||||||
//� Normal operation
|
|
||||||
//� Passive operation
|
|
||||||
//� Monitor mode
|
|
||||||
SUCC1 = 0x0080,// SUC Configuration Register 1 0C40_1000 r/w
|
|
||||||
SUCC2 = 0x0084,// SUC Configuration Register 2 0100_0504 r/w
|
|
||||||
SUCC3 = 0x0088,// SUC Configuration Register 3 0000_0011 r/w
|
|
||||||
|
|
||||||
// Network Management (NEM)
|
|
||||||
// Sets the handling of the network management vector
|
|
||||||
NEMC = 0x008C,// NEM Configuration Register 0000_0000 r/w
|
|
||||||
|
|
||||||
PRTC1 = 0x0090,// PRT Configuration Register 1 084C_0633 r/w
|
|
||||||
PRTC2 = 0x0094,// PRT Configuration Register 2 0F2D_0A0E r/w
|
|
||||||
MHDC = 0x0098,// MHD Configuration Register 0000_0000 r/w
|
|
||||||
GTUC1 = 0x00A0,// GTU Configuration Register 1 0000_0280 r/w
|
|
||||||
GTUC2 = 0x00A4,// GTU Configuration Register 2 0002_000A r/w
|
|
||||||
GTUC3 = 0x00A8,// GTU Configuration Register 3 0202_0000 r/w
|
|
||||||
GTUC4 = 0x00AC,// GTU Configuration Register 4 0008_0007 r/w
|
|
||||||
GTUC5 = 0x00B0,// GTU Configuration Register 5 0E00_0000 r/w
|
|
||||||
GTUC6 = 0x00B4,// GTU Configuration Register 6 0002_0000 r/w
|
|
||||||
GTUC7 = 0x00B8,// GTU Configuration Register 7 0002_0004 r/w
|
|
||||||
GTUC8 = 0x00BC,// GTU Configuration Register 8 0000_0002 r/w
|
|
||||||
GTUC9 = 0x00C0,// GTU Configuration Register 9 0000_0101 r/w
|
|
||||||
GTUC10 = 0x00C4,// GTU Configuration Register 10 0002_0005 r/w
|
|
||||||
GTUC11 = 0x00C8,// GTU Configuration Register 11 0000_0000 r/w
|
|
||||||
|
|
||||||
CCSV = 0x0100,// CC Status Vector Register 0010_4000 r
|
|
||||||
|
|
||||||
CCEV = 0x0104,// CC Error Vector Register 0000_0000 r
|
|
||||||
// 0x0108 =-0x010C, reserved(2) 0000_0000 r
|
|
||||||
SCV = 0x0110,//Slot Counter Value Register 0000_0000 r
|
|
||||||
MTCCV = 0x0114,//Macrotick and Cycle Counter Value Register 0000_0000 r
|
|
||||||
RCV = 0x0118,//Rate Correction Value Register 0000_0000 r
|
|
||||||
OCV = 0x011C,//Offset Correction Value Register 0000_0000 r
|
|
||||||
SFS = 0x0120,//Sync Frame Status Register 0000_0000 r
|
|
||||||
SWNIT = 0x0124,//Symbol Window and NIT Status Register 0000_0000 r
|
|
||||||
ACS = 0x0128,//Aggregated Channel Status Register 0000_0000 r/w -
|
|
||||||
|
|
||||||
ESID_START = 0x0130,
|
|
||||||
ESID_END = 0x0168,
|
|
||||||
|
|
||||||
OSID_START = 0x0170,
|
|
||||||
OSID_END = 0x01A8,
|
|
||||||
|
|
||||||
NMV1 = 0x01B0,
|
|
||||||
NMV2 = 0x01B4,
|
|
||||||
NMV3 = 0x01B8,
|
|
||||||
|
|
||||||
// Message Buffer Control Registers
|
|
||||||
MRC = 0x0300,// Message RAM Configuration Register 0180_0000 r/w
|
|
||||||
FRF = 0x0304,// FIFO Rejection Filter Register 0180_0000 r/w
|
|
||||||
FRFM = 0x0308,// FIFO Rejection Filter Mask Register 0000_0000 r/w
|
|
||||||
FCL = 0x030C,// FIFO Critical Level Register 0000_0080 r/w
|
|
||||||
|
|
||||||
// Message Buffer Status Registers
|
|
||||||
MHDS = 0x0310,// Message Handler Status Register 0000_0000 r/w
|
|
||||||
LDTS = 0x0314,// Last Dynamic Transmit Slot Register 0000_0000 r
|
|
||||||
FSR = 0x0318,// FIFO Status Register 0000_0000 r
|
|
||||||
MHDF = 0x031C,// Message Handler Constraints Flags Register 0000_0000 r/w
|
|
||||||
TXRQ1 = 0x0320,// Transmission Request Register 1 0000_0000 r
|
|
||||||
TXRQ2 = 0x0324,// Transmission Request Register 2 0000_0000 r
|
|
||||||
TXRQ3 = 0x0328,// Transmission Request Register 3 0000_0000 r
|
|
||||||
TXRQ4 = 0x032C,// Transmission Request Register 4 0000_0000 r
|
|
||||||
NDAT1 = 0x0330,// New Data Register 1 0000_0000 r
|
|
||||||
NDAT2 = 0x0334,// New Data Register 2 0000_0000 r
|
|
||||||
|
|
||||||
WRHS1 = 0x0500,// Write Header Section Register 1
|
|
||||||
WRHS2 = 0x0504,// Write Header Section Register 2
|
|
||||||
WRHS3 = 0x0508,// Write Header Section Register 3
|
|
||||||
|
|
||||||
IBCM = 0x0510,// Input Buffer Command Mask Register
|
|
||||||
IBCR = 0x0514,// Input Buffer Command Request Register
|
|
||||||
|
|
||||||
OBCM = 0x710,
|
|
||||||
OBCR = 0x714,
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __ERAYREGISTER_H_
|
|
||||||
@@ -1,38 +0,0 @@
|
|||||||
#ifndef __FLEXRAYEXTENSION_H_
|
|
||||||
#define __FLEXRAYEXTENSION_H_
|
|
||||||
|
|
||||||
#include <mutex>
|
|
||||||
#include <memory>
|
|
||||||
#include <utility>
|
|
||||||
#include "icsneo/device/extensions/flexray/erayregister.h"
|
|
||||||
#include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h"
|
|
||||||
#include "icsneo/device/extensions/deviceextension.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
class Controller;
|
|
||||||
|
|
||||||
class Extension : public DeviceExtension {
|
|
||||||
public:
|
|
||||||
Extension(Device& device, uint8_t controllerCount);
|
|
||||||
const char* getName() const override { return "FlexRay"; }
|
|
||||||
void handleMessage(const std::shared_ptr<Message>& message) override;
|
|
||||||
|
|
||||||
std::shared_ptr<Controller> getController(uint8_t index) const {
|
|
||||||
if(index >= controllers.size())
|
|
||||||
return nullptr;
|
|
||||||
return controllers[index];
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
std::vector<std::shared_ptr<Controller>> controllers;
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
|
|
||||||
#endif // __FLEXRAYEXTENSION_H_
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
#ifndef __FLEXRAYOPCODE_H_
|
|
||||||
#define __FLEXRAYOPCODE_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
// Second byte, opcode
|
|
||||||
enum class Opcode : uint8_t {
|
|
||||||
SetNetID = 0x00,
|
|
||||||
ReadCCRegs = 0x01,
|
|
||||||
WriteCCReg = 0x02,
|
|
||||||
WriteMessageBuffer = 0x03,
|
|
||||||
ReadCCStatus = 0x04,
|
|
||||||
AddConfiguredMessage = 0x05,
|
|
||||||
InitForRun = 0x06,
|
|
||||||
Unknown = 0xff
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __FLEXRAYOPCODE_H_
|
|
||||||
@@ -1,31 +0,0 @@
|
|||||||
#ifndef __FLEXRAYPOCCOMMAND_H_
|
|
||||||
#define __FLEXRAYPOCCOMMAND_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
enum class POCCommand : uint8_t {
|
|
||||||
CommandNotAccepted = 0x00,
|
|
||||||
Config = 0x01,
|
|
||||||
Ready = 0x02,
|
|
||||||
Wakeup = 0x03,
|
|
||||||
Run = 0x04,
|
|
||||||
AllSlots = 0x05,
|
|
||||||
Halt = 0x06,
|
|
||||||
Freeze = 0x07,
|
|
||||||
SendMTS = 0x08,
|
|
||||||
AllowColdstart = 0x09,
|
|
||||||
ResetStatusIndicators = 0x0a,
|
|
||||||
MonitorMode = 0x0b,
|
|
||||||
ClearRAMs = 0x0c,
|
|
||||||
Unknown = 0xff
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __FLEXRAYPOCCOMMAND_H_
|
|
||||||
@@ -1,40 +0,0 @@
|
|||||||
#ifndef __FLEXRAYPOCSTATUS_H_
|
|
||||||
#define __FLEXRAYPOCSTATUS_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
enum class POCStatus : uint8_t {
|
|
||||||
DefaultConfig = 0x00,
|
|
||||||
Ready = 0x01,
|
|
||||||
NormalActive = 0x02,
|
|
||||||
NormalPassive = 0x03,
|
|
||||||
Halt = 0x04,
|
|
||||||
MonitorMode = 0x05,
|
|
||||||
WakeupStandby = 0x10,
|
|
||||||
WakeupListen = 0x11,
|
|
||||||
WakeupSend = 0x12,
|
|
||||||
WakeupDetect = 0x13,
|
|
||||||
StartupPrepare = 0x20,
|
|
||||||
ColdstartListen = 0x21,
|
|
||||||
ColdstartCollisionResolution = 0x22,
|
|
||||||
ColdstartConsistencyCheck = 0x23,
|
|
||||||
ColdstartGap = 0x24,
|
|
||||||
ColdstartJoin = 0x25,
|
|
||||||
IntegrationColdstartCheck = 0x26,
|
|
||||||
IntegrationListen = 0x27,
|
|
||||||
IntegrationConsistencyCheck = 0x28,
|
|
||||||
InitializeSchedule = 0x29,
|
|
||||||
AbortStartup = 0x2a,
|
|
||||||
StartupSuccess = 0x2b,
|
|
||||||
Unknown = 0xff
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __FLEXRAYPOCSTATUS_H_
|
|
||||||
@@ -1,21 +0,0 @@
|
|||||||
#ifndef __FLEXRAYSYMBOL_H_
|
|
||||||
#define __FLEXRAYSYMBOL_H_
|
|
||||||
|
|
||||||
#include <cstdint>
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
namespace FlexRay {
|
|
||||||
|
|
||||||
enum class Symbol {
|
|
||||||
None = 0,
|
|
||||||
Unknown,
|
|
||||||
Wakeup,
|
|
||||||
CAS
|
|
||||||
};
|
|
||||||
|
|
||||||
} // namespace FlexRay
|
|
||||||
|
|
||||||
} // namespace icsneo
|
|
||||||
|
|
||||||
#endif // __FLEXRAYSYMBOL_H_
|
|
||||||
@@ -334,7 +334,7 @@ public:
|
|||||||
static CANBaudrate GetEnumValueForBaudrate(int64_t baudrate);
|
static CANBaudrate GetEnumValueForBaudrate(int64_t baudrate);
|
||||||
static int64_t GetBaudrateValueForEnum(CANBaudrate enumValue);
|
static int64_t GetBaudrateValueForEnum(CANBaudrate enumValue);
|
||||||
|
|
||||||
IDeviceSettings(std::shared_ptr<Communication> com, size_t size) : com(com), report(com->report), structSize(size) {}
|
IDeviceSettings(std::shared_ptr<Communication> com, size_t size) : com(com), err(com->err), structSize(size) {}
|
||||||
virtual ~IDeviceSettings() {}
|
virtual ~IDeviceSettings() {}
|
||||||
bool ok() { return !disabled && settingsLoaded; }
|
bool ok() { return !disabled && settingsLoaded; }
|
||||||
|
|
||||||
@@ -399,17 +399,13 @@ public:
|
|||||||
|
|
||||||
const size_t& getSize() const { return structSize; }
|
const size_t& getSize() const { return structSize; }
|
||||||
|
|
||||||
// if settings are disabled for this device. always false unless constructed null
|
|
||||||
bool disabled = false;
|
bool disabled = false;
|
||||||
|
|
||||||
bool readonly = false;
|
bool readonly = false;
|
||||||
bool disableGSChecksumming = false;
|
bool disableGSChecksumming = false;
|
||||||
protected:
|
protected:
|
||||||
std::shared_ptr<Communication> com;
|
std::shared_ptr<Communication> com;
|
||||||
device_eventhandler_t report;
|
device_errorhandler_t err;
|
||||||
size_t structSize;
|
size_t structSize;
|
||||||
|
|
||||||
// if we hold any local copies of the device settings
|
|
||||||
bool settingsLoaded = false;
|
bool settingsLoaded = false;
|
||||||
|
|
||||||
std::vector<uint8_t> settings; // For writing settings to, calling apply() should copy over to device RAM (and EEPROM)
|
std::vector<uint8_t> settings; // For writing settings to, calling apply() should copy over to device RAM (and EEPROM)
|
||||||
@@ -418,7 +414,7 @@ protected:
|
|||||||
// Parameter createInoperableSettings exists because it is serving as a warning that you probably don't want to do this
|
// Parameter createInoperableSettings exists because it is serving as a warning that you probably don't want to do this
|
||||||
typedef void* warn_t;
|
typedef void* warn_t;
|
||||||
IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr<Communication> com)
|
IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr<Communication> com)
|
||||||
: disabled(true), readonly(true), report(com->report), structSize(0) { (void)createInoperableSettings; }
|
: disabled(true), readonly(true), err(com->err), structSize(0) { (void)createInoperableSettings; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -36,13 +36,13 @@ private:
|
|||||||
productId = PRODUCT_ID;
|
productId = PRODUCT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
+2
-2
@@ -36,13 +36,13 @@ private:
|
|||||||
productId = PRODUCT_ID;
|
productId = PRODUCT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
+3
-3
@@ -4,7 +4,7 @@
|
|||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/device/tree/neovifire/neovifiresettings.h"
|
#include "icsneo/device/neovifire/neovifiresettings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
@@ -77,13 +77,13 @@ private:
|
|||||||
productId = PRODUCT_ID;
|
productId = PRODUCT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
+4
-4
@@ -1,9 +1,9 @@
|
|||||||
#ifndef __NEOVIFIRE2ETH_H_
|
#ifndef __NEOVIFIRE2ETH_H_
|
||||||
#define __NEOVIFIRE2ETH_H_
|
#define __NEOVIFIRE2ETH_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/neovifire2/neovifire2.h"
|
#include "icsneo/device/neovifire2/neovifire2.h"
|
||||||
#include "icsneo/platform/pcap.h"
|
#include "icsneo/platform/pcap.h"
|
||||||
#include "icsneo/device/tree/neovifire2/neovifire2settings.h"
|
#include "icsneo/device/neovifire2/neovifire2settings.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -49,9 +49,9 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setupSettings(IDeviceSettings* ssettings) {
|
void setupSettings(IDeviceSettings& ssettings) override {
|
||||||
// TODO Check firmware version, old firmwares will reset Ethernet settings on settings send
|
// TODO Check firmware version, old firmwares will reset Ethernet settings on settings send
|
||||||
ssettings->readonly = true;
|
ssettings.readonly = true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
+2
-2
@@ -1,9 +1,9 @@
|
|||||||
#ifndef __NEOVIFIRE2USB_H_
|
#ifndef __NEOVIFIRE2USB_H_
|
||||||
#define __NEOVIFIRE2USB_H_
|
#define __NEOVIFIRE2USB_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/neovifire2/neovifire2.h"
|
#include "icsneo/device/neovifire2/neovifire2.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/device/tree/neovifire2/neovifire2settings.h"
|
#include "icsneo/device/neovifire2/neovifire2settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __NEOVIION_H_
|
#ifndef __NEOVIION_H_
|
||||||
#define __NEOVIION_H_
|
#define __NEOVIION_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/plasion/plasion.h"
|
#include "icsneo/device/plasion/plasion.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __NEOVIPLASMA_H_
|
#ifndef __NEOVIPLASMA_H_
|
||||||
#define __NEOVIPLASMA_H_
|
#define __NEOVIPLASMA_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/plasion/plasion.h"
|
#include "icsneo/device/plasion/plasion.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
|
|
||||||
@@ -0,0 +1,29 @@
|
|||||||
|
#ifndef __PLASION_H_
|
||||||
|
#define __PLASION_H_
|
||||||
|
|
||||||
|
#include "icsneo/device/device.h"
|
||||||
|
#include "icsneo/communication/multichannelcommunication.h"
|
||||||
|
#include "icsneo/platform/ftdi.h"
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
class Plasion : public Device {
|
||||||
|
protected:
|
||||||
|
virtual std::shared_ptr<Communication> makeCommunication(
|
||||||
|
std::unique_ptr<ICommunication> transport,
|
||||||
|
std::shared_ptr<Packetizer> packetizer,
|
||||||
|
std::unique_ptr<Encoder> encoder,
|
||||||
|
std::unique_ptr<Decoder> decoder
|
||||||
|
) override { return std::make_shared<MultiChannelCommunication>(err, std::move(transport), packetizer, std::move(encoder), std::move(decoder)); }
|
||||||
|
|
||||||
|
// TODO: This is done so that Plasion can still transmit it's basic networks, awaiting VLAN support
|
||||||
|
virtual bool isSupportedRXNetwork(const Network&) const override { return true; }
|
||||||
|
virtual bool isSupportedTXNetwork(const Network&) const override { return true; }
|
||||||
|
|
||||||
|
public:
|
||||||
|
Plasion(neodevice_t neodevice) : Device(neodevice) {}
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+2
-2
@@ -102,13 +102,13 @@ protected:
|
|||||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,101 @@
|
|||||||
|
#ifndef __RADPLUTO_H_
|
||||||
|
#define __RADPLUTO_H_
|
||||||
|
|
||||||
|
#include "icsneo/device/device.h"
|
||||||
|
#include "icsneo/device/devicetype.h"
|
||||||
|
#include "icsneo/platform/pcap.h"
|
||||||
|
#include "icsneo/communication/packetizer.h"
|
||||||
|
#include "icsneo/communication/decoder.h"
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
class RADPluto : public Device {
|
||||||
|
public:
|
||||||
|
// Serial numbers start with PL
|
||||||
|
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADPluto;
|
||||||
|
static constexpr const uint16_t PRODUCT_ID = 0xffff; // Not yet set
|
||||||
|
static constexpr const char* SERIAL_START = "PL";
|
||||||
|
static std::vector<std::shared_ptr<Device>> Find() {
|
||||||
|
std::vector<std::shared_ptr<Device>> found;
|
||||||
|
|
||||||
|
for(auto& foundDev : PCAP::FindAll()) {
|
||||||
|
auto fakedev = std::shared_ptr<RADPluto>(new RADPluto({}));
|
||||||
|
for(auto& payload : foundDev.discoveryPackets)
|
||||||
|
fakedev->com->packetizer->input(payload);
|
||||||
|
for(auto& packet : fakedev->com->packetizer->output()) {
|
||||||
|
std::shared_ptr<Message> msg;
|
||||||
|
if(!fakedev->com->decoder->decode(msg, packet))
|
||||||
|
continue; // We failed to decode this packet
|
||||||
|
|
||||||
|
if(!msg || msg->network.getNetID() != Network::NetID::Main51)
|
||||||
|
continue; // Not a message we care about
|
||||||
|
auto sn = std::dynamic_pointer_cast<SerialNumberMessage>(msg);
|
||||||
|
if(!sn)
|
||||||
|
continue; // Not a serial number message
|
||||||
|
|
||||||
|
if(sn->deviceSerial.length() < 2)
|
||||||
|
continue;
|
||||||
|
if(sn->deviceSerial.substr(0, 2) != SERIAL_START)
|
||||||
|
continue; // Not a RADPluto
|
||||||
|
|
||||||
|
foundDev.device.serial[sn->deviceSerial.copy(foundDev.device.serial, sizeof(foundDev.device.serial))] = '\0';
|
||||||
|
found.emplace_back(new RADPluto(foundDev.device));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return found;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
|
static std::vector<Network> supportedNetworks = {
|
||||||
|
Network::NetID::HSCAN,
|
||||||
|
Network::NetID::HSCAN2,
|
||||||
|
|
||||||
|
Network::NetID::LIN,
|
||||||
|
|
||||||
|
Network::NetID::Ethernet,
|
||||||
|
|
||||||
|
Network::NetID::OP_Ethernet1,
|
||||||
|
Network::NetID::OP_Ethernet2,
|
||||||
|
Network::NetID::OP_Ethernet3,
|
||||||
|
Network::NetID::OP_Ethernet4
|
||||||
|
};
|
||||||
|
return supportedNetworks;
|
||||||
|
}
|
||||||
|
|
||||||
|
RADPluto(neodevice_t neodevice) : Device(neodevice) {
|
||||||
|
initialize<PCAP>();
|
||||||
|
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||||
|
productId = PRODUCT_ID;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected:
|
||||||
|
void setupPacketizer(Packetizer& packetizer) override {
|
||||||
|
Device::setupPacketizer(packetizer);
|
||||||
|
packetizer.disableChecksum = true;
|
||||||
|
packetizer.align16bit = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setupEncoder(Encoder& encoder) override {
|
||||||
|
Device::setupEncoder(encoder);
|
||||||
|
encoder.supportCANFD = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void setupDecoder(Decoder& decoder) override {
|
||||||
|
Device::setupDecoder(decoder);
|
||||||
|
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||||
|
}
|
||||||
|
|
||||||
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
|
for(auto& netid : GetSupportedNetworks())
|
||||||
|
rxNetworks.emplace_back(netid);
|
||||||
|
}
|
||||||
|
|
||||||
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
};
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
+3
-3
@@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/device/tree/radstar2/radstar2settings.h"
|
#include "icsneo/device/radstar2/radstar2settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
@@ -44,13 +44,13 @@ protected:
|
|||||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
RADStar2(neodevice_t neodevice) : Device(neodevice) {
|
RADStar2(neodevice_t neodevice) : Device(neodevice) {
|
||||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __RADSTAR2ETH_H_
|
#ifndef __RADSTAR2ETH_H_
|
||||||
#define __RADSTAR2ETH_H_
|
#define __RADSTAR2ETH_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/radstar2/radstar2.h"
|
#include "icsneo/device/radstar2/radstar2.h"
|
||||||
#include "icsneo/communication/network.h"
|
#include "icsneo/communication/network.h"
|
||||||
#include "icsneo/communication/message/serialnumbermessage.h"
|
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||||
#include "icsneo/platform/pcap.h"
|
#include "icsneo/platform/pcap.h"
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __RADSTAR2USB_H_
|
#ifndef __RADSTAR2USB_H_
|
||||||
#define __RADSTAR2USB_H_
|
#define __RADSTAR2USB_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/radstar2/radstar2.h"
|
#include "icsneo/device/radstar2/radstar2.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -1,91 +0,0 @@
|
|||||||
#ifndef __PLASION_H_
|
|
||||||
#define __PLASION_H_
|
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
|
||||||
#include "icsneo/communication/multichannelcommunication.h"
|
|
||||||
#include "icsneo/platform/ftdi.h"
|
|
||||||
#include "icsneo/device/extensions/flexray/extension.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class Plasion : public Device {
|
|
||||||
protected:
|
|
||||||
virtual std::shared_ptr<Communication> makeCommunication(
|
|
||||||
std::unique_ptr<ICommunication> transport,
|
|
||||||
std::shared_ptr<Packetizer> packetizer,
|
|
||||||
std::unique_ptr<Encoder> encoder,
|
|
||||||
std::unique_ptr<Decoder> decoder
|
|
||||||
) override { return std::make_shared<MultiChannelCommunication>(report, std::move(transport), packetizer, std::move(encoder), std::move(decoder)); }
|
|
||||||
|
|
||||||
// TODO: This is done so that Plasion can still transmit it's basic networks, awaiting VLAN support
|
|
||||||
virtual bool isSupportedRXNetwork(const Network&) const override { return true; }
|
|
||||||
virtual bool isSupportedTXNetwork(const Network&) const override { return true; }
|
|
||||||
virtual void setupExtensions() override {
|
|
||||||
addExtension(std::make_shared<FlexRay::Extension>(*this, (uint8_t)2));
|
|
||||||
}
|
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
|
||||||
static std::vector<Network> supportedNetworks = {
|
|
||||||
Network::NetID::HSCAN,
|
|
||||||
Network::NetID::MSCAN,
|
|
||||||
Network::NetID::HSCAN2,
|
|
||||||
Network::NetID::HSCAN3,
|
|
||||||
Network::NetID::HSCAN4,
|
|
||||||
Network::NetID::HSCAN5,
|
|
||||||
Network::NetID::HSCAN6,
|
|
||||||
Network::NetID::HSCAN7,
|
|
||||||
|
|
||||||
Network::NetID::LSFTCAN,
|
|
||||||
Network::NetID::LSFTCAN2,
|
|
||||||
|
|
||||||
Network::NetID::SWCAN,
|
|
||||||
Network::NetID::SWCAN2,
|
|
||||||
|
|
||||||
Network::NetID::Ethernet,
|
|
||||||
|
|
||||||
Network::NetID::LIN,
|
|
||||||
Network::NetID::LIN2,
|
|
||||||
Network::NetID::LIN3,
|
|
||||||
Network::NetID::LIN4,
|
|
||||||
|
|
||||||
Network::NetID::FlexRay,
|
|
||||||
Network::NetID::FlexRay2
|
|
||||||
};
|
|
||||||
return supportedNetworks;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
|
||||||
for(auto& netid : GetSupportedNetworks())
|
|
||||||
rxNetworks.emplace_back(netid);
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual std::shared_ptr<FlexRay::Controller> getFlexRayControllerByNetwork(const Network& net) const override {
|
|
||||||
uint8_t idx = 0xff;
|
|
||||||
switch(net.getNetID()) {
|
|
||||||
case Network::NetID::FlexRay:
|
|
||||||
idx = 0;
|
|
||||||
break;
|
|
||||||
case Network::NetID::FlexRay2:
|
|
||||||
idx = 1;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
return Device::getFlexRayControllerByNetwork(net);
|
|
||||||
}
|
|
||||||
|
|
||||||
auto extension = getExtension<FlexRay::Extension>();
|
|
||||||
if(!extension)
|
|
||||||
return Device::getFlexRayControllerByNetwork(net);
|
|
||||||
|
|
||||||
auto res = extension->getController(idx);
|
|
||||||
if(!res)
|
|
||||||
return Device::getFlexRayControllerByNetwork(net);
|
|
||||||
return res;
|
|
||||||
}
|
|
||||||
|
|
||||||
public:
|
|
||||||
Plasion(neodevice_t neodevice) : Device(neodevice) {}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,58 +0,0 @@
|
|||||||
#ifndef __RADPLUTO_H_
|
|
||||||
#define __RADPLUTO_H_
|
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
|
||||||
#include "icsneo/device/devicetype.h"
|
|
||||||
#include "icsneo/platform/pcap.h"
|
|
||||||
#include "icsneo/communication/packetizer.h"
|
|
||||||
#include "icsneo/communication/decoder.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class RADPluto : public Device {
|
|
||||||
public:
|
|
||||||
// Serial numbers start with PL
|
|
||||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADPluto;
|
|
||||||
static constexpr const uint16_t PRODUCT_ID = 0x1104;
|
|
||||||
static constexpr const char* SERIAL_START = "PL";
|
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
|
||||||
static std::vector<Network> supportedNetworks = {
|
|
||||||
Network::NetID::HSCAN,
|
|
||||||
Network::NetID::HSCAN2,
|
|
||||||
|
|
||||||
Network::NetID::LIN,
|
|
||||||
|
|
||||||
Network::NetID::Ethernet,
|
|
||||||
|
|
||||||
Network::NetID::OP_Ethernet1,
|
|
||||||
Network::NetID::OP_Ethernet2,
|
|
||||||
Network::NetID::OP_Ethernet3,
|
|
||||||
Network::NetID::OP_Ethernet4
|
|
||||||
};
|
|
||||||
return supportedNetworks;
|
|
||||||
}
|
|
||||||
|
|
||||||
RADPluto(neodevice_t neodevice) : Device(neodevice) {
|
|
||||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
|
||||||
productId = PRODUCT_ID;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected:
|
|
||||||
virtual void setupEncoder(Encoder& encoder) override {
|
|
||||||
Device::setupEncoder(encoder);
|
|
||||||
encoder.supportCANFD = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
|
||||||
for(auto& netid : GetSupportedNetworks())
|
|
||||||
rxNetworks.emplace_back(netid);
|
|
||||||
}
|
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
#ifndef __RADPLUTOUSB_H_
|
|
||||||
#define __RADPLUTOUSB_H_
|
|
||||||
|
|
||||||
#include "icsneo/device/tree/radpluto/radpluto.h"
|
|
||||||
#include "icsneo/platform/stm32.h"
|
|
||||||
|
|
||||||
namespace icsneo {
|
|
||||||
|
|
||||||
class RADPlutoUSB : public RADPluto {
|
|
||||||
public:
|
|
||||||
// Serial numbers start with RP
|
|
||||||
static std::vector<std::shared_ptr<Device>> Find() {
|
|
||||||
std::vector<std::shared_ptr<Device>> found;
|
|
||||||
|
|
||||||
for(auto neodevice : STM32::FindByProduct(PRODUCT_ID))
|
|
||||||
found.emplace_back(new RADPlutoUSB(neodevice));
|
|
||||||
|
|
||||||
return found;
|
|
||||||
}
|
|
||||||
|
|
||||||
private:
|
|
||||||
RADPlutoUSB(neodevice_t neodevice) : RADPluto(neodevice) {
|
|
||||||
initialize<STM32>();
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif
|
|
||||||
+3
-3
@@ -4,7 +4,7 @@
|
|||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/device/tree/valuecan3/valuecan3settings.h"
|
#include "icsneo/device/valuecan3/valuecan3settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
@@ -36,13 +36,13 @@ private:
|
|||||||
productId = PRODUCT_ID;
|
productId = PRODUCT_ID;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#define __VALUECAN4_1_2_SETTINGS_H_
|
#define __VALUECAN4_1_2_SETTINGS_H_
|
||||||
|
|
||||||
#include "icsneo/device/idevicesettings.h"
|
#include "icsneo/device/idevicesettings.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4settings.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __VALUECAN4_1_SETTINGS_H_
|
#ifndef __VALUECAN4_1_SETTINGS_H_
|
||||||
#define __VALUECAN4_1_SETTINGS_H_
|
#define __VALUECAN4_1_SETTINGS_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-1-2settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-1-2settings.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#define __VALUECAN4_2EL_SETTINGS_H_
|
#define __VALUECAN4_2EL_SETTINGS_H_
|
||||||
|
|
||||||
#include "icsneo/device/idevicesettings.h"
|
#include "icsneo/device/idevicesettings.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-4-2elsettings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-4-2elsettings.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
+1
-1
@@ -1,7 +1,7 @@
|
|||||||
#ifndef __VALUECAN4_2_SETTINGS_H_
|
#ifndef __VALUECAN4_2_SETTINGS_H_
|
||||||
#define __VALUECAN4_2_SETTINGS_H_
|
#define __VALUECAN4_2_SETTINGS_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-1-2settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-1-2settings.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#define __VALUECAN4_4_2EL_SETTINGS_H_
|
#define __VALUECAN4_4_2EL_SETTINGS_H_
|
||||||
|
|
||||||
#include "icsneo/device/idevicesettings.h"
|
#include "icsneo/device/idevicesettings.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4settings.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
+1
-1
@@ -2,7 +2,7 @@
|
|||||||
#define __VALUECAN4_4_SETTINGS_H_
|
#define __VALUECAN4_4_SETTINGS_H_
|
||||||
|
|
||||||
#include "icsneo/device/idevicesettings.h"
|
#include "icsneo/device/idevicesettings.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-4-2elsettings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-4-2elsettings.h"
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __VALUECAN4_1_H_
|
#ifndef __VALUECAN4_1_H_
|
||||||
#define __VALUECAN4_1_H_
|
#define __VALUECAN4_1_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-1settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-1settings.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -35,13 +35,13 @@ protected:
|
|||||||
encoder.supportCANFD = false; // VCAN 4-1 does not support CAN FD
|
encoder.supportCANFD = false; // VCAN 4-1 does not support CAN FD
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueCAN4_1(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
ValueCAN4_1(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __VALUECAN4_2_H_
|
#ifndef __VALUECAN4_2_H_
|
||||||
#define __VALUECAN4_2_H_
|
#define __VALUECAN4_2_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-2settings.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -31,13 +31,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueCAN4_2(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
ValueCAN4_2(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __VALUECAN4_2EL_H_
|
#ifndef __VALUECAN4_2EL_H_
|
||||||
#define __VALUECAN4_2EL_H_
|
#define __VALUECAN4_2EL_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2elsettings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-2elsettings.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -33,13 +33,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueCAN4_2EL(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
ValueCAN4_2EL(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||||
+4
-4
@@ -1,8 +1,8 @@
|
|||||||
#ifndef __VALUECAN4_4_H_
|
#ifndef __VALUECAN4_4_H_
|
||||||
#define __VALUECAN4_4_H_
|
#define __VALUECAN4_4_H_
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-4settings.h"
|
#include "icsneo/device/valuecan4/settings/valuecan4-4settings.h"
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
@@ -33,13 +33,13 @@ public:
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
virtual void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueCAN4_4(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
ValueCAN4_4(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||||
+77
-183
@@ -2,14 +2,12 @@
|
|||||||
#define __ICSNEOC_H_
|
#define __ICSNEOC_H_
|
||||||
|
|
||||||
#include <stddef.h>
|
#include <stddef.h>
|
||||||
#include <stdint.h>
|
|
||||||
#include <stdbool.h>
|
|
||||||
#include "icsneo/device/neodevice.h" // For neodevice_t
|
#include "icsneo/device/neodevice.h" // For neodevice_t
|
||||||
#include "icsneo/communication/message/neomessage.h" // For neomessage_t and friends
|
#include "icsneo/communication/message/neomessage.h" // For neomessage_t and friends
|
||||||
#include "icsneo/platform/dynamiclib.h" // Dynamic library loading and exporting
|
#include "icsneo/platform/dynamiclib.h" // Dynamic library loading and exporting
|
||||||
#include "icsneo/communication/network.h" // Network type and netID defines
|
#include "icsneo/communication/network.h" // Network type and netID defines
|
||||||
#include "icsneo/api/version.h" // For version info
|
#include "icsneo/api/version.h" // For version info
|
||||||
#include "icsneo/api/event.h" // For event and error info
|
#include "icsneo/api/error.h" // For error info
|
||||||
|
|
||||||
#ifndef ICSNEOC_DYNAMICLOAD
|
#ifndef ICSNEOC_DYNAMICLOAD
|
||||||
|
|
||||||
@@ -33,7 +31,7 @@ extern "C" {
|
|||||||
* To invoke this behavior without finding devices again, call icsneo_freeUnconnectedDevices().
|
* To invoke this behavior without finding devices again, call icsneo_freeUnconnectedDevices().
|
||||||
*
|
*
|
||||||
* If the size provided is not large enough, the output will be truncated.
|
* If the size provided is not large enough, the output will be truncated.
|
||||||
* An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
* An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
||||||
*/
|
*/
|
||||||
extern void DLLExport icsneo_findAllDevices(neodevice_t* devices, size_t* count);
|
extern void DLLExport icsneo_findAllDevices(neodevice_t* devices, size_t* count);
|
||||||
|
|
||||||
@@ -45,7 +43,7 @@ extern void DLLExport icsneo_findAllDevices(neodevice_t* devices, size_t* count)
|
|||||||
extern void DLLExport icsneo_freeUnconnectedDevices();
|
extern void DLLExport icsneo_freeUnconnectedDevices();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Convert a serial number in numerical format to its string representation.
|
* \brief Convert a serial number in numerical format to it's string representation.
|
||||||
* \param[in] num A numerical serial number.
|
* \param[in] num A numerical serial number.
|
||||||
* \param[out] str A pointer to a buffer where the string representation will be written. NULL can be passed, which will write a character count to `count`.
|
* \param[out] str A pointer to a buffer where the string representation will be written. NULL can be passed, which will write a character count to `count`.
|
||||||
* \param[inout] count A pointer to a size_t which, prior to the call,
|
* \param[inout] count A pointer to a size_t which, prior to the call,
|
||||||
@@ -64,13 +62,13 @@ extern void DLLExport icsneo_freeUnconnectedDevices();
|
|||||||
*
|
*
|
||||||
* If the size provided is not large enough, the output will be **NOT** be truncated.
|
* If the size provided is not large enough, the output will be **NOT** be truncated.
|
||||||
* Nothing will be written to the output.
|
* Nothing will be written to the output.
|
||||||
* Instead, an icsneo::APIEvent::BufferInsufficient will be available in icsneo_getLastError().
|
* Instead, an icsneo::APIError::BufferInsufficient will be available in icsneo_getLastError().
|
||||||
* False will be returned, and `count` will now contain the number of *bytes* necessary to store the full string.
|
* False will be returned, and `count` will now contain the number of *bytes* necessary to store the full string.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_serialNumToString(uint32_t num, char* str, size_t* count);
|
extern bool DLLExport icsneo_serialNumToString(uint32_t num, char* str, size_t* count);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Convert a serial number in string format to its numerical representation.
|
* \brief Convert a serial number in string format to it's numerical representation.
|
||||||
* \param[in] str A NULL terminated string containing the string representation of an Intrepid serial number.
|
* \param[in] str A NULL terminated string containing the string representation of an Intrepid serial number.
|
||||||
* \returns The numerical representation of the serial number, or 0 if the conversion was unsuccessful.
|
* \returns The numerical representation of the serial number, or 0 if the conversion was unsuccessful.
|
||||||
*
|
*
|
||||||
@@ -86,7 +84,7 @@ extern uint32_t DLLExport icsneo_serialStringToNum(const char* str);
|
|||||||
* \returns True if the neodevice_t is valid.
|
* \returns True if the neodevice_t is valid.
|
||||||
*
|
*
|
||||||
* This check is automatically performed at the beginning of any API function that operates on a device.
|
* This check is automatically performed at the beginning of any API function that operates on a device.
|
||||||
* If there is a failure, an icsneo::APIEvent::InvalidNeoDevice will be available in icsneo_getLastError().
|
* If there is a failure, an icsneo::APIError::InvalidNeoDevice will be available in icsneo_getLastError().
|
||||||
*
|
*
|
||||||
* See icsneo_findAllDevices() for information regarding the neodevice_t validity contract.
|
* See icsneo_findAllDevices() for information regarding the neodevice_t validity contract.
|
||||||
*/
|
*/
|
||||||
@@ -102,9 +100,7 @@ extern bool DLLExport icsneo_isValidNeoDevice(const neodevice_t* device);
|
|||||||
* See icsneo_goOnline() for information about enabling network communication once the device is open.
|
* See icsneo_goOnline() for information about enabling network communication once the device is open.
|
||||||
*
|
*
|
||||||
* If the open did not succeed, icsneo_getLastError() should provide more information about why.
|
* If the open did not succeed, icsneo_getLastError() should provide more information about why.
|
||||||
*
|
*/ // TODO Solidify what happens in case the connection was already open
|
||||||
* If the device was already open, an icsneo::APIEvent::DeviceCurrentlyOpen will be available in icsneo_getLastError().
|
|
||||||
*/
|
|
||||||
extern bool DLLExport icsneo_openDevice(const neodevice_t* device);
|
extern bool DLLExport icsneo_openDevice(const neodevice_t* device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -117,17 +113,6 @@ extern bool DLLExport icsneo_openDevice(const neodevice_t* device);
|
|||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_closeDevice(const neodevice_t* device);
|
extern bool DLLExport icsneo_closeDevice(const neodevice_t* device);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Verify network connection for the specified hardware
|
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
|
||||||
* \returns True if the device is connected.
|
|
||||||
*
|
|
||||||
* This function does not modify the working state of the device at all.
|
|
||||||
*
|
|
||||||
* See icsneo_openDevice() for an explanation about the concept of being "open".
|
|
||||||
*/
|
|
||||||
extern bool DLLExport icsneo_isOpen(const neodevice_t* device);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Enable network communication for the specified hardware
|
* \brief Enable network communication for the specified hardware
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
@@ -148,7 +133,7 @@ extern bool DLLExport icsneo_goOnline(const neodevice_t* device);
|
|||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
* \returns True if communication could be disabled.
|
* \returns True if communication could be disabled.
|
||||||
*
|
*
|
||||||
* See icsneo_goOnline() for an explanation about the concept of being "online".
|
* See icsneo_goOnline() for an explaination about the concept of being "online".
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_goOffline(const neodevice_t* device);
|
extern bool DLLExport icsneo_goOffline(const neodevice_t* device);
|
||||||
|
|
||||||
@@ -159,7 +144,7 @@ extern bool DLLExport icsneo_goOffline(const neodevice_t* device);
|
|||||||
*
|
*
|
||||||
* This function does not modify the working state of the device at all.
|
* This function does not modify the working state of the device at all.
|
||||||
*
|
*
|
||||||
* See icsneo_goOnline() for an explanation about the concept of being "online".
|
* See icsneo_goOnline() for an explaination about the concept of being "online".
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_isOnline(const neodevice_t* device);
|
extern bool DLLExport icsneo_isOnline(const neodevice_t* device);
|
||||||
|
|
||||||
@@ -182,9 +167,7 @@ extern bool DLLExport icsneo_isOnline(const neodevice_t* device);
|
|||||||
* The client application will have to call icsneo_getMessages() very often to avoid losing messages, or change the limit.
|
* The client application will have to call icsneo_getMessages() very often to avoid losing messages, or change the limit.
|
||||||
*
|
*
|
||||||
* If the message limit is exceeded before a call to icsneo_getMessages() takes ownership of the messages,
|
* If the message limit is exceeded before a call to icsneo_getMessages() takes ownership of the messages,
|
||||||
* the oldest message will be dropped (**LOST**) and an icsneo::APIEvent::PollingMessageOverflow will be flagged for the device.
|
* the oldest message will be dropped (**LOST**) and an icsneo::APIError::PollingMessageOverflow will be flagged for the device.
|
||||||
*
|
|
||||||
* This function will succeed even if the device is not open.
|
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_enableMessagePolling(const neodevice_t* device);
|
extern bool DLLExport icsneo_enableMessagePolling(const neodevice_t* device);
|
||||||
|
|
||||||
@@ -199,17 +182,6 @@ extern bool DLLExport icsneo_enableMessagePolling(const neodevice_t* device);
|
|||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_disableMessagePolling(const neodevice_t* device);
|
extern bool DLLExport icsneo_disableMessagePolling(const neodevice_t* device);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Verify message polling status for the specified hardware
|
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
|
||||||
* \returns True if polling is enabled.
|
|
||||||
*
|
|
||||||
* This function does not modify the working state of the device at all.
|
|
||||||
*
|
|
||||||
* See icsneo_enableMessagePolling() for an explanation about how polling works.
|
|
||||||
*/
|
|
||||||
extern bool DLLExport icsneo_isMessagePollingEnabled(const neodevice_t* device);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Read out messages which have been recieved
|
* \brief Read out messages which have been recieved
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
@@ -265,11 +237,11 @@ extern bool DLLExport icsneo_getMessages(const neodevice_t* device, neomessage_t
|
|||||||
/**
|
/**
|
||||||
* \brief Get the maximum number of messages which will be held in the API managed buffer for the specified hardware.
|
* \brief Get the maximum number of messages which will be held in the API managed buffer for the specified hardware.
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
* \returns Number of messages, or -1 if device is invalid.
|
* \returns Number of messages.
|
||||||
*
|
*
|
||||||
* See icsneo_enableMessagePolling() for more information about the message polling system.
|
* See icsneo_enableMessagePolling() for more information about the message polling system.
|
||||||
*/
|
*/
|
||||||
extern int DLLExport icsneo_getPollingMessageLimit(const neodevice_t* device);
|
extern size_t DLLExport icsneo_getPollingMessageLimit(const neodevice_t* device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set the maximum number of messages which will be held in the API managed buffer for the specified hardware.
|
* \brief Set the maximum number of messages which will be held in the API managed buffer for the specified hardware.
|
||||||
@@ -280,27 +252,10 @@ extern int DLLExport icsneo_getPollingMessageLimit(const neodevice_t* device);
|
|||||||
* See icsneo_enableMessagePolling() for more information about the message polling system.
|
* See icsneo_enableMessagePolling() for more information about the message polling system.
|
||||||
*
|
*
|
||||||
* Setting the maximum lower than the current number of stored messages will cause the oldest messages
|
* Setting the maximum lower than the current number of stored messages will cause the oldest messages
|
||||||
* to be dropped (**LOST**) and an icsneo::APIEvent::PollingMessageOverflow to be flagged for the device.
|
* to be dropped (**LOST**) and an icsneo::APIError::PollingMessageOverflow to be flagged for the device.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit);
|
extern bool DLLExport icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Adds a message callback to the specified device to be called when a new message is received.
|
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
|
||||||
* \param[in] callback A function pointer with void return type and a single neomessage_t parameter.
|
|
||||||
* \param[in] filter Unused for now. Exists as a placeholder here for future backwards-compatibility.
|
|
||||||
* \returns The id of the callback added, or -1 if the operation failed.
|
|
||||||
*/
|
|
||||||
extern int DLLExport icsneo_addMessageCallback(const neodevice_t* device, void (*callback)(neomessage_t), void*);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Removes a message callback from the specified device.
|
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
|
||||||
* \param[in] id The id of the callback to remove.
|
|
||||||
* \returns True if the callback was successfully removed.
|
|
||||||
*/
|
|
||||||
extern bool DLLExport icsneo_removeMessageCallback(const neodevice_t* device, int id);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the friendly product name for a specified device.
|
* \brief Get the friendly product name for a specified device.
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
@@ -320,7 +275,7 @@ extern bool DLLExport icsneo_removeMessageCallback(const neodevice_t* device, in
|
|||||||
* icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid.
|
* icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid.
|
||||||
*
|
*
|
||||||
* If the size provided is not large enough, the output will be truncated.
|
* If the size provided is not large enough, the output will be truncated.
|
||||||
* An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
* An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
||||||
* True will still be returned.
|
* True will still be returned.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength);
|
extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength);
|
||||||
@@ -344,7 +299,7 @@ extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str
|
|||||||
* icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid.
|
* icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid.
|
||||||
*
|
*
|
||||||
* If the size provided is not large enough, the output will be truncated.
|
* If the size provided is not large enough, the output will be truncated.
|
||||||
* An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
* An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
||||||
* True will still be returned.
|
* True will still be returned.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength);
|
extern bool DLLExport icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength);
|
||||||
@@ -407,7 +362,7 @@ extern bool DLLExport icsneo_settingsApplyDefaultsTemporary(const neodevice_t* d
|
|||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
* \param[out] structure A pointer to a device settings structure for the current device.
|
* \param[out] structure A pointer to a device settings structure for the current device.
|
||||||
* \param[in] structureSize The size of the current device settings structure in bytes.
|
* \param[in] structureSize The size of the current device settings structure in bytes.
|
||||||
* \returns Number of bytes written to structure, or -1 if the operation failed.
|
* \returns Number of bytes written to structure
|
||||||
*
|
*
|
||||||
* See icsneo_settingsApply() for further information about applying settings. See icsneo_settingsApplyDefaults() for further information about applying default settings.
|
* See icsneo_settingsApply() for further information about applying settings. See icsneo_settingsApplyDefaults() for further information about applying default settings.
|
||||||
*
|
*
|
||||||
@@ -416,7 +371,7 @@ extern bool DLLExport icsneo_settingsApplyDefaultsTemporary(const neodevice_t* d
|
|||||||
* If possible, use functions specific to the operation you want to acomplish (such as icsneo_setBaudrate()) instead of modifying the structure directly.
|
* If possible, use functions specific to the operation you want to acomplish (such as icsneo_setBaudrate()) instead of modifying the structure directly.
|
||||||
* This allows the client application to work with other hardware.
|
* This allows the client application to work with other hardware.
|
||||||
*/
|
*/
|
||||||
extern int DLLExport icsneo_settingsReadStructure(const neodevice_t* device, void* structure, size_t structureSize);
|
extern size_t DLLExport icsneo_settingsReadStructure(const neodevice_t* device, void* structure, size_t structureSize);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Apply a provided settings structure for a specified device.
|
* \brief Apply a provided settings structure for a specified device.
|
||||||
@@ -549,15 +504,6 @@ extern bool DLLExport icsneo_transmit(const neodevice_t* device, const neomessag
|
|||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_transmitMessages(const neodevice_t* device, const neomessage_t* messages, size_t count);
|
extern bool DLLExport icsneo_transmitMessages(const neodevice_t* device, const neomessage_t* messages, size_t count);
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Set the behavior of whether writing is a blocking action or not.
|
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to transmit on.
|
|
||||||
* \param[in] blocks Whether or not writing is a blocking action.
|
|
||||||
*
|
|
||||||
* By default, writing is a blocking action.
|
|
||||||
*/
|
|
||||||
extern void DLLExport icsneo_setWriteBlocks(const neodevice_t* device, bool blocks);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the friendly description for a specified device.
|
* \brief Get the friendly description for a specified device.
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to operate on.
|
||||||
@@ -577,7 +523,7 @@ extern void DLLExport icsneo_setWriteBlocks(const neodevice_t* device, bool bloc
|
|||||||
* icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid.
|
* icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid.
|
||||||
*
|
*
|
||||||
* If the size provided is not large enough, the output will be truncated.
|
* If the size provided is not large enough, the output will be truncated.
|
||||||
* An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
* An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
||||||
* True will still be returned.
|
* True will still be returned.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength);
|
extern bool DLLExport icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength);
|
||||||
@@ -589,101 +535,77 @@ extern bool DLLExport icsneo_describeDevice(const neodevice_t* device, char* str
|
|||||||
extern neoversion_t DLLExport icsneo_getVersion(void);
|
extern neoversion_t DLLExport icsneo_getVersion(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Adds an event callback to be called when a new event is added.
|
* \brief Read out errors which have occurred in API operation
|
||||||
* \param[in] callback A function pointer with void return type and a single neoevent_t parameter.
|
* \param[out] errors A pointer to a buffer which neoerror_t structures will be written to. NULL can be passed, which will write the current error count to size.
|
||||||
* \param[in] filter Unused for now. Exists as a placeholder here for future backwards-compatibility.
|
|
||||||
* \returns The id of the callback added. Does not error.
|
|
||||||
*
|
|
||||||
* Do not attempt to add or remove callbacks inside of a callback, as the stored callbacks are locked during calls.
|
|
||||||
*/
|
|
||||||
extern int DLLExport icsneo_addEventCallback(void (*callback)(neoevent_t), void*);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Removes an event callback.
|
|
||||||
* \param[in] id The id of the callback to remove.
|
|
||||||
* \returns True if the callback was successfully removed.
|
|
||||||
*/
|
|
||||||
extern bool DLLExport icsneo_removeEventCallback(int id);
|
|
||||||
|
|
||||||
/**
|
|
||||||
* \brief Read out events which have occurred in API operation
|
|
||||||
* \param[out] events A pointer to a buffer which neoevent_t structures will be written to. NULL can be passed, which will write the current event count to size.
|
|
||||||
* \param[inout] size A pointer to a size_t which, prior to the call,
|
* \param[inout] size A pointer to a size_t which, prior to the call,
|
||||||
* holds the maximum number of events to be written, and after the call holds the number of events written.
|
* holds the maximum number of errors to be written, and after the call holds the number of errors written.
|
||||||
* \returns True if the events were read out successfully (even if there were no events to report).
|
* \returns True if the errors were read out successfully (even if there were no errors to report).
|
||||||
*
|
*
|
||||||
* Events contain INFO and WARNINGS, and may potentially contain one TooManyEvents WARNING at the end. No ERRORS are found in Events, see icsneo_getLastError() instead.
|
* Errors can be caused by API usage, such as bad input or operating on a closed neodevice_t.
|
||||||
*
|
*
|
||||||
* Events can be caused by API usage, such as providing too small of a buffer or disconnecting from a device.
|
* Errors can also occur asynchronously to the client application threads, in the case of a device communication error or similar.
|
||||||
*
|
*
|
||||||
* Events can also occur asynchronously to the client application threads, in the case of a device communication event or similar.
|
* Errors are read out of the API managed buffer in order of oldest to newest.
|
||||||
*
|
|
||||||
* Events are read out of the API managed buffer in order of oldest to newest.
|
|
||||||
* As they are read out, they are removed from the API managed buffer.
|
* As they are read out, they are removed from the API managed buffer.
|
||||||
*
|
*
|
||||||
* If size is too small to contain all events, as many events as will fit will be read out.
|
* If size is too small to contain all errors, as many errors as will fit will be read out.
|
||||||
* Subsequent calls to icsneo_getEvents() can retrieve any events which were not read out.
|
* Subsequent calls to icsneo_getErrors() can retrieve any errors which were not read out.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_getEvents(neoevent_t* events, size_t* size);
|
extern bool DLLExport icsneo_getErrors(neoerror_t* errors, size_t* size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Read out events which have occurred in API operation for a specific device
|
* \brief Read out errors which have occurred in API operation for a specific device
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to read out events for. NULL can be passed, which indicates that **ONLY** events *not* associated with a device are desired (API events).
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to read out errors for. NULL can be passed, which indicates that **ONLY** errors *not* associated with a device are desired (API errors).
|
||||||
* \param[out] events A pointer to a buffer which neoevent_t structures will be written to. NULL can be passed, which will write the current event count to size.
|
* \param[out] errors A pointer to a buffer which neoerror_t structures will be written to. NULL can be passed, which will write the current error count to size.
|
||||||
* \param[inout] size A pointer to a size_t which, prior to the call,
|
* \param[inout] size A pointer to a size_t which, prior to the call,
|
||||||
* holds the maximum number of events to be written, and after the call holds the number of events written.
|
* holds the maximum number of errors to be written, and after the call holds the number of errors written.
|
||||||
* \returns True if the events were read out successfully (even if there were no events to report).
|
* \returns True if the errors were read out successfully (even if there were no errors to report).
|
||||||
*
|
*
|
||||||
* See icsneo_getEvents() for more information about the event system.
|
* See icsneo_getErrors() for more information about the error system.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_getDeviceEvents(const neodevice_t* device, neoevent_t* events, size_t* size);
|
extern bool DLLExport icsneo_getDeviceErrors(const neodevice_t* device, neoerror_t* errors, size_t* size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Read out the last error which occurred in API operation on this thread.
|
* \brief Read out the last error which occurred in API operation.
|
||||||
* \param[out] error A pointer to a buffer which a neoevent_t structure will be written to.
|
* \param[out] error A pointer to a buffer which a neoerror_t structure will be written to.
|
||||||
* \returns True if an error was read out.
|
* \returns True if an error was read out.
|
||||||
*
|
*
|
||||||
* All errors are stored on a per-thread basis, meaning that calling icsneo_getLastError() will return the last error that occured on the calling thread.
|
* See icsneo_getErrors() for more information about the error system.
|
||||||
* Any errors can only be retrieved through this function, and NOT icsneo_getEvents() or similar! Only INFO and WARNING level events are accessible through those.
|
|
||||||
* Only the last error is stored, so the intention is for this function to be called immediately following another failed API call.
|
|
||||||
*
|
*
|
||||||
* The API error system is thread-safe. Only an API error which occurred on the current thread will be returned.
|
* This operation removes the returned error from the buffer, so subsequent calls to error functions will not inlcude the error.
|
||||||
*
|
|
||||||
* See icsneo_getEvents() for more information about the event system.
|
|
||||||
*
|
|
||||||
* This operation removes the returned error from the buffer, so subsequent calls to error functions will not include the error.
|
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_getLastError(neoevent_t* error);
|
extern bool DLLExport icsneo_getLastError(neoerror_t* error);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Discard all events which have occurred in API operation. Does NOT discard any errors.
|
* \brief Discard all errors which have occurred in API operation.
|
||||||
*/
|
*/
|
||||||
extern void DLLExport icsneo_discardAllEvents(void);
|
extern void DLLExport icsneo_discardAllErrors(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Discard all events which have occurred in API operation.
|
* \brief Discard all errors which have occurred in API operation.
|
||||||
* \param[in] device A pointer to the neodevice_t structure specifying the device to discard events for. NULL can be passed, which indicates that **ONLY** events *not* associated with a device are desired (API events).
|
* \param[in] device A pointer to the neodevice_t structure specifying the device to discard errors for. NULL can be passed, which indicates that **ONLY** errors *not* associated with a device are desired (API errors).
|
||||||
* Does NOT discard any errors (device or otherwise).
|
|
||||||
*/
|
*/
|
||||||
extern void DLLExport icsneo_discardDeviceEvents(const neodevice_t* device);
|
extern void DLLExport icsneo_discardDeviceErrors(const neodevice_t* device);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Set the number of events which will be held in the API managed buffer before icsneo::APIEvent::TooManyEvents
|
* \brief Set the number of errors which will be held in the API managed buffer before icsneo::APIError::TooManyErrors
|
||||||
* \param[in] newLimit The new limit. Must be >10. 1 event slot is always reserved for a potential icsneo::APIEvent::TooManyEvents, so (newLimit - 1) other events can be stored.
|
* \param[in] newLimit The new limit. Must be >10.
|
||||||
*
|
*
|
||||||
* If the event limit is reached, an icsneo::APIEvent::TooManyEvents will be flagged.
|
* If the error limit is reached, an icsneo::APIError::TooManyErrors will be flagged.
|
||||||
*
|
*
|
||||||
* If the `newLimit` is smaller than the current event count,
|
* If the `newLimit` is smaller than the current error count,
|
||||||
* events will be removed in order of decreasing age.
|
* errors will be removed in order of increasing severity and decreasing age.
|
||||||
* This will also flag an icsneo::APIEvent::TooManyEvents.
|
* This will also flag an icsneo::APIError::TooManyErrors.
|
||||||
*/
|
*/
|
||||||
extern void DLLExport icsneo_setEventLimit(size_t newLimit);
|
extern void DLLExport icsneo_setErrorLimit(size_t newLimit);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the number of events which can be held in the API managed buffer
|
* \brief Set the number of errors which will be held in the API managed buffer before icsneo::APIError::TooManyErrors
|
||||||
* \returns The current limit.
|
* \returns The current limit.
|
||||||
|
*
|
||||||
|
* If the error limit is reached, an icsneo::APIError::TooManyErrors will be flagged.
|
||||||
*/
|
*/
|
||||||
extern size_t DLLExport icsneo_getEventLimit(void);
|
extern size_t DLLExport icsneo_getErrorLimit(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* \brief Get the devices supported by the current version of the API
|
* \brief Get the devices supported by the current version of the API
|
||||||
@@ -699,7 +621,7 @@ extern size_t DLLExport icsneo_getEventLimit(void);
|
|||||||
* A query for length (`devices == NULL`) will return false.
|
* A query for length (`devices == NULL`) will return false.
|
||||||
*
|
*
|
||||||
* If the count provided is not large enough, the output will be truncated.
|
* If the count provided is not large enough, the output will be truncated.
|
||||||
* An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
* An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case.
|
||||||
* True will still be returned.
|
* True will still be returned.
|
||||||
*/
|
*/
|
||||||
extern bool DLLExport icsneo_getSupportedDevices(devicetype_t* devices, size_t* count);
|
extern bool DLLExport icsneo_getSupportedDevices(devicetype_t* devices, size_t* count);
|
||||||
@@ -743,9 +665,6 @@ fn_icsneo_openDevice icsneo_openDevice;
|
|||||||
typedef bool(*fn_icsneo_closeDevice)(const neodevice_t* device);
|
typedef bool(*fn_icsneo_closeDevice)(const neodevice_t* device);
|
||||||
fn_icsneo_closeDevice icsneo_closeDevice;
|
fn_icsneo_closeDevice icsneo_closeDevice;
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_isOpen)(const neodevice_t* device);
|
|
||||||
fn_icsneo_isOpen icsneo_isOpen;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_goOnline)(const neodevice_t* device);
|
typedef bool(*fn_icsneo_goOnline)(const neodevice_t* device);
|
||||||
fn_icsneo_goOnline icsneo_goOnline;
|
fn_icsneo_goOnline icsneo_goOnline;
|
||||||
|
|
||||||
@@ -761,9 +680,6 @@ fn_icsneo_enableMessagePolling icsneo_enableMessagePolling;
|
|||||||
typedef bool(*fn_icsneo_disableMessagePolling)(const neodevice_t* device);
|
typedef bool(*fn_icsneo_disableMessagePolling)(const neodevice_t* device);
|
||||||
fn_icsneo_disableMessagePolling icsneo_disableMessagePolling;
|
fn_icsneo_disableMessagePolling icsneo_disableMessagePolling;
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_isMessagePollingEnabled)(const neodevice_t* device);
|
|
||||||
fn_icsneo_isMessagePollingEnabled icsneo_isMessagePollingEnabled;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_getMessages)(const neodevice_t* device, neomessage_t* messages, size_t* items, uint64_t timeout);
|
typedef bool(*fn_icsneo_getMessages)(const neodevice_t* device, neomessage_t* messages, size_t* items, uint64_t timeout);
|
||||||
fn_icsneo_getMessages icsneo_getMessages;
|
fn_icsneo_getMessages icsneo_getMessages;
|
||||||
|
|
||||||
@@ -773,12 +689,6 @@ fn_icsneo_getPollingMessageLimit icsneo_getPollingMessageLimit;
|
|||||||
typedef bool(*fn_icsneo_setPollingMessageLimit)(const neodevice_t* device, size_t newLimit);
|
typedef bool(*fn_icsneo_setPollingMessageLimit)(const neodevice_t* device, size_t newLimit);
|
||||||
fn_icsneo_setPollingMessageLimit icsneo_setPollingMessageLimit;
|
fn_icsneo_setPollingMessageLimit icsneo_setPollingMessageLimit;
|
||||||
|
|
||||||
typedef int(*fn_icsneo_addMessageCallback)(const neodevice_t* device, void (*callback)(neomessage_t), void*);
|
|
||||||
fn_icsneo_addMessageCallback icsneo_addMessageCallback;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_removeMessageCallback)(const neodevice_t* device, int id);
|
|
||||||
fn_icsneo_removeMessageCallback icsneo_removeMessageCallback;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_getProductName)(const neodevice_t* device, char* str, size_t* maxLength);
|
typedef bool(*fn_icsneo_getProductName)(const neodevice_t* device, char* str, size_t* maxLength);
|
||||||
fn_icsneo_getProductName icsneo_getProductName;
|
fn_icsneo_getProductName icsneo_getProductName;
|
||||||
|
|
||||||
@@ -797,7 +707,7 @@ fn_icsneo_settingsApplyDefaults icsneo_settingsApplyDefaults;
|
|||||||
typedef bool(*fn_icsneo_settingsApplyDefaultsTemporary)(const neodevice_t* device);
|
typedef bool(*fn_icsneo_settingsApplyDefaultsTemporary)(const neodevice_t* device);
|
||||||
fn_icsneo_settingsApplyDefaultsTemporary icsneo_settingsApplyDefaultsTemporary;
|
fn_icsneo_settingsApplyDefaultsTemporary icsneo_settingsApplyDefaultsTemporary;
|
||||||
|
|
||||||
typedef int(*fn_icsneo_settingsReadStructure)(const neodevice_t* device, void* structure, size_t structureSize);
|
typedef size_t(*fn_icsneo_settingsReadStructure)(const neodevice_t* device, void* structure, size_t structureSize);
|
||||||
fn_icsneo_settingsReadStructure icsneo_settingsReadStructure;
|
fn_icsneo_settingsReadStructure icsneo_settingsReadStructure;
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_settingsApplyStructure)(const neodevice_t* device, const void* structure, size_t structureSize);
|
typedef bool(*fn_icsneo_settingsApplyStructure)(const neodevice_t* device, const void* structure, size_t structureSize);
|
||||||
@@ -824,41 +734,32 @@ fn_icsneo_transmit icsneo_transmit;
|
|||||||
typedef bool(*fn_icsneo_transmitMessages)(const neodevice_t* device, const neomessage_t* messages, size_t count);
|
typedef bool(*fn_icsneo_transmitMessages)(const neodevice_t* device, const neomessage_t* messages, size_t count);
|
||||||
fn_icsneo_transmitMessages icsneo_transmitMessages;
|
fn_icsneo_transmitMessages icsneo_transmitMessages;
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_setWriteBlocks)(const neodevice_t* device, bool blocks);
|
|
||||||
fn_icsneo_setWriteBlocks icsneo_setWriteBlocks;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_describeDevice)(const neodevice_t* device, char* str, size_t* maxLength);
|
typedef bool(*fn_icsneo_describeDevice)(const neodevice_t* device, char* str, size_t* maxLength);
|
||||||
fn_icsneo_describeDevice icsneo_describeDevice;
|
fn_icsneo_describeDevice icsneo_describeDevice;
|
||||||
|
|
||||||
typedef neoversion_t(*fn_icsneo_getVersion)(void);
|
typedef neoversion_t(*fn_icsneo_getVersion)(void);
|
||||||
fn_icsneo_getVersion icsneo_getVersion;
|
fn_icsneo_getVersion icsneo_getVersion;
|
||||||
|
|
||||||
typedef int(*fn_icsneo_addEventCallback)(void (*callback)(neoevent_t), void*);
|
typedef bool(*fn_icsneo_getErrors)(neoerror_t* errors, size_t* size);
|
||||||
fn_icsneo_addEventCallback icsneo_addEventCallback;
|
fn_icsneo_getErrors icsneo_getErrors;
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_removeEventCallback)(int id);
|
typedef bool(*fn_icsneo_getDeviceErrors)(const neodevice_t* device, neoerror_t* errors, size_t* size);
|
||||||
fn_icsneo_removeEventCallback icsneo_removeEventCallback;
|
fn_icsneo_getDeviceErrors icsneo_getDeviceErrors;
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_getEvents)(neoevent_t* events, size_t* size);
|
typedef bool(*fn_icsneo_getLastError)(neoerror_t* error);
|
||||||
fn_icsneo_getEvents icsneo_getEvents;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_getDeviceEvents)(const neodevice_t* device, neoevent_t* events, size_t* size);
|
|
||||||
fn_icsneo_getDeviceEvents icsneo_getDeviceEvents;
|
|
||||||
|
|
||||||
typedef bool(*fn_icsneo_getLastError)(neoevent_t* error);
|
|
||||||
fn_icsneo_getLastError icsneo_getLastError;
|
fn_icsneo_getLastError icsneo_getLastError;
|
||||||
|
|
||||||
typedef void(*fn_icsneo_discardAllEvents)(void);
|
typedef void(*fn_icsneo_discardAllErrors)(void);
|
||||||
fn_icsneo_discardAllEvents icsneo_discardAllEvents;
|
fn_icsneo_discardAllErrors icsneo_discardAllErrors;
|
||||||
|
|
||||||
typedef void(*fn_icsneo_discardDeviceEvents)(const neodevice_t* device);
|
typedef void(*fn_icsneo_discardDeviceErrors)(const neodevice_t* device);
|
||||||
fn_icsneo_discardDeviceEvents icsneo_discardDeviceEvents;
|
fn_icsneo_discardDeviceErrors icsneo_discardDeviceErrors;
|
||||||
|
|
||||||
typedef void(*fn_icsneo_setEventLimit)(size_t newLimit);
|
typedef void(*fn_icsneo_setErrorLimit)(size_t newLimit);
|
||||||
fn_icsneo_setEventLimit icsneo_setEventLimit;
|
fn_icsneo_setErrorLimit icsneo_setErrorLimit;
|
||||||
|
|
||||||
typedef size_t(*fn_icsneo_getEventLimit)(void);
|
typedef size_t(*fn_icsneo_getErrorLimit)(void);
|
||||||
fn_icsneo_getEventLimit icsneo_getEventLimit;
|
fn_icsneo_getErrorLimit icsneo_getErrorLimit;
|
||||||
|
|
||||||
#define ICSNEO_IMPORT(func) func = (fn_##func)icsneo_dynamicLibraryGetFunction(icsneo_libraryHandle, #func)
|
#define ICSNEO_IMPORT(func) func = (fn_##func)icsneo_dynamicLibraryGetFunction(icsneo_libraryHandle, #func)
|
||||||
#define ICSNEO_IMPORTASSERT(func) if((ICSNEO_IMPORT(func)) == NULL) return 3
|
#define ICSNEO_IMPORTASSERT(func) if((ICSNEO_IMPORT(func)) == NULL) return 3
|
||||||
@@ -881,18 +782,14 @@ int icsneo_init() {
|
|||||||
ICSNEO_IMPORTASSERT(icsneo_isValidNeoDevice);
|
ICSNEO_IMPORTASSERT(icsneo_isValidNeoDevice);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_openDevice);
|
ICSNEO_IMPORTASSERT(icsneo_openDevice);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_closeDevice);
|
ICSNEO_IMPORTASSERT(icsneo_closeDevice);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_isOpen);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_goOnline);
|
ICSNEO_IMPORTASSERT(icsneo_goOnline);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_goOffline);
|
ICSNEO_IMPORTASSERT(icsneo_goOffline);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_isOnline);
|
ICSNEO_IMPORTASSERT(icsneo_isOnline);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_enableMessagePolling);
|
ICSNEO_IMPORTASSERT(icsneo_enableMessagePolling);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_disableMessagePolling);
|
ICSNEO_IMPORTASSERT(icsneo_disableMessagePolling);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_isMessagePollingEnabled);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getMessages);
|
ICSNEO_IMPORTASSERT(icsneo_getMessages);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getPollingMessageLimit);
|
ICSNEO_IMPORTASSERT(icsneo_getPollingMessageLimit);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_setPollingMessageLimit);
|
ICSNEO_IMPORTASSERT(icsneo_setPollingMessageLimit);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_addMessageCallback);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_removeMessageCallback);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getProductName);
|
ICSNEO_IMPORTASSERT(icsneo_getProductName);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_settingsRefresh);
|
ICSNEO_IMPORTASSERT(icsneo_settingsRefresh);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_settingsApply);
|
ICSNEO_IMPORTASSERT(icsneo_settingsApply);
|
||||||
@@ -908,18 +805,15 @@ int icsneo_init() {
|
|||||||
ICSNEO_IMPORTASSERT(icsneo_setFDBaudrate);
|
ICSNEO_IMPORTASSERT(icsneo_setFDBaudrate);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_transmit);
|
ICSNEO_IMPORTASSERT(icsneo_transmit);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_transmitMessages);
|
ICSNEO_IMPORTASSERT(icsneo_transmitMessages);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_setWriteBlocks);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_describeDevice);
|
ICSNEO_IMPORTASSERT(icsneo_describeDevice);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getVersion);
|
ICSNEO_IMPORTASSERT(icsneo_getVersion);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_addEventCallback);
|
ICSNEO_IMPORTASSERT(icsneo_getErrors);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_removeEventCallback);
|
ICSNEO_IMPORTASSERT(icsneo_getDeviceErrors);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getEvents);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getDeviceEvents);
|
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getLastError);
|
ICSNEO_IMPORTASSERT(icsneo_getLastError);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_discardAllEvents);
|
ICSNEO_IMPORTASSERT(icsneo_discardAllErrors);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_discardDeviceEvents);
|
ICSNEO_IMPORTASSERT(icsneo_discardDeviceErrors);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_setEventLimit);
|
ICSNEO_IMPORTASSERT(icsneo_setErrorLimit);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getEventLimit);
|
ICSNEO_IMPORTASSERT(icsneo_getErrorLimit);
|
||||||
|
|
||||||
icsneo_initialized = true;
|
icsneo_initialized = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
+10
-10
@@ -6,7 +6,7 @@
|
|||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/api/version.h"
|
#include "icsneo/api/version.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/errormanager.h"
|
||||||
|
|
||||||
#include "icsneo/communication/message/canmessage.h"
|
#include "icsneo/communication/message/canmessage.h"
|
||||||
#include "icsneo/communication/message/ethernetmessage.h"
|
#include "icsneo/communication/message/ethernetmessage.h"
|
||||||
@@ -16,15 +16,15 @@ namespace icsneo {
|
|||||||
std::vector<std::shared_ptr<Device>> FindAllDevices();
|
std::vector<std::shared_ptr<Device>> FindAllDevices();
|
||||||
std::vector<DeviceType> GetSupportedDevices();
|
std::vector<DeviceType> GetSupportedDevices();
|
||||||
|
|
||||||
size_t EventCount(EventFilter filter = EventFilter());
|
size_t ErrorCount(ErrorFilter filter = ErrorFilter());
|
||||||
std::vector<APIEvent> GetEvents(EventFilter filter, size_t max = 0);
|
std::vector<APIError> GetErrors(ErrorFilter filter, size_t max = 0);
|
||||||
std::vector<APIEvent> GetEvents(size_t max = 0, EventFilter filter = EventFilter());
|
std::vector<APIError> GetErrors(size_t max = 0, ErrorFilter filter = ErrorFilter());
|
||||||
void GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max = 0);
|
void GetErrors(std::vector<APIError>& errors, ErrorFilter filter, size_t max = 0);
|
||||||
void GetEvents(std::vector<APIEvent>& events, size_t max = 0, EventFilter filter = EventFilter());
|
void GetErrors(std::vector<APIError>& errors, size_t max = 0, ErrorFilter filter = ErrorFilter());
|
||||||
APIEvent GetLastError();
|
bool GetLastError(APIError& error, ErrorFilter filter = ErrorFilter());
|
||||||
void DiscardEvents(EventFilter filter = EventFilter());
|
void DiscardErrors(ErrorFilter filter = ErrorFilter());
|
||||||
void SetEventLimit(size_t newLimit);
|
void SetErrorLimit(size_t newLimit);
|
||||||
size_t GetEventLimit();
|
size_t GetErrorLimit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
#ifndef __DYNAMICLIB_DARWIN_H_
|
#ifndef __DYNAMICLIB_DARWIN_H_
|
||||||
#define __DYNAMICLIB_DARWIN_H_
|
#define __DYNAMICLIB_DARWIN_H_
|
||||||
|
|
||||||
#define icsneo_dynamicLibraryLoad() dlopen("libicsneoc.dylib", RTLD_LAZY)
|
#define icsneo_dynamicLibraryLoad() dlopen("/Users/paulywog/Code/icsneonext/build/libicsneoc.dylib", RTLD_LAZY)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
@@ -0,0 +1,11 @@
|
|||||||
|
#ifndef __MACADDR_DARWIN_H_
|
||||||
|
#define __MACADDR_DARWIN_H_
|
||||||
|
|
||||||
|
#include <net/if_dl.h>
|
||||||
|
|
||||||
|
#define ICSNEO_AF_MACADDR (AF_LINK)
|
||||||
|
|
||||||
|
// Points towards the first byte of the MAC address, given a sockaddr*
|
||||||
|
#define PLATFORM_MAC_FROM_SOCKADDR(SADDR) (((struct sockaddr_dl*)SADDR)->sdl_data + ((struct sockaddr_dl*)SADDR)->sdl_nlen)
|
||||||
|
|
||||||
|
#endif
|
||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user