mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
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.
This commit is contained in:
+43
-5
@@ -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,17 +89,41 @@ endif()
|
||||
|
||||
if(${CMAKE_SYSTEM_NAME} STREQUAL "Windows")
|
||||
set(PLATFORM_SRC
|
||||
platform/windows/pcap.cpp
|
||||
platform/windows/registry.cpp
|
||||
platform/windows/vcp.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
|
||||
set(PLATFORM_SRC)
|
||||
|
||||
if(LIBICSNEO_ENABLE_RAW_ETHERNET)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/pcap.cpp
|
||||
)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_ENABLE_FTDI)
|
||||
list(APPEND PLATFORM_SRC
|
||||
platform/posix/ftdi.cpp
|
||||
)
|
||||
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
|
||||
@@ -107,11 +134,12 @@ else() # Darwin or Linux
|
||||
)
|
||||
if(NOT ${CMAKE_SYSTEM_NAME} STREQUAL "Linux")
|
||||
message(WARNING
|
||||
"There is no platform port defined for ${CMAKE_SYSTEM_NAME}!\n"
|
||||
"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()
|
||||
|
||||
if(LIBICSNEO_BUILD_EXAMPLES)
|
||||
@@ -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
|
||||
|
||||
+172
-186
@@ -1,11 +1,166 @@
|
||||
#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));
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
// Offer found devices to each of the subclasses
|
||||
for (const FoundDevice& dev : driverFoundDevices) {
|
||||
#ifdef __ETHERBADGE_H_
|
||||
makeIfSerialMatches<EtherBADGE>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2PRO_H_
|
||||
makeIfSerialMatches<NeoOBD2PRO>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2SIM_H_
|
||||
makeIfSerialMatches<NeoOBD2SIM>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
makeIfPIDMatches<NeoVIFIRE>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2_H_
|
||||
makeIfSerialMatches<NeoVIFIRE2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIRED2_H_
|
||||
makeIfSerialMatches<NeoVIRED2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
makeIfPIDMatches<NeoVIION>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
makeIfPIDMatches<NeoVIPLASMA>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
makeIfSerialMatches<RADEpsilon>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
makeIfSerialMatches<RADGalaxy>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_H_
|
||||
makeIfSerialMatches<RADMars>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_H_
|
||||
makeIfSerialMatches<RADGigastar>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOON2_H_
|
||||
makeIfSerialMatches<RADMoon2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
makeIfSerialMatches<RADMoonDuo>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADPLUTO_H_
|
||||
makeIfSerialMatches<RADPluto>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2_H_
|
||||
makeIfSerialMatches<RADStar2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
makeIfSerialMatches<RADSupermoon>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
makeIfPIDMatches<ValueCAN3>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_1_H_
|
||||
makeIfSerialMatches<ValueCAN4_1>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2_H_
|
||||
makeIfSerialMatches<ValueCAN4_2>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_2EL_H_
|
||||
makeIfSerialMatches<ValueCAN4_2EL>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4_4_H_
|
||||
makeIfSerialMatches<ValueCAN4_4>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN4INDUSTRIAL_H_
|
||||
makeIfSerialMatches<ValueCAN4Industrial>(dev, foundDevices);
|
||||
#endif
|
||||
|
||||
#ifdef __VIVIDCAN_H_
|
||||
makeIfSerialMatches<VividCAN>(dev, foundDevices);
|
||||
#endif
|
||||
}
|
||||
|
||||
for(auto& device : foundDevices) {
|
||||
AddBuiltInExtensionsTo(device);
|
||||
}
|
||||
|
||||
return foundDevices;
|
||||
}
|
||||
|
||||
const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
static std::vector<DeviceType> supportedDevices = {
|
||||
|
||||
#ifdef __ETHERBADGE_H_
|
||||
EtherBADGE::DEVICE_TYPE,
|
||||
@@ -27,12 +182,8 @@ static std::vector<DeviceType> supportedDevices = {
|
||||
NeoVIFIRE::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2ETH_H_
|
||||
NeoVIFIRE2ETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2USB_H_
|
||||
NeoVIFIRE2USB::DEVICE_TYPE,
|
||||
#ifdef __NEOVIFIRE2_H_
|
||||
NeoVIFIRE2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
@@ -51,20 +202,12 @@ static std::vector<DeviceType> supportedDevices = {
|
||||
RADGalaxy::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_ETH_H_
|
||||
RADMarsETH::DEVICE_TYPE,
|
||||
#ifdef __RADMARS_H_
|
||||
RADMars::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,
|
||||
#ifdef __RADGIGASTAR_H_
|
||||
RADGigastar::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOON2_H_
|
||||
@@ -75,16 +218,12 @@ static std::vector<DeviceType> supportedDevices = {
|
||||
RADMoonDuo::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADPLUTOUSB_H_
|
||||
RADPlutoUSB::DEVICE_TYPE,
|
||||
#ifdef __RADPLUTO_H_
|
||||
RADPluto::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2ETH_H_
|
||||
RADStar2ETH::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2USB_H_
|
||||
RADStar2USB::DEVICE_TYPE,
|
||||
#ifdef __RADSTAR2_H_
|
||||
RADStar2::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
@@ -103,176 +242,23 @@ static std::vector<DeviceType> supportedDevices = {
|
||||
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,
|
||||
#ifdef __VALUECAN4_2EL_H_
|
||||
ValueCAN4_2EL::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,
|
||||
#ifdef __VALUECAN4INDUSTRIAL_H_
|
||||
ValueCAN4Industrial::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
#ifdef __VIVIDCAN_H_
|
||||
VividCAN::DEVICE_TYPE,
|
||||
#endif
|
||||
|
||||
};
|
||||
};
|
||||
|
||||
std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||
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
|
||||
|
||||
#ifdef __ETHERBADGE_H_
|
||||
findResults.push_back(EtherBADGE::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2PRO_H_
|
||||
findResults.push_back(NeoOBD2PRO::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __NEOOBD2SIM_H_
|
||||
findResults.push_back(NeoOBD2SIM::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE_H_
|
||||
findResults.push_back(NeoVIFIRE::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2ETH_H_
|
||||
findResults.push_back(NeoVIFIRE2ETH::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIFIRE2USB_H_
|
||||
findResults.push_back(NeoVIFIRE2USB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIRED2_H_
|
||||
findResults.push_back(NeoVIRED2::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIION_H_
|
||||
findResults.push_back(NeoVIION::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __NEOVIPLASMA_H_
|
||||
findResults.push_back(NeoVIPLASMA::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADEPSILON_H_
|
||||
findResults.push_back(RADEpsilon::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADGALAXY_H_
|
||||
findResults.push_back(RADGalaxy::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_ETH_H_
|
||||
findResults.push_back(RADMarsETH::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __RADMARS_USB_H_
|
||||
findResults.push_back(RADMarsUSB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_ETH_H_
|
||||
findResults.push_back(RADGigastarETH::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __RADGIGASTAR_USB_H_
|
||||
findResults.push_back(RADGigastarUSB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOON2_H_
|
||||
findResults.push_back(RADMoon2::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADMOONDUO_H_
|
||||
findResults.push_back(RADMoonDuo::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADPLUTOUSB_H_
|
||||
findResults.push_back(RADPlutoUSB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2ETH_H_
|
||||
findResults.push_back(RADStar2ETH::Find(pcapDevices));
|
||||
#endif
|
||||
|
||||
#ifdef __RADSTAR2USB_H_
|
||||
findResults.push_back(RADStar2USB::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __RADSUPERMOON_H_
|
||||
findResults.push_back(RADSupermoon::Find());
|
||||
#endif
|
||||
|
||||
#ifdef __VALUECAN3_H_
|
||||
findResults.push_back(ValueCAN3::Find());
|
||||
#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()));
|
||||
}
|
||||
|
||||
for(auto& device : foundDevices) {
|
||||
AddBuiltInExtensionsTo(device);
|
||||
}
|
||||
|
||||
return foundDevices;
|
||||
}
|
||||
|
||||
const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||
if(!supportedDevicesCached) {
|
||||
supportedDevices.erase(std::unique(supportedDevices.begin(), supportedDevices.end()), supportedDevices.end());
|
||||
supportedDevicesCached = true;
|
||||
}
|
||||
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) {
|
||||
|
||||
+34
-29
@@ -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) {
|
||||
|
||||
+40
-41
@@ -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) {
|
||||
|
||||
+42
-42
@@ -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) {
|
||||
|
||||
+19
-16
@@ -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) {
|
||||
|
||||
Vendored
+4
-2
@@ -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);
|
||||
|
||||
Reference in New Issue
Block a user