diff --git a/CMakeLists.txt b/CMakeLists.txt index 844d25c..5c9892b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -355,7 +355,7 @@ if(LIBICSNEO_ENABLE_DXX) include(FetchContent) FetchContent_Declare(libredxx GIT_REPOSITORY https://github.com/Zeranoe/libredxx.git - GIT_TAG 3acc754d0af4fe529f05dbc2488b2da77ad9729c + GIT_TAG 070402e425fa6e1a9da08967bbadee00fb7b5e68 ) set(LIBREDXX_DISABLE_INSTALL ON) FetchContent_MakeAvailable(libredxx) diff --git a/communication/driver.cpp b/communication/driver.cpp index c50dec5..5c56638 100644 --- a/communication/driver.cpp +++ b/communication/driver.cpp @@ -38,18 +38,10 @@ bool Driver::waitForRx(std::function predicate, std::chrono::millisecond } bool Driver::readWait(std::vector& bytes, std::chrono::milliseconds timeout, size_t limit) { - // A limit of zero indicates no limit - if(limit == 0) - limit = (size_t)-1; - - if(limit > (readBuffer.size() + 4)) - limit = (readBuffer.size() + 4); - - - // wait until we have enough data, or the timout occurs + // wait until we have enough data, or the timeout occurs waitForRx(limit, timeout); - size_t actuallyRead = std::min(readBuffer.size(), limit); + size_t actuallyRead = readBuffer.size(); bytes.resize(actuallyRead); readBuffer.read(bytes.data(), 0, actuallyRead); diff --git a/communication/multichannelcommunication.cpp b/communication/multichannelcommunication.cpp index ec4ef55..0c70609 100644 --- a/communication/multichannelcommunication.cpp +++ b/communication/multichannelcommunication.cpp @@ -24,6 +24,7 @@ void MultiChannelCommunication::spawnThreads() { void MultiChannelCommunication::joinThreads() { closing = true; + ringBufCV.notify_all(); if(hidReadThread.joinable()) hidReadThread.join(); for(auto& thread : vnetThreads) { @@ -179,6 +180,9 @@ void MultiChannelCommunication::vnetReadTask(size_t vnetIndex) { while(!closing) { std::unique_lock lk(ringBufMutex); ringBufCV.wait(lk); + if(closing) { + break; + } if(vnetPacketizer->input(packetRB)) { for(const auto& packet : vnetPacketizer->output()) { std::shared_ptr msg; diff --git a/device/devicefinder.cpp b/device/devicefinder.cpp index cad92e2..bcbf08e 100644 --- a/device/devicefinder.cpp +++ b/device/devicefinder.cpp @@ -35,15 +35,6 @@ static void makeIfSerialMatches(const FoundDevice& dev, std::vector(dev)); } -template -static void makeIfPIDMatches(const FoundDevice& dev, std::vector>& 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(dev)); -} - template static void makeIfSerialRangeMatches(const FoundDevice& dev, std::vector>& into) { // Relies on the subclass to have @@ -139,7 +130,7 @@ std::vector> DeviceFinder::FindAll() { #endif #ifdef __NEOVIFIRE_H_ - makeIfPIDMatches(dev, newFoundDevices); + makeIfSerialRangeMatches(dev, newFoundDevices); #endif #ifdef __NEOVIFIRE2_H_ @@ -159,11 +150,11 @@ std::vector> DeviceFinder::FindAll() { #endif #ifdef __NEOVIION_H_ - makeIfPIDMatches(dev, newFoundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __NEOVIPLASMA_H_ - makeIfPIDMatches(dev, newFoundDevices); + makeIfSerialMatches(dev, newFoundDevices); #endif #ifdef __RADA2B_H_ @@ -247,7 +238,7 @@ std::vector> DeviceFinder::FindAll() { #endif #ifdef __VALUECAN3_H_ - makeIfPIDMatches(dev, newFoundDevices); + makeIfSerialRangeMatches(dev, newFoundDevices); #endif #ifdef __VALUECAN4_1_H_ diff --git a/include/icsneo/communication/driver.h b/include/icsneo/communication/driver.h index 2949537..515b0c9 100644 --- a/include/icsneo/communication/driver.h +++ b/include/icsneo/communication/driver.h @@ -31,7 +31,7 @@ public: bool waitForRx(size_t limit, std::chrono::milliseconds timeout); bool waitForRx(std::function predicate, std::chrono::milliseconds timeout); - bool readWait(std::vector& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 0); + bool readWait(std::vector& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 1); bool write(const std::vector& bytes); virtual bool isEthernet() const { return false; } bool readAvailable() { return readBuffer.size() > 0; } diff --git a/include/icsneo/device/tree/neovifire/neovifire.h b/include/icsneo/device/tree/neovifire/neovifire.h index f1562ca..331f9e0 100644 --- a/include/icsneo/device/tree/neovifire/neovifire.h +++ b/include/icsneo/device/tree/neovifire/neovifire.h @@ -12,7 +12,7 @@ namespace icsneo { class NeoVIFIRE : public Device { public: // USB PID is 0x0701, standard driver is DXX - ICSNEO_FINDABLE_DEVICE_BY_PID(NeoVIFIRE, DeviceType::FIRE, 0x0701); + ICSNEO_FINDABLE_DEVICE_BY_SERIAL_RANGE(NeoVIFIRE, DeviceType::FIRE, "50000", "79999"); static const std::vector& GetSupportedNetworks() { static std::vector supportedNetworks = { diff --git a/include/icsneo/device/tree/plasion/neoviion.h b/include/icsneo/device/tree/plasion/neoviion.h index 432c28c..9cf5405 100644 --- a/include/icsneo/device/tree/plasion/neoviion.h +++ b/include/icsneo/device/tree/plasion/neoviion.h @@ -13,7 +13,7 @@ namespace icsneo { class NeoVIION : public Plasion { public: // USB PID is 0x0901, standard driver is DXX - ICSNEO_FINDABLE_DEVICE_BY_PID(NeoVIION, DeviceType::ION, 0x0901); + ICSNEO_FINDABLE_DEVICE(NeoVIION, DeviceType::ION, "40"); private: NeoVIION(neodevice_t neodevice, const driver_factory_t& makeDriver) : Plasion(neodevice) { diff --git a/include/icsneo/device/tree/plasion/neoviplasma.h b/include/icsneo/device/tree/plasion/neoviplasma.h index 89af1bb..22bcfd0 100644 --- a/include/icsneo/device/tree/plasion/neoviplasma.h +++ b/include/icsneo/device/tree/plasion/neoviplasma.h @@ -11,7 +11,7 @@ namespace icsneo { class NeoVIPLASMA : public Plasion { public: // USB PID is 0x0801, standard driver is DXX - ICSNEO_FINDABLE_DEVICE_BY_PID(NeoVIPLASMA, DeviceType::PLASMA, 0x0801); + ICSNEO_FINDABLE_DEVICE(NeoVIPLASMA, DeviceType::PLASMA, "30"); private: NeoVIPLASMA(neodevice_t neodevice, const driver_factory_t& makeDriver) : Plasion(neodevice) { diff --git a/include/icsneo/device/tree/plasion/plasion.h b/include/icsneo/device/tree/plasion/plasion.h index 8d0a645..8fcae8f 100644 --- a/include/icsneo/device/tree/plasion/plasion.h +++ b/include/icsneo/device/tree/plasion/plasion.h @@ -43,6 +43,8 @@ public: // Until VNET support is added, assume we have one FIRE 2 VNET or FlexRay VNETZ as the main size_t getEthernetActivationLineCount() const override { return 1; } + bool supportsComponentVersions() const override { return true; } + protected: using Device::Device; diff --git a/include/icsneo/device/tree/valuecan3/valuecan3.h b/include/icsneo/device/tree/valuecan3/valuecan3.h index e9d3a79..337fb35 100644 --- a/include/icsneo/device/tree/valuecan3/valuecan3.h +++ b/include/icsneo/device/tree/valuecan3/valuecan3.h @@ -12,7 +12,7 @@ namespace icsneo { class ValueCAN3 : public Device { public: // USB PID is 0x0601, standard driver is DXX - ICSNEO_FINDABLE_DEVICE_BY_PID(ValueCAN3, DeviceType::VCAN3, 0x0601); + ICSNEO_FINDABLE_DEVICE_BY_SERIAL_RANGE(ValueCAN3, DeviceType::VCAN3, "80000", "139999"); static const std::vector& GetSupportedNetworks() { static std::vector supportedNetworks = { diff --git a/platform/dxx.cpp b/platform/dxx.cpp index 8dd869b..9318d32 100644 --- a/platform/dxx.cpp +++ b/platform/dxx.cpp @@ -20,9 +20,13 @@ void DXX::Find(std::vector& found) { static libredxx_find_filter filters[] = { { LIBREDXX_DEVICE_TYPE_D2XX, { ICS_USB_VID, 0x0005 } }, // RAD-Star 2 { LIBREDXX_DEVICE_TYPE_D2XX, { ICS_USB_VID, 0x0006 } }, // RAD-A2B Rev A + { LIBREDXX_DEVICE_TYPE_D2XX, { ICS_USB_VID, 0x0601 } }, // ValueCAN 3 + { LIBREDXX_DEVICE_TYPE_D2XX, { ICS_USB_VID, 0x0701 } }, // FIRE + { LIBREDXX_DEVICE_TYPE_D2XX, { ICS_USB_VID, 0x0901 } }, // neoVI ION { LIBREDXX_DEVICE_TYPE_D2XX, { ICS_USB_VID, 0x1000 } }, // neoVI FIRE2 { LIBREDXX_DEVICE_TYPE_D3XX, { ICS_USB_VID, 0x1201 } }, // RAD-SuperMoon { LIBREDXX_DEVICE_TYPE_D3XX, { ICS_USB_VID, 0x1202 } }, // RAD-Moon2 + { LIBREDXX_DEVICE_TYPE_D3XX, { ICS_USB_VID, 0x1205 } }, // RAD-Moon2 { LIBREDXX_DEVICE_TYPE_D3XX, { ICS_USB_VID, 0x1203 } }, // RAD-Gigalog { LIBREDXX_DEVICE_TYPE_D3XX, { ICS_USB_VID, 0x1204 } }, // RAD-Gigastar { LIBREDXX_DEVICE_TYPE_D3XX, { ICS_USB_VID, 0x1206 } }, // RAD-A2B Rev B @@ -67,7 +71,8 @@ void DXX::Find(std::vector& found) { } auto& device = found.emplace_back(); - std::copy(serial.serial, serial.serial + sizeof(device.serial), device.serial); + // -1 to make sure serial has a trailing '\0' + std::copy(serial.serial, serial.serial + (sizeof(device.serial) - 1), device.serial); device.makeDriver = [id, type](device_eventhandler_t err, neodevice_t& forDevice) { return std::make_unique(err, forDevice, id.pid, type); }; @@ -104,7 +109,8 @@ bool DXX::open() { EventManager::GetInstance().add(eventError(status), APIEvent::Severity::EventWarning); continue; } - if(strcmp(serial.serial, neodevice.serial) == 0) { + + if(strncmp(serial.serial, neodevice.serial, sizeof(neodevice.serial) - 1) == 0) { foundDevice = foundDevices[i]; break; } diff --git a/platform/windows/cdcacm.cpp b/platform/windows/cdcacm.cpp index b595dd4..2a195b8 100644 --- a/platform/windows/cdcacm.cpp +++ b/platform/windows/cdcacm.cpp @@ -7,6 +7,8 @@ using namespace icsneo; +#define SERIAL_SIZE 6 + CDCACM::CDCACM(const device_eventhandler_t& err, const std::wstring& path) : Driver(err), path(path) { } @@ -205,14 +207,23 @@ void CDCACM::Find(std::vector& found) { continue; } - std::wstring wserial; - while(!SetupDiGetDevicePropertyW(deviceInfoSet, deviceInfoData, &DEVPKEY_Device_BusReportedDeviceDesc, &DataT, reinterpret_cast(wserial.data()), static_cast((wserial.size() + 1) * WSTRING_ELEMENT_SIZE), &buffersize, 0)) { - wserial.resize((buffersize - 1) / WSTRING_ELEMENT_SIZE); + auto serialOffset = deviceInstanceId.find_last_of('\\'); + + if(serialOffset == std::string::npos) { + continue; } - FoundDevice device; + ++serialOffset; // move past '\' - if(WideCharToMultiByte(CP_ACP, 0, wserial.c_str(), (int)wserial.size(), device.serial, sizeof(device.serial), NULL, NULL) == 0) { + if(deviceInstanceId.size() < serialOffset + SERIAL_SIZE) { + continue; + } + + std::wstring wserial(deviceInstanceId.c_str() + serialOffset, SERIAL_SIZE); + + FoundDevice device = {0}; + + if(WideCharToMultiByte(CP_ACP, 0, wserial.c_str(), (int)wserial.size(), device.serial, SERIAL_SIZE, NULL, NULL) == 0) { EventManager::GetInstance().add(APIEvent::Type::SyscallError, APIEvent::Severity::Error); continue; }