Repo: Normalize source files to LF
parent
781fc2c034
commit
008a1620c8
File diff suppressed because it is too large
Load Diff
|
|
@ -1,48 +1,48 @@
|
||||||
#include "icsneo/icsneocpp.h"
|
#include "icsneo/icsneocpp.h"
|
||||||
#include "icsneo/device/devicefinder.h"
|
#include "icsneo/device/devicefinder.h"
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Device>> icsneo::FindAllDevices() {
|
std::vector<std::shared_ptr<Device>> icsneo::FindAllDevices() {
|
||||||
return DeviceFinder::FindAll();
|
return DeviceFinder::FindAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<DeviceType> icsneo::GetSupportedDevices() {
|
std::vector<DeviceType> icsneo::GetSupportedDevices() {
|
||||||
return DeviceFinder::GetSupportedDevices();
|
return DeviceFinder::GetSupportedDevices();
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t icsneo::EventCount(EventFilter filter) {
|
size_t icsneo::EventCount(EventFilter filter) {
|
||||||
return EventManager::GetInstance().eventCount(filter);
|
return EventManager::GetInstance().eventCount(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<APIEvent> icsneo::GetEvents(EventFilter filter, size_t max) {
|
std::vector<APIEvent> icsneo::GetEvents(EventFilter filter, size_t max) {
|
||||||
return EventManager::GetInstance().get(filter, max);
|
return EventManager::GetInstance().get(filter, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<APIEvent> icsneo::GetEvents(size_t max, EventFilter filter) {
|
std::vector<APIEvent> icsneo::GetEvents(size_t max, EventFilter filter) {
|
||||||
return EventManager::GetInstance().get(max, filter);
|
return EventManager::GetInstance().get(max, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max) {
|
void icsneo::GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max) {
|
||||||
EventManager::GetInstance().get(events, filter, max);
|
EventManager::GetInstance().get(events, filter, max);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::GetEvents(std::vector<APIEvent>& events, size_t max, EventFilter filter) {
|
void icsneo::GetEvents(std::vector<APIEvent>& events, size_t max, EventFilter filter) {
|
||||||
EventManager::GetInstance().get(events, max, filter);
|
EventManager::GetInstance().get(events, max, filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
APIEvent icsneo::GetLastError() {
|
APIEvent icsneo::GetLastError() {
|
||||||
return EventManager::GetInstance().getLastError();
|
return EventManager::GetInstance().getLastError();
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::DiscardEvents(EventFilter filter) {
|
void icsneo::DiscardEvents(EventFilter filter) {
|
||||||
EventManager::GetInstance().discard(filter);
|
EventManager::GetInstance().discard(filter);
|
||||||
}
|
}
|
||||||
|
|
||||||
void icsneo::SetEventLimit(size_t newLimit) {
|
void icsneo::SetEventLimit(size_t newLimit) {
|
||||||
EventManager::GetInstance().setEventLimit(newLimit);
|
EventManager::GetInstance().setEventLimit(newLimit);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t icsneo::GetEventLimit() {
|
size_t icsneo::GetEventLimit() {
|
||||||
return EventManager::GetInstance().getEventLimit();
|
return EventManager::GetInstance().getEventLimit();
|
||||||
}
|
}
|
||||||
|
|
@ -1,264 +1,264 @@
|
||||||
#include "icsneo/device/devicefinder.h"
|
#include "icsneo/device/devicefinder.h"
|
||||||
#include "icsneo/platform/devices.h"
|
#include "icsneo/platform/devices.h"
|
||||||
#include "icsneo/device/founddevice.h"
|
#include "icsneo/device/founddevice.h"
|
||||||
#include "generated/extensions/builtin.h"
|
#include "generated/extensions/builtin.h"
|
||||||
|
|
||||||
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
||||||
#include "icsneo/platform/pcap.h"
|
#include "icsneo/platform/pcap.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ICSNEO_ENABLE_CDCACM
|
#ifdef ICSNEO_ENABLE_CDCACM
|
||||||
#include "icsneo/platform/cdcacm.h"
|
#include "icsneo/platform/cdcacm.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ICSNEO_ENABLE_FTDI
|
#ifdef ICSNEO_ENABLE_FTDI
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void makeIfSerialMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
|
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"`
|
// Relies on the subclass to have a `static constexpr const char* SERIAL_START = "XX"`
|
||||||
// and also a public constructor `T(const FoundDevice& dev)`
|
// and also a public constructor `T(const FoundDevice& dev)`
|
||||||
// Use macro ICSNEO_FINDABLE_DEVICE() to create these
|
// Use macro ICSNEO_FINDABLE_DEVICE() to create these
|
||||||
if(dev.serial[0] == T::SERIAL_START[0] && dev.serial[1] == T::SERIAL_START[1])
|
if(dev.serial[0] == T::SERIAL_START[0] && dev.serial[1] == T::SERIAL_START[1])
|
||||||
into.push_back(std::make_shared<T>(dev));
|
into.push_back(std::make_shared<T>(dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
template<typename T>
|
template<typename T>
|
||||||
static void makeIfPIDMatches(const FoundDevice& dev, std::vector<std::shared_ptr<Device>>& into) {
|
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`
|
// Relies on the subclass to have a `static constexpr uint16_t PRODUCT_ID = 0x1111`
|
||||||
// and also a public constructor `T(const FoundDevice& dev)`
|
// and also a public constructor `T(const FoundDevice& dev)`
|
||||||
// Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these
|
// Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these
|
||||||
if(dev.productId == T::PRODUCT_ID)
|
if(dev.productId == T::PRODUCT_ID)
|
||||||
into.push_back(std::make_shared<T>(dev));
|
into.push_back(std::make_shared<T>(dev));
|
||||||
}
|
}
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
std::vector<std::shared_ptr<Device>> DeviceFinder::FindAll() {
|
||||||
static std::vector<FoundDevice> driverFoundDevices;
|
static std::vector<FoundDevice> driverFoundDevices;
|
||||||
driverFoundDevices.clear();
|
driverFoundDevices.clear();
|
||||||
|
|
||||||
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
#ifdef ICSNEO_ENABLE_RAW_ETHERNET
|
||||||
PCAP::Find(driverFoundDevices);
|
PCAP::Find(driverFoundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ICSNEO_ENABLE_CDCACM
|
#ifdef ICSNEO_ENABLE_CDCACM
|
||||||
CDCACM::Find(driverFoundDevices);
|
CDCACM::Find(driverFoundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef ICSNEO_ENABLE_FTDI
|
#ifdef ICSNEO_ENABLE_FTDI
|
||||||
FTDI::Find(driverFoundDevices);
|
FTDI::Find(driverFoundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Device>> foundDevices;
|
std::vector<std::shared_ptr<Device>> foundDevices;
|
||||||
|
|
||||||
// Offer found devices to each of the subclasses
|
// Offer found devices to each of the subclasses
|
||||||
for (const FoundDevice& dev : driverFoundDevices) {
|
for (const FoundDevice& dev : driverFoundDevices) {
|
||||||
#ifdef __ETHERBADGE_H_
|
#ifdef __ETHERBADGE_H_
|
||||||
makeIfSerialMatches<EtherBADGE>(dev, foundDevices);
|
makeIfSerialMatches<EtherBADGE>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOOBD2PRO_H_
|
#ifdef __NEOOBD2PRO_H_
|
||||||
makeIfSerialMatches<NeoOBD2PRO>(dev, foundDevices);
|
makeIfSerialMatches<NeoOBD2PRO>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOOBD2SIM_H_
|
#ifdef __NEOOBD2SIM_H_
|
||||||
makeIfSerialMatches<NeoOBD2SIM>(dev, foundDevices);
|
makeIfSerialMatches<NeoOBD2SIM>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIFIRE_H_
|
#ifdef __NEOVIFIRE_H_
|
||||||
makeIfPIDMatches<NeoVIFIRE>(dev, foundDevices);
|
makeIfPIDMatches<NeoVIFIRE>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIFIRE2_H_
|
#ifdef __NEOVIFIRE2_H_
|
||||||
makeIfSerialMatches<NeoVIFIRE2>(dev, foundDevices);
|
makeIfSerialMatches<NeoVIFIRE2>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIRED2_H_
|
#ifdef __NEOVIRED2_H_
|
||||||
makeIfSerialMatches<NeoVIRED2>(dev, foundDevices);
|
makeIfSerialMatches<NeoVIRED2>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIION_H_
|
#ifdef __NEOVIION_H_
|
||||||
makeIfPIDMatches<NeoVIION>(dev, foundDevices);
|
makeIfPIDMatches<NeoVIION>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIPLASMA_H_
|
#ifdef __NEOVIPLASMA_H_
|
||||||
makeIfPIDMatches<NeoVIPLASMA>(dev, foundDevices);
|
makeIfPIDMatches<NeoVIPLASMA>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADEPSILON_H_
|
#ifdef __RADEPSILON_H_
|
||||||
makeIfSerialMatches<RADEpsilon>(dev, foundDevices);
|
makeIfSerialMatches<RADEpsilon>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADGALAXY_H_
|
#ifdef __RADGALAXY_H_
|
||||||
makeIfSerialMatches<RADGalaxy>(dev, foundDevices);
|
makeIfSerialMatches<RADGalaxy>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADMARS_H_
|
#ifdef __RADMARS_H_
|
||||||
makeIfSerialMatches<RADMars>(dev, foundDevices);
|
makeIfSerialMatches<RADMars>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADGIGASTAR_H_
|
#ifdef __RADGIGASTAR_H_
|
||||||
makeIfSerialMatches<RADGigastar>(dev, foundDevices);
|
makeIfSerialMatches<RADGigastar>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADMOON2_H_
|
#ifdef __RADMOON2_H_
|
||||||
makeIfSerialMatches<RADMoon2>(dev, foundDevices);
|
makeIfSerialMatches<RADMoon2>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADMOONDUO_H_
|
#ifdef __RADMOONDUO_H_
|
||||||
makeIfSerialMatches<RADMoonDuo>(dev, foundDevices);
|
makeIfSerialMatches<RADMoonDuo>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADPLUTO_H_
|
#ifdef __RADPLUTO_H_
|
||||||
makeIfSerialMatches<RADPluto>(dev, foundDevices);
|
makeIfSerialMatches<RADPluto>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADSTAR2_H_
|
#ifdef __RADSTAR2_H_
|
||||||
makeIfSerialMatches<RADStar2>(dev, foundDevices);
|
makeIfSerialMatches<RADStar2>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADSUPERMOON_H_
|
#ifdef __RADSUPERMOON_H_
|
||||||
makeIfSerialMatches<RADSupermoon>(dev, foundDevices);
|
makeIfSerialMatches<RADSupermoon>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN3_H_
|
#ifdef __VALUECAN3_H_
|
||||||
makeIfPIDMatches<ValueCAN3>(dev, foundDevices);
|
makeIfPIDMatches<ValueCAN3>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_1_H_
|
#ifdef __VALUECAN4_1_H_
|
||||||
makeIfSerialMatches<ValueCAN4_1>(dev, foundDevices);
|
makeIfSerialMatches<ValueCAN4_1>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_2_H_
|
#ifdef __VALUECAN4_2_H_
|
||||||
makeIfSerialMatches<ValueCAN4_2>(dev, foundDevices);
|
makeIfSerialMatches<ValueCAN4_2>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_2EL_H_
|
#ifdef __VALUECAN4_2EL_H_
|
||||||
makeIfSerialMatches<ValueCAN4_2EL>(dev, foundDevices);
|
makeIfSerialMatches<ValueCAN4_2EL>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_4_H_
|
#ifdef __VALUECAN4_4_H_
|
||||||
makeIfSerialMatches<ValueCAN4_4>(dev, foundDevices);
|
makeIfSerialMatches<ValueCAN4_4>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4INDUSTRIAL_H_
|
#ifdef __VALUECAN4INDUSTRIAL_H_
|
||||||
makeIfSerialMatches<ValueCAN4Industrial>(dev, foundDevices);
|
makeIfSerialMatches<ValueCAN4Industrial>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VIVIDCAN_H_
|
#ifdef __VIVIDCAN_H_
|
||||||
makeIfSerialMatches<VividCAN>(dev, foundDevices);
|
makeIfSerialMatches<VividCAN>(dev, foundDevices);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
for(auto& device : foundDevices) {
|
for(auto& device : foundDevices) {
|
||||||
AddBuiltInExtensionsTo(device);
|
AddBuiltInExtensionsTo(device);
|
||||||
}
|
}
|
||||||
|
|
||||||
return foundDevices;
|
return foundDevices;
|
||||||
}
|
}
|
||||||
|
|
||||||
const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
const std::vector<DeviceType>& DeviceFinder::GetSupportedDevices() {
|
||||||
static std::vector<DeviceType> supportedDevices = {
|
static std::vector<DeviceType> supportedDevices = {
|
||||||
|
|
||||||
#ifdef __ETHERBADGE_H_
|
#ifdef __ETHERBADGE_H_
|
||||||
EtherBADGE::DEVICE_TYPE,
|
EtherBADGE::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOOBD2PRO_H_
|
#ifdef __NEOOBD2PRO_H_
|
||||||
NeoOBD2PRO::DEVICE_TYPE,
|
NeoOBD2PRO::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOOBD2SIM_H_
|
#ifdef __NEOOBD2SIM_H_
|
||||||
NeoOBD2SIM::DEVICE_TYPE,
|
NeoOBD2SIM::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIRED2_H_
|
#ifdef __NEOVIRED2_H_
|
||||||
NeoVIRED2::DEVICE_TYPE,
|
NeoVIRED2::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIFIRE_H_
|
#ifdef __NEOVIFIRE_H_
|
||||||
NeoVIFIRE::DEVICE_TYPE,
|
NeoVIFIRE::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIFIRE2_H_
|
#ifdef __NEOVIFIRE2_H_
|
||||||
NeoVIFIRE2::DEVICE_TYPE,
|
NeoVIFIRE2::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIION_H_
|
#ifdef __NEOVIION_H_
|
||||||
NeoVIION::DEVICE_TYPE,
|
NeoVIION::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __NEOVIPLASMA_H_
|
#ifdef __NEOVIPLASMA_H_
|
||||||
NeoVIPLASMA::DEVICE_TYPE,
|
NeoVIPLASMA::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADEPSILON_H_
|
#ifdef __RADEPSILON_H_
|
||||||
RADEpsilon::DEVICE_TYPE,
|
RADEpsilon::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADGALAXY_H_
|
#ifdef __RADGALAXY_H_
|
||||||
RADGalaxy::DEVICE_TYPE,
|
RADGalaxy::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADMARS_H_
|
#ifdef __RADMARS_H_
|
||||||
RADMars::DEVICE_TYPE,
|
RADMars::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADGIGASTAR_H_
|
#ifdef __RADGIGASTAR_H_
|
||||||
RADGigastar::DEVICE_TYPE,
|
RADGigastar::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADMOON2_H_
|
#ifdef __RADMOON2_H_
|
||||||
RADMoon2::DEVICE_TYPE,
|
RADMoon2::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADMOONDUO_H_
|
#ifdef __RADMOONDUO_H_
|
||||||
RADMoonDuo::DEVICE_TYPE,
|
RADMoonDuo::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADPLUTO_H_
|
#ifdef __RADPLUTO_H_
|
||||||
RADPluto::DEVICE_TYPE,
|
RADPluto::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADSTAR2_H_
|
#ifdef __RADSTAR2_H_
|
||||||
RADStar2::DEVICE_TYPE,
|
RADStar2::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __RADSUPERMOON_H_
|
#ifdef __RADSUPERMOON_H_
|
||||||
RADSupermoon::DEVICE_TYPE,
|
RADSupermoon::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN3_H_
|
#ifdef __VALUECAN3_H_
|
||||||
ValueCAN3::DEVICE_TYPE,
|
ValueCAN3::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_1_H_
|
#ifdef __VALUECAN4_1_H_
|
||||||
ValueCAN4_1::DEVICE_TYPE,
|
ValueCAN4_1::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_2_H_
|
#ifdef __VALUECAN4_2_H_
|
||||||
ValueCAN4_2::DEVICE_TYPE,
|
ValueCAN4_2::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_2EL_H_
|
#ifdef __VALUECAN4_2EL_H_
|
||||||
ValueCAN4_2EL::DEVICE_TYPE,
|
ValueCAN4_2EL::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4_4_H_
|
#ifdef __VALUECAN4_4_H_
|
||||||
ValueCAN4_4::DEVICE_TYPE,
|
ValueCAN4_4::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VALUECAN4INDUSTRIAL_H_
|
#ifdef __VALUECAN4INDUSTRIAL_H_
|
||||||
ValueCAN4Industrial::DEVICE_TYPE,
|
ValueCAN4Industrial::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef __VIVIDCAN_H_
|
#ifdef __VIVIDCAN_H_
|
||||||
VividCAN::DEVICE_TYPE,
|
VividCAN::DEVICE_TYPE,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
return supportedDevices;
|
return supportedDevices;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,61 +1,61 @@
|
||||||
#ifndef __DRIVER_H_
|
#ifndef __DRIVER_H_
|
||||||
#define __DRIVER_H_
|
#define __DRIVER_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <mutex>
|
#include <mutex>
|
||||||
#include <condition_variable>
|
#include <condition_variable>
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/eventmanager.h"
|
||||||
#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h"
|
#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class Driver {
|
class Driver {
|
||||||
public:
|
public:
|
||||||
Driver(const device_eventhandler_t& handler) : report(handler) {}
|
Driver(const device_eventhandler_t& handler) : report(handler) {}
|
||||||
virtual ~Driver() {}
|
virtual ~Driver() {}
|
||||||
virtual bool open() = 0;
|
virtual bool open() = 0;
|
||||||
virtual bool isOpen() = 0;
|
virtual bool isOpen() = 0;
|
||||||
virtual void modeChangeIncoming() {}
|
virtual void modeChangeIncoming() {}
|
||||||
virtual void awaitModeChangeComplete() {}
|
virtual void awaitModeChangeComplete() {}
|
||||||
virtual bool isDisconnected() { return disconnected; };
|
virtual bool isDisconnected() { return disconnected; };
|
||||||
virtual bool close() = 0;
|
virtual bool close() = 0;
|
||||||
virtual bool read(std::vector<uint8_t>& bytes, size_t limit = 0);
|
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 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 write(const std::vector<uint8_t>& bytes);
|
||||||
virtual bool isEthernet() const { return false; }
|
virtual bool isEthernet() const { return false; }
|
||||||
|
|
||||||
device_eventhandler_t report;
|
device_eventhandler_t report;
|
||||||
|
|
||||||
size_t writeQueueSize = 50;
|
size_t writeQueueSize = 50;
|
||||||
bool writeBlocks = true; // Otherwise it just fails when the queue is full
|
bool writeBlocks = true; // Otherwise it just fails when the queue is full
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
class WriteOperation {
|
class WriteOperation {
|
||||||
public:
|
public:
|
||||||
WriteOperation() {}
|
WriteOperation() {}
|
||||||
WriteOperation(const std::vector<uint8_t>& b) : bytes(b) {}
|
WriteOperation(const std::vector<uint8_t>& b) : bytes(b) {}
|
||||||
std::vector<uint8_t> bytes;
|
std::vector<uint8_t> bytes;
|
||||||
};
|
};
|
||||||
enum IOTaskState {
|
enum IOTaskState {
|
||||||
LAUNCH,
|
LAUNCH,
|
||||||
WAIT
|
WAIT
|
||||||
};
|
};
|
||||||
virtual void readTask() = 0;
|
virtual void readTask() = 0;
|
||||||
virtual void writeTask() = 0;
|
virtual void writeTask() = 0;
|
||||||
moodycamel::BlockingConcurrentQueue<uint8_t> readQueue;
|
moodycamel::BlockingConcurrentQueue<uint8_t> readQueue;
|
||||||
moodycamel::BlockingConcurrentQueue<WriteOperation> writeQueue;
|
moodycamel::BlockingConcurrentQueue<WriteOperation> writeQueue;
|
||||||
std::thread readThread, writeThread;
|
std::thread readThread, writeThread;
|
||||||
std::atomic<bool> closing{false};
|
std::atomic<bool> closing{false};
|
||||||
std::atomic<bool> disconnected{false};
|
std::atomic<bool> disconnected{false};
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,50 +1,50 @@
|
||||||
#ifndef __MESSAGECALLBACK_H_
|
#ifndef __MESSAGECALLBACK_H_
|
||||||
#define __MESSAGECALLBACK_H_
|
#define __MESSAGECALLBACK_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/communication/message/message.h"
|
#include "icsneo/communication/message/message.h"
|
||||||
#include "icsneo/communication/message/filter/messagefilter.h"
|
#include "icsneo/communication/message/filter/messagefilter.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <functional>
|
#include <functional>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class MessageCallback {
|
class MessageCallback {
|
||||||
public:
|
public:
|
||||||
typedef std::function< void( std::shared_ptr<Message> ) > fn_messageCallback;
|
typedef std::function< void( std::shared_ptr<Message> ) > fn_messageCallback;
|
||||||
|
|
||||||
MessageCallback(fn_messageCallback cb, std::shared_ptr<MessageFilter> f)
|
MessageCallback(fn_messageCallback cb, std::shared_ptr<MessageFilter> f)
|
||||||
: callback(cb), filter(f ? f : std::make_shared<MessageFilter>()) {
|
: callback(cb), filter(f ? f : std::make_shared<MessageFilter>()) {
|
||||||
if(!cb)
|
if(!cb)
|
||||||
throw std::bad_function_call();
|
throw std::bad_function_call();
|
||||||
}
|
}
|
||||||
|
|
||||||
MessageCallback(fn_messageCallback cb, MessageFilter f = MessageFilter())
|
MessageCallback(fn_messageCallback cb, MessageFilter f = MessageFilter())
|
||||||
: MessageCallback(cb, std::make_shared<MessageFilter>(f)) {}
|
: MessageCallback(cb, std::make_shared<MessageFilter>(f)) {}
|
||||||
|
|
||||||
// Allow the filter to be placed first if the user wants (maybe in the case of a lambda)
|
// Allow the filter to be placed first if the user wants (maybe in the case of a lambda)
|
||||||
MessageCallback(std::shared_ptr<MessageFilter> f, fn_messageCallback cb)
|
MessageCallback(std::shared_ptr<MessageFilter> f, fn_messageCallback cb)
|
||||||
: MessageCallback(cb, f) {}
|
: MessageCallback(cb, f) {}
|
||||||
MessageCallback(MessageFilter f, fn_messageCallback cb)
|
MessageCallback(MessageFilter f, fn_messageCallback cb)
|
||||||
: MessageCallback(cb, std::make_shared<MessageFilter>(f)) {}
|
: MessageCallback(cb, std::make_shared<MessageFilter>(f)) {}
|
||||||
|
|
||||||
virtual bool callIfMatch(const std::shared_ptr<Message>& message) const {
|
virtual bool callIfMatch(const std::shared_ptr<Message>& message) const {
|
||||||
bool ret = filter->match(message);
|
bool ret = filter->match(message);
|
||||||
if(ret)
|
if(ret)
|
||||||
callback(message);
|
callback(message);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
const MessageFilter& getFilter() const { return *filter; }
|
const MessageFilter& getFilter() const { return *filter; }
|
||||||
const fn_messageCallback& getCallback() const { return callback; }
|
const fn_messageCallback& getCallback() const { return callback; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const fn_messageCallback callback;
|
const fn_messageCallback callback;
|
||||||
const std::shared_ptr<MessageFilter> filter;
|
const std::shared_ptr<MessageFilter> filter;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,25 +1,25 @@
|
||||||
#ifndef __CANMESSAGE_H_
|
#ifndef __CANMESSAGE_H_
|
||||||
#define __CANMESSAGE_H_
|
#define __CANMESSAGE_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/communication/message/message.h"
|
#include "icsneo/communication/message/message.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class CANMessage : public Frame {
|
class CANMessage : public Frame {
|
||||||
public:
|
public:
|
||||||
uint32_t arbid;
|
uint32_t arbid;
|
||||||
uint8_t dlcOnWire;
|
uint8_t dlcOnWire;
|
||||||
bool isRemote = false; // Not allowed if CAN FD
|
bool isRemote = false; // Not allowed if CAN FD
|
||||||
bool isExtended = false;
|
bool isExtended = false;
|
||||||
bool isCANFD = false;
|
bool isCANFD = false;
|
||||||
bool baudrateSwitch = false; // CAN FD only
|
bool baudrateSwitch = false; // CAN FD only
|
||||||
bool errorStateIndicator = false; // CAN FD only
|
bool errorStateIndicator = false; // CAN FD only
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,68 +1,68 @@
|
||||||
#ifndef __MESSAGEFILTER_H_
|
#ifndef __MESSAGEFILTER_H_
|
||||||
#define __MESSAGEFILTER_H_
|
#define __MESSAGEFILTER_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/communication/network.h"
|
#include "icsneo/communication/network.h"
|
||||||
#include "icsneo/communication/message/message.h"
|
#include "icsneo/communication/message/message.h"
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class MessageFilter {
|
class MessageFilter {
|
||||||
public:
|
public:
|
||||||
MessageFilter() {}
|
MessageFilter() {}
|
||||||
MessageFilter(Message::Type type) : includeInternalInAny(neomessagetype_t(type) & 0x8000), messageType(type) {}
|
MessageFilter(Message::Type type) : includeInternalInAny(neomessagetype_t(type) & 0x8000), messageType(type) {}
|
||||||
MessageFilter(Network::NetID netid) : MessageFilter(Network::GetTypeOfNetID(netid), netid) {}
|
MessageFilter(Network::NetID netid) : MessageFilter(Network::GetTypeOfNetID(netid), netid) {}
|
||||||
MessageFilter(Network::Type type, Network::NetID net = Network::NetID::Any) : networkType(type), netid(net) {
|
MessageFilter(Network::Type type, Network::NetID net = Network::NetID::Any) : networkType(type), netid(net) {
|
||||||
// If a Network::Type::Internal is used, we want to also get internal Message::Types
|
// If a Network::Type::Internal is used, we want to also get internal Message::Types
|
||||||
// The NetID we want may be in there
|
// The NetID we want may be in there
|
||||||
includeInternalInAny = (networkType == Network::Type::Internal);
|
includeInternalInAny = (networkType == Network::Type::Internal);
|
||||||
}
|
}
|
||||||
virtual ~MessageFilter() = default;
|
virtual ~MessageFilter() = default;
|
||||||
// When getting "all" types of messages, include the ones marked as "internal only"
|
// When getting "all" types of messages, include the ones marked as "internal only"
|
||||||
bool includeInternalInAny = false;
|
bool includeInternalInAny = false;
|
||||||
|
|
||||||
virtual bool match(const std::shared_ptr<Message>& message) const {
|
virtual bool match(const std::shared_ptr<Message>& message) const {
|
||||||
if(!matchMessageType(message->type))
|
if(!matchMessageType(message->type))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(message->type == Message::Type::Frame || message->type == Message::Type::Main51 ||
|
if(message->type == Message::Type::Frame || message->type == Message::Type::Main51 ||
|
||||||
message->type == Message::Type::RawMessage || message->type == Message::Type::ReadSettings) {
|
message->type == Message::Type::RawMessage || message->type == Message::Type::ReadSettings) {
|
||||||
RawMessage& frame = *static_cast<RawMessage*>(message.get());
|
RawMessage& frame = *static_cast<RawMessage*>(message.get());
|
||||||
if(!matchNetworkType(frame.network.getType()))
|
if(!matchNetworkType(frame.network.getType()))
|
||||||
return false;
|
return false;
|
||||||
if(!matchNetID(frame.network.getNetID()))
|
if(!matchNetID(frame.network.getNetID()))
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
Message::Type messageType = Message::Type::Invalid; // Used here for "any"
|
Message::Type messageType = Message::Type::Invalid; // Used here for "any"
|
||||||
bool matchMessageType(Message::Type mtype) const {
|
bool matchMessageType(Message::Type mtype) const {
|
||||||
if(messageType == Message::Type::Invalid && ((neomessagetype_t(mtype) & 0x8000) == 0 || includeInternalInAny))
|
if(messageType == Message::Type::Invalid && ((neomessagetype_t(mtype) & 0x8000) == 0 || includeInternalInAny))
|
||||||
return true;
|
return true;
|
||||||
return messageType == mtype;
|
return messageType == mtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
Network::Type networkType = Network::Type::Any;
|
Network::Type networkType = Network::Type::Any;
|
||||||
bool matchNetworkType(Network::Type mtype) const {
|
bool matchNetworkType(Network::Type mtype) const {
|
||||||
if(networkType == Network::Type::Any && (mtype != Network::Type::Internal || includeInternalInAny))
|
if(networkType == Network::Type::Any && (mtype != Network::Type::Internal || includeInternalInAny))
|
||||||
return true;
|
return true;
|
||||||
return networkType == mtype;
|
return networkType == mtype;
|
||||||
}
|
}
|
||||||
|
|
||||||
Network::NetID netid = Network::NetID::Any;
|
Network::NetID netid = Network::NetID::Any;
|
||||||
bool matchNetID(Network::NetID mnetid) const {
|
bool matchNetID(Network::NetID mnetid) const {
|
||||||
if(netid == Network::NetID::Any)
|
if(netid == Network::NetID::Any)
|
||||||
return true;
|
return true;
|
||||||
return netid == mnetid;
|
return netid == mnetid;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
#ifndef __ISO9141MESSAGE_H_
|
#ifndef __ISO9141MESSAGE_H_
|
||||||
#define __ISO9141MESSAGE_H_
|
#define __ISO9141MESSAGE_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/communication/message/message.h"
|
#include "icsneo/communication/message/message.h"
|
||||||
#include <array>
|
#include <array>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ISO9141Message : public Frame {
|
class ISO9141Message : public Frame {
|
||||||
public:
|
public:
|
||||||
std::array<uint8_t, 3> header;
|
std::array<uint8_t, 3> header;
|
||||||
bool isInit = false;
|
bool isInit = false;
|
||||||
bool isBreak = false;
|
bool isBreak = false;
|
||||||
bool framingError = false;
|
bool framingError = false;
|
||||||
bool overflowError = false;
|
bool overflowError = false;
|
||||||
bool parityError = false;
|
bool parityError = false;
|
||||||
bool rxTimeoutError = false;
|
bool rxTimeoutError = false;
|
||||||
// Checksum not yet implemted, it's just at the end of the data if enabled for now
|
// Checksum not yet implemted, it's just at the end of the data if enabled for now
|
||||||
// bool checksumError = false;
|
// bool checksumError = false;
|
||||||
// bool hasChecksum = false;
|
// bool hasChecksum = false;
|
||||||
// uint8_t checksum = 0;
|
// uint8_t checksum = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,77 +1,77 @@
|
||||||
#ifndef __MESSAGE_H_
|
#ifndef __MESSAGE_H_
|
||||||
#define __MESSAGE_H_
|
#define __MESSAGE_H_
|
||||||
|
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
typedef uint16_t neomessagetype_t;
|
typedef uint16_t neomessagetype_t;
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/communication/network.h"
|
#include "icsneo/communication/network.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class Message {
|
class Message {
|
||||||
public:
|
public:
|
||||||
enum class Type : neomessagetype_t {
|
enum class Type : neomessagetype_t {
|
||||||
Frame = 0,
|
Frame = 0,
|
||||||
|
|
||||||
CANErrorCount = 0x100,
|
CANErrorCount = 0x100,
|
||||||
|
|
||||||
// Past 0x8000 are all for internal use only
|
// Past 0x8000 are all for internal use only
|
||||||
Invalid = 0x8000,
|
Invalid = 0x8000,
|
||||||
RawMessage = 0x8001,
|
RawMessage = 0x8001,
|
||||||
ReadSettings = 0x8002,
|
ReadSettings = 0x8002,
|
||||||
ResetStatus = 0x8003,
|
ResetStatus = 0x8003,
|
||||||
DeviceVersion = 0x8004,
|
DeviceVersion = 0x8004,
|
||||||
Main51 = 0x8005,
|
Main51 = 0x8005,
|
||||||
FlexRayControl = 0x8006,
|
FlexRayControl = 0x8006,
|
||||||
EthernetPhyRegister = 0x8007,
|
EthernetPhyRegister = 0x8007,
|
||||||
LogicalDiskInfo = 0x8008,
|
LogicalDiskInfo = 0x8008,
|
||||||
};
|
};
|
||||||
|
|
||||||
Message(Type t) : type(t) {}
|
Message(Type t) : type(t) {}
|
||||||
virtual ~Message() = default;
|
virtual ~Message() = default;
|
||||||
const Type type;
|
const Type type;
|
||||||
uint64_t timestamp = 0;
|
uint64_t timestamp = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class RawMessage : public Message {
|
class RawMessage : public Message {
|
||||||
public:
|
public:
|
||||||
RawMessage(Message::Type type = Message::Type::RawMessage) : Message(type) {}
|
RawMessage(Message::Type type = Message::Type::RawMessage) : Message(type) {}
|
||||||
RawMessage(Message::Type type, Network net) : Message(type), network(net) {}
|
RawMessage(Message::Type type, Network net) : Message(type), network(net) {}
|
||||||
RawMessage(Network net) : Message(Message::Type::RawMessage), network(net) {}
|
RawMessage(Network net) : Message(Message::Type::RawMessage), network(net) {}
|
||||||
RawMessage(Network net, std::vector<uint8_t> d) : Message(Message::Type::RawMessage), network(net), data(d) {}
|
RawMessage(Network net, std::vector<uint8_t> d) : Message(Message::Type::RawMessage), network(net), data(d) {}
|
||||||
|
|
||||||
Network network;
|
Network network;
|
||||||
std::vector<uint8_t> data;
|
std::vector<uint8_t> data;
|
||||||
};
|
};
|
||||||
|
|
||||||
class Frame : public RawMessage {
|
class Frame : public RawMessage {
|
||||||
public:
|
public:
|
||||||
Frame() : RawMessage(Message::Type::Frame) {}
|
Frame() : RawMessage(Message::Type::Frame) {}
|
||||||
|
|
||||||
uint16_t description = 0;
|
uint16_t description = 0;
|
||||||
bool transmitted = false;
|
bool transmitted = false;
|
||||||
bool error = false;
|
bool error = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#ifdef __ICSNEOC_H_
|
#ifdef __ICSNEOC_H_
|
||||||
|
|
||||||
#define ICSNEO_MESSAGE_TYPE_FRAME (0x0)
|
#define ICSNEO_MESSAGE_TYPE_FRAME (0x0)
|
||||||
#define ICSNEO_MESSAGE_TYPE_CAN_ERROR_COUNT (0x100)
|
#define ICSNEO_MESSAGE_TYPE_CAN_ERROR_COUNT (0x100)
|
||||||
#define ICSNEO_MESSAGE_TYPE_INVALID (0x8000)
|
#define ICSNEO_MESSAGE_TYPE_INVALID (0x8000)
|
||||||
#define ICSNEO_MESSAGE_TYPE_RAW_MESSAGE (0x8001)
|
#define ICSNEO_MESSAGE_TYPE_RAW_MESSAGE (0x8001)
|
||||||
#define ICSNEO_MESSAGE_TYPE_READ_SETTINGS (0x8002)
|
#define ICSNEO_MESSAGE_TYPE_READ_SETTINGS (0x8002)
|
||||||
#define ICSNEO_MESSAGE_TYPE_RESET_STATUS (0x8003)
|
#define ICSNEO_MESSAGE_TYPE_RESET_STATUS (0x8003)
|
||||||
#define ICSNEO_MESSAGE_TYPE_DEVICE_VERSION (0x8004)
|
#define ICSNEO_MESSAGE_TYPE_DEVICE_VERSION (0x8004)
|
||||||
#define ICSNEO_MESSAGE_TYPE_MAIN51 (0x8005)
|
#define ICSNEO_MESSAGE_TYPE_MAIN51 (0x8005)
|
||||||
#define ICSNEO_MESSAGE_TYPE_FLEXRAY_CONTROL (0x8006)
|
#define ICSNEO_MESSAGE_TYPE_FLEXRAY_CONTROL (0x8006)
|
||||||
|
|
||||||
#endif // __ICSNEOC_H_
|
#endif // __ICSNEOC_H_
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
File diff suppressed because it is too large
Load Diff
|
|
@ -1,23 +1,23 @@
|
||||||
#ifndef __DEVICEFINDER_H_
|
#ifndef __DEVICEFINDER_H_
|
||||||
#define __DEVICEFINDER_H_
|
#define __DEVICEFINDER_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class DeviceFinder {
|
class DeviceFinder {
|
||||||
public:
|
public:
|
||||||
static std::vector<std::shared_ptr<Device>> FindAll();
|
static std::vector<std::shared_ptr<Device>> FindAll();
|
||||||
static const std::vector<DeviceType>& GetSupportedDevices();
|
static const std::vector<DeviceType>& GetSupportedDevices();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,90 +1,90 @@
|
||||||
#ifndef __RADMOON2_H_
|
#ifndef __RADMOON2_H_
|
||||||
#define __RADMOON2_H_
|
#define __RADMOON2_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/device/tree/radmoon2/radmoon2settings.h"
|
#include "icsneo/device/tree/radmoon2/radmoon2settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class RADMoon2 : public Device {
|
class RADMoon2 : public Device {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with RM
|
// Serial numbers start with RM
|
||||||
// USB PID is 0x1202, standard driver is FTDI3
|
// USB PID is 0x1202, standard driver is FTDI3
|
||||||
ICSNEO_FINDABLE_DEVICE(RADMoon2, DeviceType::RADMoon2, "RM");
|
ICSNEO_FINDABLE_DEVICE(RADMoon2, DeviceType::RADMoon2, "RM");
|
||||||
|
|
||||||
enum class SKU {
|
enum class SKU {
|
||||||
Standard,
|
Standard,
|
||||||
APM1000E, // Keysight Branding
|
APM1000E, // Keysight Branding
|
||||||
APM1000E_CLK, // Clock Option and Keysight Branding
|
APM1000E_CLK, // Clock Option and Keysight Branding
|
||||||
};
|
};
|
||||||
|
|
||||||
SKU getSKU() const {
|
SKU getSKU() const {
|
||||||
switch(getSerial().back()) {
|
switch(getSerial().back()) {
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'B':
|
case 'B':
|
||||||
return SKU::APM1000E;
|
return SKU::APM1000E;
|
||||||
case 'C':
|
case 'C':
|
||||||
case 'D':
|
case 'D':
|
||||||
return SKU::APM1000E_CLK;
|
return SKU::APM1000E_CLK;
|
||||||
default:
|
default:
|
||||||
return SKU::Standard;
|
return SKU::Standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getProductName() const override {
|
std::string getProductName() const override {
|
||||||
switch(getSKU()) {
|
switch(getSKU()) {
|
||||||
case SKU::Standard: break;
|
case SKU::Standard: break;
|
||||||
case SKU::APM1000E:
|
case SKU::APM1000E:
|
||||||
return "Keysight APM1000E";
|
return "Keysight APM1000E";
|
||||||
case SKU::APM1000E_CLK:
|
case SKU::APM1000E_CLK:
|
||||||
return "Keysight APM1000E-CLK";
|
return "Keysight APM1000E-CLK";
|
||||||
}
|
}
|
||||||
return Device::getProductName();
|
return Device::getProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
// RADMoon 2 does not go online, you can only set settings and
|
// RADMoon 2 does not go online, you can only set settings and
|
||||||
// view PHY information (when supported)
|
// view PHY information (when supported)
|
||||||
bool goOnline() override {
|
bool goOnline() override {
|
||||||
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool goOffline() override {
|
bool goOffline() override {
|
||||||
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEthPhyRegControlSupported() const override { return true; }
|
bool getEthPhyRegControlSupported() const override { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<RADMoon2Settings>(makeDriver);
|
initialize<RADMoon2Settings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupPacketizer(Packetizer& packetizer) override {
|
void setupPacketizer(Packetizer& packetizer) override {
|
||||||
Device::setupPacketizer(packetizer);
|
Device::setupPacketizer(packetizer);
|
||||||
packetizer.disableChecksum = true;
|
packetizer.disableChecksum = true;
|
||||||
packetizer.align16bit = false;
|
packetizer.align16bit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupEncoder(Encoder& encoder) override {
|
virtual void setupEncoder(Encoder& encoder) override {
|
||||||
Device::setupEncoder(encoder);
|
Device::setupEncoder(encoder);
|
||||||
encoder.supportEthPhy = true;
|
encoder.supportEthPhy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupDecoder(Decoder& decoder) override {
|
void setupDecoder(Decoder& decoder) override {
|
||||||
Device::setupDecoder(decoder);
|
Device::setupDecoder(decoder);
|
||||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||||
}
|
}
|
||||||
|
|
||||||
bool requiresVehiclePower() const override { return false; }
|
bool requiresVehiclePower() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,54 +1,54 @@
|
||||||
#ifndef __RADMOONDUO_H_
|
#ifndef __RADMOONDUO_H_
|
||||||
#define __RADMOONDUO_H_
|
#define __RADMOONDUO_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/device/tree/radmoonduo/radmoonduosettings.h"
|
#include "icsneo/device/tree/radmoonduo/radmoonduosettings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class RADMoonDuo : public Device {
|
class RADMoonDuo : public Device {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with MD
|
// Serial numbers start with MD
|
||||||
// USB PID is 1106, standard driver is CDCACM
|
// USB PID is 1106, standard driver is CDCACM
|
||||||
ICSNEO_FINDABLE_DEVICE(RADMoonDuo, DeviceType::RADMoonDuo, "MD");
|
ICSNEO_FINDABLE_DEVICE(RADMoonDuo, DeviceType::RADMoonDuo, "MD");
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
// If Converter1 Target is set to USB/CM, OP_Ethernet2 will be exposed to the PC
|
// If Converter1 Target is set to USB/CM, OP_Ethernet2 will be exposed to the PC
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::OP_Ethernet2
|
Network::NetID::OP_Ethernet2
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEthPhyRegControlSupported() const override { return true; }
|
bool getEthPhyRegControlSupported() const override { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RADMoonDuo(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
RADMoonDuo(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<RADMoonDuoSettings>(makeDriver);
|
initialize<RADMoonDuoSettings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupEncoder(Encoder& encoder) override {
|
virtual void setupEncoder(Encoder& encoder) override {
|
||||||
Device::setupEncoder(encoder);
|
Device::setupEncoder(encoder);
|
||||||
encoder.supportEthPhy = true;
|
encoder.supportEthPhy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
bool requiresVehiclePower() const override { return false; }
|
bool requiresVehiclePower() const override { return false; }
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,88 +1,88 @@
|
||||||
#ifndef __RADSUPERMOON_H_
|
#ifndef __RADSUPERMOON_H_
|
||||||
#define __RADSUPERMOON_H_
|
#define __RADSUPERMOON_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/device/tree/radsupermoon/radsupermoonsettings.h"
|
#include "icsneo/device/tree/radsupermoon/radsupermoonsettings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class RADSupermoon : public Device {
|
class RADSupermoon : public Device {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with SM
|
// Serial numbers start with SM
|
||||||
// USB PID is 0x1201, standard driver is FTDI3
|
// USB PID is 0x1201, standard driver is FTDI3
|
||||||
ICSNEO_FINDABLE_DEVICE(RADSupermoon, DeviceType::RADSupermoon, "SM");
|
ICSNEO_FINDABLE_DEVICE(RADSupermoon, DeviceType::RADSupermoon, "SM");
|
||||||
|
|
||||||
enum class SKU {
|
enum class SKU {
|
||||||
Standard,
|
Standard,
|
||||||
APM1000ET, // Keysight Branding
|
APM1000ET, // Keysight Branding
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::Ethernet,
|
Network::NetID::Ethernet,
|
||||||
Network::NetID::OP_Ethernet1,
|
Network::NetID::OP_Ethernet1,
|
||||||
Network::NetID::OP_Ethernet2
|
Network::NetID::OP_Ethernet2
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
SKU getSKU() const {
|
SKU getSKU() const {
|
||||||
switch(getSerial().back()) {
|
switch(getSerial().back()) {
|
||||||
case 'A':
|
case 'A':
|
||||||
return SKU::APM1000ET;
|
return SKU::APM1000ET;
|
||||||
default:
|
default:
|
||||||
return SKU::Standard;
|
return SKU::Standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getProductName() const override {
|
std::string getProductName() const override {
|
||||||
switch(getSKU()) {
|
switch(getSKU()) {
|
||||||
case SKU::Standard: break;
|
case SKU::Standard: break;
|
||||||
case SKU::APM1000ET:
|
case SKU::APM1000ET:
|
||||||
return "Keysight APM1000ET";
|
return "Keysight APM1000ET";
|
||||||
}
|
}
|
||||||
return Device::getProductName();
|
return Device::getProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool getEthPhyRegControlSupported() const override { return true; }
|
bool getEthPhyRegControlSupported() const override { return true; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
RADSupermoon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
RADSupermoon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<RADSupermoonSettings>(makeDriver);
|
initialize<RADSupermoonSettings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupPacketizer(Packetizer& packetizer) override {
|
void setupPacketizer(Packetizer& packetizer) override {
|
||||||
Device::setupPacketizer(packetizer);
|
Device::setupPacketizer(packetizer);
|
||||||
packetizer.disableChecksum = true;
|
packetizer.disableChecksum = true;
|
||||||
packetizer.align16bit = false;
|
packetizer.align16bit = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void setupEncoder(Encoder& encoder) override {
|
virtual void setupEncoder(Encoder& encoder) override {
|
||||||
Device::setupEncoder(encoder);
|
Device::setupEncoder(encoder);
|
||||||
encoder.supportEthPhy = true;
|
encoder.supportEthPhy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupDecoder(Decoder& decoder) override {
|
void setupDecoder(Decoder& decoder) override {
|
||||||
Device::setupDecoder(decoder);
|
Device::setupDecoder(decoder);
|
||||||
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
bool requiresVehiclePower() const override { return false; }
|
bool requiresVehiclePower() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,46 +1,46 @@
|
||||||
#ifndef __VALUECAN3_H_
|
#ifndef __VALUECAN3_H_
|
||||||
#define __VALUECAN3_H_
|
#define __VALUECAN3_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/device/tree/valuecan3/valuecan3settings.h"
|
#include "icsneo/device/tree/valuecan3/valuecan3settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN3 : public Device {
|
class ValueCAN3 : public Device {
|
||||||
public:
|
public:
|
||||||
// USB PID is 0x0601, standard driver is FTDI
|
// USB PID is 0x0601, standard driver is FTDI
|
||||||
ICSNEO_FINDABLE_DEVICE_BY_PID(ValueCAN3, DeviceType::VCAN3, 0x0701);
|
ICSNEO_FINDABLE_DEVICE_BY_PID(ValueCAN3, DeviceType::VCAN3, 0x0701);
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::HSCAN,
|
Network::NetID::HSCAN,
|
||||||
Network::NetID::MSCAN
|
Network::NetID::MSCAN
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
private:
|
private:
|
||||||
ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<ValueCAN3Settings>(makeDriver);
|
initialize<ValueCAN3Settings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
bool requiresVehiclePower() const override { return false; }
|
bool requiresVehiclePower() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,47 +1,47 @@
|
||||||
#ifndef __VALUECAN4_1_H_
|
#ifndef __VALUECAN4_1_H_
|
||||||
#define __VALUECAN4_1_H_
|
#define __VALUECAN4_1_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-1settings.h"
|
#include "icsneo/device/tree/valuecan4/settings/valuecan4-1settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN4_1 : public ValueCAN4 {
|
class ValueCAN4_1 : public ValueCAN4 {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with V1 for 4-1
|
// Serial numbers start with V1 for 4-1
|
||||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_1, DeviceType::VCAN4_1, "V1");
|
ICSNEO_FINDABLE_DEVICE(ValueCAN4_1, DeviceType::VCAN4_1, "V1");
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::HSCAN
|
Network::NetID::HSCAN
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValueCAN4_1(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
ValueCAN4_1(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||||
initialize<ValueCAN4_1Settings>(makeDriver);
|
initialize<ValueCAN4_1Settings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupEncoder(Encoder& encoder) override {
|
void setupEncoder(Encoder& encoder) override {
|
||||||
ValueCAN4::setupEncoder(encoder);
|
ValueCAN4::setupEncoder(encoder);
|
||||||
encoder.supportCANFD = false; // VCAN 4-1 does not support CAN FD
|
encoder.supportCANFD = false; // VCAN 4-1 does not support CAN FD
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,67 +1,67 @@
|
||||||
#ifndef __VALUECAN4_2_H_
|
#ifndef __VALUECAN4_2_H_
|
||||||
#define __VALUECAN4_2_H_
|
#define __VALUECAN4_2_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2settings.h"
|
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN4_2 : public ValueCAN4 {
|
class ValueCAN4_2 : public ValueCAN4 {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with V2 for 4-2
|
// Serial numbers start with V2 for 4-2
|
||||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_2, DeviceType::VCAN4_2, "V2");
|
ICSNEO_FINDABLE_DEVICE(ValueCAN4_2, DeviceType::VCAN4_2, "V2");
|
||||||
|
|
||||||
enum class SKU {
|
enum class SKU {
|
||||||
Standard,
|
Standard,
|
||||||
AP0200A, // USB A and Keysight Branding
|
AP0200A, // USB A and Keysight Branding
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::HSCAN,
|
Network::NetID::HSCAN,
|
||||||
Network::NetID::HSCAN2
|
Network::NetID::HSCAN2
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
SKU getSKU() const {
|
SKU getSKU() const {
|
||||||
switch(getSerial().back()) {
|
switch(getSerial().back()) {
|
||||||
case 'A':
|
case 'A':
|
||||||
case 'B':
|
case 'B':
|
||||||
return SKU::AP0200A;
|
return SKU::AP0200A;
|
||||||
default:
|
default:
|
||||||
return SKU::Standard;
|
return SKU::Standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getProductName() const override {
|
std::string getProductName() const override {
|
||||||
switch(getSKU()) {
|
switch(getSKU()) {
|
||||||
case SKU::Standard: break;
|
case SKU::Standard: break;
|
||||||
case SKU::AP0200A:
|
case SKU::AP0200A:
|
||||||
return "Keysight AP0200A";
|
return "Keysight AP0200A";
|
||||||
}
|
}
|
||||||
return Device::getProductName();
|
return Device::getProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValueCAN4_2(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
ValueCAN4_2(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||||
initialize<ValueCAN4_2Settings>(makeDriver);
|
initialize<ValueCAN4_2Settings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,98 +1,98 @@
|
||||||
#ifndef __VALUECAN4_2EL_H_
|
#ifndef __VALUECAN4_2EL_H_
|
||||||
#define __VALUECAN4_2EL_H_
|
#define __VALUECAN4_2EL_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2elsettings.h"
|
#include "icsneo/device/tree/valuecan4/settings/valuecan4-2elsettings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN4_2EL : public ValueCAN4 {
|
class ValueCAN4_2EL : public ValueCAN4 {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with VE for 4-2EL
|
// Serial numbers start with VE for 4-2EL
|
||||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||||
// Ethernet MAC allocation is 0x0B, standard driver is Raw
|
// Ethernet MAC allocation is 0x0B, standard driver is Raw
|
||||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_2EL, DeviceType::VCAN4_2EL, "VE");
|
ICSNEO_FINDABLE_DEVICE(ValueCAN4_2EL, DeviceType::VCAN4_2EL, "VE");
|
||||||
|
|
||||||
enum class SKU {
|
enum class SKU {
|
||||||
Standard,
|
Standard,
|
||||||
AP04E0A_D26, // HDB26, USB A, and Keysight Branding
|
AP04E0A_D26, // HDB26, USB A, and Keysight Branding
|
||||||
AP04E0A_MUL, // Multi-connectors, USB A, and Keysight Branding
|
AP04E0A_MUL, // Multi-connectors, USB A, and Keysight Branding
|
||||||
AP04E0A_OBD, // OBD, USB A, and Keysight Branding
|
AP04E0A_OBD, // OBD, USB A, and Keysight Branding
|
||||||
};
|
};
|
||||||
|
|
||||||
SKU getSKU() const {
|
SKU getSKU() const {
|
||||||
switch(getSerial().back()) {
|
switch(getSerial().back()) {
|
||||||
case 'A':
|
case 'A':
|
||||||
return SKU::AP04E0A_D26;
|
return SKU::AP04E0A_D26;
|
||||||
case 'B':
|
case 'B':
|
||||||
return SKU::AP04E0A_MUL;
|
return SKU::AP04E0A_MUL;
|
||||||
case 'C':
|
case 'C':
|
||||||
return SKU::AP04E0A_OBD;
|
return SKU::AP04E0A_OBD;
|
||||||
default:
|
default:
|
||||||
return SKU::Standard;
|
return SKU::Standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getProductName() const override {
|
std::string getProductName() const override {
|
||||||
switch(getSKU()) {
|
switch(getSKU()) {
|
||||||
case SKU::Standard: break;
|
case SKU::Standard: break;
|
||||||
case SKU::AP04E0A_D26:
|
case SKU::AP04E0A_D26:
|
||||||
return "Keysight AP04E0A-D26";
|
return "Keysight AP04E0A-D26";
|
||||||
case SKU::AP04E0A_MUL:
|
case SKU::AP04E0A_MUL:
|
||||||
return "Keysight AP04E0A-MUL";
|
return "Keysight AP04E0A-MUL";
|
||||||
case SKU::AP04E0A_OBD:
|
case SKU::AP04E0A_OBD:
|
||||||
return "Keysight AP04E0A-OBD";
|
return "Keysight AP04E0A-OBD";
|
||||||
}
|
}
|
||||||
return Device::getProductName();
|
return Device::getProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::HSCAN,
|
Network::NetID::HSCAN,
|
||||||
Network::NetID::HSCAN2,
|
Network::NetID::HSCAN2,
|
||||||
|
|
||||||
Network::NetID::Ethernet,
|
Network::NetID::Ethernet,
|
||||||
|
|
||||||
Network::NetID::LIN
|
Network::NetID::LIN
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValueCAN4_2EL(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
ValueCAN4_2EL(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||||
initialize<ValueCAN4_2ELSettings>(makeDriver);
|
initialize<ValueCAN4_2ELSettings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
size_t getEthernetActivationLineCount() const override { return 1; }
|
size_t getEthernetActivationLineCount() const override { return 1; }
|
||||||
|
|
||||||
void handleDeviceStatus(const std::shared_ptr<RawMessage>& message) override {
|
void handleDeviceStatus(const std::shared_ptr<RawMessage>& message) override {
|
||||||
if(message->data.size() < sizeof(valuecan4_2el_status_t))
|
if(message->data.size() < sizeof(valuecan4_2el_status_t))
|
||||||
return;
|
return;
|
||||||
std::lock_guard<std::mutex> lk(ioMutex);
|
std::lock_guard<std::mutex> lk(ioMutex);
|
||||||
const valuecan4_2el_status_t* status = reinterpret_cast<const valuecan4_2el_status_t*>(message->data.data());
|
const valuecan4_2el_status_t* status = reinterpret_cast<const valuecan4_2el_status_t*>(message->data.data());
|
||||||
ethActivationStatus = status->ethernetActivationLineEnabled;
|
ethActivationStatus = status->ethernetActivationLineEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
||||||
|
|
||||||
void setupPacketizer(Packetizer& packetizer) override {
|
void setupPacketizer(Packetizer& packetizer) override {
|
||||||
ValueCAN4::setupPacketizer(packetizer);
|
ValueCAN4::setupPacketizer(packetizer);
|
||||||
packetizer.align16bit = !com->driver->isEthernet();
|
packetizer.align16bit = !com->driver->isEthernet();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,78 +1,78 @@
|
||||||
#ifndef __VALUECAN4_4_H_
|
#ifndef __VALUECAN4_4_H_
|
||||||
#define __VALUECAN4_4_H_
|
#define __VALUECAN4_4_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4-4settings.h"
|
#include "icsneo/device/tree/valuecan4/settings/valuecan4-4settings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN4_4 : public ValueCAN4 {
|
class ValueCAN4_4 : public ValueCAN4 {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with V4 for 4-4
|
// Serial numbers start with V4 for 4-4
|
||||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4_4, DeviceType::VCAN4_4, "V4");
|
ICSNEO_FINDABLE_DEVICE(ValueCAN4_4, DeviceType::VCAN4_4, "V4");
|
||||||
|
|
||||||
enum class SKU {
|
enum class SKU {
|
||||||
Standard,
|
Standard,
|
||||||
AP0400A_D26, // HDB26, USB A, and Keysight Branding
|
AP0400A_D26, // HDB26, USB A, and Keysight Branding
|
||||||
AP0400A_DB9, // 4xDB9, USB A, and Keysight Branding
|
AP0400A_DB9, // 4xDB9, USB A, and Keysight Branding
|
||||||
AP0400A_OBD, // OBD, USB A, and Keysight Branding
|
AP0400A_OBD, // OBD, USB A, and Keysight Branding
|
||||||
};
|
};
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::HSCAN,
|
Network::NetID::HSCAN,
|
||||||
Network::NetID::HSCAN2,
|
Network::NetID::HSCAN2,
|
||||||
Network::NetID::HSCAN3,
|
Network::NetID::HSCAN3,
|
||||||
Network::NetID::HSCAN4
|
Network::NetID::HSCAN4
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
SKU getSKU() const {
|
SKU getSKU() const {
|
||||||
switch(getSerial().back()) {
|
switch(getSerial().back()) {
|
||||||
case 'A':
|
case 'A':
|
||||||
return SKU::AP0400A_D26;
|
return SKU::AP0400A_D26;
|
||||||
case 'B':
|
case 'B':
|
||||||
return SKU::AP0400A_DB9;
|
return SKU::AP0400A_DB9;
|
||||||
case 'C':
|
case 'C':
|
||||||
return SKU::AP0400A_OBD;
|
return SKU::AP0400A_OBD;
|
||||||
default:
|
default:
|
||||||
return SKU::Standard;
|
return SKU::Standard;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::string getProductName() const override {
|
std::string getProductName() const override {
|
||||||
switch(getSKU()) {
|
switch(getSKU()) {
|
||||||
case SKU::Standard: break;
|
case SKU::Standard: break;
|
||||||
case SKU::AP0400A_D26:
|
case SKU::AP0400A_D26:
|
||||||
return "Keysight AP0400A-D26";
|
return "Keysight AP0400A-D26";
|
||||||
case SKU::AP0400A_DB9:
|
case SKU::AP0400A_DB9:
|
||||||
return "Keysight AP0400A-DB9";
|
return "Keysight AP0400A-DB9";
|
||||||
case SKU::AP0400A_OBD:
|
case SKU::AP0400A_OBD:
|
||||||
return "Keysight AP0400A-OBD";
|
return "Keysight AP0400A-OBD";
|
||||||
}
|
}
|
||||||
return Device::getProductName();
|
return Device::getProductName();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValueCAN4_4(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
ValueCAN4_4(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||||
initialize<ValueCAN4_4Settings>(makeDriver);
|
initialize<ValueCAN4_4Settings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,30 +1,30 @@
|
||||||
#ifndef __VALUECAN4_H_
|
#ifndef __VALUECAN4_H_
|
||||||
#define __VALUECAN4_H_
|
#define __VALUECAN4_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN4 : public Device {
|
class ValueCAN4 : public Device {
|
||||||
public:
|
public:
|
||||||
// All ValueCAN 4 devices share a USB PID of 0x1101
|
// All ValueCAN 4 devices share a USB PID of 0x1101
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
using Device::Device;
|
using Device::Device;
|
||||||
|
|
||||||
virtual void setupEncoder(Encoder& encoder) override {
|
virtual void setupEncoder(Encoder& encoder) override {
|
||||||
Device::setupEncoder(encoder);
|
Device::setupEncoder(encoder);
|
||||||
encoder.supportCANFD = true;
|
encoder.supportCANFD = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool requiresVehiclePower() const override { return false; }
|
bool requiresVehiclePower() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,55 +1,55 @@
|
||||||
#ifndef __VALUECAN4INDUSTRIAL_H_
|
#ifndef __VALUECAN4INDUSTRIAL_H_
|
||||||
#define __VALUECAN4INDUSTRIAL_H_
|
#define __VALUECAN4INDUSTRIAL_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
#include "icsneo/device/tree/valuecan4/valuecan4.h"
|
||||||
#include "icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h"
|
#include "icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class ValueCAN4Industrial : public ValueCAN4 {
|
class ValueCAN4Industrial : public ValueCAN4 {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with IV for Industrial
|
// Serial numbers start with IV for Industrial
|
||||||
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
// USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM
|
||||||
// Ethernet MAC allocation is 0x12, standard driver is Raw
|
// Ethernet MAC allocation is 0x12, standard driver is Raw
|
||||||
ICSNEO_FINDABLE_DEVICE(ValueCAN4Industrial, DeviceType::VCAN4_IND, "IV");
|
ICSNEO_FINDABLE_DEVICE(ValueCAN4Industrial, DeviceType::VCAN4_IND, "IV");
|
||||||
|
|
||||||
static const std::vector<Network>& GetSupportedNetworks() {
|
static const std::vector<Network>& GetSupportedNetworks() {
|
||||||
static std::vector<Network> supportedNetworks = {
|
static std::vector<Network> supportedNetworks = {
|
||||||
Network::NetID::HSCAN,
|
Network::NetID::HSCAN,
|
||||||
Network::NetID::HSCAN2,
|
Network::NetID::HSCAN2,
|
||||||
|
|
||||||
Network::NetID::Ethernet,
|
Network::NetID::Ethernet,
|
||||||
|
|
||||||
Network::NetID::LIN
|
Network::NetID::LIN
|
||||||
};
|
};
|
||||||
return supportedNetworks;
|
return supportedNetworks;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) {
|
||||||
initialize<ValueCAN4IndustrialSettings>(makeDriver);
|
initialize<ValueCAN4IndustrialSettings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
void setupSupportedRXNetworks(std::vector<Network>& rxNetworks) override {
|
||||||
for(auto& netid : GetSupportedNetworks())
|
for(auto& netid : GetSupportedNetworks())
|
||||||
rxNetworks.emplace_back(netid);
|
rxNetworks.emplace_back(netid);
|
||||||
}
|
}
|
||||||
|
|
||||||
// The supported TX networks are the same as the supported RX networks for this device
|
// The supported TX networks are the same as the supported RX networks for this device
|
||||||
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
void setupSupportedTXNetworks(std::vector<Network>& txNetworks) override { setupSupportedRXNetworks(txNetworks); }
|
||||||
|
|
||||||
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); }
|
||||||
|
|
||||||
void setupPacketizer(Packetizer& packetizer) override {
|
void setupPacketizer(Packetizer& packetizer) override {
|
||||||
ValueCAN4::setupPacketizer(packetizer);
|
ValueCAN4::setupPacketizer(packetizer);
|
||||||
packetizer.align16bit = !com->driver->isEthernet();
|
packetizer.align16bit = !com->driver->isEthernet();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,42 +1,42 @@
|
||||||
#ifndef __VIVIDCAN_H_
|
#ifndef __VIVIDCAN_H_
|
||||||
#define __VIVIDCAN_H_
|
#define __VIVIDCAN_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/device/devicetype.h"
|
#include "icsneo/device/devicetype.h"
|
||||||
#include "icsneo/platform/cdcacm.h"
|
#include "icsneo/platform/cdcacm.h"
|
||||||
#include "icsneo/device/tree/vividcan/vividcansettings.h"
|
#include "icsneo/device/tree/vividcan/vividcansettings.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class VividCAN : public Device {
|
class VividCAN : public Device {
|
||||||
public:
|
public:
|
||||||
// Serial numbers start with VV
|
// Serial numbers start with VV
|
||||||
// USB PID is 0x1102, standard driver is CDCACM
|
// USB PID is 0x1102, standard driver is CDCACM
|
||||||
ICSNEO_FINDABLE_DEVICE(VividCAN, DeviceType::VividCAN, "VV");
|
ICSNEO_FINDABLE_DEVICE(VividCAN, DeviceType::VividCAN, "VV");
|
||||||
|
|
||||||
// VividCAN does not go online, you can only set settings
|
// VividCAN does not go online, you can only set settings
|
||||||
bool goOnline() override {
|
bool goOnline() override {
|
||||||
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool goOffline() override {
|
bool goOffline() override {
|
||||||
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
VividCAN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
VividCAN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) {
|
||||||
initialize<VividCANSettings>(makeDriver);
|
initialize<VividCANSettings>(makeDriver);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool requiresVehiclePower() const override { return false; }
|
bool requiresVehiclePower() const override { return false; }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,39 +1,39 @@
|
||||||
#ifndef __ICSNEOCPP_H_
|
#ifndef __ICSNEOCPP_H_
|
||||||
#define __ICSNEOCPP_H_
|
#define __ICSNEOCPP_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/api/version.h"
|
#include "icsneo/api/version.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
|
||||||
#include "icsneo/communication/message/canmessage.h"
|
#include "icsneo/communication/message/canmessage.h"
|
||||||
#include "icsneo/communication/message/ethernetmessage.h"
|
#include "icsneo/communication/message/ethernetmessage.h"
|
||||||
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
#include "icsneo/communication/message/flexray/flexraymessage.h"
|
||||||
#include "icsneo/communication/message/iso9141message.h"
|
#include "icsneo/communication/message/iso9141message.h"
|
||||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||||
#include "icsneo/communication/message/ethphymessage.h"
|
#include "icsneo/communication/message/ethphymessage.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Device>> FindAllDevices();
|
std::vector<std::shared_ptr<Device>> FindAllDevices();
|
||||||
std::vector<DeviceType> GetSupportedDevices();
|
std::vector<DeviceType> GetSupportedDevices();
|
||||||
|
|
||||||
size_t EventCount(EventFilter filter = EventFilter());
|
size_t EventCount(EventFilter filter = EventFilter());
|
||||||
std::vector<APIEvent> GetEvents(EventFilter filter, size_t max = 0);
|
std::vector<APIEvent> GetEvents(EventFilter filter, size_t max = 0);
|
||||||
std::vector<APIEvent> GetEvents(size_t max = 0, EventFilter filter = EventFilter());
|
std::vector<APIEvent> GetEvents(size_t max = 0, EventFilter filter = EventFilter());
|
||||||
void GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max = 0);
|
void GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max = 0);
|
||||||
void GetEvents(std::vector<APIEvent>& events, size_t max = 0, EventFilter filter = EventFilter());
|
void GetEvents(std::vector<APIEvent>& events, size_t max = 0, EventFilter filter = EventFilter());
|
||||||
APIEvent GetLastError();
|
APIEvent GetLastError();
|
||||||
void DiscardEvents(EventFilter filter = EventFilter());
|
void DiscardEvents(EventFilter filter = EventFilter());
|
||||||
void SetEventLimit(size_t newLimit);
|
void SetEventLimit(size_t newLimit);
|
||||||
size_t GetEventLimit();
|
size_t GetEventLimit();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
#ifndef __CDCACM_H_
|
#ifndef __CDCACM_H_
|
||||||
#define __CDCACM_H_
|
#define __CDCACM_H_
|
||||||
|
|
||||||
#define INTREPID_USB_VENDOR_ID (0x093c)
|
#define INTREPID_USB_VENDOR_ID (0x093c)
|
||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
#include "icsneo/platform/windows/cdcacm.h"
|
#include "icsneo/platform/windows/cdcacm.h"
|
||||||
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||||
#include "icsneo/platform/posix/cdcacm.h"
|
#include "icsneo/platform/posix/cdcacm.h"
|
||||||
#else
|
#else
|
||||||
#warning "This platform is not supported by the CDC ACM driver"
|
#warning "This platform is not supported by the CDC ACM driver"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,12 +1,12 @@
|
||||||
#ifndef __DYNAMICLIB_H_
|
#ifndef __DYNAMICLIB_H_
|
||||||
#define __DYNAMICLIB_H_
|
#define __DYNAMICLIB_H_
|
||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
#include "icsneo/platform/windows/dynamiclib.h"
|
#include "icsneo/platform/windows/dynamiclib.h"
|
||||||
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||||
#include "icsneo/platform/posix/dynamiclib.h"
|
#include "icsneo/platform/posix/dynamiclib.h"
|
||||||
#else
|
#else
|
||||||
#warning "This platform is not supported by the dynamic library driver"
|
#warning "This platform is not supported by the dynamic library driver"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,14 +1,14 @@
|
||||||
#ifndef __FTDI_H_
|
#ifndef __FTDI_H_
|
||||||
#define __FTDI_H_
|
#define __FTDI_H_
|
||||||
|
|
||||||
#define INTREPID_USB_VENDOR_ID (0x093c)
|
#define INTREPID_USB_VENDOR_ID (0x093c)
|
||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
#include "icsneo/platform/windows/ftdi.h"
|
#include "icsneo/platform/windows/ftdi.h"
|
||||||
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__))
|
||||||
#include "icsneo/platform/posix/ftdi.h"
|
#include "icsneo/platform/posix/ftdi.h"
|
||||||
#else
|
#else
|
||||||
#warning "This platform is not supported by the FTDI driver"
|
#warning "This platform is not supported by the FTDI driver"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,24 +1,24 @@
|
||||||
#ifndef __DYNAMICLIB_POSIX_H_
|
#ifndef __DYNAMICLIB_POSIX_H_
|
||||||
#define __DYNAMICLIB_POSIX_H_
|
#define __DYNAMICLIB_POSIX_H_
|
||||||
|
|
||||||
#include <dlfcn.h>
|
#include <dlfcn.h>
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#include "icsneo/platform/posix/darwin/dynamiclib.h"
|
#include "icsneo/platform/posix/darwin/dynamiclib.h"
|
||||||
#else
|
#else
|
||||||
#include "icsneo/platform/posix/linux/dynamiclib.h"
|
#include "icsneo/platform/posix/linux/dynamiclib.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define DLLExport __attribute__((visibility("default")))
|
#define DLLExport __attribute__((visibility("default")))
|
||||||
#define LegacyDLLExport DLLExport
|
#define LegacyDLLExport DLLExport
|
||||||
|
|
||||||
// #ifndef ICSNEO_NO_AUTO_DESTRUCT
|
// #ifndef ICSNEO_NO_AUTO_DESTRUCT
|
||||||
// #define ICSNEO_DESTRUCTOR __attribute__((destructor));
|
// #define ICSNEO_DESTRUCTOR __attribute__((destructor));
|
||||||
// #else
|
// #else
|
||||||
#define ICSNEO_DESTRUCTOR
|
#define ICSNEO_DESTRUCTOR
|
||||||
// #endif
|
// #endif
|
||||||
|
|
||||||
#define icsneo_dynamicLibraryGetFunction(handle, func) dlsym(handle, func)
|
#define icsneo_dynamicLibraryGetFunction(handle, func) dlsym(handle, func)
|
||||||
#define icsneo_dynamicLibraryClose(handle) (dlclose(handle) == 0)
|
#define icsneo_dynamicLibraryClose(handle) (dlclose(handle) == 0)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,6 +1,6 @@
|
||||||
#ifndef __TCHAR_POSIX_H_
|
#ifndef __TCHAR_POSIX_H_
|
||||||
#define __TCHAR_POSIX_H_
|
#define __TCHAR_POSIX_H_
|
||||||
|
|
||||||
typedef char TCHAR;
|
typedef char TCHAR;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,10 +1,10 @@
|
||||||
#ifndef __REGISTRY_H_
|
#ifndef __REGISTRY_H_
|
||||||
#define __REGISTRY_H_
|
#define __REGISTRY_H_
|
||||||
|
|
||||||
#if defined _WIN32
|
#if defined _WIN32
|
||||||
#include "icsneo/platform/windows/registry.h"
|
#include "icsneo/platform/windows/registry.h"
|
||||||
#else
|
#else
|
||||||
#warning "This platform is not supported by the registry driver"
|
#warning "This platform is not supported by the registry driver"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
#ifndef __CDCACM_WINDOWS_H_
|
#ifndef __CDCACM_WINDOWS_H_
|
||||||
#define __CDCACM_WINDOWS_H_
|
#define __CDCACM_WINDOWS_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/platform/windows/vcp.h"
|
#include "icsneo/platform/windows/vcp.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class CDCACM : public VCP {
|
class CDCACM : public VCP {
|
||||||
public:
|
public:
|
||||||
CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {}
|
CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {}
|
||||||
static void Find(std::vector<FoundDevice>& found) { return VCP::Find(found, { L"usbser" }); }
|
static void Find(std::vector<FoundDevice>& found) { return VCP::Find(found, { L"usbser" }); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
#ifndef __DYNAMICLIB_WINDOWS_H_
|
#ifndef __DYNAMICLIB_WINDOWS_H_
|
||||||
#define __DYNAMICLIB_WINDOWS_H_
|
#define __DYNAMICLIB_WINDOWS_H_
|
||||||
|
|
||||||
#include "icsneo/platform/windows.h"
|
#include "icsneo/platform/windows.h"
|
||||||
|
|
||||||
#ifdef ICSNEOC_MAKEDLL
|
#ifdef ICSNEOC_MAKEDLL
|
||||||
#define DLLExport __declspec(dllexport)
|
#define DLLExport __declspec(dllexport)
|
||||||
#else
|
#else
|
||||||
#define DLLExport __declspec(dllimport)
|
#define DLLExport __declspec(dllimport)
|
||||||
#endif
|
#endif
|
||||||
#define LegacyDLLExport DLLExport _stdcall
|
#define LegacyDLLExport DLLExport _stdcall
|
||||||
|
|
||||||
// MSVC does not have the ability to specify a destructor
|
// MSVC does not have the ability to specify a destructor
|
||||||
#define ICSNEO_DESTRUCTOR
|
#define ICSNEO_DESTRUCTOR
|
||||||
|
|
||||||
#define icsneo_dynamicLibraryLoad() LoadLibrary(TEXT("icsneoc.dll"))
|
#define icsneo_dynamicLibraryLoad() LoadLibrary(TEXT("icsneoc.dll"))
|
||||||
#define icsneo_dynamicLibraryGetFunction(handle, func) GetProcAddress((HMODULE) handle, func)
|
#define icsneo_dynamicLibraryGetFunction(handle, func) GetProcAddress((HMODULE) handle, func)
|
||||||
#define icsneo_dynamicLibraryClose(handle) FreeLibrary((HMODULE) handle)
|
#define icsneo_dynamicLibraryClose(handle) FreeLibrary((HMODULE) handle)
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,20 +1,20 @@
|
||||||
#ifndef __FTDI_WINDOWS_H_
|
#ifndef __FTDI_WINDOWS_H_
|
||||||
#define __FTDI_WINDOWS_H_
|
#define __FTDI_WINDOWS_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include "icsneo/platform/windows/vcp.h"
|
#include "icsneo/platform/windows/vcp.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class FTDI : public VCP {
|
class FTDI : public VCP {
|
||||||
public:
|
public:
|
||||||
FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {}
|
FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {}
|
||||||
static void Find(std::vector<FoundDevice>& found) { return VCP::Find(found, { L"serenum" /*, L"ftdibus" */ }); }
|
static void Find(std::vector<FoundDevice>& found) { return VCP::Find(found, { L"serenum" /*, L"ftdibus" */ }); }
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,28 +1,28 @@
|
||||||
#ifndef __REGISTRY_WINDOWS_H_
|
#ifndef __REGISTRY_WINDOWS_H_
|
||||||
#define __REGISTRY_WINDOWS_H_
|
#define __REGISTRY_WINDOWS_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
class Registry {
|
class Registry {
|
||||||
public:
|
public:
|
||||||
static bool EnumerateSubkeys(std::wstring path, std::vector<std::wstring>& subkeys);
|
static bool EnumerateSubkeys(std::wstring path, std::vector<std::wstring>& subkeys);
|
||||||
|
|
||||||
// Get string value
|
// Get string value
|
||||||
static bool Get(std::wstring path, std::wstring key, std::wstring& value);
|
static bool Get(std::wstring path, std::wstring key, std::wstring& value);
|
||||||
static bool Get(std::string path, std::string key, std::string& value);
|
static bool Get(std::string path, std::string key, std::string& value);
|
||||||
|
|
||||||
// Get DWORD value
|
// Get DWORD value
|
||||||
static bool Get(std::wstring path, std::wstring key, uint32_t& value);
|
static bool Get(std::wstring path, std::wstring key, uint32_t& value);
|
||||||
static bool Get(std::string path, std::string key, uint32_t& value);
|
static bool Get(std::string path, std::string key, uint32_t& value);
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,48 +1,48 @@
|
||||||
#ifndef __VCP_WINDOWS_H_
|
#ifndef __VCP_WINDOWS_H_
|
||||||
#define __VCP_WINDOWS_H_
|
#define __VCP_WINDOWS_H_
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <string>
|
#include <string>
|
||||||
#include <thread>
|
#include <thread>
|
||||||
#include <atomic>
|
#include <atomic>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include "icsneo/device/neodevice.h"
|
#include "icsneo/device/neodevice.h"
|
||||||
#include "icsneo/communication/driver.h"
|
#include "icsneo/communication/driver.h"
|
||||||
#include "icsneo/api/eventmanager.h"
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
// Virtual COM Port Communication
|
// Virtual COM Port Communication
|
||||||
class VCP : public Driver {
|
class VCP : public Driver {
|
||||||
public:
|
public:
|
||||||
static void Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driverName);
|
static void Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driverName);
|
||||||
static bool IsHandleValid(neodevice_handle_t handle);
|
static bool IsHandleValid(neodevice_handle_t handle);
|
||||||
typedef void(*fn_boolCallback)(bool success);
|
typedef void(*fn_boolCallback)(bool success);
|
||||||
|
|
||||||
VCP(const device_eventhandler_t& err, neodevice_t& forDevice);
|
VCP(const device_eventhandler_t& err, neodevice_t& forDevice);
|
||||||
~VCP() { close(); }
|
~VCP() { close(); }
|
||||||
bool open() { return open(false); }
|
bool open() { return open(false); }
|
||||||
void openAsync(fn_boolCallback callback);
|
void openAsync(fn_boolCallback callback);
|
||||||
bool close();
|
bool close();
|
||||||
bool isOpen();
|
bool isOpen();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
bool open(bool fromAsync);
|
bool open(bool fromAsync);
|
||||||
bool opening = false;
|
bool opening = false;
|
||||||
neodevice_t& device;
|
neodevice_t& device;
|
||||||
|
|
||||||
struct Detail;
|
struct Detail;
|
||||||
std::shared_ptr<Detail> detail;
|
std::shared_ptr<Detail> detail;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<std::thread>> threads;
|
std::vector<std::shared_ptr<std::thread>> threads;
|
||||||
void readTask();
|
void readTask();
|
||||||
void writeTask();
|
void writeTask();
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif // __cplusplus
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -1,120 +1,120 @@
|
||||||
#include "icsneo/platform/windows/registry.h"
|
#include "icsneo/platform/windows/registry.h"
|
||||||
#include "icsneo/platform/windows.h"
|
#include "icsneo/platform/windows.h"
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <locale>
|
#include <locale>
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||||
|
|
||||||
class Key {
|
class Key {
|
||||||
public:
|
public:
|
||||||
Key(std::wstring path, bool readwrite = false);
|
Key(std::wstring path, bool readwrite = false);
|
||||||
~Key();
|
~Key();
|
||||||
HKEY GetKey() { return key; }
|
HKEY GetKey() { return key; }
|
||||||
bool IsOpen() { return key != nullptr; }
|
bool IsOpen() { return key != nullptr; }
|
||||||
private:
|
private:
|
||||||
HKEY key;
|
HKEY key;
|
||||||
};
|
};
|
||||||
|
|
||||||
Key::Key(std::wstring path, bool readwrite) {
|
Key::Key(std::wstring path, bool readwrite) {
|
||||||
DWORD dwDisposition;
|
DWORD dwDisposition;
|
||||||
if(readwrite)
|
if(readwrite)
|
||||||
RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition);
|
RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition);
|
||||||
else
|
else
|
||||||
RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
|
RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key);
|
||||||
}
|
}
|
||||||
|
|
||||||
Key::~Key() {
|
Key::~Key() {
|
||||||
if(IsOpen())
|
if(IsOpen())
|
||||||
RegCloseKey(key);
|
RegCloseKey(key);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Registry::EnumerateSubkeys(std::wstring path, std::vector<std::wstring>& subkeys) {
|
bool Registry::EnumerateSubkeys(std::wstring path, std::vector<std::wstring>& subkeys) {
|
||||||
Key regKey(path);
|
Key regKey(path);
|
||||||
if(!regKey.IsOpen())
|
if(!regKey.IsOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
wchar_t className[MAX_PATH];
|
wchar_t className[MAX_PATH];
|
||||||
memset(className, 0, sizeof(className));
|
memset(className, 0, sizeof(className));
|
||||||
DWORD classNameLen = MAX_PATH;
|
DWORD classNameLen = MAX_PATH;
|
||||||
DWORD subKeyCount = 0;
|
DWORD subKeyCount = 0;
|
||||||
DWORD maxSubKeyLen, maxClassStringLen, valueCount, maxValueNameLen, maxValueDataLen, securityDescriptorLen;
|
DWORD maxSubKeyLen, maxClassStringLen, valueCount, maxValueNameLen, maxValueDataLen, securityDescriptorLen;
|
||||||
FILETIME lastWriteTime;
|
FILETIME lastWriteTime;
|
||||||
auto ret = RegQueryInfoKeyW(
|
auto ret = RegQueryInfoKeyW(
|
||||||
regKey.GetKey(),
|
regKey.GetKey(),
|
||||||
className,
|
className,
|
||||||
&classNameLen,
|
&classNameLen,
|
||||||
nullptr,
|
nullptr,
|
||||||
&subKeyCount,
|
&subKeyCount,
|
||||||
&maxSubKeyLen,
|
&maxSubKeyLen,
|
||||||
&maxClassStringLen,
|
&maxClassStringLen,
|
||||||
&valueCount,
|
&valueCount,
|
||||||
&maxValueNameLen,
|
&maxValueNameLen,
|
||||||
&maxValueDataLen,
|
&maxValueDataLen,
|
||||||
&securityDescriptorLen,
|
&securityDescriptorLen,
|
||||||
&lastWriteTime);
|
&lastWriteTime);
|
||||||
|
|
||||||
if(ret != ERROR_SUCCESS)
|
if(ret != ERROR_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
subkeys.clear();
|
subkeys.clear();
|
||||||
for(DWORD i = 0; i < subKeyCount; i++) {
|
for(DWORD i = 0; i < subKeyCount; i++) {
|
||||||
DWORD nameLen = MAX_PATH;
|
DWORD nameLen = MAX_PATH;
|
||||||
wchar_t name[MAX_PATH];
|
wchar_t name[MAX_PATH];
|
||||||
memset(name, 0, sizeof(name));
|
memset(name, 0, sizeof(name));
|
||||||
ret = RegEnumKeyExW(regKey.GetKey(), i, name, &nameLen, nullptr, nullptr, nullptr, &lastWriteTime);
|
ret = RegEnumKeyExW(regKey.GetKey(), i, name, &nameLen, nullptr, nullptr, nullptr, &lastWriteTime);
|
||||||
if(ret == ERROR_SUCCESS)
|
if(ret == ERROR_SUCCESS)
|
||||||
subkeys.push_back(name);
|
subkeys.push_back(name);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) {
|
bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) {
|
||||||
Key regKey(path);
|
Key regKey(path);
|
||||||
if(!regKey.IsOpen())
|
if(!regKey.IsOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Query for the type and size of the data
|
// Query for the type and size of the data
|
||||||
DWORD type, size;
|
DWORD type, size;
|
||||||
auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)nullptr, &size);
|
auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)nullptr, &size);
|
||||||
if(ret != ERROR_SUCCESS)
|
if(ret != ERROR_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Query for the data itself
|
// Query for the data itself
|
||||||
std::vector<wchar_t> data(size / 2 + 1);
|
std::vector<wchar_t> data(size / 2 + 1);
|
||||||
DWORD bytesRead = size; // We want to read up to the size we got earlier
|
DWORD bytesRead = size; // We want to read up to the size we got earlier
|
||||||
ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)data.data(), &bytesRead);
|
ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)data.data(), &bytesRead);
|
||||||
if(ret != ERROR_SUCCESS)
|
if(ret != ERROR_SUCCESS)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
value = data.data();
|
value = data.data();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Registry::Get(std::string path, std::string key, std::string& value) {
|
bool Registry::Get(std::string path, std::string key, std::string& value) {
|
||||||
std::wstring wvalue;
|
std::wstring wvalue;
|
||||||
bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue);
|
bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue);
|
||||||
value = converter.to_bytes(wvalue);
|
value = converter.to_bytes(wvalue);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) {
|
bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) {
|
||||||
Key regKey(path);
|
Key regKey(path);
|
||||||
if(!regKey.IsOpen())
|
if(!regKey.IsOpen())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// Query for the data
|
// Query for the data
|
||||||
DWORD type, size = sizeof(DWORD), kvalue;
|
DWORD type, size = sizeof(DWORD), kvalue;
|
||||||
auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)&kvalue, &size);
|
auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)&kvalue, &size);
|
||||||
if(ret != ERROR_SUCCESS || type != REG_DWORD)
|
if(ret != ERROR_SUCCESS || type != REG_DWORD)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
value = kvalue;
|
value = kvalue;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Registry::Get(std::string path, std::string key, uint32_t& value) {
|
bool Registry::Get(std::string path, std::string key, uint32_t& value) {
|
||||||
return Get(converter.from_bytes(path), converter.from_bytes(key), value);
|
return Get(converter.from_bytes(path), converter.from_bytes(key), value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,466 +1,466 @@
|
||||||
#include "icsneo/platform/windows/ftdi.h"
|
#include "icsneo/platform/windows/ftdi.h"
|
||||||
#include "icsneo/platform/ftdi.h"
|
#include "icsneo/platform/ftdi.h"
|
||||||
#include "icsneo/platform/registry.h"
|
#include "icsneo/platform/registry.h"
|
||||||
#include "icsneo/device/founddevice.h"
|
#include "icsneo/device/founddevice.h"
|
||||||
#include <windows.h>
|
#include <windows.h>
|
||||||
#include <iostream>
|
#include <iostream>
|
||||||
#include <iomanip>
|
#include <iomanip>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <cwctype>
|
#include <cwctype>
|
||||||
#include <algorithm>
|
#include <algorithm>
|
||||||
#include <codecvt>
|
#include <codecvt>
|
||||||
#include <limits>
|
#include <limits>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
|
||||||
using namespace icsneo;
|
using namespace icsneo;
|
||||||
|
|
||||||
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
static std::wstring_convert<std::codecvt_utf8_utf16<wchar_t>> converter;
|
||||||
static const std::wstring DRIVER_SERVICES_REG_KEY = L"SYSTEM\\CurrentControlSet\\services\\";
|
static const std::wstring DRIVER_SERVICES_REG_KEY = L"SYSTEM\\CurrentControlSet\\services\\";
|
||||||
static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\";
|
static const std::wstring ALL_ENUM_REG_KEY = L"SYSTEM\\CurrentControlSet\\Enum\\";
|
||||||
static constexpr unsigned int RETRY_TIMES = 5;
|
static constexpr unsigned int RETRY_TIMES = 5;
|
||||||
static constexpr unsigned int RETRY_DELAY = 50;
|
static constexpr unsigned int RETRY_DELAY = 50;
|
||||||
|
|
||||||
struct VCP::Detail {
|
struct VCP::Detail {
|
||||||
Detail() {
|
Detail() {
|
||||||
overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
||||||
overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
||||||
overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
HANDLE handle = INVALID_HANDLE_VALUE;
|
HANDLE handle = INVALID_HANDLE_VALUE;
|
||||||
OVERLAPPED overlappedRead = {};
|
OVERLAPPED overlappedRead = {};
|
||||||
OVERLAPPED overlappedWrite = {};
|
OVERLAPPED overlappedWrite = {};
|
||||||
OVERLAPPED overlappedWait = {};
|
OVERLAPPED overlappedWait = {};
|
||||||
};
|
};
|
||||||
|
|
||||||
void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driverNames) {
|
void VCP::Find(std::vector<FoundDevice>& found, std::vector<std::wstring> driverNames) {
|
||||||
for(auto& driverName : driverNames) {
|
for(auto& driverName : driverNames) {
|
||||||
std::wstringstream regss;
|
std::wstringstream regss;
|
||||||
regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\";
|
regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\";
|
||||||
std::wstring driverEnumRegKey = regss.str();
|
std::wstring driverEnumRegKey = regss.str();
|
||||||
|
|
||||||
uint32_t deviceCount = 0;
|
uint32_t deviceCount = 0;
|
||||||
if(!Registry::Get(driverEnumRegKey, L"Count", deviceCount))
|
if(!Registry::Get(driverEnumRegKey, L"Count", deviceCount))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
for(uint32_t i = 0; i < deviceCount; i++) {
|
for(uint32_t i = 0; i < deviceCount; i++) {
|
||||||
FoundDevice device;
|
FoundDevice device;
|
||||||
|
|
||||||
device.makeDriver = [](const device_eventhandler_t& reportFn, neodevice_t& device) {
|
device.makeDriver = [](const device_eventhandler_t& reportFn, neodevice_t& device) {
|
||||||
return std::unique_ptr<Driver>(new VCP(reportFn, device));
|
return std::unique_ptr<Driver>(new VCP(reportFn, device));
|
||||||
};
|
};
|
||||||
|
|
||||||
// First we want to look at what devices FTDI is enumerating (inside driverEnumRegKey)
|
// 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"
|
// The entry for a ValueCAN 3 with SN 138635 looks like "FTDIBUS\VID_093C+PID_0601+138635A\0000"
|
||||||
// The entry for a ValueCAN 4 with SN V20227 looks like "USB\VID_093C&PID_1101\V20227"
|
// The entry for a ValueCAN 4 with SN V20227 looks like "USB\VID_093C&PID_1101\V20227"
|
||||||
std::wstringstream ss;
|
std::wstringstream ss;
|
||||||
ss << i;
|
ss << i;
|
||||||
std::wstring entry;
|
std::wstring entry;
|
||||||
if(!Registry::Get(driverEnumRegKey, ss.str(), entry))
|
if(!Registry::Get(driverEnumRegKey, ss.str(), entry))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::transform(entry.begin(), entry.end(), entry.begin(), std::towupper);
|
std::transform(entry.begin(), entry.end(), entry.begin(), std::towupper);
|
||||||
|
|
||||||
std::wstringstream vss;
|
std::wstringstream vss;
|
||||||
vss << "VID_" << std::setfill(L'0') << std::setw(4) << std::uppercase << std::hex << INTREPID_USB_VENDOR_ID; // Intrepid Vendor ID
|
vss << "VID_" << std::setfill(L'0') << std::setw(4) << std::uppercase << std::hex << INTREPID_USB_VENDOR_ID; // Intrepid Vendor ID
|
||||||
if(entry.find(vss.str()) == std::wstring::npos)
|
if(entry.find(vss.str()) == std::wstring::npos)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto pidpos = entry.find(L"PID_");
|
auto pidpos = entry.find(L"PID_");
|
||||||
if(pidpos == std::wstring::npos)
|
if(pidpos == std::wstring::npos)
|
||||||
continue;
|
continue;
|
||||||
// We will later use this and startchar to parse the PID
|
// We will later use this and startchar to parse the PID
|
||||||
|
|
||||||
// Okay, this is a device we want
|
// Okay, this is a device we want
|
||||||
// Get the serial number
|
// Get the serial number
|
||||||
auto startchar = entry.find(L"+", pidpos + 1);
|
auto startchar = entry.find(L"+", pidpos + 1);
|
||||||
if(startchar == std::wstring::npos)
|
if(startchar == std::wstring::npos)
|
||||||
startchar = entry.find(L"\\", pidpos + 1);
|
startchar = entry.find(L"\\", pidpos + 1);
|
||||||
bool conversionError = false;
|
bool conversionError = false;
|
||||||
int sn = 0;
|
int sn = 0;
|
||||||
try {
|
try {
|
||||||
sn = std::stoi(entry.substr(startchar + 1));
|
sn = std::stoi(entry.substr(startchar + 1));
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) {
|
||||||
conversionError = true;
|
conversionError = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::wstringstream oss;
|
std::wstringstream oss;
|
||||||
if(!sn || conversionError)
|
if(!sn || conversionError)
|
||||||
oss << entry.substr(startchar + 1, 6); // This is a device with characters in the serial number
|
oss << entry.substr(startchar + 1, 6); // This is a device with characters in the serial number
|
||||||
else
|
else
|
||||||
oss << sn;
|
oss << sn;
|
||||||
|
|
||||||
device.productId = uint16_t(std::wcstol(entry.c_str() + pidpos + 4, nullptr, 16));
|
device.productId = uint16_t(std::wcstol(entry.c_str() + pidpos + 4, nullptr, 16));
|
||||||
if(!device.productId)
|
if(!device.productId)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
std::string serial = converter.to_bytes(oss.str());
|
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.
|
// 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) {
|
if(serial.find_first_of('\\') != std::string::npos) {
|
||||||
// The serial number was not in the first serenum key where we expected it.
|
// 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
|
// We can try to match the ContainerID with the one in ALL_ENUM\USB and get a serial that way
|
||||||
std::wstringstream uess;
|
std::wstringstream uess;
|
||||||
uess << ALL_ENUM_REG_KEY << L"\\USB\\" << vss.str() << L"&PID_" << std::setfill(L'0') << std::setw(4)
|
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::uppercase << std::hex << device.productId << L'\\';
|
||||||
std::wstringstream ciss;
|
std::wstringstream ciss;
|
||||||
ciss << ALL_ENUM_REG_KEY << entry;
|
ciss << ALL_ENUM_REG_KEY << entry;
|
||||||
std::wstring containerIDFromEntry, containerIDFromEnum;
|
std::wstring containerIDFromEntry, containerIDFromEnum;
|
||||||
if(!Registry::Get(ciss.str(), L"ContainerID", containerIDFromEntry))
|
if(!Registry::Get(ciss.str(), L"ContainerID", containerIDFromEntry))
|
||||||
continue; // We did not get a container ID. This can happen on Windows XP and before.
|
continue; // We did not get a container ID. This can happen on Windows XP and before.
|
||||||
if(containerIDFromEntry.empty())
|
if(containerIDFromEntry.empty())
|
||||||
continue; // The container ID was empty?
|
continue; // The container ID was empty?
|
||||||
std::vector<std::wstring> subkeys;
|
std::vector<std::wstring> subkeys;
|
||||||
if(!Registry::EnumerateSubkeys(uess.str(), subkeys))
|
if(!Registry::EnumerateSubkeys(uess.str(), subkeys))
|
||||||
continue; // VID/PID combo was not present at all.
|
continue; // VID/PID combo was not present at all.
|
||||||
if(subkeys.empty())
|
if(subkeys.empty())
|
||||||
continue; // No devices for VID/PID.
|
continue; // No devices for VID/PID.
|
||||||
std::wstring correctSerial;
|
std::wstring correctSerial;
|
||||||
for(auto& subkey : subkeys) {
|
for(auto& subkey : subkeys) {
|
||||||
std::wstringstream skss;
|
std::wstringstream skss;
|
||||||
skss << uess.str() << L'\\' << subkey;
|
skss << uess.str() << L'\\' << subkey;
|
||||||
if(!Registry::Get(skss.str(), L"ContainerID", containerIDFromEnum))
|
if(!Registry::Get(skss.str(), L"ContainerID", containerIDFromEnum))
|
||||||
continue;
|
continue;
|
||||||
if(containerIDFromEntry != containerIDFromEnum)
|
if(containerIDFromEntry != containerIDFromEnum)
|
||||||
continue;
|
continue;
|
||||||
correctSerial = subkey;
|
correctSerial = subkey;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if(correctSerial.empty())
|
if(correctSerial.empty())
|
||||||
continue; // Didn't find the device within the subkeys of the enumeration
|
continue; // Didn't find the device within the subkeys of the enumeration
|
||||||
|
|
||||||
sn = 0;
|
sn = 0;
|
||||||
conversionError = false;
|
conversionError = false;
|
||||||
try {
|
try {
|
||||||
sn = std::stoi(correctSerial);
|
sn = std::stoi(correctSerial);
|
||||||
}
|
}
|
||||||
catch(...) {
|
catch(...) {
|
||||||
conversionError = true;
|
conversionError = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!sn || conversionError) {
|
if(!sn || conversionError) {
|
||||||
// This is a device with characters in the serial number
|
// This is a device with characters in the serial number
|
||||||
if(correctSerial.size() != 6)
|
if(correctSerial.size() != 6)
|
||||||
continue;
|
continue;
|
||||||
serial = converter.to_bytes(correctSerial);
|
serial = converter.to_bytes(correctSerial);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
std::wstringstream soss;
|
std::wstringstream soss;
|
||||||
soss << sn;
|
soss << sn;
|
||||||
serial = converter.to_bytes(soss.str());
|
serial = converter.to_bytes(soss.str());
|
||||||
}
|
}
|
||||||
|
|
||||||
if(serial.find_first_of('\\') != std::string::npos)
|
if(serial.find_first_of('\\') != std::string::npos)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
strcpy_s(device.serial, sizeof(device.serial), serial.c_str());
|
strcpy_s(device.serial, sizeof(device.serial), serial.c_str());
|
||||||
|
|
||||||
// Serial number is saved, we want the COM port number now
|
// Serial number is saved, we want the COM port number now
|
||||||
// This will be stored under ALL_ENUM_REG_KEY\entry\Device Parameters\PortName (entry from the FTDI_ENUM)
|
// This will be stored under ALL_ENUM_REG_KEY\entry\Device Parameters\PortName (entry from the FTDI_ENUM)
|
||||||
std::wstringstream dpss;
|
std::wstringstream dpss;
|
||||||
dpss << ALL_ENUM_REG_KEY << entry << L"\\Device Parameters";
|
dpss << ALL_ENUM_REG_KEY << entry << L"\\Device Parameters";
|
||||||
std::wstring port;
|
std::wstring port;
|
||||||
Registry::Get(dpss.str(), L"PortName", port); // TODO If error do something else (Plasma maybe?)
|
Registry::Get(dpss.str(), L"PortName", port); // TODO If error do something else (Plasma maybe?)
|
||||||
std::transform(port.begin(), port.end(), port.begin(), std::towupper);
|
std::transform(port.begin(), port.end(), port.begin(), std::towupper);
|
||||||
auto compos = port.find(L"COM");
|
auto compos = port.find(L"COM");
|
||||||
device.handle = 0;
|
device.handle = 0;
|
||||||
if(compos != std::wstring::npos) {
|
if(compos != std::wstring::npos) {
|
||||||
try {
|
try {
|
||||||
device.handle = std::stoi(port.substr(compos + 3));
|
device.handle = std::stoi(port.substr(compos + 3));
|
||||||
}
|
}
|
||||||
catch(...) {} // In case of this, or any other error, handle has already been initialized to 0
|
catch(...) {} // In case of this, or any other error, handle has already been initialized to 0
|
||||||
}
|
}
|
||||||
|
|
||||||
bool alreadyFound = false;
|
bool alreadyFound = false;
|
||||||
FoundDevice* shouldReplace = nullptr;
|
FoundDevice* shouldReplace = nullptr;
|
||||||
for(auto& foundDev : found) {
|
for(auto& foundDev : found) {
|
||||||
if((foundDev.handle == device.handle || foundDev.handle == 0 || device.handle == 0) && serial == foundDev.serial) {
|
if((foundDev.handle == device.handle || foundDev.handle == 0 || device.handle == 0) && serial == foundDev.serial) {
|
||||||
alreadyFound = true;
|
alreadyFound = true;
|
||||||
if(foundDev.handle == 0)
|
if(foundDev.handle == 0)
|
||||||
shouldReplace = &foundDev;
|
shouldReplace = &foundDev;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!alreadyFound)
|
if(!alreadyFound)
|
||||||
found.push_back(device);
|
found.push_back(device);
|
||||||
else if(shouldReplace != nullptr)
|
else if(shouldReplace != nullptr)
|
||||||
*shouldReplace = device;
|
*shouldReplace = device;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
VCP::VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
|
VCP::VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) {
|
||||||
detail = std::make_shared<Detail>();
|
detail = std::make_shared<Detail>();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCP::IsHandleValid(neodevice_handle_t handle) {
|
bool VCP::IsHandleValid(neodevice_handle_t handle) {
|
||||||
if(handle < 1)
|
if(handle < 1)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if(handle > 256) // Windows default max COM port is COM256
|
if(handle > 256) // Windows default max COM port is COM256
|
||||||
return false; // TODO Enumerate subkeys of HKLM\HARDWARE\DEVICEMAP\SERIALCOMM as a user might have more serial ports somehow
|
return false; // TODO Enumerate subkeys of HKLM\HARDWARE\DEVICEMAP\SERIALCOMM as a user might have more serial ports somehow
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCP::open(bool fromAsync) {
|
bool VCP::open(bool fromAsync) {
|
||||||
if(isOpen() || (!fromAsync && opening)) {
|
if(isOpen() || (!fromAsync && opening)) {
|
||||||
report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(!IsHandleValid(device.handle)) {
|
if(!IsHandleValid(device.handle)) {
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
opening = true;
|
opening = true;
|
||||||
|
|
||||||
std::wstringstream comss;
|
std::wstringstream comss;
|
||||||
comss << L"\\\\.\\COM" << device.handle;
|
comss << L"\\\\.\\COM" << device.handle;
|
||||||
|
|
||||||
// We're going to attempt to open 5 (RETRY_TIMES) times in a row
|
// We're going to attempt to open 5 (RETRY_TIMES) times in a row
|
||||||
for(int i = 0; !isOpen() && i < RETRY_TIMES; i++) {
|
for(int i = 0; !isOpen() && i < RETRY_TIMES; i++) {
|
||||||
detail->handle = CreateFileW(comss.str().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
|
detail->handle = CreateFileW(comss.str().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr,
|
||||||
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
|
OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr);
|
||||||
if(GetLastError() == ERROR_SUCCESS)
|
if(GetLastError() == ERROR_SUCCESS)
|
||||||
break; // We have the file handle
|
break; // We have the file handle
|
||||||
|
|
||||||
std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_DELAY));
|
std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_DELAY));
|
||||||
}
|
}
|
||||||
|
|
||||||
opening = false;
|
opening = false;
|
||||||
|
|
||||||
if(!isOpen()) {
|
if(!isOpen()) {
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the timeouts
|
// Set the timeouts
|
||||||
COMMTIMEOUTS timeouts;
|
COMMTIMEOUTS timeouts;
|
||||||
if(!GetCommTimeouts(detail->handle, &timeouts)) {
|
if(!GetCommTimeouts(detail->handle, &timeouts)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// See https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_commtimeouts#remarks
|
// See https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_commtimeouts#remarks
|
||||||
timeouts.ReadIntervalTimeout = MAXDWORD;
|
timeouts.ReadIntervalTimeout = MAXDWORD;
|
||||||
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
|
timeouts.ReadTotalTimeoutMultiplier = MAXDWORD;
|
||||||
timeouts.ReadTotalTimeoutConstant = 100;
|
timeouts.ReadTotalTimeoutConstant = 100;
|
||||||
timeouts.WriteTotalTimeoutConstant = 10000;
|
timeouts.WriteTotalTimeoutConstant = 10000;
|
||||||
timeouts.WriteTotalTimeoutMultiplier = 0;
|
timeouts.WriteTotalTimeoutMultiplier = 0;
|
||||||
|
|
||||||
if(!SetCommTimeouts(detail->handle, &timeouts)) {
|
if(!SetCommTimeouts(detail->handle, &timeouts)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set the COM state
|
// Set the COM state
|
||||||
DCB comstate;
|
DCB comstate;
|
||||||
if(!GetCommState(detail->handle, &comstate)) {
|
if(!GetCommState(detail->handle, &comstate)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
comstate.BaudRate = 115200;
|
comstate.BaudRate = 115200;
|
||||||
comstate.ByteSize = 8;
|
comstate.ByteSize = 8;
|
||||||
comstate.Parity = NOPARITY;
|
comstate.Parity = NOPARITY;
|
||||||
comstate.StopBits = 0;
|
comstate.StopBits = 0;
|
||||||
comstate.fDtrControl = DTR_CONTROL_ENABLE;
|
comstate.fDtrControl = DTR_CONTROL_ENABLE;
|
||||||
comstate.fRtsControl = RTS_CONTROL_ENABLE;
|
comstate.fRtsControl = RTS_CONTROL_ENABLE;
|
||||||
|
|
||||||
if(!SetCommState(detail->handle, &comstate)) {
|
if(!SetCommState(detail->handle, &comstate)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
PurgeComm(detail->handle, PURGE_RXCLEAR);
|
PurgeComm(detail->handle, PURGE_RXCLEAR);
|
||||||
|
|
||||||
// Set up events so that overlapped IO can work with them
|
// Set up events so that overlapped IO can work with them
|
||||||
detail->overlappedRead.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
detail->overlappedRead.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
||||||
detail->overlappedWrite.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
detail->overlappedWrite.hEvent = CreateEvent(nullptr, false, false, nullptr);
|
||||||
detail->overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr);
|
detail->overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr);
|
||||||
if (detail->overlappedRead.hEvent == nullptr || detail->overlappedWrite.hEvent == nullptr || detail->overlappedWait.hEvent == nullptr) {
|
if (detail->overlappedRead.hEvent == nullptr || detail->overlappedWrite.hEvent == nullptr || detail->overlappedWait.hEvent == nullptr) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Set up event so that we will satisfy overlappedWait when a character comes in
|
// Set up event so that we will satisfy overlappedWait when a character comes in
|
||||||
if(!SetCommMask(detail->handle, EV_RXCHAR)) {
|
if(!SetCommMask(detail->handle, EV_RXCHAR)) {
|
||||||
close();
|
close();
|
||||||
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO Set up some sort of shared memory, save which COM port we have open so we don't try to open it again
|
// TODO Set up some sort of shared memory, save which COM port we have open so we don't try to open it again
|
||||||
|
|
||||||
// Create threads
|
// Create threads
|
||||||
readThread = std::thread(&VCP::readTask, this);
|
readThread = std::thread(&VCP::readTask, this);
|
||||||
writeThread = std::thread(&VCP::writeTask, this);
|
writeThread = std::thread(&VCP::writeTask, this);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCP::openAsync(fn_boolCallback callback) {
|
void VCP::openAsync(fn_boolCallback callback) {
|
||||||
threads.push_back(std::make_shared<std::thread>([&]() {
|
threads.push_back(std::make_shared<std::thread>([&]() {
|
||||||
callback(open(true));
|
callback(open(true));
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCP::close() {
|
bool VCP::close() {
|
||||||
if(!isOpen()) {
|
if(!isOpen()) {
|
||||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
closing = true; // Signal the threads that we are closing
|
closing = true; // Signal the threads that we are closing
|
||||||
for(auto& t : threads)
|
for(auto& t : threads)
|
||||||
t->join(); // Wait for the threads to close
|
t->join(); // Wait for the threads to close
|
||||||
readThread.join();
|
readThread.join();
|
||||||
writeThread.join();
|
writeThread.join();
|
||||||
closing = false;
|
closing = false;
|
||||||
|
|
||||||
if(!CloseHandle(detail->handle)) {
|
if(!CloseHandle(detail->handle)) {
|
||||||
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
detail->handle = INVALID_HANDLE_VALUE;
|
detail->handle = INVALID_HANDLE_VALUE;
|
||||||
|
|
||||||
bool ret = true; // If one of the events fails closing, we probably still want to try and close the others
|
bool ret = true; // If one of the events fails closing, we probably still want to try and close the others
|
||||||
if(detail->overlappedRead.hEvent != INVALID_HANDLE_VALUE) {
|
if(detail->overlappedRead.hEvent != INVALID_HANDLE_VALUE) {
|
||||||
if(!CloseHandle(detail->overlappedRead.hEvent))
|
if(!CloseHandle(detail->overlappedRead.hEvent))
|
||||||
ret = false;
|
ret = false;
|
||||||
detail->overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
detail->overlappedRead.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if(detail->overlappedWrite.hEvent != INVALID_HANDLE_VALUE) {
|
if(detail->overlappedWrite.hEvent != INVALID_HANDLE_VALUE) {
|
||||||
if(!CloseHandle(detail->overlappedWrite.hEvent))
|
if(!CloseHandle(detail->overlappedWrite.hEvent))
|
||||||
ret = false;
|
ret = false;
|
||||||
detail->overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
detail->overlappedWrite.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
if(detail->overlappedWait.hEvent != INVALID_HANDLE_VALUE) {
|
if(detail->overlappedWait.hEvent != INVALID_HANDLE_VALUE) {
|
||||||
if(!CloseHandle(detail->overlappedWait.hEvent))
|
if(!CloseHandle(detail->overlappedWait.hEvent))
|
||||||
ret = false;
|
ret = false;
|
||||||
detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t flush;
|
uint8_t flush;
|
||||||
WriteOperation flushop;
|
WriteOperation flushop;
|
||||||
while(readQueue.try_dequeue(flush)) {}
|
while(readQueue.try_dequeue(flush)) {}
|
||||||
while(writeQueue.try_dequeue(flushop)) {}
|
while(writeQueue.try_dequeue(flushop)) {}
|
||||||
|
|
||||||
if(!ret)
|
if(!ret)
|
||||||
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error);
|
||||||
|
|
||||||
// TODO Set up some sort of shared memory, free which COM port we had open so we can try to open it again
|
// TODO Set up some sort of shared memory, free which COM port we had open so we can try to open it again
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool VCP::isOpen() {
|
bool VCP::isOpen() {
|
||||||
return detail->handle != INVALID_HANDLE_VALUE;
|
return detail->handle != INVALID_HANDLE_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCP::readTask() {
|
void VCP::readTask() {
|
||||||
constexpr size_t READ_BUFFER_SIZE = 10240;
|
constexpr size_t READ_BUFFER_SIZE = 10240;
|
||||||
uint8_t readbuf[READ_BUFFER_SIZE];
|
uint8_t readbuf[READ_BUFFER_SIZE];
|
||||||
IOTaskState state = LAUNCH;
|
IOTaskState state = LAUNCH;
|
||||||
DWORD bytesRead = 0;
|
DWORD bytesRead = 0;
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
while(!closing && !isDisconnected()) {
|
while(!closing && !isDisconnected()) {
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case LAUNCH: {
|
case LAUNCH: {
|
||||||
COMSTAT comStatus;
|
COMSTAT comStatus;
|
||||||
unsigned long errorCodes;
|
unsigned long errorCodes;
|
||||||
ClearCommError(detail->handle, &errorCodes, &comStatus);
|
ClearCommError(detail->handle, &errorCodes, &comStatus);
|
||||||
|
|
||||||
bytesRead = 0;
|
bytesRead = 0;
|
||||||
if(ReadFile(detail->handle, readbuf, READ_BUFFER_SIZE, nullptr, &detail->overlappedRead)) {
|
if(ReadFile(detail->handle, readbuf, READ_BUFFER_SIZE, nullptr, &detail->overlappedRead)) {
|
||||||
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
||||||
if(bytesRead)
|
if(bytesRead)
|
||||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||||
}
|
}
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
auto lastError = GetLastError();
|
auto lastError = GetLastError();
|
||||||
if(lastError == ERROR_IO_PENDING)
|
if(lastError == ERROR_IO_PENDING)
|
||||||
state = WAIT;
|
state = WAIT;
|
||||||
else if(lastError != ERROR_SUCCESS) {
|
else if(lastError != ERROR_SUCCESS) {
|
||||||
if(lastError == ERROR_ACCESS_DENIED) {
|
if(lastError == ERROR_ACCESS_DENIED) {
|
||||||
if(!isDisconnected()) {
|
if(!isDisconnected()) {
|
||||||
disconnected = true;
|
disconnected = true;
|
||||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT: {
|
case WAIT: {
|
||||||
auto ret = WaitForSingleObject(detail->overlappedRead.hEvent, 100);
|
auto ret = WaitForSingleObject(detail->overlappedRead.hEvent, 100);
|
||||||
if(ret == WAIT_OBJECT_0) {
|
if(ret == WAIT_OBJECT_0) {
|
||||||
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) {
|
||||||
readQueue.enqueue_bulk(readbuf, bytesRead);
|
readQueue.enqueue_bulk(readbuf, bytesRead);
|
||||||
state = LAUNCH;
|
state = LAUNCH;
|
||||||
} else
|
} else
|
||||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
if(ret == WAIT_ABANDONED || ret == WAIT_FAILED) {
|
if(ret == WAIT_ABANDONED || ret == WAIT_FAILED) {
|
||||||
state = LAUNCH;
|
state = LAUNCH;
|
||||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void VCP::writeTask() {
|
void VCP::writeTask() {
|
||||||
IOTaskState state = LAUNCH;
|
IOTaskState state = LAUNCH;
|
||||||
VCP::WriteOperation writeOp;
|
VCP::WriteOperation writeOp;
|
||||||
DWORD bytesWritten = 0;
|
DWORD bytesWritten = 0;
|
||||||
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
EventManager::GetInstance().downgradeErrorsOnCurrentThread();
|
||||||
while(!closing && !isDisconnected()) {
|
while(!closing && !isDisconnected()) {
|
||||||
switch(state) {
|
switch(state) {
|
||||||
case LAUNCH: {
|
case LAUNCH: {
|
||||||
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
|
if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100)))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
bytesWritten = 0;
|
bytesWritten = 0;
|
||||||
if(WriteFile(detail->handle, writeOp.bytes.data(), (DWORD)writeOp.bytes.size(), nullptr, &detail->overlappedWrite))
|
if(WriteFile(detail->handle, writeOp.bytes.data(), (DWORD)writeOp.bytes.size(), nullptr, &detail->overlappedWrite))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
auto winerr = GetLastError();
|
auto winerr = GetLastError();
|
||||||
if(winerr == ERROR_IO_PENDING) {
|
if(winerr == ERROR_IO_PENDING) {
|
||||||
state = WAIT;
|
state = WAIT;
|
||||||
}
|
}
|
||||||
else if(winerr == ERROR_ACCESS_DENIED) {
|
else if(winerr == ERROR_ACCESS_DENIED) {
|
||||||
if(!isDisconnected()) {
|
if(!isDisconnected()) {
|
||||||
disconnected = true;
|
disconnected = true;
|
||||||
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case WAIT: {
|
case WAIT: {
|
||||||
auto ret = WaitForSingleObject(detail->overlappedWrite.hEvent, 50);
|
auto ret = WaitForSingleObject(detail->overlappedWrite.hEvent, 50);
|
||||||
if(ret == WAIT_OBJECT_0) {
|
if(ret == WAIT_OBJECT_0) {
|
||||||
if(!GetOverlappedResult(detail->handle, &detail->overlappedWrite, &bytesWritten, FALSE))
|
if(!GetOverlappedResult(detail->handle, &detail->overlappedWrite, &bytesWritten, FALSE))
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||||
state = LAUNCH;
|
state = LAUNCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(ret == WAIT_ABANDONED) {
|
if(ret == WAIT_ABANDONED) {
|
||||||
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error);
|
||||||
state = LAUNCH;
|
state = LAUNCH;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue