Drivers: Decouple from devices
This allows us to better implement alternative drivers for devices, such as for device sharing servers or talking to CoreMini processors within the same device.v0.3.0-dev
parent
0ff12300f3
commit
781fc2c034
|
|
@ -8,6 +8,9 @@ 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(LIBICSNEO_NPCAP_INCLUDE_DIR "" CACHE STRING "Npcap include directory; set to build with Npcap")
|
||||
option(LIBICSNEO_ENABLE_RAW_ETHERNET "Enable devices which communicate over raw ethernet" ON)
|
||||
option(LIBICSNEO_ENABLE_CDCACM "Enable devices which communicate over USB CDC ACM" ON)
|
||||
option(LIBICSNEO_ENABLE_FTDI "Enable devices which communicate over USB FTDI2XX" ON)
|
||||
|
||||
if(NOT CMAKE_CXX_STANDARD)
|
||||
set(CMAKE_CXX_STANDARD 11)
|
||||
|
|
@ -86,30 +89,55 @@ endif()
|
|||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(PLATFORM_SRC
|
||||
platform/windows/pcap.cpp
|
||||
platform/windows/registry.cpp
|
||||
platform/windows/vcp.cpp
|
||||
platform/windows/internal/pcapdll.cpp
|
||||
)
|
||||
|
||||
if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/windows/pcap.cpp
|
||||
platform/windows/internal/pcapdll.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_CDCACM OR LIBICSNEO_ENABLE_FTDI)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/windows/vcp.cpp
|
||||
)
|
||||
endif()
|
||||
else() # Darwin or Linux
|
||||
set(PLATFORM_SRC
|
||||
platform/posix/ftdi.cpp
|
||||
platform/posix/pcap.cpp
|
||||
platform/posix/cdcacm.cpp
|
||||
)
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
set(PLATFORM_SRC)
|
||||
|
||||
if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/darwin/cdcacmdarwin.cpp
|
||||
platform/posix/pcap.cpp
|
||||
)
|
||||
else() # Linux or other
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_FTDI)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/linux/cdcacmlinux.cpp
|
||||
platform/posix/ftdi.cpp
|
||||
)
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
message(WARNING
|
||||
"There is no platform port defined for ${CMAKE_SYSTEM_NAME}!\n"
|
||||
"The Linux platform code will be used, as it will generally allow building, but some devices may not enumerate properly."
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_CDCACM)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/cdcacm.cpp
|
||||
)
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Darwin")
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/darwin/cdcacmdarwin.cpp
|
||||
)
|
||||
else() # Linux or other
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/linux/cdcacmlinux.cpp
|
||||
)
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
message(WARNING
|
||||
"There is no CDCACM platform port defined for ${CMAKE_SYSTEM_NAME}!\n"
|
||||
"The Linux platform code will be used, as it will generally allow building, but some devices may not enumerate properly."
|
||||
)
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
endif()
|
||||
|
|
@ -149,6 +177,7 @@ set(SRC_FILES
|
|||
device/idevicesettings.cpp
|
||||
device/devicefinder.cpp
|
||||
device/device.cpp
|
||||
device/neodevice.cpp
|
||||
disk/diskreaddriver.cpp
|
||||
disk/diskwritedriver.cpp
|
||||
disk/nulldiskdriver.cpp
|
||||
|
|
@ -220,6 +249,15 @@ 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)
|
||||
message("Loaded extensions: " ${LIBICSNEO_EXTENSION_TARGETS})
|
||||
target_link_libraries(icsneocpp PUBLIC ${LIBICSNEO_EXTENSION_TARGETS})
|
||||
if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_RAW_ETHERNET)
|
||||
endif()
|
||||
if(LIBICSNEO_ENABLE_CDCACM)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_CDCACM)
|
||||
endif()
|
||||
if(LIBICSNEO_ENABLE_FTDI)
|
||||
target_compile_definitions(icsneocpp PRIVATE ICSNEO_ENABLE_FTDI)
|
||||
endif()
|
||||
|
||||
# fatfs
|
||||
add_subdirectory(third-party/fatfs)
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@
|
|||
#include <iterator>
|
||||
#include <cstring>
|
||||
#include <cassert>
|
||||
#include <iostream>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
|
|
@ -74,7 +75,7 @@ bool EthernetPacketizer::inputUp(std::vector<uint8_t> bytes) {
|
|||
memcmp(packet.destMAC, BROADCAST_MAC, sizeof(packet.destMAC)) != 0)
|
||||
return false; // Packet is not addressed to us or broadcast
|
||||
|
||||
if(memcmp(packet.srcMAC, deviceMAC, sizeof(deviceMAC)) != 0)
|
||||
if(!allowInPacketsFromAnyMAC && memcmp(packet.srcMAC, deviceMAC, sizeof(deviceMAC)) != 0)
|
||||
return false; // Not a packet from the device we're concerned with
|
||||
|
||||
// Handle single packets
|
||||
|
|
|
|||
|
|
@ -1,265 +1,155 @@
|
|||
#include "icsneo/device/devicefinder.h"
|
||||
#include "icsneo/platform/devices.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include "generated/extensions/builtin.h"
|
||||
|
||||
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
||||
#include "icsneo/platform/pcap.h"
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_CDCACM
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_FTDI
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#endif
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static bool supportedDevicesCached = false;
|
||||
static std::vector<DeviceType> supportedDevices = {
|
||||
template<typename T>
|
||||
static void makeIfSerialMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
|
||||
// Relies on the subclass to have a `static constexpr const char* SERIAL_START = "XX"`
|
||||
// and also a public constructor `T(const FoundDevice& dev)`
|
||||
// Use macro ICSNEO_FINDABLE_DEVICE() to create these
|
||||
if(dev.serial[0] == T::SERIAL_START[0] && dev.serial[1] == T::SERIAL_START[1])
|
||||
into.push_back(std::make_shared<T>(dev));
|
||||
}
|
||||
|
||||
#ifdef __ETHERBADGE_H_
|
||||
EtherBADGE::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2PRO_H_
|
||||
NeoOBD2PRO::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2SIM_H_
|
||||
NeoOBD2SIM::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIRED2_H_
|
||||
NeoVIRED2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
NeoVIFIRE::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2ETH_H_
|
||||
NeoVIFIRE2ETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2USB_H_
|
||||
NeoVIFIRE2USB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
NeoVIION::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
NeoVIPLASMA::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
RADEpsilon::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
RADGalaxy::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_ETH_H_
|
||||
RADMarsETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_USB_H_
|
||||
RADMarsUSB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_ETH_H_
|
||||
RADGigastarETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_USB_H_
|
||||
RADGigastarUSB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOON2_H_
|
||||
RADMoon2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
RADMoonDuo::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADPLUTOUSB_H_
|
||||
RADPlutoUSB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2ETH_H_
|
||||
RADStar2ETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2USB_H_
|
||||
RADStar2USB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
RADSupermoon::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
ValueCAN3::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_1_H_
|
||||
ValueCAN4_1::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2_H_
|
||||
ValueCAN4_2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2EL_ETH_H_
|
||||
ValueCAN4_2EL_ETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2EL_USB_H_
|
||||
ValueCAN4_2EL_USB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_4_H_
|
||||
ValueCAN4_4::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4INDUSTRIAL_ETH_H_
|
||||
ValueCAN4IndustrialETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4INDUSTRIAL_USB_H_
|
||||
ValueCAN4IndustrialUSB::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VIVIDCAN_H_
|
||||
VividCAN::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
};
|
||||
template<typename T>
|
||||
static void makeIfPIDMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
|
||||
// Relies on the subclass to have a `static constexpr uint16_t PRODUCT_ID = 0x1111`
|
||||
// and also a public constructor `T(const FoundDevice& dev)`
|
||||
// Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these
|
||||
if(dev.productId == T::PRODUCT_ID)
|
||||
into.push_back(std::make_shared<T>(dev));
|
||||
}
|
||||
|
||||
std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
static std::vector<FoundDevice> driverFoundDevices;
|
||||
driverFoundDevices.clear();
|
||||
|
||||
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
||||
PCAP::Find(driverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_CDCACM
|
||||
CDCACM::Find(driverFoundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef ICSNEO_ENABLE_FTDI
|
||||
FTDI::Find(driverFoundDevices);
|
||||
#endif
|
||||
|
||||
std::vector<std::shared_ptr<Device>> foundDevices;
|
||||
std::vector<std::vector<std::shared_ptr<Device>>> findResults;
|
||||
|
||||
#if defined(LIBICSNEO_HAVE_PCAP) && LIBICSNEO_HAVE_PCAP == 1
|
||||
auto pcapDevices = PCAP::FindAll();
|
||||
#endif
|
||||
// Offer found devices to each of the subclasses
|
||||
for (const FoundDevice& dev : driverFoundDevices) {
|
||||
#ifdef __ETHERBADGE_H_
|
||||
makeIfSerialMatches<EtherBADGE>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __ETHERBADGE_H_
|
||||
findResults.push_back(EtherBADGE::Find());
|
||||
#endif
|
||||
#ifdef __NEOOBD2PRO_H_
|
||||
makeIfSerialMatches<NeoOBD2PRO>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2PRO_H_
|
||||
findResults.push_back(NeoOBD2PRO::Find());
|
||||
#endif
|
||||
#ifdef __NEOOBD2SIM_H_
|
||||
makeIfSerialMatches<NeoOBD2SIM>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2SIM_H_
|
||||
findResults.push_back(NeoOBD2SIM::Find());
|
||||
#endif
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
makeIfPIDMatches<NeoVIFIRE>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
findResults.push_back(NeoVIFIRE::Find());
|
||||
#endif
|
||||
#ifdef __NEOVIFIRE2_H_
|
||||
makeIfSerialMatches<NeoVIFIRE2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2ETH_H_
|
||||
findResults.push_back(NeoVIFIRE2ETH::Find(pcapDevices));
|
||||
#endif
|
||||
#ifdef __NEOVIRED2_H_
|
||||
makeIfSerialMatches<NeoVIRED2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2USB_H_
|
||||
findResults.push_back(NeoVIFIRE2USB::Find());
|
||||
#endif
|
||||
#ifdef __NEOVIION_H_
|
||||
makeIfPIDMatches<NeoVIION>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIRED2_H_
|
||||
findResults.push_back(NeoVIRED2::Find(pcapDevices));
|
||||
#endif
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
makeIfPIDMatches<NeoVIPLASMA>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
findResults.push_back(NeoVIION::Find());
|
||||
#endif
|
||||
#ifdef __RADEPSILON_H_
|
||||
makeIfSerialMatches<RADEpsilon>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
findResults.push_back(NeoVIPLASMA::Find());
|
||||
#endif
|
||||
#ifdef __RADGALAXY_H_
|
||||
makeIfSerialMatches<RADGalaxy>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
findResults.push_back(RADEpsilon::Find());
|
||||
#endif
|
||||
#ifdef __RADMARS_H_
|
||||
makeIfSerialMatches<RADMars>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
findResults.push_back(RADGalaxy::Find(pcapDevices));
|
||||
#endif
|
||||
#ifdef __RADGIGASTAR_H_
|
||||
makeIfSerialMatches<RADGigastar>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_ETH_H_
|
||||
findResults.push_back(RADMarsETH::Find(pcapDevices));
|
||||
#endif
|
||||
#ifdef __RADMOON2_H_
|
||||
makeIfSerialMatches<RADMoon2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_USB_H_
|
||||
findResults.push_back(RADMarsUSB::Find());
|
||||
#endif
|
||||
#ifdef __RADMOONDUO_H_
|
||||
makeIfSerialMatches<RADMoonDuo>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_ETH_H_
|
||||
findResults.push_back(RADGigastarETH::Find(pcapDevices));
|
||||
#endif
|
||||
#ifdef __RADPLUTO_H_
|
||||
makeIfSerialMatches<RADPluto>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_USB_H_
|
||||
findResults.push_back(RADGigastarUSB::Find());
|
||||
#endif
|
||||
#ifdef __RADSTAR2_H_
|
||||
makeIfSerialMatches<RADStar2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOON2_H_
|
||||
findResults.push_back(RADMoon2::Find());
|
||||
#endif
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
makeIfSerialMatches<RADSupermoon>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
findResults.push_back(RADMoonDuo::Find());
|
||||
#endif
|
||||
#ifdef __VALUECAN3_H_
|
||||
makeIfPIDMatches<ValueCAN3>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADPLUTOUSB_H_
|
||||
findResults.push_back(RADPlutoUSB::Find());
|
||||
#endif
|
||||
#ifdef __VALUECAN4_1_H_
|
||||
makeIfSerialMatches<ValueCAN4_1>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2ETH_H_
|
||||
findResults.push_back(RADStar2ETH::Find(pcapDevices));
|
||||
#endif
|
||||
#ifdef __VALUECAN4_2_H_
|
||||
makeIfSerialMatches<ValueCAN4_2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2USB_H_
|
||||
findResults.push_back(RADStar2USB::Find());
|
||||
#endif
|
||||
#ifdef __VALUECAN4_2EL_H_
|
||||
makeIfSerialMatches<ValueCAN4_2EL>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
findResults.push_back(RADSupermoon::Find());
|
||||
#endif
|
||||
#ifdef __VALUECAN4_4_H_
|
||||
makeIfSerialMatches<ValueCAN4_4>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
findResults.push_back(ValueCAN3::Find());
|
||||
#endif
|
||||
#ifdef __VALUECAN4INDUSTRIAL_H_
|
||||
makeIfSerialMatches<ValueCAN4Industrial>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_1_H_
|
||||
findResults.push_back(ValueCAN4_1::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2_H_
|
||||
findResults.push_back(ValueCAN4_2::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2EL_ETH_H_
|
||||
findResults.push_back(ValueCAN4_2EL_ETH::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2EL_USB_H_
|
||||
findResults.push_back(ValueCAN4_2EL_USB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_4_H_
|
||||
findResults.push_back(ValueCAN4_4::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4INDUSTRIAL_ETH_H_
|
||||
findResults.push_back(ValueCAN4IndustrialETH::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4INDUSTRIAL_USB_H_
|
||||
findResults.push_back(ValueCAN4IndustrialUSB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __VIVIDCAN_H_
|
||||
findResults.push_back(VividCAN::Find());
|
||||
#endif
|
||||
|
||||
for(auto& results : findResults) {
|
||||
if(results.size())
|
||||
foundDevices.insert(foundDevices.end(), std::make_move_iterator(results.begin()), std::make_move_iterator(results.end()));
|
||||
#ifdef __VIVIDCAN_H_
|
||||
makeIfSerialMatches<VividCAN>(dev, foundDevices);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(auto& device : foundDevices) {
|
||||
|
|
@ -270,9 +160,105 @@ std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
|||
}
|
||||
|
||||
const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
if(!supportedDevicesCached) {
|
||||
supportedDevices.erase(std::unique(supportedDevices.begin(), supportedDevices.end()), supportedDevices.end());
|
||||
supportedDevicesCached = true;
|
||||
}
|
||||
static std::vector<DeviceType> supportedDevices = {
|
||||
|
||||
#ifdef __ETHERBADGE_H_
|
||||
EtherBADGE::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2PRO_H_
|
||||
NeoOBD2PRO::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2SIM_H_
|
||||
NeoOBD2SIM::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIRED2_H_
|
||||
NeoVIRED2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
NeoVIFIRE::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2_H_
|
||||
NeoVIFIRE2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
NeoVIION::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
NeoVIPLASMA::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
RADEpsilon::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
RADGalaxy::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_H_
|
||||
RADMars::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_H_
|
||||
RADGigastar::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOON2_H_
|
||||
RADMoon2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
RADMoonDuo::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADPLUTO_H_
|
||||
RADPluto::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2_H_
|
||||
RADStar2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
RADSupermoon::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
ValueCAN3::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_1_H_
|
||||
ValueCAN4_1::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2_H_
|
||||
ValueCAN4_2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2EL_H_
|
||||
ValueCAN4_2EL::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_4_H_
|
||||
ValueCAN4_4::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4INDUSTRIAL_H_
|
||||
ValueCAN4Industrial::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VIVIDCAN_H_
|
||||
VividCAN::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
};
|
||||
|
||||
return supportedDevices;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -0,0 +1,13 @@
|
|||
#include "icsneo/device/neodevice.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include <cstring>
|
||||
|
||||
neodevice_t::neodevice_t() : device(nullptr), handle(0), type(0) {
|
||||
memset(serial, 0, sizeof(serial));
|
||||
}
|
||||
|
||||
neodevice_t::neodevice_t(const icsneo::FoundDevice& found, devicetype_t inType)
|
||||
: device(nullptr), handle(found.handle), type(inType) {
|
||||
static_assert(sizeof(found.serial) == sizeof(serial), "Serial sizes should match!");
|
||||
memcpy(serial, found.serial, sizeof(serial));
|
||||
}
|
||||
|
|
@ -26,14 +26,14 @@ namespace icsneo {
|
|||
|
||||
class Communication {
|
||||
public:
|
||||
// Note that the Packetizer is not created by the constructor,
|
||||
// and should be done once the Communication module is in place.
|
||||
Communication(
|
||||
device_eventhandler_t report,
|
||||
std::unique_ptr<Driver>&& driver,
|
||||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer,
|
||||
std::unique_ptr<Encoder>&& e,
|
||||
std::unique_ptr<Decoder>&& md) : makeConfiguredPacketizer(makeConfiguredPacketizer), encoder(std::move(e)), decoder(std::move(md)), report(report), driver(std::move(driver)) {
|
||||
packetizer = makeConfiguredPacketizer();
|
||||
}
|
||||
std::unique_ptr<Decoder>&& md) : makeConfiguredPacketizer(makeConfiguredPacketizer), encoder(std::move(e)), decoder(std::move(md)), driver(std::move(driver)), report(report) {}
|
||||
virtual ~Communication();
|
||||
|
||||
bool open();
|
||||
|
|
@ -77,10 +77,10 @@ public:
|
|||
std::unique_ptr<Packetizer> packetizer;
|
||||
std::unique_ptr<Encoder> encoder;
|
||||
std::unique_ptr<Decoder> decoder;
|
||||
std::unique_ptr<Driver> driver;
|
||||
device_eventhandler_t report;
|
||||
|
||||
protected:
|
||||
std::unique_ptr<Driver> driver;
|
||||
static int messageCallbackIDCounter;
|
||||
std::mutex messageCallbacksLock;
|
||||
std::map<int, MessageCallback> messageCallbacks;
|
||||
|
|
|
|||
|
|
@ -27,6 +27,7 @@ public:
|
|||
virtual bool read(std::vector<uint8_t>& bytes, size_t limit = 0);
|
||||
virtual bool readWait(std::vector<uint8_t>& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 0);
|
||||
virtual bool write(const std::vector<uint8_t>& bytes);
|
||||
virtual bool isEthernet() const { return false; }
|
||||
|
||||
device_eventhandler_t report;
|
||||
|
||||
|
|
|
|||
|
|
@ -61,6 +61,7 @@ public:
|
|||
|
||||
uint8_t hostMAC[6] = { 0x00, 0xFC, 0x70, 0xFF, 0xFF, 0xFF };
|
||||
uint8_t deviceMAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
bool allowInPacketsFromAnyMAC = false; // Used when discovering devices
|
||||
|
||||
private:
|
||||
bool reassembling = false;
|
||||
|
|
|
|||
|
|
@ -7,6 +7,7 @@
|
|||
#include <memory>
|
||||
#include <utility>
|
||||
#include <cstring>
|
||||
#include <cstdint>
|
||||
#include <atomic>
|
||||
#include <type_traits>
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
|
@ -16,6 +17,7 @@
|
|||
#include "icsneo/device/nullsettings.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/device/deviceversion.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include "icsneo/disk/diskreaddriver.h"
|
||||
#include "icsneo/disk/diskwritedriver.h"
|
||||
#include "icsneo/disk/nulldiskdriver.h"
|
||||
|
|
@ -32,6 +34,20 @@
|
|||
#include "icsneo/platform/optional.h"
|
||||
#include "icsneo/platform/nodiscard.h"
|
||||
|
||||
#define ICSNEO_FINDABLE_DEVICE_BASE(className, type) \
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = type; \
|
||||
className(const FoundDevice& dev) : className(neodevice_t(dev, DEVICE_TYPE), dev.makeDriver) {}
|
||||
|
||||
// Devices which are discernable by the first two characters of their serial
|
||||
#define ICSNEO_FINDABLE_DEVICE(className, type, serialStart) \
|
||||
static constexpr const char* SERIAL_START = serialStart; \
|
||||
ICSNEO_FINDABLE_DEVICE_BASE(className, type)
|
||||
|
||||
// Devices which are discernable by their USB PID
|
||||
#define ICSNEO_FINDABLE_DEVICE_BY_PID(className, type, pid) \
|
||||
static constexpr const uint16_t PRODUCT_ID = pid; \
|
||||
ICSNEO_FINDABLE_DEVICE_BASE(className, type)
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class DeviceExtension;
|
||||
|
|
@ -46,7 +62,6 @@ public:
|
|||
|
||||
uint16_t getTimestampResolution() const;
|
||||
DeviceType getType() const { return DeviceType(data.type); }
|
||||
uint16_t getProductId() const { return productId; }
|
||||
std::string getSerial() const { return data.serial; }
|
||||
uint32_t getSerialNumber() const { return Device::SerialStringToNum(getSerial()); }
|
||||
const neodevice_t& getNeoDevice() const { return data; }
|
||||
|
|
@ -308,7 +323,6 @@ public:
|
|||
std::unique_ptr<IDeviceSettings> settings;
|
||||
|
||||
protected:
|
||||
uint16_t productId = 0;
|
||||
bool online = false;
|
||||
int messagePollingCallbackID = 0;
|
||||
int internalHandlerCallbackID = 0;
|
||||
|
|
@ -323,21 +337,23 @@ protected:
|
|||
std::array<optional<double>, 2> miscAnalog;
|
||||
|
||||
// START Initialization Functions
|
||||
Device(neodevice_t neodevice = { 0 }) {
|
||||
data = neodevice;
|
||||
Device(neodevice_t neodevice) : data(neodevice) {
|
||||
data.device = this;
|
||||
}
|
||||
|
||||
template<typename Driver, typename Settings = NullSettings, typename DiskRead = Disk::NullDriver, typename DiskWrite = Disk::NullDriver>
|
||||
void initialize() {
|
||||
template<typename Settings = NullSettings, typename DiskRead = Disk::NullDriver, typename DiskWrite = Disk::NullDriver>
|
||||
void initialize(const driver_factory_t& makeDriver) {
|
||||
report = makeEventHandler();
|
||||
auto driver = makeDriver<Driver>();
|
||||
setupDriver(*driver);
|
||||
auto encoder = makeEncoder();
|
||||
setupEncoder(*encoder);
|
||||
auto decoder = makeDecoder();
|
||||
setupDecoder(*decoder);
|
||||
com = makeCommunication(std::move(driver), std::bind(&Device::makeConfiguredPacketizer, this), std::move(encoder), std::move(decoder));
|
||||
com = makeCommunication(
|
||||
makeDriver(report, getWritableNeoDevice()),
|
||||
std::bind(&Device::makeConfiguredPacketizer, this),
|
||||
std::move(encoder),
|
||||
std::move(decoder)
|
||||
);
|
||||
setupCommunication(*com);
|
||||
settings = makeSettings<Settings>(com);
|
||||
setupSettings(*settings);
|
||||
|
|
@ -354,10 +370,6 @@ protected:
|
|||
};
|
||||
}
|
||||
|
||||
template<typename Driver>
|
||||
std::unique_ptr<Driver> makeDriver() { return std::unique_ptr<Driver>(new Driver(report, getWritableNeoDevice())); }
|
||||
virtual void setupDriver(Driver&) {}
|
||||
|
||||
virtual std::unique_ptr<Packetizer> makePacketizer() { return std::unique_ptr<Packetizer>(new Packetizer(report)); }
|
||||
virtual void setupPacketizer(Packetizer&) {}
|
||||
std::unique_ptr<Packetizer> makeConfiguredPacketizer() {
|
||||
|
|
@ -377,7 +389,9 @@ protected:
|
|||
std::function<std::unique_ptr<Packetizer>()> makeConfiguredPacketizer,
|
||||
std::unique_ptr<Encoder> e,
|
||||
std::unique_ptr<Decoder> d) { return std::make_shared<Communication>(report, std::move(t), makeConfiguredPacketizer, std::move(e), std::move(d)); }
|
||||
virtual void setupCommunication(Communication&) {}
|
||||
virtual void setupCommunication(Communication& communication) {
|
||||
communication.packetizer = communication.makeConfiguredPacketizer();
|
||||
}
|
||||
|
||||
template<typename Settings>
|
||||
std::unique_ptr<IDeviceSettings> makeSettings(std::shared_ptr<Communication> com) {
|
||||
|
|
|
|||
|
|
@ -0,0 +1,21 @@
|
|||
#ifndef __FOUNDDEVICE_H_
|
||||
#define __FOUNDDEVICE_H_
|
||||
|
||||
#include "icsneo/communication/driver.h"
|
||||
#include "icsneo/device/neodevice.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
typedef std::function< std::unique_ptr<Driver>(device_eventhandler_t err, neodevice_t& forDevice) > driver_factory_t;
|
||||
|
||||
class FoundDevice {
|
||||
public:
|
||||
neodevice_handle_t handle = 0;
|
||||
char serial[7] = {};
|
||||
uint16_t productId = 0;
|
||||
driver_factory_t makeDriver;
|
||||
};
|
||||
|
||||
} // namespace icsneo
|
||||
|
||||
#endif // __FOUNDDEVICE_H_
|
||||
|
|
@ -9,6 +9,7 @@
|
|||
namespace icsneo {
|
||||
|
||||
class Device;
|
||||
class FoundDevice;
|
||||
|
||||
}
|
||||
typedef icsneo::Device* devicehandle_t;
|
||||
|
|
@ -20,7 +21,13 @@ typedef int32_t neodevice_handle_t;
|
|||
|
||||
#pragma pack(push, 1)
|
||||
|
||||
#ifdef __cplusplus
|
||||
typedef struct neodevice_t {
|
||||
neodevice_t();
|
||||
neodevice_t(const icsneo::FoundDevice& found, devicetype_t inType);
|
||||
#else
|
||||
typedef struct {
|
||||
#endif
|
||||
devicehandle_t device; // Pointer back to the C++ device object
|
||||
neodevice_handle_t handle; // Handle for use by the underlying driver
|
||||
devicetype_t type;
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#include "icsneo/device/tree/etherbadge/etherbadgesettings.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
|
@ -15,49 +14,35 @@ namespace icsneo {
|
|||
class EtherBADGE : public Device {
|
||||
public:
|
||||
// Serial numbers start with EB
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::EtherBADGE;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1107;
|
||||
static constexpr const char* SERIAL_START = "EB";
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new EtherBADGE(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x1107, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(EtherBADGE, DeviceType::EtherBADGE, "EB");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
|
||||
Network::NetID::LIN,
|
||||
|
||||
Network::NetID::OP_Ethernet1
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
EtherBADGE(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
initialize<CDCACM, EtherBADGESettings>();
|
||||
protected:
|
||||
EtherBADGE(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<EtherBADGESettings>(makeDriver);
|
||||
}
|
||||
|
||||
protected:
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportCANFD = true;
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,23 +5,14 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoOBD2PRO : public Device {
|
||||
public:
|
||||
// Serial numbers are NP****
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::OBD2_PRO;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1103;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new NeoOBD2PRO(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// Serial numbers start with NP
|
||||
// USB PID is 0x1103, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(NeoOBD2PRO, DeviceType::OBD2_PRO, "NP");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -32,19 +23,17 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
NeoOBD2PRO(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<CDCACM>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
NeoOBD2PRO(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,23 +5,14 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoOBD2SIM : public Device {
|
||||
public:
|
||||
// Serial numbers are OS****
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::OBD2_SIM;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1100;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new NeoOBD2SIM(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// Serial numbers start with OS
|
||||
// USB PID is 0x1100, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(NeoOBD2SIM, DeviceType::OBD2_SIM, "OS");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -32,19 +23,17 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
NeoOBD2SIM(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<CDCACM>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
NeoOBD2SIM(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,23 +5,14 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/device/tree/neovifire/neovifiresettings.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoVIFIRE : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::FIRE;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0701;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new NeoVIFIRE(neodevice)); // Creation of the shared_ptr
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x0701, standard driver is FTDI
|
||||
ICSNEO_FINDABLE_DEVICE_BY_PID(NeoVIFIRE, DeviceType::FIRE, 0x0701);
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -67,19 +58,17 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
NeoVIFIRE(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<FTDI, NeoVIFIRESettings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
NeoVIFIRE(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<NeoVIFIRESettings>(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,16 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2settings.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoVIFIRE2 : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::FIRE2;
|
||||
static constexpr const char* SERIAL_START = "CY";
|
||||
// Serial numbers start with CY
|
||||
// USB PID is 0x1000, standard driver is FTDI
|
||||
// Ethernet MAC allocation is 0x04, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(NeoVIFIRE2, DeviceType::FIRE2, "CY");
|
||||
|
||||
enum class SKU {
|
||||
Standard,
|
||||
|
|
@ -87,8 +88,22 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
NeoVIFIRE2(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
NeoVIFIRE2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<NeoVIFIRE2Settings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupSettings(IDeviceSettings& ssettings) override {
|
||||
if(com->driver->isEthernet()) {
|
||||
// TODO Check firmware version, old firmwares will reset Ethernet settings on settings send
|
||||
ssettings.readonly = true;
|
||||
}
|
||||
}
|
||||
|
||||
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
Device::setupPacketizer(packetizer);
|
||||
packetizer.align16bit = !com->driver->isEthernet();
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
|
|
@ -96,13 +111,13 @@ protected:
|
|||
encoder.supportCANFD = true;
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
void handleDeviceStatus(const std::shared_ptr<RawMessage>& message) override {
|
||||
if(message->data.size() < sizeof(neovifire2_status_t))
|
||||
|
|
|
|||
|
|
@ -1,71 +0,0 @@
|
|||
#ifndef __NEOVIFIRE2ETH_H_
|
||||
#define __NEOVIFIRE2ETH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
#include <memory>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoVIFIRE2ETH : public NeoVIFIRE2 {
|
||||
public:
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0004;
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<NeoVIFIRE2ETH>(new NeoVIFIRE2ETH({}));
|
||||
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->type != Message::Type::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 FIRE 2
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.push_back(std::make_shared<NeoVIFIRE2ETH>(std::move(device)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
NeoVIFIRE2ETH(neodevice_t neodevice) : NeoVIFIRE2(neodevice) {
|
||||
initialize<PCAP, NeoVIFIRE2Settings>();
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
|
||||
bool currentDriverSupportsDFU() const override { return false; }
|
||||
|
||||
protected:
|
||||
void setupSettings(IDeviceSettings& ssettings) override {
|
||||
// TODO Check firmware version, old firmwares will reset Ethernet settings on settings send
|
||||
ssettings.readonly = true;
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
NeoVIFIRE2::setupPacketizer(packetizer);
|
||||
packetizer.align16bit = false;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef __NEOVIFIRE2USB_H_
|
||||
#define __NEOVIFIRE2USB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoVIFIRE2USB : public NeoVIFIRE2 {
|
||||
public:
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1000;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new NeoVIFIRE2USB(neodevice)); // Creation of the shared_ptr
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
NeoVIFIRE2USB(neodevice_t neodevice) : NeoVIFIRE2(neodevice) {
|
||||
initialize<FTDI, NeoVIFIRE2Settings>();
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -3,7 +3,6 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
#include "icsneo/disk/extextractordiskreaddriver.h"
|
||||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
#include "icsneo/device/tree/neovired2/neovired2settings.h"
|
||||
|
|
@ -12,41 +11,9 @@ namespace icsneo {
|
|||
|
||||
class NeoVIRED2 : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RED2;
|
||||
static constexpr const char* SERIAL_START = "D2";
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x000E;
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<NeoVIRED2>(new NeoVIRED2({}));
|
||||
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->type != Message::Type::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 RED 2
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.emplace_back(new NeoVIRED2(std::move(device)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
// Serial numbers start with D2
|
||||
// Ethernet MAC allocation is 0x0E, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(NeoVIRED2, DeviceType::RED2, "D2");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -68,10 +35,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
NeoVIRED2(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<PCAP, NeoVIRED2Settings, Disk::ExtExtractorDiskReadDriver, Disk::NeoMemoryDiskDriver>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
NeoVIRED2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<NeoVIRED2Settings, Disk::ExtExtractorDiskReadDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
|
|
@ -84,13 +49,13 @@ protected:
|
|||
packetizer.align16bit = false;
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "icsneo/device/tree/plasion/plasion.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/disk/plasiondiskreaddriver.h"
|
||||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
|
||||
|
|
@ -13,22 +12,12 @@ namespace icsneo {
|
|||
|
||||
class NeoVIION : public Plasion {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::ION;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0901;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new NeoVIION(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x0901, standard driver is FTDI
|
||||
ICSNEO_FINDABLE_DEVICE_BY_PID(NeoVIION, DeviceType::ION, 0x0901);
|
||||
|
||||
private:
|
||||
NeoVIION(neodevice_t neodevice) : Plasion(neodevice) {
|
||||
initialize<FTDI, NullSettings, Disk::PlasionDiskReadDriver, Disk::NeoMemoryDiskDriver>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
NeoVIION(neodevice_t neodevice, const driver_factory_t& makeDriver) : Plasion(neodevice) {
|
||||
initialize<NullSettings, Disk::PlasionDiskReadDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<Communication> makeCommunication(
|
||||
|
|
|
|||
|
|
@ -5,28 +5,17 @@
|
|||
|
||||
#include "icsneo/device/tree/plasion/plasion.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class NeoVIPLASMA : public Plasion {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::PLASMA;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0801;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new NeoVIPLASMA(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x0801, standard driver is FTDI
|
||||
ICSNEO_FINDABLE_DEVICE_BY_PID(NeoVIPLASMA, DeviceType::PLASMA, 0x0801);
|
||||
|
||||
private:
|
||||
NeoVIPLASMA(neodevice_t neodevice) : Plasion(neodevice) {
|
||||
initialize<FTDI>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
NeoVIPLASMA(neodevice_t neodevice, const driver_factory_t& makeDriver) : Plasion(neodevice) {
|
||||
initialize<NullSettings, Disk::PlasionDiskReadDriver, Disk::NeoMemoryDiskDriver>(makeDriver);
|
||||
}
|
||||
|
||||
virtual std::shared_ptr<Communication> makeCommunication(
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/multichannelcommunication.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/device/extensions/flexray/extension.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
|
@ -45,6 +44,8 @@ public:
|
|||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
protected:
|
||||
using Device::Device;
|
||||
|
||||
// TODO This is done so that Plasion can still transmit it's basic networks, awaiting slave VNET support
|
||||
virtual bool isSupportedRXNetwork(const Network&) const override { return true; }
|
||||
virtual bool isSupportedTXNetwork(const Network&) const override { return true; }
|
||||
|
|
@ -55,7 +56,7 @@ protected:
|
|||
addExtension(std::make_shared<FlexRay::Extension>(*this, flexRayControllers));
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
for(auto& netid : GetSupportedNetworks())
|
||||
rxNetworks.emplace_back(netid);
|
||||
// TODO Check configuration for FlexRay ColdStart mode, disable FlexRay 2 if so
|
||||
|
|
@ -87,9 +88,6 @@ protected:
|
|||
const fire2vnet_status_t* status = reinterpret_cast<const fire2vnet_status_t*>(message->data.data());
|
||||
ethActivationStatus = status->ethernetActivationLineEnabled;
|
||||
}
|
||||
|
||||
public:
|
||||
Plasion(neodevice_t neodevice) : Device(neodevice) {}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3,23 +3,14 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADEpsilon : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADEpsilon;
|
||||
static constexpr const char* SERIAL_START = "RE";
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1109;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADEpsilon(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// Serial numbers start with RE
|
||||
// USB PID is 0x1109, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(RADEpsilon, DeviceType::RADEpsilon, "RE");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -34,10 +25,8 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
RADEpsilon(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<CDCACM>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
RADEpsilon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
|
|
@ -45,13 +34,13 @@ protected:
|
|||
encoder.supportCANFD = true;
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,7 +5,6 @@
|
|||
|
||||
#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"
|
||||
#include "icsneo/device/tree/radgalaxy/radgalaxysettings.h"
|
||||
|
|
@ -15,41 +14,8 @@ namespace icsneo {
|
|||
class RADGalaxy : public Device {
|
||||
public:
|
||||
// Serial numbers start with RG
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADGalaxy;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0003;
|
||||
static constexpr const char* SERIAL_START = "RG";
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<RADGalaxy>(new RADGalaxy({}));
|
||||
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->type != Message::Type::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 RADGalaxy
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.emplace_back(new RADGalaxy(std::move(device)));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
// Ethernet MAC allocation is 0x03, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(RADGalaxy, DeviceType::RADGalaxy, "RG");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -85,15 +51,13 @@ public:
|
|||
return supportedNetworks;
|
||||
}
|
||||
|
||||
RADGalaxy(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<PCAP, RADGalaxySettings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
protected:
|
||||
RADGalaxy(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADGalaxySettings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
Device::setupPacketizer(packetizer);
|
||||
packetizer.disableChecksum = true;
|
||||
|
|
|
|||
|
|
@ -11,16 +11,18 @@ namespace icsneo {
|
|||
|
||||
class RADGigastar : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADGigastar;
|
||||
static constexpr const char* SERIAL_START = "GS";
|
||||
// Serial numbers start with GS
|
||||
// USB PID is 0x1204, standard driver is FTDI3
|
||||
// Ethernet MAC allocation is 0x0F, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(RADGigastar, DeviceType::RADGigastar, "GS");
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADGigastar(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
RADGigastar(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADGigastarSettings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef __RADGIGASTAR_ETH_H_
|
||||
#define __RADGIGASTAR_ETH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radgigastar/radgigastar.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADGigastarETH : public RADGigastar {
|
||||
public:
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x000F;
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<RADGigastarETH>(new RADGigastarETH({}));
|
||||
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->type != Message::Type::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 RADGigastar
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.push_back(std::shared_ptr<RADGigastarETH>(new RADGigastarETH(std::move(device))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
RADGigastarETH(neodevice_t neodevice) : RADGigastar(neodevice) {
|
||||
initialize<PCAP, RADGigastarSettings>();
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef __RADGIGASTAR_USB_H_
|
||||
#define __RADGIGASTAR_USB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radgigastar/radgigastar.h"
|
||||
#include "icsneo/platform/ftdi3.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADGigastarUSB : public RADGigastar {
|
||||
public:
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1204;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI3::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADGigastarUSB(neodevice)); // Creation of the shared_ptr
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
RADGigastarUSB(neodevice_t neodevice) : RADGigastar(neodevice) {
|
||||
initialize<FTDI3, RADGigastarSettings>();
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -11,14 +11,16 @@ namespace icsneo {
|
|||
|
||||
class RADMars : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADMars;
|
||||
static constexpr const char* SERIAL_START = "GL";
|
||||
// Serial numbers start with GL (previously, RAD-Gigalog)
|
||||
// USB PID is 0x1203, standard driver is FTDI3
|
||||
// Ethernet MAC allocation is 0x0A, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(RADMars, DeviceType::RADMars, "GL");
|
||||
|
||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||
|
||||
protected:
|
||||
RADMars(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
RADMars(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADMarsSettings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef __RADMARS_ETH_H_
|
||||
#define __RADMARS_ETH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radmars/radmars.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADMarsETH : public RADMars {
|
||||
public:
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x000A;
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<RADMarsETH>(new RADMarsETH({}));
|
||||
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->type != Message::Type::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 RAD-Mars
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.push_back(std::shared_ptr<RADMarsETH>(new RADMarsETH(std::move(device))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
RADMarsETH(neodevice_t neodevice) : RADMars(neodevice) {
|
||||
initialize<PCAP, RADMarsSettings>();
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
#ifndef __RADMARS_USB_H_
|
||||
#define __RADMARS_USB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radmars/radmars.h"
|
||||
#include "icsneo/platform/ftdi3.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADMarsUSB : public RADMars {
|
||||
public:
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1203;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI3::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADMarsUSB(neodevice)); // Creation of the shared_ptr
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
RADMarsUSB(neodevice_t neodevice) : RADMars(neodevice) {
|
||||
initialize<FTDI3, RADMarsSettings>();
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -6,15 +6,14 @@
|
|||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/device/tree/radmoon2/radmoon2settings.h"
|
||||
#include "icsneo/platform/ftdi3.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADMoon2 : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADMoon2;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1202;
|
||||
static constexpr const char* SERIAL_START = "RM";
|
||||
// Serial numbers start with RM
|
||||
// USB PID is 0x1202, standard driver is FTDI3
|
||||
ICSNEO_FINDABLE_DEVICE(RADMoon2, DeviceType::RADMoon2, "RM");
|
||||
|
||||
enum class SKU {
|
||||
Standard,
|
||||
|
|
@ -22,15 +21,6 @@ public:
|
|||
APM1000E_CLK, // Clock Option and Keysight Branding
|
||||
};
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI3::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADMoon2(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
SKU getSKU() const {
|
||||
switch(getSerial().back()) {
|
||||
case 'A':
|
||||
|
|
@ -70,10 +60,8 @@ public:
|
|||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADMoon2(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<FTDI3, RADMoon2Settings>();
|
||||
productId = PRODUCT_ID;
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADMoon2Settings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
|
|
|
|||
|
|
@ -6,24 +6,14 @@
|
|||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/device/tree/radmoonduo/radmoonduosettings.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADMoonDuo : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADMoonDuo;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1106;
|
||||
static constexpr const char* SERIAL_START = "MD";
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADMoonDuo(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// Serial numbers start with MD
|
||||
// USB PID is 1106, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(RADMoonDuo, DeviceType::RADMoonDuo, "MD");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
// If Converter1 Target is set to USB/CM, OP_Ethernet2 will be exposed to the PC
|
||||
|
|
@ -36,10 +26,8 @@ public:
|
|||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADMoonDuo(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<CDCACM, RADMoonDuoSettings>();
|
||||
productId = PRODUCT_ID;
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
RADMoonDuo(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADMoonDuoSettings>(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
|
|
|
|||
|
|
@ -5,8 +5,6 @@
|
|||
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
#include "icsneo/device/tree/radpluto/radplutosettings.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
|
@ -14,9 +12,8 @@ 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";
|
||||
// USB PID is 1104, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(RADPluto, DeviceType::RADPluto, "PL");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -35,27 +32,26 @@ public:
|
|||
return supportedNetworks;
|
||||
}
|
||||
|
||||
RADPluto(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
|
||||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADPluto(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADPlutoSettings>(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportCANFD = true;
|
||||
encoder.supportEthPhy = true;
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef __RADPLUTOUSB_H_
|
||||
#define __RADPLUTOUSB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radpluto/radpluto.h"
|
||||
#include "icsneo/platform/cdcacm.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 : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADPlutoUSB(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
RADPlutoUSB(neodevice_t neodevice) : RADPluto(neodevice) {
|
||||
initialize<CDCACM, RADPlutoSettings>();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -12,9 +12,9 @@ namespace icsneo {
|
|||
class RADStar2 : public Device {
|
||||
public:
|
||||
// Serial numbers start with RS
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADStar2;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0005;
|
||||
static constexpr const char* SERIAL_START = "RS";
|
||||
// USB PID is 0x0005, standard driver is FTDI
|
||||
// Ethernet MAC allocation is 0x05, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(RADStar2, DeviceType::RADStar2, "RS");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -30,6 +30,10 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
RADStar2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADStar2Settings>(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupPacketizer(Packetizer& packetizer) override {
|
||||
Device::setupPacketizer(packetizer);
|
||||
packetizer.disableChecksum = true;
|
||||
|
|
@ -46,18 +50,13 @@ protected:
|
|||
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())
|
||||
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); }
|
||||
|
||||
RADStar2(neodevice_t neodevice) : Device(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
}
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,58 +0,0 @@
|
|||
#ifndef __RADSTAR2ETH_H_
|
||||
#define __RADSTAR2ETH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radstar2/radstar2.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
#include "icsneo/communication/message/serialnumbermessage.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADStar2ETH : public RADStar2 {
|
||||
public:
|
||||
// Serial numbers start with RS
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<RADStar2ETH>(new RADStar2ETH({}));
|
||||
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->type != Message::Type::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 RADStar2
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.push_back(std::make_shared<RADStar2ETH>(device));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
RADStar2ETH(neodevice_t neodevice) : RADStar2(neodevice) {
|
||||
initialize<PCAP, RADStar2Settings>();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -1,33 +0,0 @@
|
|||
#ifndef __RADSTAR2USB_H_
|
||||
#define __RADSTAR2USB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/radstar2/radstar2.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADStar2USB : public RADStar2 {
|
||||
public:
|
||||
// Serial numbers start with RS
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADStar2USB(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
RADStar2USB(neodevice_t neodevice) : RADStar2(neodevice) {
|
||||
initialize<FTDI, RADStar2Settings>();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -6,30 +6,20 @@
|
|||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/device/tree/radsupermoon/radsupermoonsettings.h"
|
||||
#include "icsneo/platform/ftdi3.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class RADSupermoon : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::RADSupermoon;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1201;
|
||||
static constexpr const char* SERIAL_START = "SM";
|
||||
// Serial numbers start with SM
|
||||
// USB PID is 0x1201, standard driver is FTDI3
|
||||
ICSNEO_FINDABLE_DEVICE(RADSupermoon, DeviceType::RADSupermoon, "SM");
|
||||
|
||||
enum class SKU {
|
||||
Standard,
|
||||
APM1000ET, // Keysight Branding
|
||||
};
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI3::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new RADSupermoon(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::Ethernet,
|
||||
|
|
@ -60,10 +50,8 @@ public:
|
|||
bool getEthPhyRegControlSupported() const override { return true; }
|
||||
|
||||
protected:
|
||||
RADSupermoon(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<FTDI3, RADSupermoonSettings>();
|
||||
productId = PRODUCT_ID;
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
RADSupermoon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<RADSupermoonSettings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
|
|
|
|||
|
|
@ -12,16 +12,8 @@ namespace icsneo {
|
|||
|
||||
class ValueCAN3 : public Device {
|
||||
public:
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN3;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x0601;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : FTDI::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new ValueCAN3(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x0601, standard driver is FTDI
|
||||
ICSNEO_FINDABLE_DEVICE_BY_PID(ValueCAN3, DeviceType::VCAN3, 0x0701);
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -32,19 +24,17 @@ public:
|
|||
}
|
||||
|
||||
private:
|
||||
ValueCAN3(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<FTDI, ValueCAN3Settings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<ValueCAN3Settings>(makeDriver);
|
||||
}
|
||||
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
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); }
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
|
|
|||
|
|
@ -5,27 +5,14 @@
|
|||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-1settings.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4_1 : public ValueCAN4 {
|
||||
public:
|
||||
// Serial numbers start with V1 for 4-1
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN4_1;
|
||||
static constexpr const char* SERIAL_START = "V1";
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(USB_PRODUCT_ID)) {
|
||||
if(std::string(neodevice.serial).substr(0, 2) == SERIAL_START)
|
||||
found.emplace_back(new ValueCAN4_1(neodevice));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_1, DeviceType::VCAN4_1, "V1");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
|
|
@ -35,25 +22,22 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
ValueCAN4_1(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||
initialize<ValueCAN4_1Settings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupEncoder(Encoder& encoder) override {
|
||||
ValueCAN4::setupEncoder(encoder);
|
||||
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())
|
||||
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); }
|
||||
|
||||
private:
|
||||
ValueCAN4_1(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||
initialize<CDCACM, ValueCAN4_1Settings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = USB_PRODUCT_ID;
|
||||
}
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,33 +5,20 @@
|
|||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2settings.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4_2 : public ValueCAN4 {
|
||||
public:
|
||||
// Serial numbers start with V2 for 4-2
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN4_2;
|
||||
static constexpr const char* SERIAL_START = "V2";
|
||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_2, DeviceType::VCAN4_2, "V2");
|
||||
|
||||
enum class SKU {
|
||||
Standard,
|
||||
AP0200A, // USB A and Keysight Branding
|
||||
};
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(USB_PRODUCT_ID)) {
|
||||
if(std::string(neodevice.serial).substr(0, 2) == SERIAL_START)
|
||||
found.emplace_back(new ValueCAN4_2(neodevice));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
|
|
@ -60,20 +47,17 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
ValueCAN4_2(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||
initialize<ValueCAN4_2Settings>(makeDriver);
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
private:
|
||||
ValueCAN4_2(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||
initialize<CDCACM, ValueCAN4_2Settings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = USB_PRODUCT_ID;
|
||||
}
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,15 +5,15 @@
|
|||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2elsettings.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4_2EL : public ValueCAN4 {
|
||||
public:
|
||||
// Serial numbers start with VE for 4-2EL
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN4_2EL;
|
||||
static constexpr const char* SERIAL_START = "VE";
|
||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||
// Ethernet MAC allocation is 0x0B, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_2EL, DeviceType::VCAN4_2EL, "VE");
|
||||
|
||||
enum class SKU {
|
||||
Standard,
|
||||
|
|
@ -53,14 +53,16 @@ public:
|
|||
Network::NetID::HSCAN,
|
||||
Network::NetID::HSCAN2,
|
||||
|
||||
Network::NetID::Ethernet
|
||||
Network::NetID::Ethernet,
|
||||
|
||||
Network::NetID::LIN
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
protected:
|
||||
ValueCAN4_2EL(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
ValueCAN4_2EL(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||
initialize<ValueCAN4_2ELSettings>(makeDriver);
|
||||
}
|
||||
|
||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
|
|
@ -80,6 +82,13 @@ protected:
|
|||
const valuecan4_2el_status_t* status = reinterpret_cast<const valuecan4_2el_status_t*>(message->data.data());
|
||||
ethActivationStatus = status->ethernetActivationLineEnabled;
|
||||
}
|
||||
|
||||
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
ValueCAN4::setupPacketizer(packetizer);
|
||||
packetizer.align16bit = !com->driver->isEthernet();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,68 +0,0 @@
|
|||
#ifndef __VALUECAN4_2EL_ETH_H_
|
||||
#define __VALUECAN4_2EL_ETH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2el.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4_2EL_ETH : public ValueCAN4_2EL {
|
||||
public:
|
||||
static constexpr const uint16_t ETH_PRODUCT_ID = 0x000B;
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<ValueCAN4_2EL_ETH>(new ValueCAN4_2EL_ETH({}));
|
||||
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->type != Message::Type::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 ValueCAN4-2EL
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.push_back(std::shared_ptr<ValueCAN4_2EL_ETH>(new ValueCAN4_2EL_ETH(std::move(device))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
bool currentDriverSupportsDFU() const override { return false; }
|
||||
|
||||
protected:
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
ValueCAN4_2EL::setupPacketizer(packetizer);
|
||||
packetizer.align16bit = false;
|
||||
}
|
||||
|
||||
private:
|
||||
ValueCAN4_2EL_ETH(neodevice_t neodevice) : ValueCAN4_2EL(neodevice) {
|
||||
initialize<PCAP, ValueCAN4_2ELSettings>();
|
||||
productId = ETH_PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -1,36 +0,0 @@
|
|||
#ifndef __VALUECAN4_2EL_USB_H_
|
||||
#define __VALUECAN4_2EL_USB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2el.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4_2EL_USB : public ValueCAN4_2EL {
|
||||
public:
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(USB_PRODUCT_ID)) {
|
||||
if(std::string(neodevice.serial).substr(0, 2) == SERIAL_START)
|
||||
found.emplace_back(new ValueCAN4_2EL_USB(neodevice));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
private:
|
||||
ValueCAN4_2EL_USB(neodevice_t neodevice) : ValueCAN4_2EL(neodevice) {
|
||||
initialize<CDCACM, ValueCAN4_2ELSettings>();
|
||||
productId = USB_PRODUCT_ID;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -5,16 +5,14 @@
|
|||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-4settings.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4_4 : public ValueCAN4 {
|
||||
public:
|
||||
// Serial numbers start with V4 for 4-4
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN4_4;
|
||||
static constexpr const char* SERIAL_START = "V4";
|
||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_4, DeviceType::VCAN4_4, "V4");
|
||||
|
||||
enum class SKU {
|
||||
Standard,
|
||||
|
|
@ -23,17 +21,6 @@ public:
|
|||
AP0400A_OBD, // OBD, USB A, and Keysight Branding
|
||||
};
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(USB_PRODUCT_ID)) {
|
||||
if(std::string(neodevice.serial).substr(0, 2) == SERIAL_START)
|
||||
found.emplace_back(new ValueCAN4_4(neodevice));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
|
|
@ -71,20 +58,17 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
virtual void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||
ValueCAN4_4(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||
initialize<ValueCAN4_4Settings>(makeDriver);
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
private:
|
||||
ValueCAN4_4(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||
initialize<CDCACM, ValueCAN4_4Settings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = USB_PRODUCT_ID;
|
||||
}
|
||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,17 +10,16 @@ namespace icsneo {
|
|||
|
||||
class ValueCAN4 : public Device {
|
||||
public:
|
||||
// All ValueCAN 4 devices share a USB PID
|
||||
static constexpr const uint16_t USB_PRODUCT_ID = 0x1101;
|
||||
// All ValueCAN 4 devices share a USB PID of 0x1101
|
||||
|
||||
protected:
|
||||
using Device::Device;
|
||||
|
||||
virtual void setupEncoder(Encoder& encoder) override {
|
||||
Device::setupEncoder(encoder);
|
||||
encoder.supportCANFD = true;
|
||||
}
|
||||
|
||||
ValueCAN4(neodevice_t neodevice) : Device(neodevice) {}
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -11,12 +11,40 @@ namespace icsneo {
|
|||
class ValueCAN4Industrial : public ValueCAN4 {
|
||||
public:
|
||||
// Serial numbers start with IV for Industrial
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VCAN4_IND;
|
||||
static constexpr const char* SERIAL_START = "IV";
|
||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||
// Ethernet MAC allocation is 0x12, standard driver is Raw
|
||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4Industrial, DeviceType::VCAN4_IND, "IV");
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
Network::NetID::HSCAN2,
|
||||
|
||||
Network::NetID::Ethernet,
|
||||
|
||||
Network::NetID::LIN
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
protected:
|
||||
ValueCAN4Industrial(neodevice_t neodevice) : ValueCAN4(neodevice) {
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||
initialize<ValueCAN4IndustrialSettings>(makeDriver);
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
||||
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
ValueCAN4::setupPacketizer(packetizer);
|
||||
packetizer.align16bit = !com->driver->isEthernet();
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
|||
|
|
@ -1,85 +0,0 @@
|
|||
#ifndef __VALUECAN4INDUSTRIAL_ETH_H_
|
||||
#define __VALUECAN4INDUSTRIAL_ETH_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrial.h"
|
||||
#include "icsneo/platform/pcap.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4IndustrialETH : public ValueCAN4Industrial {
|
||||
public:
|
||||
static constexpr const uint16_t ETH_PRODUCT_ID = 0x0012;
|
||||
|
||||
static std::vector<std::shared_ptr<Device>> Find(const std::vector<PCAP::PCAPFoundDevice>& pcapDevices) {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto& foundDev : pcapDevices) {
|
||||
auto fakedev = std::shared_ptr<ValueCAN4IndustrialETH>(new ValueCAN4IndustrialETH({}));
|
||||
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->type != Message::Type::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 ValueCAN 4 Industrial
|
||||
|
||||
auto device = foundDev.device;
|
||||
device.serial[sn->deviceSerial.copy(device.serial, sizeof(device.serial))] = '\0';
|
||||
found.push_back(std::shared_ptr<ValueCAN4IndustrialETH>(new ValueCAN4IndustrialETH(std::move(device))));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
Network::NetID::HSCAN2,
|
||||
|
||||
// No Network::NetID::Ethernet, since we're communicating over it instead
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
bool currentDriverSupportsDFU() const override { return false; }
|
||||
|
||||
protected:
|
||||
void setupPacketizer(Packetizer& packetizer) override {
|
||||
ValueCAN4Industrial::setupPacketizer(packetizer);
|
||||
packetizer.align16bit = false;
|
||||
}
|
||||
|
||||
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); }
|
||||
|
||||
private:
|
||||
ValueCAN4IndustrialETH(neodevice_t neodevice) : ValueCAN4Industrial(neodevice) {
|
||||
initialize<PCAP, ValueCAN4IndustrialSettings>();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -1,54 +0,0 @@
|
|||
#ifndef __VALUECAN4INDUSTRIAL_USB_H_
|
||||
#define __VALUECAN4INDUSTRIAL_USB_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrial.h"
|
||||
#include "icsneo/platform/cdcacm.h"
|
||||
#include <string>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class ValueCAN4IndustrialUSB : public ValueCAN4Industrial {
|
||||
public:
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(USB_PRODUCT_ID)) {
|
||||
if(std::string(neodevice.serial).substr(0, 2) == SERIAL_START)
|
||||
found.emplace_back(new ValueCAN4IndustrialUSB(neodevice));
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
static const std::vector<Network>& GetSupportedNetworks() {
|
||||
static std::vector<Network> supportedNetworks = {
|
||||
Network::NetID::HSCAN,
|
||||
Network::NetID::HSCAN2,
|
||||
|
||||
Network::NetID::Ethernet
|
||||
};
|
||||
return supportedNetworks;
|
||||
}
|
||||
|
||||
protected:
|
||||
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); }
|
||||
|
||||
private:
|
||||
ValueCAN4IndustrialUSB(neodevice_t neodevice) : ValueCAN4Industrial(neodevice) {
|
||||
initialize<CDCACM, ValueCAN4IndustrialSettings>();
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -13,16 +13,8 @@ namespace icsneo {
|
|||
class VividCAN : public Device {
|
||||
public:
|
||||
// Serial numbers start with VV
|
||||
static constexpr DeviceType::Enum DEVICE_TYPE = DeviceType::VividCAN;
|
||||
static constexpr const uint16_t PRODUCT_ID = 0x1102;
|
||||
static std::vector<std::shared_ptr<Device>> Find() {
|
||||
std::vector<std::shared_ptr<Device>> found;
|
||||
|
||||
for(auto neodevice : CDCACM::FindByProduct(PRODUCT_ID))
|
||||
found.emplace_back(new VividCAN(neodevice));
|
||||
|
||||
return found;
|
||||
}
|
||||
// USB PID is 0x1102, standard driver is CDCACM
|
||||
ICSNEO_FINDABLE_DEVICE(VividCAN, DeviceType::VividCAN, "VV");
|
||||
|
||||
// VividCAN does not go online, you can only set settings
|
||||
bool goOnline() override {
|
||||
|
|
@ -36,14 +28,11 @@ public:
|
|||
}
|
||||
|
||||
protected:
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
|
||||
private:
|
||||
VividCAN(neodevice_t neodevice) : Device(neodevice) {
|
||||
initialize<CDCACM, VividCANSettings>();
|
||||
getWritableNeoDevice().type = DEVICE_TYPE;
|
||||
productId = PRODUCT_ID;
|
||||
VividCAN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||
initialize<VividCANSettings>(makeDriver);
|
||||
}
|
||||
|
||||
bool requiresVehiclePower() const override { return false; }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,14 +1,12 @@
|
|||
#ifndef __PCAP_H_
|
||||
#define __PCAP_H_
|
||||
|
||||
#if defined _WIN32
|
||||
#ifdef _WIN32
|
||||
#include "icsneo/platform/windows/pcap.h"
|
||||
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||
#elif defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))
|
||||
#include "icsneo/platform/posix/pcap.h"
|
||||
#else
|
||||
#warning "This platform is not supported by the PCAP driver"
|
||||
#endif
|
||||
|
||||
#define LIBICSNEO_HAVE_PCAP 1
|
||||
|
||||
#endif
|
||||
|
|
@ -27,7 +27,7 @@ public:
|
|||
*/
|
||||
CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {}
|
||||
~CDCACM();
|
||||
static std::vector<neodevice_t> FindByProduct(int product);
|
||||
static void Find(std::vector<FoundDevice>& found);
|
||||
|
||||
bool open() override;
|
||||
bool isOpen() override;
|
||||
|
|
|
|||
|
|
@ -5,31 +5,25 @@
|
|||
#include "icsneo/device/tree/neoobd2pro/neoobd2pro.h"
|
||||
#include "icsneo/device/tree/neoobd2sim/neoobd2sim.h"
|
||||
#include "icsneo/device/tree/neovifire/neovifire.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2eth.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2usb.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2.h"
|
||||
#include "icsneo/device/tree/neovired2/neovired2.h"
|
||||
#include "icsneo/device/tree/plasion/neoviion.h"
|
||||
#include "icsneo/device/tree/plasion/neoviplasma.h"
|
||||
#include "icsneo/device/tree/radepsilon/radepsilon.h"
|
||||
#include "icsneo/device/tree/radgalaxy/radgalaxy.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastareth.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastarusb.h"
|
||||
#include "icsneo/device/tree/radmars/radmarseth.h"
|
||||
#include "icsneo/device/tree/radmars/radmarsusb.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastar.h"
|
||||
#include "icsneo/device/tree/radmars/radmars.h"
|
||||
#include "icsneo/device/tree/radmoon2/radmoon2.h"
|
||||
#include "icsneo/device/tree/radmoonduo/radmoonduo.h"
|
||||
#include "icsneo/device/tree/radpluto/radplutousb.h"
|
||||
#include "icsneo/device/tree/radstar2/radstar2eth.h"
|
||||
#include "icsneo/device/tree/radstar2/radstar2usb.h"
|
||||
#include "icsneo/device/tree/radpluto/radpluto.h"
|
||||
#include "icsneo/device/tree/radstar2/radstar2.h"
|
||||
#include "icsneo/device/tree/radsupermoon/radsupermoon.h"
|
||||
#include "icsneo/device/tree/valuecan3/valuecan3.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-1.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2eleth.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2elusb.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2el.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-4.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrialeth.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrialusb.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrial.h"
|
||||
#include "icsneo/device/tree/vividcan/vividcan.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -16,7 +16,7 @@ namespace icsneo {
|
|||
|
||||
class FTDI : public Driver {
|
||||
public:
|
||||
static std::vector<neodevice_t> FindByProduct(int product);
|
||||
static void Find(std::vector<FoundDevice>& found);
|
||||
|
||||
FTDI(const device_eventhandler_t& err, neodevice_t& forDevice);
|
||||
~FTDI() { if(isOpen()) close(); }
|
||||
|
|
@ -34,7 +34,9 @@ private:
|
|||
context = nullptr;
|
||||
}
|
||||
|
||||
std::pair<int, std::vector<std::string>> findDevices(int pid);
|
||||
// A PID of 0 disables filtering by PID
|
||||
std::pair<int, std::vector< std::pair<std::string, uint16_t> > > findDevices(int pid = 0);
|
||||
|
||||
int openDevice(int pid, const char* serial);
|
||||
bool closeDevice();
|
||||
bool isOpen() const { return deviceOpen; }
|
||||
|
|
@ -52,7 +54,7 @@ private:
|
|||
};
|
||||
FTDIContext ftdi;
|
||||
|
||||
static std::vector<std::tuple<int, std::string>> handles;
|
||||
static std::vector<std::string> handles;
|
||||
|
||||
static bool ErrorIsDisconnection(int errorCode);
|
||||
void readTask();
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@
|
|||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/device/neodevice.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include "icsneo/communication/driver.h"
|
||||
#include "icsneo/communication/ethernetpacketizer.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
|
|
@ -14,33 +15,28 @@ namespace icsneo {
|
|||
|
||||
class PCAP : public Driver {
|
||||
public:
|
||||
class PCAPFoundDevice {
|
||||
public:
|
||||
neodevice_t device;
|
||||
std::vector<std::vector<uint8_t>> discoveryPackets;
|
||||
};
|
||||
|
||||
static std::vector<PCAPFoundDevice> FindAll();
|
||||
static void Find(std::vector<FoundDevice>& foundDevices);
|
||||
static std::string GetEthDevSerialFromMacAddress(uint8_t product, uint16_t macSerial);
|
||||
static bool IsHandleValid(neodevice_handle_t handle);
|
||||
|
||||
PCAP(device_eventhandler_t err, neodevice_t& forDevice);
|
||||
bool open();
|
||||
bool isOpen();
|
||||
bool close();
|
||||
bool open() override;
|
||||
bool isOpen() override;
|
||||
bool close() override;
|
||||
bool isEthernet() const override { return true; }
|
||||
private:
|
||||
char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
|
||||
neodevice_t& device;
|
||||
uint8_t deviceMAC[6];
|
||||
bool openable = true;
|
||||
EthernetPacketizer ethPacketizer;
|
||||
void readTask();
|
||||
void writeTask();
|
||||
void readTask() override;
|
||||
void writeTask() override;
|
||||
|
||||
class NetworkInterface {
|
||||
public:
|
||||
uint8_t uuid;
|
||||
uint8_t macAddress[8];
|
||||
uint8_t macAddress[6];
|
||||
std::string nameFromPCAP;
|
||||
std::string descriptionFromPCAP;
|
||||
std::string fullName;
|
||||
|
|
|
|||
|
|
@ -10,7 +10,7 @@ namespace icsneo {
|
|||
class CDCACM : public VCP {
|
||||
public:
|
||||
CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {}
|
||||
static std::vector<neodevice_t> FindByProduct(int product) { return VCP::FindByProduct(product, { L"usbser" }); }
|
||||
static void Find(std::vector<FoundDevice>& found) { return VCP::Find(found, { L"usbser" }); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -5,31 +5,25 @@
|
|||
#include "icsneo/device/tree/neoobd2pro/neoobd2pro.h"
|
||||
#include "icsneo/device/tree/neoobd2sim/neoobd2sim.h"
|
||||
#include "icsneo/device/tree/neovifire/neovifire.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2eth.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2usb.h"
|
||||
#include "icsneo/device/tree/neovifire2/neovifire2.h"
|
||||
#include "icsneo/device/tree/neovired2/neovired2.h"
|
||||
#include "icsneo/device/tree/plasion/neoviion.h"
|
||||
#include "icsneo/device/tree/plasion/neoviplasma.h"
|
||||
#include "icsneo/device/tree/radepsilon/radepsilon.h"
|
||||
#include "icsneo/device/tree/radgalaxy/radgalaxy.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastareth.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastarusb.h"
|
||||
#include "icsneo/device/tree/radmars/radmarseth.h"
|
||||
#include "icsneo/device/tree/radmars/radmarsusb.h"
|
||||
#include "icsneo/device/tree/radgigastar/radgigastar.h"
|
||||
#include "icsneo/device/tree/radmars/radmars.h"
|
||||
#include "icsneo/device/tree/radmoon2/radmoon2.h"
|
||||
#include "icsneo/device/tree/radmoonduo/radmoonduo.h"
|
||||
#include "icsneo/device/tree/radpluto/radplutousb.h"
|
||||
#include "icsneo/device/tree/radstar2/radstar2eth.h"
|
||||
#include "icsneo/device/tree/radstar2/radstar2usb.h"
|
||||
#include "icsneo/device/tree/radpluto/radpluto.h"
|
||||
#include "icsneo/device/tree/radstar2/radstar2.h"
|
||||
#include "icsneo/device/tree/radsupermoon/radsupermoon.h"
|
||||
#include "icsneo/device/tree/valuecan3/valuecan3.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-1.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2eleth.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2elusb.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-2el.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4-4.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrialeth.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrialusb.h"
|
||||
#include "icsneo/device/tree/valuecan4/valuecan4industrial.h"
|
||||
#include "icsneo/device/tree/vividcan/vividcan.h"
|
||||
|
||||
#endif
|
||||
|
|
@ -10,7 +10,7 @@ namespace icsneo {
|
|||
class FTDI : public VCP {
|
||||
public:
|
||||
FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {}
|
||||
static std::vector<neodevice_t> FindByProduct(int product) { return VCP::FindByProduct(product, { L"serenum" /*, L"ftdibus" */ }); }
|
||||
static void Find(std::vector<FoundDevice>& found) { return VCP::Find(found, { L"serenum" /*, L"ftdibus" */ }); }
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@
|
|||
#include "icsneo/platform/windows/internal/pcapdll.h"
|
||||
#include "icsneo/device/neodevice.h"
|
||||
#include "icsneo/communication/driver.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/communication/ethernetpacketizer.h"
|
||||
#include <string>
|
||||
|
|
@ -14,20 +15,15 @@ namespace icsneo {
|
|||
|
||||
class PCAP : public Driver {
|
||||
public:
|
||||
class PCAPFoundDevice {
|
||||
public:
|
||||
neodevice_t device;
|
||||
std::vector<std::vector<uint8_t>> discoveryPackets;
|
||||
};
|
||||
|
||||
static std::vector<PCAPFoundDevice> FindAll();
|
||||
static void Find(std::vector<FoundDevice>& foundDevices);
|
||||
static std::string GetEthDevSerialFromMacAddress(uint8_t product, uint16_t macSerial);
|
||||
static bool IsHandleValid(neodevice_handle_t handle);
|
||||
|
||||
PCAP(const device_eventhandler_t& err, neodevice_t& forDevice);
|
||||
bool open();
|
||||
bool isOpen();
|
||||
bool close();
|
||||
bool open() override;
|
||||
bool isOpen() override;
|
||||
bool close() override;
|
||||
bool isEthernet() const override { return true; }
|
||||
private:
|
||||
const PCAPDLL& pcap;
|
||||
char errbuf[PCAP_ERRBUF_SIZE] = { 0 };
|
||||
|
|
@ -48,7 +44,7 @@ private:
|
|||
class NetworkInterface {
|
||||
public:
|
||||
uint8_t uuid;
|
||||
uint8_t macAddress[8];
|
||||
uint8_t macAddress[6];
|
||||
std::string nameFromWinPCAP;
|
||||
std::string nameFromWin32API;
|
||||
std::string descriptionFromWinPCAP;
|
||||
|
|
|
|||
|
|
@ -17,7 +17,7 @@ namespace icsneo {
|
|||
// Virtual COM Port Communication
|
||||
class VCP : public Driver {
|
||||
public:
|
||||
static std::vector<neodevice_t> FindByProduct(int product, std::vector<std::wstring> driverName);
|
||||
static void Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driverName);
|
||||
static bool IsHandleValid(neodevice_handle_t handle);
|
||||
typedef void(*fn_boolCallback)(bool success);
|
||||
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "icsneo/platform/cdcacm.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include <mutex>
|
||||
#include <vector>
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
|
|
@ -79,22 +80,19 @@ private:
|
|||
io_object_t toRelease;
|
||||
};
|
||||
|
||||
std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
||||
std::vector<neodevice_t> found;
|
||||
|
||||
void CDCACM::Find(std::vector<FoundDevice>& found) {
|
||||
CFMutableDictionaryRef ref = IOServiceMatching(kIOSerialBSDServiceValue);
|
||||
if(ref == nullptr)
|
||||
return found;
|
||||
return;
|
||||
io_iterator_t matchingServices = 0;
|
||||
kern_return_t kernResult = IOServiceGetMatchingServices(kIOMasterPortDefault, ref, &matchingServices);
|
||||
if(KERN_SUCCESS != kernResult || matchingServices == 0)
|
||||
return found;
|
||||
return;
|
||||
IOReleaser matchingServicesReleaser(matchingServices);
|
||||
|
||||
io_object_t serialPort;
|
||||
while((serialPort = IOIteratorNext(matchingServices))) {
|
||||
IOReleaser serialPortReleaser(serialPort);
|
||||
neodevice_t device;
|
||||
|
||||
// First get the parent device
|
||||
// We want to check that it has the right VID/PID
|
||||
|
|
@ -138,10 +136,10 @@ std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
|||
CFReleaser productPropReleaser(productProp);
|
||||
if(CFGetTypeID(productProp) != CFNumberGetTypeID())
|
||||
continue;
|
||||
uint16_t pid = 0;
|
||||
if(!CFNumberGetValue(static_cast<CFNumberRef>(productProp), kCFNumberSInt16Type, &pid))
|
||||
continue;
|
||||
if(pid != product)
|
||||
|
||||
// Read the PID directly into the FoundDevice structure
|
||||
FoundDevice device;
|
||||
if(!CFNumberGetValue(static_cast<CFNumberRef>(productProp), kCFNumberSInt16Type, &device.productId))
|
||||
continue;
|
||||
|
||||
// Now, let's get the "call-out" device (/dev/cu.*)
|
||||
|
|
@ -173,10 +171,13 @@ std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
|||
continue;
|
||||
device.serial[serial.copy(device.serial, sizeof(device.serial)-1)] = '\0';
|
||||
|
||||
// Add a factory to make the driver
|
||||
device.makeDriver = [](const device_eventhandler_t& report, neodevice_t& device) {
|
||||
return std::unique_ptr<Driver>(new CDCACM(report, device));
|
||||
};
|
||||
|
||||
found.push_back(device);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
std::string CDCACM::HandleToTTY(neodevice_handle_t handle) {
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include <iostream>
|
||||
#include <stdio.h>
|
||||
#include <cstring>
|
||||
|
|
@ -9,22 +10,21 @@
|
|||
|
||||
using namespace icsneo;
|
||||
|
||||
std::vector<std::tuple<int, std::string>> FTDI::handles;
|
||||
std::vector<std::string> FTDI::handles;
|
||||
|
||||
std::vector<neodevice_t> FTDI::FindByProduct(int product) {
|
||||
void FTDI::Find(std::vector<FoundDevice>& found) {
|
||||
constexpr size_t deviceSerialBufferLength = sizeof(device.serial);
|
||||
std::vector<neodevice_t> found;
|
||||
static FTDIContext context;
|
||||
|
||||
std::pair<int, std::vector<std::string>> result = context.findDevices(product);
|
||||
const auto result = context.findDevices();
|
||||
if(result.first < 0)
|
||||
return found; // TODO Flag an error for the client application, there was an issue with FTDI
|
||||
return; // TODO Flag an error for the client application, there was an issue with FTDI
|
||||
|
||||
for(auto& serial : result.second) {
|
||||
neodevice_t d;
|
||||
for(const auto& [serial, pid] : result.second) {
|
||||
FoundDevice d;
|
||||
strncpy(d.serial, serial.c_str(), deviceSerialBufferLength - 1);
|
||||
d.serial[deviceSerialBufferLength - 1] = '\0'; // strncpy does not write a null terminator if serial is too long
|
||||
std::tuple<int, std::string> devHandle = std::make_tuple(product, serial);
|
||||
std::string devHandle = serial;
|
||||
auto it = std::find(handles.begin(), handles.end(), devHandle);
|
||||
size_t foundHandle = SIZE_MAX;
|
||||
if(it != handles.end()) {
|
||||
|
|
@ -34,10 +34,14 @@ std::vector<neodevice_t> FTDI::FindByProduct(int product) {
|
|||
handles.push_back(devHandle);
|
||||
}
|
||||
d.handle = foundHandle;
|
||||
d.productId = pid;
|
||||
|
||||
d.makeDriver = [](const device_eventhandler_t& report, neodevice_t& device) {
|
||||
return std::unique_ptr<Driver>(new FTDI(report, device));
|
||||
};
|
||||
|
||||
found.push_back(d);
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
FTDI::FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
|
||||
|
|
@ -56,8 +60,8 @@ bool FTDI::open() {
|
|||
}
|
||||
|
||||
// At this point the handle has been checked to be within the bounds of the handles array
|
||||
std::tuple<int, std::string>& handle = handles[device.handle];
|
||||
const int openError = ftdi.openDevice(std::get<0>(handle), std::get<1>(handle).c_str());
|
||||
auto& handle = handles[device.handle];
|
||||
const int openError = ftdi.openDevice(0, handle.c_str());
|
||||
if(openError == -5) { // Unable to claim device
|
||||
report(APIEvent::Type::DeviceInUse, APIEvent::Severity::Error);
|
||||
return false;
|
||||
|
|
@ -112,17 +116,13 @@ bool FTDI::close() {
|
|||
return ret;
|
||||
}
|
||||
|
||||
std::pair<int, std::vector<std::string>> FTDI::FTDIContext::findDevices(int pid) {
|
||||
std::pair<int, std::vector<std::string>> ret;
|
||||
std::pair<int, std::vector< std::pair<std::string, uint16_t> > > FTDI::FTDIContext::findDevices(int pid) {
|
||||
std::pair<int, std::vector< std::pair<std::string, uint16_t> > > ret;
|
||||
|
||||
if(context == nullptr) {
|
||||
ret.first = -1;
|
||||
return ret;
|
||||
}
|
||||
if(pid == 0) {
|
||||
ret.first = -2;
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct ftdi_device_list* devlist = nullptr;
|
||||
ret.first = ftdi_usb_find_all(context, &devlist, INTREPID_USB_VENDOR_ID, pid);
|
||||
|
|
@ -138,18 +138,23 @@ std::pair<int, std::vector<std::string>> FTDI::FTDIContext::findDevices(int pid)
|
|||
return ret;
|
||||
}
|
||||
|
||||
for (struct ftdi_device_list* curdev = devlist; curdev != NULL;) {
|
||||
char serial[32];
|
||||
memset(serial, 0, sizeof(serial));
|
||||
int result = ftdi_usb_get_strings(context, curdev->dev, nullptr, 0, nullptr, 0, serial, 32);
|
||||
size_t len = strlen(serial);
|
||||
if(result >= 0 && len > 0)
|
||||
ret.second.emplace_back(serial);
|
||||
else if(ret.first > 0)
|
||||
ret.first--; // We're discarding this device
|
||||
curdev = curdev->next;
|
||||
for(struct ftdi_device_list* curdev = devlist; curdev != nullptr; curdev = curdev->next) {
|
||||
struct libusb_device_descriptor descriptor = {};
|
||||
// Check against bDeviceClass here as it will be 0 for FTDI devices
|
||||
// It will be 2 for CDC ACM devices, which we don't want to handle here
|
||||
if(libusb_get_device_descriptor(curdev->dev, &descriptor) != 0 || descriptor.bDeviceClass != 0)
|
||||
continue;
|
||||
|
||||
char serial[16] = {};
|
||||
if(ftdi_usb_get_strings(context, curdev->dev, nullptr, 0, nullptr, 0, serial, sizeof(serial)) < 0)
|
||||
continue;
|
||||
|
||||
const auto len = strnlen(serial, sizeof(serial));
|
||||
if(len > 4 && len < 10)
|
||||
ret.second.emplace_back(serial, descriptor.idProduct);
|
||||
}
|
||||
|
||||
ret.first = static_cast<int>(ret.second.size());
|
||||
ftdi_list_free(&devlist);
|
||||
return ret;
|
||||
}
|
||||
|
|
@ -157,7 +162,7 @@ std::pair<int, std::vector<std::string>> FTDI::FTDIContext::findDevices(int pid)
|
|||
int FTDI::FTDIContext::openDevice(int pid, const char* serial) {
|
||||
if(context == nullptr)
|
||||
return 1;
|
||||
if(pid == 0 || serial == nullptr)
|
||||
if(serial == nullptr)
|
||||
return 2;
|
||||
if(serial[0] == '\0')
|
||||
return 3;
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
#include "icsneo/platform/cdcacm.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include <dirent.h>
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
|
@ -80,12 +81,10 @@ private:
|
|||
std::string serial;
|
||||
};
|
||||
|
||||
std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
||||
std::vector<neodevice_t> found;
|
||||
|
||||
void CDCACM::Find(std::vector<FoundDevice>& found) {
|
||||
Directory directory("/sys/bus/usb/drivers/cdc_acm"); // Query the CDCACM driver
|
||||
if(!directory.openedSuccessfully())
|
||||
return found;
|
||||
return;
|
||||
|
||||
std::vector<std::string> foundusbs;
|
||||
for(auto& entry : directory.ls()) {
|
||||
|
|
@ -100,8 +99,9 @@ std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
|||
foundusbs.emplace_back(entry.getName());
|
||||
}
|
||||
|
||||
// Pair the USB and TTY if found
|
||||
std::map<std::string, std::string> foundttys;
|
||||
// Map the USB directory to the TTY and PID if found
|
||||
// The PID will be filled later
|
||||
std::map< std::string, std::pair<std::string, uint16_t> > foundttys;
|
||||
for(auto& usb : foundusbs) {
|
||||
std::stringstream ss;
|
||||
ss << "/sys/bus/usb/drivers/cdc_acm/" << usb << "/tty";
|
||||
|
|
@ -113,15 +113,16 @@ std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
|||
if(listing.size() != 1) // We either got no serial ports or multiple, either way no good
|
||||
continue;
|
||||
|
||||
foundttys.insert(std::make_pair(usb, listing[0].getName()));
|
||||
foundttys.insert(std::make_pair(usb, std::make_pair(listing[0].getName(), 0)));
|
||||
}
|
||||
|
||||
// We're going to remove from the map if this is not the product we're looking for
|
||||
for(auto iter = foundttys.begin(); iter != foundttys.end(); ) {
|
||||
const auto& dev = *iter;
|
||||
auto& [_, pair] = *iter;
|
||||
auto& [tty, ttyPid] = pair;
|
||||
const std::string matchString = "PRODUCT=";
|
||||
std::stringstream ss;
|
||||
ss << "/sys/class/tty/" << dev.second << "/device/uevent"; // Read the uevent file, which contains should have a line like "PRODUCT=93c/1101/100"
|
||||
ss << "/sys/class/tty/" << tty << "/device/uevent"; // Read the uevent file, which contains should have a line like "PRODUCT=93c/1101/100"
|
||||
std::ifstream fs(ss.str());
|
||||
std::string productLine;
|
||||
size_t pos = std::string::npos;
|
||||
|
|
@ -153,32 +154,34 @@ std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
|||
continue;
|
||||
}
|
||||
|
||||
if(vid != INTREPID_USB_VENDOR_ID || pid != product) {
|
||||
iter = foundttys.erase(iter); // Not the right VID or PID, remove
|
||||
if(vid != INTREPID_USB_VENDOR_ID) {
|
||||
iter = foundttys.erase(iter); // Not the right VID, remove
|
||||
continue;
|
||||
}
|
||||
ttyPid = pid; // Set the PID for this TTY
|
||||
iter++; // If the loop ends without erasing the iter from the map, the item is good
|
||||
}
|
||||
|
||||
// At this point, foundttys contains the the devices we want
|
||||
|
||||
// Get the serial number, create the neodevice_t
|
||||
for(auto& dev : foundttys) {
|
||||
neodevice_t device;
|
||||
for(auto& [usb, pair] : foundttys) {
|
||||
auto& [tty, ttyPid] = pair;
|
||||
FoundDevice device;
|
||||
|
||||
USBSerialGetter getter(dev.first);
|
||||
USBSerialGetter getter(usb);
|
||||
if(!getter.success())
|
||||
continue; // Failure, could not get serial number
|
||||
|
||||
// In ttyACM0, we want the i to be the first character of the number
|
||||
size_t i;
|
||||
for(i = 0; i < dev.second.length(); i++) {
|
||||
if(isdigit(dev.second[i]))
|
||||
for(i = 0; i < tty.length(); i++) {
|
||||
if(isdigit(tty[i]))
|
||||
break;
|
||||
}
|
||||
// Now we try to parse the number so we have a handle for later
|
||||
try {
|
||||
device.handle = (neodevice_handle_t)std::stoul(dev.second.substr(i));
|
||||
device.handle = (neodevice_handle_t)std::stoul(tty.substr(i));
|
||||
/* The TTY numbering starts at zero, but we want to keep zero for an undefined
|
||||
* handle, so add a constant, and we'll subtract that constant in the open function.
|
||||
*/
|
||||
|
|
@ -187,12 +190,16 @@ std::vector<neodevice_t> CDCACM::FindByProduct(int product) {
|
|||
continue; // Somehow this failed, have to toss the device
|
||||
}
|
||||
|
||||
device.productId = ttyPid;
|
||||
device.serial[getter.getSerial().copy(device.serial, sizeof(device.serial)-1)] = '\0';
|
||||
|
||||
// Add a factory to make the driver
|
||||
device.makeDriver = [](const device_eventhandler_t& report, neodevice_t& device) {
|
||||
return std::unique_ptr<Driver>(new CDCACM(report, device));
|
||||
};
|
||||
|
||||
found.push_back(device); // Finally, add device to search results
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
std::string CDCACM::HandleToTTY(neodevice_handle_t handle) {
|
||||
|
|
|
|||
|
|
@ -1,7 +1,9 @@
|
|||
#include "icsneo/platform/posix/pcap.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
#include "icsneo/communication/communication.h"
|
||||
#include "icsneo/communication/ethernetpacketizer.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
#include <codecvt>
|
||||
#include <chrono>
|
||||
#include <cstring>
|
||||
|
|
@ -15,14 +17,10 @@
|
|||
|
||||
using namespace icsneo;
|
||||
|
||||
static const uint8_t BROADCAST_MAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const uint8_t ICS_UNSET_MAC[6] = { 0x00, 0xFC, 0x70, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
std::vector<PCAP::NetworkInterface> PCAP::knownInterfaces;
|
||||
|
||||
std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
||||
void PCAP::Find(std::vector<FoundDevice>& found) {
|
||||
static bool warned = false; // Only warn once for failure to open devices
|
||||
std::vector<PCAPFoundDevice> foundDevices;
|
||||
|
||||
// First we ask PCAP to give us all of the devices
|
||||
pcap_if_t* alldevs;
|
||||
|
|
@ -39,7 +37,7 @@ std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
|||
|
||||
if(!success) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error);
|
||||
return std::vector<PCAPFoundDevice>();
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<NetworkInterface> interfaces;
|
||||
|
|
@ -138,7 +136,7 @@ std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
|||
pcap_sendpacket(iface.fp, bs.data(), (int)bs.size());
|
||||
|
||||
auto timeout = std::chrono::high_resolution_clock::now() + std::chrono::milliseconds(50);
|
||||
while(std::chrono::high_resolution_clock::now() <= timeout) { // Wait up to 5ms for the response
|
||||
while(std::chrono::high_resolution_clock::now() <= timeout) { // Wait up to 50ms for the response
|
||||
struct pcap_pkthdr* header;
|
||||
const uint8_t* data;
|
||||
auto res = pcap_next_ex(iface.fp, &header, &data);
|
||||
|
|
@ -153,47 +151,48 @@ std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
|||
if(res == 0)
|
||||
continue; // Keep waiting for that packet
|
||||
|
||||
EthernetPacketizer::EthernetPacket packet(data, header->caplen);
|
||||
// Is this an ICS response packet (0xCAB2) from an ICS MAC, either to broadcast or directly to us?
|
||||
if(packet.etherType == 0xCAB2 && packet.srcMAC[0] == 0x00 && packet.srcMAC[1] == 0xFC && packet.srcMAC[2] == 0x70 && (
|
||||
memcmp(packet.destMAC, iface.macAddress, sizeof(packet.destMAC)) == 0 ||
|
||||
memcmp(packet.destMAC, BROADCAST_MAC, sizeof(packet.destMAC)) == 0 ||
|
||||
memcmp(packet.destMAC, ICS_UNSET_MAC, sizeof(packet.destMAC)) == 0
|
||||
)) {
|
||||
/* We have received a packet from a device. We don't know if this is the device we're
|
||||
* looking for, we don't know if it's actually a response to our RequestSerialNumber
|
||||
* or not, we just know we got something.
|
||||
*
|
||||
* Unlike most transport layers, we can't get the serial number here as we actually
|
||||
* need to parse this message that has been returned. Some devices parse messages
|
||||
* differently, so we need to use their communication layer. We could technically
|
||||
* create a communication layer to parse the packet we have in `payload` here, but
|
||||
* we'd need to be given a packetizer and decoder for the device. I'm intentionally
|
||||
* avoiding passing that information down here for code quality's sake. Instead, pass
|
||||
* the packet we received back up so the device can handle it.
|
||||
*/
|
||||
neodevice_handle_t handle = (neodevice_handle_t)((i << 24) | (packet.srcMAC[3] << 16) | (packet.srcMAC[4] << 8) | (packet.srcMAC[5]));
|
||||
PCAPFoundDevice* alreadyExists = nullptr;
|
||||
for(auto& dev : foundDevices)
|
||||
if(dev.device.handle == handle)
|
||||
alreadyExists = &dev;
|
||||
EthernetPacketizer ethPacketizer([](APIEvent::Type, APIEvent::Severity) {});
|
||||
memcpy(ethPacketizer.hostMAC, iface.macAddress, sizeof(ethPacketizer.hostMAC));
|
||||
ethPacketizer.allowInPacketsFromAnyMAC = true;
|
||||
if(!ethPacketizer.inputUp({ data, data + header->caplen }))
|
||||
continue; // This packet is not for us
|
||||
|
||||
if(alreadyExists == nullptr) {
|
||||
PCAPFoundDevice foundDevice;
|
||||
foundDevice.device.handle = handle;
|
||||
foundDevice.discoveryPackets.push_back(std::move(packet.payload));
|
||||
foundDevices.push_back(foundDevice);
|
||||
} else {
|
||||
alreadyExists->discoveryPackets.push_back(std::move(packet.payload));
|
||||
}
|
||||
Packetizer packetizer([](APIEvent::Type, APIEvent::Severity) {});
|
||||
if(!packetizer.input(ethPacketizer.outputUp()))
|
||||
continue; // This packet was not well formed
|
||||
|
||||
EthernetPacketizer::EthernetPacket decoded(data, header->caplen);
|
||||
Decoder decoder([](APIEvent::Type, APIEvent::Severity) {});
|
||||
for(const auto& packet : packetizer.output()) {
|
||||
std::shared_ptr<Message> message;
|
||||
if(!decoder.decode(message, packet))
|
||||
continue;
|
||||
|
||||
const neodevice_handle_t handle = (neodevice_handle_t)((i << 24) | (decoded.srcMAC[3] << 16) | (decoded.srcMAC[4] << 8) | (decoded.srcMAC[5]));
|
||||
if(std::any_of(found.begin(), found.end(), [&handle](const auto& found) { return handle == found.handle; }))
|
||||
continue; // We already have this device on this interface
|
||||
|
||||
const auto serial = std::dynamic_pointer_cast<SerialNumberMessage>(message);
|
||||
if(!serial || serial->deviceSerial.size() != 6)
|
||||
continue;
|
||||
|
||||
FoundDevice foundDevice;
|
||||
foundDevice.handle = handle;
|
||||
foundDevice.productId = decoded.srcMAC[2];
|
||||
memcpy(foundDevice.serial, serial->deviceSerial.c_str(), sizeof(foundDevice.serial) - 1);
|
||||
foundDevice.serial[sizeof(foundDevice.serial) - 1] = '\0';
|
||||
|
||||
foundDevice.makeDriver = [](const device_eventhandler_t& report, neodevice_t& device) {
|
||||
return std::unique_ptr<Driver>(new PCAP(report, device));
|
||||
};
|
||||
|
||||
found.push_back(foundDevice);
|
||||
}
|
||||
}
|
||||
|
||||
pcap_close(iface.fp);
|
||||
iface.fp = nullptr;
|
||||
}
|
||||
|
||||
return foundDevices;
|
||||
}
|
||||
|
||||
bool PCAP::IsHandleValid(neodevice_handle_t handle) {
|
||||
|
|
|
|||
|
|
@ -4,8 +4,9 @@
|
|||
#include "icsneo/platform/windows/pcap.h"
|
||||
#include "icsneo/communication/network.h"
|
||||
#include "icsneo/communication/communication.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/ethernetpacketizer.h"
|
||||
#include "icsneo/communication/packetizer.h"
|
||||
#include "icsneo/communication/decoder.h"
|
||||
#include <pcap.h>
|
||||
#include <iphlpapi.h>
|
||||
#pragma comment(lib, "IPHLPAPI.lib")
|
||||
|
|
@ -17,17 +18,14 @@
|
|||
using namespace icsneo;
|
||||
|
||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||
static const uint8_t BROADCAST_MAC[6] = { 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF };
|
||||
static const uint8_t ICS_UNSET_MAC[6] = { 0x00, 0xFC, 0x70, 0xFF, 0xFF, 0xFF };
|
||||
|
||||
std::vector<PCAP::NetworkInterface> PCAP::knownInterfaces;
|
||||
|
||||
std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
||||
std::vector<PCAPFoundDevice> foundDevices;
|
||||
void PCAP::Find(std::vector<FoundDevice>& found) {
|
||||
const PCAPDLL& pcap = PCAPDLL::getInstance();
|
||||
if(!pcap.ok()) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotStart, APIEvent::Severity::Error);
|
||||
return std::vector<PCAPFoundDevice>();
|
||||
return;
|
||||
}
|
||||
|
||||
// First we ask WinPCAP to give us all of the devices
|
||||
|
|
@ -45,7 +43,7 @@ std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
|||
|
||||
if(!success) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error);
|
||||
return std::vector<PCAPFoundDevice>();
|
||||
return;
|
||||
}
|
||||
|
||||
std::vector<NetworkInterface> interfaces;
|
||||
|
|
@ -62,13 +60,13 @@ std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
|||
ULONG size = 0;
|
||||
if(GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &size) != ERROR_BUFFER_OVERFLOW) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error);
|
||||
return std::vector<PCAPFoundDevice>();
|
||||
return;
|
||||
}
|
||||
std::vector<uint8_t> adapterAddressBuffer;
|
||||
adapterAddressBuffer.resize(size);
|
||||
if(GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, (IP_ADAPTER_ADDRESSES*)adapterAddressBuffer.data(), &size) != ERROR_SUCCESS) {
|
||||
EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error);
|
||||
return std::vector<PCAPFoundDevice>();
|
||||
return;
|
||||
}
|
||||
|
||||
// aa->AdapterName constains a unique name of the interface like "{3B1D2791-435A-456F-8A7B-9CB0EEE5DAB3}"
|
||||
|
|
@ -137,46 +135,48 @@ std::vector<PCAP::PCAPFoundDevice> PCAP::FindAll() {
|
|||
if(res == 0)
|
||||
continue; // Keep waiting for that packet
|
||||
|
||||
EthernetPacketizer::EthernetPacket packet(data, header->caplen);
|
||||
// Is this an ICS response packet (0xCAB2) from an ICS MAC, either to broadcast or directly to us?
|
||||
if(packet.etherType == 0xCAB2 && packet.srcMAC[0] == 0x00 && packet.srcMAC[1] == 0xFC && packet.srcMAC[2] == 0x70 && (
|
||||
memcmp(packet.destMAC, iface.macAddress, sizeof(packet.destMAC)) == 0 ||
|
||||
memcmp(packet.destMAC, BROADCAST_MAC, sizeof(packet.destMAC)) == 0
|
||||
)) {
|
||||
/* We have received a packet from a device. We don't know if this is the device we're
|
||||
* looking for, we don't know if it's actually a response to our RequestSerialNumber
|
||||
* or not, we just know we got something.
|
||||
*
|
||||
* Unlike most transport layers, we can't get the serial number here as we actually
|
||||
* need to parse this message that has been returned. Some devices parse messages
|
||||
* differently, so we need to use their communication layer. We could technically
|
||||
* create a communication layer to parse the packet we have in `payload` here, but
|
||||
* we'd need to be given a packetizer and decoder for the device. I'm intentionally
|
||||
* avoiding passing that information down here for code quality's sake. Instead, pass
|
||||
* the packet we received back up so the device can handle it.
|
||||
*/
|
||||
neodevice_handle_t handle = (neodevice_handle_t)((i << 24) | (packet.srcMAC[3] << 16) | (packet.srcMAC[4] << 8) | (packet.srcMAC[5]));
|
||||
PCAPFoundDevice* alreadyExists = nullptr;
|
||||
for(auto& dev : foundDevices)
|
||||
if(dev.device.handle == handle)
|
||||
alreadyExists = &dev;
|
||||
EthernetPacketizer ethPacketizer([](APIEvent::Type, APIEvent::Severity) {});
|
||||
memcpy(ethPacketizer.hostMAC, iface.macAddress, sizeof(ethPacketizer.hostMAC));
|
||||
ethPacketizer.allowInPacketsFromAnyMAC = true;
|
||||
if(!ethPacketizer.inputUp({ data, data + header->caplen }))
|
||||
continue; // This packet is not for us
|
||||
|
||||
if(alreadyExists == nullptr) {
|
||||
PCAPFoundDevice foundDevice;
|
||||
foundDevice.device.handle = handle;
|
||||
foundDevice.discoveryPackets.push_back(std::move(packet.payload));
|
||||
foundDevices.push_back(foundDevice);
|
||||
} else {
|
||||
alreadyExists->discoveryPackets.push_back(std::move(packet.payload));
|
||||
}
|
||||
Packetizer packetizer([](APIEvent::Type, APIEvent::Severity) {});
|
||||
if(!packetizer.input(ethPacketizer.outputUp()))
|
||||
continue; // This packet was not well formed
|
||||
|
||||
EthernetPacketizer::EthernetPacket decoded(data, header->caplen);
|
||||
for(const auto& packet : packetizer.output()) {
|
||||
Decoder decoder([](APIEvent::Type, APIEvent::Severity) {});
|
||||
std::shared_ptr<Message> message;
|
||||
if(!decoder.decode(message, packet))
|
||||
continue;
|
||||
|
||||
const neodevice_handle_t handle = (neodevice_handle_t)((i << 24) | (decoded.srcMAC[3] << 16) | (decoded.srcMAC[4] << 8) | (decoded.srcMAC[5]));
|
||||
if(std::any_of(found.begin(), found.end(), [&handle](const auto& found) { return handle == found.handle; }))
|
||||
continue; // We already have this device on this interface
|
||||
|
||||
const auto serial = std::dynamic_pointer_cast<SerialNumberMessage>(message);
|
||||
if(!serial || serial->deviceSerial.size() != 6)
|
||||
continue;
|
||||
|
||||
FoundDevice foundDevice;
|
||||
foundDevice.handle = handle;
|
||||
foundDevice.productId = decoded.srcMAC[2];
|
||||
memcpy(foundDevice.serial, serial->deviceSerial.c_str(), sizeof(foundDevice.serial) - 1);
|
||||
foundDevice.serial[sizeof(foundDevice.serial) - 1] = '\0';
|
||||
|
||||
foundDevice.makeDriver = [](const device_eventhandler_t& reportFn, neodevice_t& device) {
|
||||
return std::unique_ptr<Driver>(new PCAP(reportFn, device));
|
||||
};
|
||||
|
||||
found.push_back(foundDevice);
|
||||
}
|
||||
}
|
||||
|
||||
pcap.close(iface.fp);
|
||||
iface.fp = nullptr;
|
||||
}
|
||||
|
||||
return foundDevices;
|
||||
}
|
||||
|
||||
bool PCAP::IsHandleValid(neodevice_handle_t handle) {
|
||||
|
|
|
|||
|
|
@ -1,6 +1,7 @@
|
|||
#include "icsneo/platform/windows/ftdi.h"
|
||||
#include "icsneo/platform/ftdi.h"
|
||||
#include "icsneo/platform/registry.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include <windows.h>
|
||||
#include <iostream>
|
||||
#include <iomanip>
|
||||
|
|
@ -19,8 +20,7 @@ static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\
|
|||
static constexpr unsigned int RETRY_TIMES = 5;
|
||||
static constexpr unsigned int RETRY_DELAY = 50;
|
||||
|
||||
struct VCP::Detail
|
||||
{
|
||||
struct VCP::Detail {
|
||||
Detail() {
|
||||
overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
||||
overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
||||
|
|
@ -32,21 +32,22 @@ struct VCP::Detail
|
|||
OVERLAPPED overlappedWait = {};
|
||||
};
|
||||
|
||||
std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstring> driverNames) {
|
||||
std::vector<neodevice_t> found;
|
||||
|
||||
void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driverNames) {
|
||||
for(auto& driverName : driverNames) {
|
||||
std::wstringstream regss;
|
||||
regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\";
|
||||
std::wstring driverEnumRegKey = regss.str();
|
||||
|
||||
uint32_t deviceCount = 0;
|
||||
if(!Registry::Get(driverEnumRegKey, L"Count", deviceCount)) {
|
||||
return found;
|
||||
}
|
||||
if(!Registry::Get(driverEnumRegKey, L"Count", deviceCount))
|
||||
continue;
|
||||
|
||||
for(uint32_t i = 0; i < deviceCount; i++) {
|
||||
neodevice_t device = {};
|
||||
FoundDevice device;
|
||||
|
||||
device.makeDriver = [](const device_eventhandler_t& reportFn, neodevice_t& device) {
|
||||
return std::unique_ptr<Driver>(new VCP(reportFn, device));
|
||||
};
|
||||
|
||||
// First we want to look at what devices FTDI is enumerating (inside driverEnumRegKey)
|
||||
// The entry for a ValueCAN 3 with SN 138635 looks like "FTDIBUS\VID_093C+PID_0601+138635A\0000"
|
||||
|
|
@ -64,11 +65,10 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstrin
|
|||
if(entry.find(vss.str()) == std::wstring::npos)
|
||||
continue;
|
||||
|
||||
std::wstringstream pss;
|
||||
pss << "PID_" << std::setfill(L'0') << std::setw(4) << std::uppercase << std::hex << product;
|
||||
auto pidpos = entry.find(pss.str());
|
||||
auto pidpos = entry.find(L"PID_");
|
||||
if(pidpos == std::wstring::npos)
|
||||
continue;
|
||||
// We will later use this and startchar to parse the PID
|
||||
|
||||
// Okay, this is a device we want
|
||||
// Get the serial number
|
||||
|
|
@ -90,13 +90,18 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstrin
|
|||
else
|
||||
oss << sn;
|
||||
|
||||
device.productId = uint16_t(std::wcstol(entry.c_str() + pidpos + 4, nullptr, 16));
|
||||
if(!device.productId)
|
||||
continue;
|
||||
|
||||
std::string serial = converter.to_bytes(oss.str());
|
||||
// The serial number should not have a path slash in it. If it does, that means we don't have the real serial.
|
||||
if(serial.find_first_of('\\') != std::string::npos) {
|
||||
// The serial number was not in the first serenum key where we expected it.
|
||||
// We can try to match the ContainerID with the one in ALL_ENUM\USB and get a serial that way
|
||||
std::wstringstream uess;
|
||||
uess << ALL_ENUM_REG_KEY << L"\\USB\\" << vss.str() << L'&' << pss.str() << L'\\';
|
||||
uess << ALL_ENUM_REG_KEY << L"\\USB\\" << vss.str() << L"&PID_" << std::setfill(L'0') << std::setw(4)
|
||||
<< std::uppercase << std::hex << device.productId << L'\\';
|
||||
std::wstringstream ciss;
|
||||
ciss << ALL_ENUM_REG_KEY << entry;
|
||||
std::wstring containerIDFromEntry, containerIDFromEnum;
|
||||
|
|
@ -166,7 +171,7 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstrin
|
|||
}
|
||||
|
||||
bool alreadyFound = false;
|
||||
neodevice_t* shouldReplace = nullptr;
|
||||
FoundDevice* shouldReplace = nullptr;
|
||||
for(auto& foundDev : found) {
|
||||
if((foundDev.handle == device.handle || foundDev.handle == 0 || device.handle == 0) && serial == foundDev.serial) {
|
||||
alreadyFound = true;
|
||||
|
|
@ -182,8 +187,6 @@ std::vector<neodevice_t> VCP::FindByProduct(int product, std::vector<std::wstrin
|
|||
*shouldReplace = device;
|
||||
}
|
||||
}
|
||||
|
||||
return found;
|
||||
}
|
||||
|
||||
VCP::VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
|
||||
|
|
|
|||
|
|
@ -328,8 +328,9 @@ int ftdi_usb_find_all(struct ftdi_context *ftdi, struct ftdi_device_list **devli
|
|||
if (libusb_get_device_descriptor(dev, &desc) < 0)
|
||||
ftdi_error_return_free_device_list(-6, "libusb_get_device_descriptor() failed", devs);
|
||||
|
||||
// Intrepid modification: PID 0 returns all devices with the correct VID
|
||||
if (((vendor || product) &&
|
||||
desc.idVendor == vendor && desc.idProduct == product) ||
|
||||
desc.idVendor == vendor && (desc.idProduct == product || !product)) ||
|
||||
(!(vendor || product) &&
|
||||
(desc.idVendor == 0x403) && (desc.idProduct == 0x6001 || desc.idProduct == 0x6010
|
||||
|| desc.idProduct == 0x6011 || desc.idProduct == 0x6014
|
||||
|
|
@ -774,7 +775,8 @@ int ftdi_usb_open_desc_index(struct ftdi_context *ftdi, int vendor, int product,
|
|||
if (libusb_get_device_descriptor(dev, &desc) < 0)
|
||||
ftdi_error_return_free_device_list(-13, "libusb_get_device_descriptor() failed", devs);
|
||||
|
||||
if (desc.idVendor == vendor && desc.idProduct == product)
|
||||
// Intrepid modification: PID 0 disables filtering by PID
|
||||
if (desc.idVendor == vendor && (desc.idProduct == product || !product))
|
||||
{
|
||||
if (libusb_open(dev, &ftdi->usb_dev) < 0)
|
||||
ftdi_error_return_free_device_list(-4, "usb_open() failed", devs);
|
||||
|
|
|
|||
Loading…
Reference in New Issue