From 008a1620c81f9e3ead5a53755c06a72c07dfdcb9 Mon Sep 17 00:00:00 2001 From: Paul Hollinsky Date: Sun, 27 Mar 2022 14:37:39 -0400 Subject: [PATCH] Repo: Normalize source files to LF --- api/icsneoc/icsneoc.cpp | 1372 ++++++------ api/icsneocpp/icsneocpp.cpp | 94 +- device/devicefinder.cpp | 528 ++--- include/icsneo/communication/driver.h | 120 +- .../message/callback/messagecallback.h | 98 +- .../icsneo/communication/message/canmessage.h | 48 +- .../message/filter/messagefilter.h | 134 +- .../communication/message/iso9141message.h | 58 +- .../icsneo/communication/message/message.h | 152 +- include/icsneo/communication/network.h | 1886 ++++++++--------- include/icsneo/device/devicefinder.h | 44 +- .../icsneo/device/tree/radmoon2/radmoon2.h | 178 +- .../device/tree/radmoonduo/radmoonduo.h | 106 +- .../device/tree/radsupermoon/radsupermoon.h | 174 +- .../icsneo/device/tree/valuecan3/valuecan3.h | 90 +- .../device/tree/valuecan4/valuecan4-1.h | 92 +- .../device/tree/valuecan4/valuecan4-2.h | 132 +- .../device/tree/valuecan4/valuecan4-2el.h | 194 +- .../device/tree/valuecan4/valuecan4-4.h | 154 +- .../icsneo/device/tree/valuecan4/valuecan4.h | 58 +- .../tree/valuecan4/valuecan4industrial.h | 108 +- .../icsneo/device/tree/vividcan/vividcan.h | 82 +- include/icsneo/icsneocpp.h | 76 +- include/icsneo/platform/cdcacm.h | 26 +- include/icsneo/platform/dynamiclib.h | 22 +- include/icsneo/platform/ftdi.h | 26 +- include/icsneo/platform/posix/dynamiclib.h | 46 +- include/icsneo/platform/posix/tchar.h | 10 +- include/icsneo/platform/registry.h | 18 +- include/icsneo/platform/windows/cdcacm.h | 38 +- include/icsneo/platform/windows/dynamiclib.h | 38 +- include/icsneo/platform/windows/ftdi.h | 38 +- include/icsneo/platform/windows/registry.h | 54 +- include/icsneo/platform/windows/vcp.h | 94 +- platform/windows/registry.cpp | 240 +-- platform/windows/vcp.cpp | 930 ++++---- 36 files changed, 3779 insertions(+), 3779 deletions(-) diff --git a/api/icsneoc/icsneoc.cpp b/api/icsneoc/icsneoc.cpp index 32fa724..b255edb 100644 --- a/api/icsneoc/icsneoc.cpp +++ b/api/icsneoc/icsneoc.cpp @@ -1,686 +1,686 @@ -#ifndef __cplusplus -#error "icsneoc.cpp must be compiled with a C++ compiler!" -#endif - -#define ICSNEOC_MAKEDLL - -#include "icsneo/icsneoc.h" -#include "icsneo/icsneocpp.h" -#include "icsneo/platform/dynamiclib.h" -#include "icsneo/api/eventmanager.h" -#include "icsneo/device/devicefinder.h" -#include -#include -#include -#include -#include -#include -#include - -using namespace icsneo; - -// Holds references for the shared_ptrs so they do not get freed until we're ready -static std::vector> connectableFoundDevices, connectedDevices; - -// We store an array of shared_ptr messages per device, this is the owner of the shared_ptr on behalf of the C interface -static std::map>> polledMessageStorage; - -void icsneo_findAllDevices(neodevice_t* devices, size_t* count) { - std::vector> foundDevices = icsneo::FindAllDevices(); - - if(count == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return; - } - - if(devices == nullptr) { - *count = foundDevices.size(); - return; - } - - icsneo_freeUnconnectedDevices(); // Mark previous results as freed so they can no longer be connected to - - size_t inputSize = *count; - *count = foundDevices.size(); - size_t outputSize = *count; - if(outputSize > inputSize) { - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - outputSize = inputSize; - } - - for(size_t i = 0; i < outputSize; i++) { - connectableFoundDevices.push_back(foundDevices[i]); - devices[i] = foundDevices[i]->getNeoDevice(); - } -} - -void icsneo_freeUnconnectedDevices() { - connectableFoundDevices.clear(); -} - -bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) { - // TAG String copy function - if(count == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - auto result = Device::SerialNumToString(num); - - if(str == nullptr) { - *count = result.length() + 1; - return false; - } - - if(*count < result.length()) { - *count = result.length() + 1; // This is how big of a buffer we need - EventManager::GetInstance().add(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error); - return false; - } - - *count = result.copy(str, *count); - str[*count] = '\0'; - return true; -} - -uint32_t icsneo_serialStringToNum(const char* str) { - if(!str) - return 0; - - return Device::SerialStringToNum(str); -} - -bool icsneo_isValidNeoDevice(const neodevice_t* device) { - // return false on nullptr - if(!device) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - // If this neodevice_t was returned by a previous search, it will no longer be valid (as the underlying icsneo::Device is freed) - for(auto& dev : connectedDevices) { - if(dev.get() == device->device) - return true; - } - for(auto& dev : connectableFoundDevices) { - if(dev.get() == device->device) - return true; - } - - EventManager::GetInstance().add(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error); - return false; -} - -bool icsneo_openDevice(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(!device->device->open()) - return false; - - // We connected successfully, move the device to connected devices - std::vector>::iterator> itemsToMove; - for(auto it = connectableFoundDevices.begin(); it < connectableFoundDevices.end(); it++) { - if((*it).get() == device->device) - itemsToMove.push_back(it); - } - for(auto it : itemsToMove) { - connectedDevices.push_back(*it); - connectableFoundDevices.erase(it); - } - - return true; -} - -bool icsneo_closeDevice(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(!device->device->close()) - return false; - - // We disconnected successfully, free the device - std::vector>::iterator> itemsToDelete; - for(auto it = connectedDevices.begin(); it < connectedDevices.end(); it++) { - if((*it).get() == device->device) - itemsToDelete.push_back(it); - } - for(auto it : itemsToDelete) - connectedDevices.erase(it); - - return true; -} - -bool icsneo_isOpen(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->isOpen(); -} - -bool icsneo_goOnline(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->goOnline(); -} - -bool icsneo_goOffline(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->goOffline(); -} - -bool icsneo_isOnline(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->isOnline(); -} - -bool icsneo_enableMessagePolling(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->enableMessagePolling(); -} - -bool icsneo_disableMessagePolling(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->disableMessagePolling(); -} - -bool icsneo_isMessagePollingEnabled(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->isMessagePollingEnabled(); -} - -bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_t* items, uint64_t timeout) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(items == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - if(messages == nullptr) { - // A NULL value for messages means the user wants the current size of the buffer into items - *items = device->device->getCurrentMessageCount(); - return true; - } - - std::vector>& storage = polledMessageStorage[device->device]; - - if(!device->device->getMessages(storage, *items, std::chrono::milliseconds(timeout))) - return false; - - *items = storage.size(); - - for(size_t i = 0; i < *items; i++) { - // For each message, copy into neomessage_t buffer given - messages[i] = CreateNeoMessage(storage[i]); - } - - // The user now has until the next call of icsneo_getMessages (for this device) to use the data, after which point it's freed - // The user should copy the data out if they want it - return true; -} - -int icsneo_getPollingMessageLimit(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return -1; - - return (int)device->device->getPollingMessageLimit(); -} - -bool icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - device->device->setPollingMessageLimit(newLimit); - return true; -} - -int icsneo_addMessageCallback(const neodevice_t* device, void (*callback)(neomessage_t), void*) { - if(!icsneo_isValidNeoDevice(device)) - return -1; - - return device->device->addMessageCallback( - MessageCallback( - [=](std::shared_ptr msg) { - return callback(CreateNeoMessage(msg)); - } - ) - ); -} - -bool icsneo_removeMessageCallback(const neodevice_t* device, int id) { - if(!icsneo_isValidNeoDevice(device)) - return false; - return device->device->removeMessageCallback(id); -} - -neonetid_t icsneo_getNetworkByNumber(const neodevice_t* device, neonettype_t type, unsigned int number) { - if(!icsneo_isValidNeoDevice(device)) - return false; - return neonetid_t(device->device->getNetworkByNumber(icsneo::Network::Type(type), size_t(number)).getNetID()); -} - -bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength) { - // TAG String copy function - if(maxLength == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - if(!icsneo_isValidNeoDevice(device)) - return false; - - std::string output = device->device->getProductName(); - - if(str == nullptr) { - *maxLength = output.length(); - return false; - } - - *maxLength = output.copy(str, *maxLength); - str[*maxLength] = '\0'; - - if(output.length() > *maxLength) - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - - return true; -} - -bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength) { - // TAG String copy function - if(maxLength == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - std::string output = DeviceType(type).getGenericProductName(); - - if(str == nullptr) { - *maxLength = output.length(); - return false; - } - - *maxLength = output.copy(str, *maxLength); - str[*maxLength] = '\0'; - - if(output.length() > *maxLength) - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - - return true; -} - -bool icsneo_settingsRefresh(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->refresh(); -} - -bool icsneo_settingsApply(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->apply(); -} - -bool icsneo_settingsApplyTemporary(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->apply(true); -} - -bool icsneo_settingsApplyDefaults(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->applyDefaults(); -} - -bool icsneo_settingsApplyDefaultsTemporary(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->applyDefaults(true); -} - -int icsneo_settingsReadStructure(const neodevice_t* device, void* structure, size_t structureSize) { - if(!icsneo_isValidNeoDevice(device)) - return -1; - - size_t readSize = device->device->settings->getSize(); - if(structure == nullptr) // Structure size request - return (int)readSize; - if(readSize > structureSize) { - // Client application has a smaller structure than we do - // It is probably built against an older version of the API - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - readSize = structureSize; - } - - const void* deviceStructure = device->device->settings->getRawStructurePointer(); - if(deviceStructure == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); - return -1; - } - - memcpy(structure, deviceStructure, readSize); - - if(readSize < structureSize) // Client application is attempting to read more than we have - memset((uint8_t*)structure + readSize, 0, structureSize - readSize); - - return (int)readSize; -} - -// Not exported -static bool icsneo_settingsWriteStructure(const neodevice_t* device, const void* structure, size_t structureSize) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(structure == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - size_t writeSize = device->device->settings->getSize(); - if(writeSize < structureSize) { - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - structureSize = writeSize; - } - - void* deviceStructure = device->device->settings->getMutableRawStructurePointer(); - if(deviceStructure == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); - return false; - } - - memcpy(deviceStructure, structure, structureSize); - - // If writeSize > structureSize that means that the user has given us a smaller structure - // This is okay, we will keep the end of the structure intact - // TODO Flag an error - return true; -} - -bool icsneo_settingsApplyStructure(const neodevice_t* device, const void* structure, size_t structureSize) { - return icsneo_settingsWriteStructure(device, structure, structureSize) && icsneo_settingsApply(device); -} - -bool icsneo_settingsApplyStructureTemporary(const neodevice_t* device, const void* structure, size_t structureSize) { - return icsneo_settingsWriteStructure(device, structure, structureSize) && icsneo_settingsApplyTemporary(device); -} - -int64_t icsneo_getBaudrate(const neodevice_t* device, neonetid_t netid) { - if(!icsneo_isValidNeoDevice(device)) - return -1; - - return device->device->settings->getBaudrateFor(netid); -} - -bool icsneo_setBaudrate(const neodevice_t* device, neonetid_t netid, int64_t newBaudrate) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->setBaudrateFor(netid, newBaudrate); -} - -int64_t icsneo_getFDBaudrate(const neodevice_t* device, neonetid_t netid) { - if(!icsneo_isValidNeoDevice(device)) - return -1; - - return device->device->settings->getFDBaudrateFor(netid); -} - -bool icsneo_setFDBaudrate(const neodevice_t* device, neonetid_t netid, int64_t newBaudrate) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->setFDBaudrateFor(netid, newBaudrate); -} - -bool icsneo_transmit(const neodevice_t* device, const neomessage_t* message) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(auto frame = std::dynamic_pointer_cast(CreateMessageFromNeoMessage(message))) - return device->device->transmit(frame); - - return false; -} - -bool icsneo_transmitMessages(const neodevice_t* device, const neomessage_t* messages, size_t count) { - // Transmit implements neodevice_t check so it is not needed here - // TODO This can be implemented faster - for(size_t i = 0; i < count; i++) { - if(!icsneo_transmit(device, messages + i)) - return false; - } - return true; -} - -void icsneo_setWriteBlocks(const neodevice_t* device, bool blocks) { - if(!icsneo_isValidNeoDevice(device)) - return; - - device->device->setWriteBlocks(blocks); -} - -bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength) { - // TAG String copy function - if(maxLength == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - if(!icsneo_isValidNeoDevice(device)) - return false; - - std::string output = device->device->describe(); - - *maxLength = output.copy(str, *maxLength); - str[*maxLength] = '\0'; - - if(output.length() > *maxLength) - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - - return true; -} - -neoversion_t icsneo_getVersion(void) { - return icsneo::GetVersion(); -} - -int icsneo_addEventCallback(void (*callback)(neoevent_t), void*) { - return EventManager::GetInstance().addEventCallback( - EventCallback( - [=](std::shared_ptr evt) { - return callback(*(evt->getNeoEvent())); - } - ) - ); -} - -bool icsneo_removeEventCallback(int id) { - return EventManager::GetInstance().removeEventCallback(id); -} - -bool icsneo_getEvents(neoevent_t* events, size_t* size) { - if(size == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - if(events == nullptr) { - *size = icsneo::EventCount(); - return false; - } - - auto cppErrors = icsneo::GetEvents(*size); - for(size_t i = 0; i < cppErrors.size(); i++) - memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t)); - *size = cppErrors.size(); - - return true; -} - -bool icsneo_getDeviceEvents(const neodevice_t* device, neoevent_t* events, size_t* size) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(size == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - // Creating the filter will nullptr is okay! It will find any events not associated with a device. - EventFilter filter = (device != nullptr ? device->device : nullptr); - - if(events == nullptr) { - *size = icsneo::EventCount(filter); - return false; - } - - auto cppErrors = icsneo::GetEvents(*size, filter); - for(size_t i = 0; i < cppErrors.size(); i++) - memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t)); - *size = cppErrors.size(); - - return true; -} - -bool icsneo_getLastError(neoevent_t* error) { - if(error == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - APIEvent cppErr = icsneo::GetLastError(); - if(cppErr.getType() == icsneo::APIEvent::Type::NoErrorFound) - return false; - memcpy(error, cppErr.getNeoEvent(), sizeof(neoevent_t)); - return true; -} - -void icsneo_discardAllEvents(void) { - icsneo::DiscardEvents(); -} - -void icsneo_discardDeviceEvents(const neodevice_t* device) { - if(!icsneo_isValidNeoDevice(device)) - return; - - if(device == nullptr) - icsneo::DiscardEvents(nullptr); // Discard events not associated with a device - else - icsneo::DiscardEvents(device->device); -} - -void icsneo_setEventLimit(size_t newLimit) { - icsneo::SetEventLimit(newLimit); -} - -size_t icsneo_getEventLimit(void) { - return icsneo::GetEventLimit(); -} - -bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) { - if(count == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - auto supported = DeviceFinder::GetSupportedDevices(); - auto len = supported.size(); - - if(devices == nullptr) { - *count = len; - return false; - } - - if(*count < len) { - len = *count; - EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); - } - - for(size_t i = 0; i < len; i++) - devices[i] = supported[i]; - *count = len; - - return true; -} - -bool icsneo_getTimestampResolution(const neodevice_t* device, uint16_t* resolution) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(resolution == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - *resolution = device->device->getTimestampResolution(); - return true; -} - -bool icsneo_getDigitalIO(const neodevice_t* device, neoio_t type, uint32_t number, bool* value) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - if(value == nullptr) { - EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); - return false; - } - - const optional val = device->device->getDigitalIO(static_cast(type), number); - if(!val.has_value()) - return false; - - *value = *val; - return true; -} - -bool icsneo_setDigitalIO(const neodevice_t* device, neoio_t type, uint32_t number, bool value) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->setDigitalIO(static_cast(type), number, value); -} - -bool icsneo_isTerminationSupportedFor(const neodevice_t* device, neonetid_t netid) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->isTerminationSupportedFor(Network(netid)); -} - -bool icsneo_canTerminationBeEnabledFor(const neodevice_t* device, neonetid_t netid) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->canTerminationBeEnabledFor(Network(netid)); -} - -bool icsneo_isTerminationEnabledFor(const neodevice_t* device, neonetid_t netid) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->isTerminationEnabledFor(Network(netid)).value_or(false); -} - -bool icsneo_setTerminationFor(const neodevice_t* device, neonetid_t netid, bool enabled) { - if(!icsneo_isValidNeoDevice(device)) - return false; - - return device->device->settings->setTerminationFor(Network(netid), enabled); -} +#ifndef __cplusplus +#error "icsneoc.cpp must be compiled with a C++ compiler!" +#endif + +#define ICSNEOC_MAKEDLL + +#include "icsneo/icsneoc.h" +#include "icsneo/icsneocpp.h" +#include "icsneo/platform/dynamiclib.h" +#include "icsneo/api/eventmanager.h" +#include "icsneo/device/devicefinder.h" +#include +#include +#include +#include +#include +#include +#include + +using namespace icsneo; + +// Holds references for the shared_ptrs so they do not get freed until we're ready +static std::vector> connectableFoundDevices, connectedDevices; + +// We store an array of shared_ptr messages per device, this is the owner of the shared_ptr on behalf of the C interface +static std::map>> polledMessageStorage; + +void icsneo_findAllDevices(neodevice_t* devices, size_t* count) { + std::vector> foundDevices = icsneo::FindAllDevices(); + + if(count == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return; + } + + if(devices == nullptr) { + *count = foundDevices.size(); + return; + } + + icsneo_freeUnconnectedDevices(); // Mark previous results as freed so they can no longer be connected to + + size_t inputSize = *count; + *count = foundDevices.size(); + size_t outputSize = *count; + if(outputSize > inputSize) { + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + outputSize = inputSize; + } + + for(size_t i = 0; i < outputSize; i++) { + connectableFoundDevices.push_back(foundDevices[i]); + devices[i] = foundDevices[i]->getNeoDevice(); + } +} + +void icsneo_freeUnconnectedDevices() { + connectableFoundDevices.clear(); +} + +bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) { + // TAG String copy function + if(count == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + auto result = Device::SerialNumToString(num); + + if(str == nullptr) { + *count = result.length() + 1; + return false; + } + + if(*count < result.length()) { + *count = result.length() + 1; // This is how big of a buffer we need + EventManager::GetInstance().add(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error); + return false; + } + + *count = result.copy(str, *count); + str[*count] = '\0'; + return true; +} + +uint32_t icsneo_serialStringToNum(const char* str) { + if(!str) + return 0; + + return Device::SerialStringToNum(str); +} + +bool icsneo_isValidNeoDevice(const neodevice_t* device) { + // return false on nullptr + if(!device) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + // If this neodevice_t was returned by a previous search, it will no longer be valid (as the underlying icsneo::Device is freed) + for(auto& dev : connectedDevices) { + if(dev.get() == device->device) + return true; + } + for(auto& dev : connectableFoundDevices) { + if(dev.get() == device->device) + return true; + } + + EventManager::GetInstance().add(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error); + return false; +} + +bool icsneo_openDevice(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(!device->device->open()) + return false; + + // We connected successfully, move the device to connected devices + std::vector>::iterator> itemsToMove; + for(auto it = connectableFoundDevices.begin(); it < connectableFoundDevices.end(); it++) { + if((*it).get() == device->device) + itemsToMove.push_back(it); + } + for(auto it : itemsToMove) { + connectedDevices.push_back(*it); + connectableFoundDevices.erase(it); + } + + return true; +} + +bool icsneo_closeDevice(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(!device->device->close()) + return false; + + // We disconnected successfully, free the device + std::vector>::iterator> itemsToDelete; + for(auto it = connectedDevices.begin(); it < connectedDevices.end(); it++) { + if((*it).get() == device->device) + itemsToDelete.push_back(it); + } + for(auto it : itemsToDelete) + connectedDevices.erase(it); + + return true; +} + +bool icsneo_isOpen(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->isOpen(); +} + +bool icsneo_goOnline(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->goOnline(); +} + +bool icsneo_goOffline(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->goOffline(); +} + +bool icsneo_isOnline(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->isOnline(); +} + +bool icsneo_enableMessagePolling(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->enableMessagePolling(); +} + +bool icsneo_disableMessagePolling(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->disableMessagePolling(); +} + +bool icsneo_isMessagePollingEnabled(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->isMessagePollingEnabled(); +} + +bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_t* items, uint64_t timeout) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(items == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + if(messages == nullptr) { + // A NULL value for messages means the user wants the current size of the buffer into items + *items = device->device->getCurrentMessageCount(); + return true; + } + + std::vector>& storage = polledMessageStorage[device->device]; + + if(!device->device->getMessages(storage, *items, std::chrono::milliseconds(timeout))) + return false; + + *items = storage.size(); + + for(size_t i = 0; i < *items; i++) { + // For each message, copy into neomessage_t buffer given + messages[i] = CreateNeoMessage(storage[i]); + } + + // The user now has until the next call of icsneo_getMessages (for this device) to use the data, after which point it's freed + // The user should copy the data out if they want it + return true; +} + +int icsneo_getPollingMessageLimit(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return -1; + + return (int)device->device->getPollingMessageLimit(); +} + +bool icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + device->device->setPollingMessageLimit(newLimit); + return true; +} + +int icsneo_addMessageCallback(const neodevice_t* device, void (*callback)(neomessage_t), void*) { + if(!icsneo_isValidNeoDevice(device)) + return -1; + + return device->device->addMessageCallback( + MessageCallback( + [=](std::shared_ptr msg) { + return callback(CreateNeoMessage(msg)); + } + ) + ); +} + +bool icsneo_removeMessageCallback(const neodevice_t* device, int id) { + if(!icsneo_isValidNeoDevice(device)) + return false; + return device->device->removeMessageCallback(id); +} + +neonetid_t icsneo_getNetworkByNumber(const neodevice_t* device, neonettype_t type, unsigned int number) { + if(!icsneo_isValidNeoDevice(device)) + return false; + return neonetid_t(device->device->getNetworkByNumber(icsneo::Network::Type(type), size_t(number)).getNetID()); +} + +bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength) { + // TAG String copy function + if(maxLength == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + if(!icsneo_isValidNeoDevice(device)) + return false; + + std::string output = device->device->getProductName(); + + if(str == nullptr) { + *maxLength = output.length(); + return false; + } + + *maxLength = output.copy(str, *maxLength); + str[*maxLength] = '\0'; + + if(output.length() > *maxLength) + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + + return true; +} + +bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength) { + // TAG String copy function + if(maxLength == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + std::string output = DeviceType(type).getGenericProductName(); + + if(str == nullptr) { + *maxLength = output.length(); + return false; + } + + *maxLength = output.copy(str, *maxLength); + str[*maxLength] = '\0'; + + if(output.length() > *maxLength) + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + + return true; +} + +bool icsneo_settingsRefresh(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->refresh(); +} + +bool icsneo_settingsApply(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->apply(); +} + +bool icsneo_settingsApplyTemporary(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->apply(true); +} + +bool icsneo_settingsApplyDefaults(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->applyDefaults(); +} + +bool icsneo_settingsApplyDefaultsTemporary(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->applyDefaults(true); +} + +int icsneo_settingsReadStructure(const neodevice_t* device, void* structure, size_t structureSize) { + if(!icsneo_isValidNeoDevice(device)) + return -1; + + size_t readSize = device->device->settings->getSize(); + if(structure == nullptr) // Structure size request + return (int)readSize; + if(readSize > structureSize) { + // Client application has a smaller structure than we do + // It is probably built against an older version of the API + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + readSize = structureSize; + } + + const void* deviceStructure = device->device->settings->getRawStructurePointer(); + if(deviceStructure == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); + return -1; + } + + memcpy(structure, deviceStructure, readSize); + + if(readSize < structureSize) // Client application is attempting to read more than we have + memset((uint8_t*)structure + readSize, 0, structureSize - readSize); + + return (int)readSize; +} + +// Not exported +static bool icsneo_settingsWriteStructure(const neodevice_t* device, const void* structure, size_t structureSize) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(structure == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + size_t writeSize = device->device->settings->getSize(); + if(writeSize < structureSize) { + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + structureSize = writeSize; + } + + void* deviceStructure = device->device->settings->getMutableRawStructurePointer(); + if(deviceStructure == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); + return false; + } + + memcpy(deviceStructure, structure, structureSize); + + // If writeSize > structureSize that means that the user has given us a smaller structure + // This is okay, we will keep the end of the structure intact + // TODO Flag an error + return true; +} + +bool icsneo_settingsApplyStructure(const neodevice_t* device, const void* structure, size_t structureSize) { + return icsneo_settingsWriteStructure(device, structure, structureSize) && icsneo_settingsApply(device); +} + +bool icsneo_settingsApplyStructureTemporary(const neodevice_t* device, const void* structure, size_t structureSize) { + return icsneo_settingsWriteStructure(device, structure, structureSize) && icsneo_settingsApplyTemporary(device); +} + +int64_t icsneo_getBaudrate(const neodevice_t* device, neonetid_t netid) { + if(!icsneo_isValidNeoDevice(device)) + return -1; + + return device->device->settings->getBaudrateFor(netid); +} + +bool icsneo_setBaudrate(const neodevice_t* device, neonetid_t netid, int64_t newBaudrate) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->setBaudrateFor(netid, newBaudrate); +} + +int64_t icsneo_getFDBaudrate(const neodevice_t* device, neonetid_t netid) { + if(!icsneo_isValidNeoDevice(device)) + return -1; + + return device->device->settings->getFDBaudrateFor(netid); +} + +bool icsneo_setFDBaudrate(const neodevice_t* device, neonetid_t netid, int64_t newBaudrate) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->setFDBaudrateFor(netid, newBaudrate); +} + +bool icsneo_transmit(const neodevice_t* device, const neomessage_t* message) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(auto frame = std::dynamic_pointer_cast(CreateMessageFromNeoMessage(message))) + return device->device->transmit(frame); + + return false; +} + +bool icsneo_transmitMessages(const neodevice_t* device, const neomessage_t* messages, size_t count) { + // Transmit implements neodevice_t check so it is not needed here + // TODO This can be implemented faster + for(size_t i = 0; i < count; i++) { + if(!icsneo_transmit(device, messages + i)) + return false; + } + return true; +} + +void icsneo_setWriteBlocks(const neodevice_t* device, bool blocks) { + if(!icsneo_isValidNeoDevice(device)) + return; + + device->device->setWriteBlocks(blocks); +} + +bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength) { + // TAG String copy function + if(maxLength == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + if(!icsneo_isValidNeoDevice(device)) + return false; + + std::string output = device->device->describe(); + + *maxLength = output.copy(str, *maxLength); + str[*maxLength] = '\0'; + + if(output.length() > *maxLength) + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + + return true; +} + +neoversion_t icsneo_getVersion(void) { + return icsneo::GetVersion(); +} + +int icsneo_addEventCallback(void (*callback)(neoevent_t), void*) { + return EventManager::GetInstance().addEventCallback( + EventCallback( + [=](std::shared_ptr evt) { + return callback(*(evt->getNeoEvent())); + } + ) + ); +} + +bool icsneo_removeEventCallback(int id) { + return EventManager::GetInstance().removeEventCallback(id); +} + +bool icsneo_getEvents(neoevent_t* events, size_t* size) { + if(size == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + if(events == nullptr) { + *size = icsneo::EventCount(); + return false; + } + + auto cppErrors = icsneo::GetEvents(*size); + for(size_t i = 0; i < cppErrors.size(); i++) + memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t)); + *size = cppErrors.size(); + + return true; +} + +bool icsneo_getDeviceEvents(const neodevice_t* device, neoevent_t* events, size_t* size) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(size == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + // Creating the filter will nullptr is okay! It will find any events not associated with a device. + EventFilter filter = (device != nullptr ? device->device : nullptr); + + if(events == nullptr) { + *size = icsneo::EventCount(filter); + return false; + } + + auto cppErrors = icsneo::GetEvents(*size, filter); + for(size_t i = 0; i < cppErrors.size(); i++) + memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t)); + *size = cppErrors.size(); + + return true; +} + +bool icsneo_getLastError(neoevent_t* error) { + if(error == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + APIEvent cppErr = icsneo::GetLastError(); + if(cppErr.getType() == icsneo::APIEvent::Type::NoErrorFound) + return false; + memcpy(error, cppErr.getNeoEvent(), sizeof(neoevent_t)); + return true; +} + +void icsneo_discardAllEvents(void) { + icsneo::DiscardEvents(); +} + +void icsneo_discardDeviceEvents(const neodevice_t* device) { + if(!icsneo_isValidNeoDevice(device)) + return; + + if(device == nullptr) + icsneo::DiscardEvents(nullptr); // Discard events not associated with a device + else + icsneo::DiscardEvents(device->device); +} + +void icsneo_setEventLimit(size_t newLimit) { + icsneo::SetEventLimit(newLimit); +} + +size_t icsneo_getEventLimit(void) { + return icsneo::GetEventLimit(); +} + +bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) { + if(count == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + auto supported = DeviceFinder::GetSupportedDevices(); + auto len = supported.size(); + + if(devices == nullptr) { + *count = len; + return false; + } + + if(*count < len) { + len = *count; + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); + } + + for(size_t i = 0; i < len; i++) + devices[i] = supported[i]; + *count = len; + + return true; +} + +bool icsneo_getTimestampResolution(const neodevice_t* device, uint16_t* resolution) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(resolution == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + *resolution = device->device->getTimestampResolution(); + return true; +} + +bool icsneo_getDigitalIO(const neodevice_t* device, neoio_t type, uint32_t number, bool* value) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + if(value == nullptr) { + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); + return false; + } + + const optional val = device->device->getDigitalIO(static_cast(type), number); + if(!val.has_value()) + return false; + + *value = *val; + return true; +} + +bool icsneo_setDigitalIO(const neodevice_t* device, neoio_t type, uint32_t number, bool value) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->setDigitalIO(static_cast(type), number, value); +} + +bool icsneo_isTerminationSupportedFor(const neodevice_t* device, neonetid_t netid) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->isTerminationSupportedFor(Network(netid)); +} + +bool icsneo_canTerminationBeEnabledFor(const neodevice_t* device, neonetid_t netid) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->canTerminationBeEnabledFor(Network(netid)); +} + +bool icsneo_isTerminationEnabledFor(const neodevice_t* device, neonetid_t netid) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->isTerminationEnabledFor(Network(netid)).value_or(false); +} + +bool icsneo_setTerminationFor(const neodevice_t* device, neonetid_t netid, bool enabled) { + if(!icsneo_isValidNeoDevice(device)) + return false; + + return device->device->settings->setTerminationFor(Network(netid), enabled); +} diff --git a/api/icsneocpp/icsneocpp.cpp b/api/icsneocpp/icsneocpp.cpp index b9f41b1..e3200aa 100644 --- a/api/icsneocpp/icsneocpp.cpp +++ b/api/icsneocpp/icsneocpp.cpp @@ -1,48 +1,48 @@ -#include "icsneo/icsneocpp.h" -#include "icsneo/device/devicefinder.h" - -using namespace icsneo; - -std::vector> icsneo::FindAllDevices() { - return DeviceFinder::FindAll(); -} - -std::vector icsneo::GetSupportedDevices() { - return DeviceFinder::GetSupportedDevices(); -} - -size_t icsneo::EventCount(EventFilter filter) { - return EventManager::GetInstance().eventCount(filter); -} - -std::vector icsneo::GetEvents(EventFilter filter, size_t max) { - return EventManager::GetInstance().get(filter, max); -} - -std::vector icsneo::GetEvents(size_t max, EventFilter filter) { - return EventManager::GetInstance().get(max, filter); -} - -void icsneo::GetEvents(std::vector& events, EventFilter filter, size_t max) { - EventManager::GetInstance().get(events, filter, max); -} - -void icsneo::GetEvents(std::vector& events, size_t max, EventFilter filter) { - EventManager::GetInstance().get(events, max, filter); -} - -APIEvent icsneo::GetLastError() { - return EventManager::GetInstance().getLastError(); -} - -void icsneo::DiscardEvents(EventFilter filter) { - EventManager::GetInstance().discard(filter); -} - -void icsneo::SetEventLimit(size_t newLimit) { - EventManager::GetInstance().setEventLimit(newLimit); -} - -size_t icsneo::GetEventLimit() { - return EventManager::GetInstance().getEventLimit(); +#include "icsneo/icsneocpp.h" +#include "icsneo/device/devicefinder.h" + +using namespace icsneo; + +std::vector> icsneo::FindAllDevices() { + return DeviceFinder::FindAll(); +} + +std::vector icsneo::GetSupportedDevices() { + return DeviceFinder::GetSupportedDevices(); +} + +size_t icsneo::EventCount(EventFilter filter) { + return EventManager::GetInstance().eventCount(filter); +} + +std::vector icsneo::GetEvents(EventFilter filter, size_t max) { + return EventManager::GetInstance().get(filter, max); +} + +std::vector icsneo::GetEvents(size_t max, EventFilter filter) { + return EventManager::GetInstance().get(max, filter); +} + +void icsneo::GetEvents(std::vector& events, EventFilter filter, size_t max) { + EventManager::GetInstance().get(events, filter, max); +} + +void icsneo::GetEvents(std::vector& events, size_t max, EventFilter filter) { + EventManager::GetInstance().get(events, max, filter); +} + +APIEvent icsneo::GetLastError() { + return EventManager::GetInstance().getLastError(); +} + +void icsneo::DiscardEvents(EventFilter filter) { + EventManager::GetInstance().discard(filter); +} + +void icsneo::SetEventLimit(size_t newLimit) { + EventManager::GetInstance().setEventLimit(newLimit); +} + +size_t icsneo::GetEventLimit() { + return EventManager::GetInstance().getEventLimit(); } \ No newline at end of file diff --git a/device/devicefinder.cpp b/device/devicefinder.cpp index a84a38f..e61297f 100644 --- a/device/devicefinder.cpp +++ b/device/devicefinder.cpp @@ -1,264 +1,264 @@ -#include "icsneo/device/devicefinder.h" -#include "icsneo/platform/devices.h" -#include "icsneo/device/founddevice.h" -#include "generated/extensions/builtin.h" - -#ifdef ICSNEO_ENABLE_RAW_ETHERNET -#include "icsneo/platform/pcap.h" -#endif - -#ifdef ICSNEO_ENABLE_CDCACM -#include "icsneo/platform/cdcacm.h" -#endif - -#ifdef ICSNEO_ENABLE_FTDI -#include "icsneo/platform/ftdi.h" -#endif - -using namespace icsneo; - -template -static void makeIfSerialMatches(const FoundDevice& dev, std::vector>& into) { - // Relies on the subclass to have a `static constexpr const char* SERIAL_START = "XX"` - // and also a public constructor `T(const FoundDevice& dev)` - // Use macro ICSNEO_FINDABLE_DEVICE() to create these - if(dev.serial[0] == T::SERIAL_START[0] && dev.serial[1] == T::SERIAL_START[1]) - into.push_back(std::make_shared(dev)); -} - -template -static void makeIfPIDMatches(const FoundDevice& dev, std::vector>& into) { - // Relies on the subclass to have a `static constexpr uint16_t PRODUCT_ID = 0x1111` - // and also a public constructor `T(const FoundDevice& dev)` - // Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these - if(dev.productId == T::PRODUCT_ID) - into.push_back(std::make_shared(dev)); -} - -std::vector> DeviceFinder::FindAll() { - static std::vector driverFoundDevices; - driverFoundDevices.clear(); - - #ifdef ICSNEO_ENABLE_RAW_ETHERNET - PCAP::Find(driverFoundDevices); - #endif - - #ifdef ICSNEO_ENABLE_CDCACM - CDCACM::Find(driverFoundDevices); - #endif - - #ifdef ICSNEO_ENABLE_FTDI - FTDI::Find(driverFoundDevices); - #endif - - std::vector> foundDevices; - - // Offer found devices to each of the subclasses - for (const FoundDevice& dev : driverFoundDevices) { - #ifdef __ETHERBADGE_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __NEOOBD2PRO_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __NEOOBD2SIM_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __NEOVIFIRE_H_ - makeIfPIDMatches(dev, foundDevices); - #endif - - #ifdef __NEOVIFIRE2_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __NEOVIRED2_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __NEOVIION_H_ - makeIfPIDMatches(dev, foundDevices); - #endif - - #ifdef __NEOVIPLASMA_H_ - makeIfPIDMatches(dev, foundDevices); - #endif - - #ifdef __RADEPSILON_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADGALAXY_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADMARS_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADGIGASTAR_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADMOON2_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADMOONDUO_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADPLUTO_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADSTAR2_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __RADSUPERMOON_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __VALUECAN3_H_ - makeIfPIDMatches(dev, foundDevices); - #endif - - #ifdef __VALUECAN4_1_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __VALUECAN4_2_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __VALUECAN4_2EL_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __VALUECAN4_4_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __VALUECAN4INDUSTRIAL_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - - #ifdef __VIVIDCAN_H_ - makeIfSerialMatches(dev, foundDevices); - #endif - } - - for(auto& device : foundDevices) { - AddBuiltInExtensionsTo(device); - } - - return foundDevices; -} - -const std::vector& DeviceFinder::GetSupportedDevices() { - static std::vector supportedDevices = { - - #ifdef __ETHERBADGE_H_ - EtherBADGE::DEVICE_TYPE, - #endif - - #ifdef __NEOOBD2PRO_H_ - NeoOBD2PRO::DEVICE_TYPE, - #endif - - #ifdef __NEOOBD2SIM_H_ - NeoOBD2SIM::DEVICE_TYPE, - #endif - - #ifdef __NEOVIRED2_H_ - NeoVIRED2::DEVICE_TYPE, - #endif - - #ifdef __NEOVIFIRE_H_ - NeoVIFIRE::DEVICE_TYPE, - #endif - - #ifdef __NEOVIFIRE2_H_ - NeoVIFIRE2::DEVICE_TYPE, - #endif - - #ifdef __NEOVIION_H_ - NeoVIION::DEVICE_TYPE, - #endif - - #ifdef __NEOVIPLASMA_H_ - NeoVIPLASMA::DEVICE_TYPE, - #endif - - #ifdef __RADEPSILON_H_ - RADEpsilon::DEVICE_TYPE, - #endif - - #ifdef __RADGALAXY_H_ - RADGalaxy::DEVICE_TYPE, - #endif - - #ifdef __RADMARS_H_ - RADMars::DEVICE_TYPE, - #endif - - #ifdef __RADGIGASTAR_H_ - RADGigastar::DEVICE_TYPE, - #endif - - #ifdef __RADMOON2_H_ - RADMoon2::DEVICE_TYPE, - #endif - - #ifdef __RADMOONDUO_H_ - RADMoonDuo::DEVICE_TYPE, - #endif - - #ifdef __RADPLUTO_H_ - RADPluto::DEVICE_TYPE, - #endif - - #ifdef __RADSTAR2_H_ - RADStar2::DEVICE_TYPE, - #endif - - #ifdef __RADSUPERMOON_H_ - RADSupermoon::DEVICE_TYPE, - #endif - - #ifdef __VALUECAN3_H_ - ValueCAN3::DEVICE_TYPE, - #endif - - #ifdef __VALUECAN4_1_H_ - ValueCAN4_1::DEVICE_TYPE, - #endif - - #ifdef __VALUECAN4_2_H_ - ValueCAN4_2::DEVICE_TYPE, - #endif - - #ifdef __VALUECAN4_2EL_H_ - ValueCAN4_2EL::DEVICE_TYPE, - #endif - - #ifdef __VALUECAN4_4_H_ - ValueCAN4_4::DEVICE_TYPE, - #endif - - #ifdef __VALUECAN4INDUSTRIAL_H_ - ValueCAN4Industrial::DEVICE_TYPE, - #endif - - #ifdef __VIVIDCAN_H_ - VividCAN::DEVICE_TYPE, - #endif - - }; - - return supportedDevices; -} +#include "icsneo/device/devicefinder.h" +#include "icsneo/platform/devices.h" +#include "icsneo/device/founddevice.h" +#include "generated/extensions/builtin.h" + +#ifdef ICSNEO_ENABLE_RAW_ETHERNET +#include "icsneo/platform/pcap.h" +#endif + +#ifdef ICSNEO_ENABLE_CDCACM +#include "icsneo/platform/cdcacm.h" +#endif + +#ifdef ICSNEO_ENABLE_FTDI +#include "icsneo/platform/ftdi.h" +#endif + +using namespace icsneo; + +template +static void makeIfSerialMatches(const FoundDevice& dev, std::vector>& into) { + // Relies on the subclass to have a `static constexpr const char* SERIAL_START = "XX"` + // and also a public constructor `T(const FoundDevice& dev)` + // Use macro ICSNEO_FINDABLE_DEVICE() to create these + if(dev.serial[0] == T::SERIAL_START[0] && dev.serial[1] == T::SERIAL_START[1]) + into.push_back(std::make_shared(dev)); +} + +template +static void makeIfPIDMatches(const FoundDevice& dev, std::vector>& into) { + // Relies on the subclass to have a `static constexpr uint16_t PRODUCT_ID = 0x1111` + // and also a public constructor `T(const FoundDevice& dev)` + // Use macro ICSNEO_FINDABLE_DEVICE_BY_PID() to create these + if(dev.productId == T::PRODUCT_ID) + into.push_back(std::make_shared(dev)); +} + +std::vector> DeviceFinder::FindAll() { + static std::vector driverFoundDevices; + driverFoundDevices.clear(); + + #ifdef ICSNEO_ENABLE_RAW_ETHERNET + PCAP::Find(driverFoundDevices); + #endif + + #ifdef ICSNEO_ENABLE_CDCACM + CDCACM::Find(driverFoundDevices); + #endif + + #ifdef ICSNEO_ENABLE_FTDI + FTDI::Find(driverFoundDevices); + #endif + + std::vector> foundDevices; + + // Offer found devices to each of the subclasses + for (const FoundDevice& dev : driverFoundDevices) { + #ifdef __ETHERBADGE_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __NEOOBD2PRO_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __NEOOBD2SIM_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __NEOVIFIRE_H_ + makeIfPIDMatches(dev, foundDevices); + #endif + + #ifdef __NEOVIFIRE2_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __NEOVIRED2_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __NEOVIION_H_ + makeIfPIDMatches(dev, foundDevices); + #endif + + #ifdef __NEOVIPLASMA_H_ + makeIfPIDMatches(dev, foundDevices); + #endif + + #ifdef __RADEPSILON_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADGALAXY_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADMARS_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADGIGASTAR_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADMOON2_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADMOONDUO_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADPLUTO_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADSTAR2_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __RADSUPERMOON_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __VALUECAN3_H_ + makeIfPIDMatches(dev, foundDevices); + #endif + + #ifdef __VALUECAN4_1_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __VALUECAN4_2_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __VALUECAN4_2EL_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __VALUECAN4_4_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __VALUECAN4INDUSTRIAL_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + + #ifdef __VIVIDCAN_H_ + makeIfSerialMatches(dev, foundDevices); + #endif + } + + for(auto& device : foundDevices) { + AddBuiltInExtensionsTo(device); + } + + return foundDevices; +} + +const std::vector& DeviceFinder::GetSupportedDevices() { + static std::vector supportedDevices = { + + #ifdef __ETHERBADGE_H_ + EtherBADGE::DEVICE_TYPE, + #endif + + #ifdef __NEOOBD2PRO_H_ + NeoOBD2PRO::DEVICE_TYPE, + #endif + + #ifdef __NEOOBD2SIM_H_ + NeoOBD2SIM::DEVICE_TYPE, + #endif + + #ifdef __NEOVIRED2_H_ + NeoVIRED2::DEVICE_TYPE, + #endif + + #ifdef __NEOVIFIRE_H_ + NeoVIFIRE::DEVICE_TYPE, + #endif + + #ifdef __NEOVIFIRE2_H_ + NeoVIFIRE2::DEVICE_TYPE, + #endif + + #ifdef __NEOVIION_H_ + NeoVIION::DEVICE_TYPE, + #endif + + #ifdef __NEOVIPLASMA_H_ + NeoVIPLASMA::DEVICE_TYPE, + #endif + + #ifdef __RADEPSILON_H_ + RADEpsilon::DEVICE_TYPE, + #endif + + #ifdef __RADGALAXY_H_ + RADGalaxy::DEVICE_TYPE, + #endif + + #ifdef __RADMARS_H_ + RADMars::DEVICE_TYPE, + #endif + + #ifdef __RADGIGASTAR_H_ + RADGigastar::DEVICE_TYPE, + #endif + + #ifdef __RADMOON2_H_ + RADMoon2::DEVICE_TYPE, + #endif + + #ifdef __RADMOONDUO_H_ + RADMoonDuo::DEVICE_TYPE, + #endif + + #ifdef __RADPLUTO_H_ + RADPluto::DEVICE_TYPE, + #endif + + #ifdef __RADSTAR2_H_ + RADStar2::DEVICE_TYPE, + #endif + + #ifdef __RADSUPERMOON_H_ + RADSupermoon::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN3_H_ + ValueCAN3::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN4_1_H_ + ValueCAN4_1::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN4_2_H_ + ValueCAN4_2::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN4_2EL_H_ + ValueCAN4_2EL::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN4_4_H_ + ValueCAN4_4::DEVICE_TYPE, + #endif + + #ifdef __VALUECAN4INDUSTRIAL_H_ + ValueCAN4Industrial::DEVICE_TYPE, + #endif + + #ifdef __VIVIDCAN_H_ + VividCAN::DEVICE_TYPE, + #endif + + }; + + return supportedDevices; +} diff --git a/include/icsneo/communication/driver.h b/include/icsneo/communication/driver.h index 21e6798..fa8bb15 100644 --- a/include/icsneo/communication/driver.h +++ b/include/icsneo/communication/driver.h @@ -1,61 +1,61 @@ -#ifndef __DRIVER_H_ -#define __DRIVER_H_ - -#ifdef __cplusplus - -#include -#include -#include -#include -#include -#include -#include "icsneo/api/eventmanager.h" -#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h" - -namespace icsneo { - -class Driver { -public: - Driver(const device_eventhandler_t& handler) : report(handler) {} - virtual ~Driver() {} - virtual bool open() = 0; - virtual bool isOpen() = 0; - virtual void modeChangeIncoming() {} - virtual void awaitModeChangeComplete() {} - virtual bool isDisconnected() { return disconnected; }; - virtual bool close() = 0; - virtual bool read(std::vector& bytes, size_t limit = 0); - virtual bool readWait(std::vector& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 0); - virtual bool write(const std::vector& bytes); - virtual bool isEthernet() const { return false; } - - device_eventhandler_t report; - - size_t writeQueueSize = 50; - bool writeBlocks = true; // Otherwise it just fails when the queue is full - -protected: - class WriteOperation { - public: - WriteOperation() {} - WriteOperation(const std::vector& b) : bytes(b) {} - std::vector bytes; - }; - enum IOTaskState { - LAUNCH, - WAIT - }; - virtual void readTask() = 0; - virtual void writeTask() = 0; - moodycamel::BlockingConcurrentQueue readQueue; - moodycamel::BlockingConcurrentQueue writeQueue; - std::thread readThread, writeThread; - std::atomic closing{false}; - std::atomic disconnected{false}; -}; - -} - -#endif // __cplusplus - +#ifndef __DRIVER_H_ +#define __DRIVER_H_ + +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include +#include "icsneo/api/eventmanager.h" +#include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h" + +namespace icsneo { + +class Driver { +public: + Driver(const device_eventhandler_t& handler) : report(handler) {} + virtual ~Driver() {} + virtual bool open() = 0; + virtual bool isOpen() = 0; + virtual void modeChangeIncoming() {} + virtual void awaitModeChangeComplete() {} + virtual bool isDisconnected() { return disconnected; }; + virtual bool close() = 0; + virtual bool read(std::vector& bytes, size_t limit = 0); + virtual bool readWait(std::vector& bytes, std::chrono::milliseconds timeout = std::chrono::milliseconds(100), size_t limit = 0); + virtual bool write(const std::vector& bytes); + virtual bool isEthernet() const { return false; } + + device_eventhandler_t report; + + size_t writeQueueSize = 50; + bool writeBlocks = true; // Otherwise it just fails when the queue is full + +protected: + class WriteOperation { + public: + WriteOperation() {} + WriteOperation(const std::vector& b) : bytes(b) {} + std::vector bytes; + }; + enum IOTaskState { + LAUNCH, + WAIT + }; + virtual void readTask() = 0; + virtual void writeTask() = 0; + moodycamel::BlockingConcurrentQueue readQueue; + moodycamel::BlockingConcurrentQueue writeQueue; + std::thread readThread, writeThread; + std::atomic closing{false}; + std::atomic disconnected{false}; +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/communication/message/callback/messagecallback.h b/include/icsneo/communication/message/callback/messagecallback.h index 60616f3..e49f3e0 100644 --- a/include/icsneo/communication/message/callback/messagecallback.h +++ b/include/icsneo/communication/message/callback/messagecallback.h @@ -1,50 +1,50 @@ -#ifndef __MESSAGECALLBACK_H_ -#define __MESSAGECALLBACK_H_ - -#ifdef __cplusplus - -#include "icsneo/communication/message/message.h" -#include "icsneo/communication/message/filter/messagefilter.h" -#include -#include - -namespace icsneo { - -class MessageCallback { -public: - typedef std::function< void( std::shared_ptr ) > fn_messageCallback; - - MessageCallback(fn_messageCallback cb, std::shared_ptr f) - : callback(cb), filter(f ? f : std::make_shared()) { - if(!cb) - throw std::bad_function_call(); - } - - MessageCallback(fn_messageCallback cb, MessageFilter f = MessageFilter()) - : MessageCallback(cb, std::make_shared(f)) {} - - // Allow the filter to be placed first if the user wants (maybe in the case of a lambda) - MessageCallback(std::shared_ptr f, fn_messageCallback cb) - : MessageCallback(cb, f) {} - MessageCallback(MessageFilter f, fn_messageCallback cb) - : MessageCallback(cb, std::make_shared(f)) {} - - virtual bool callIfMatch(const std::shared_ptr& message) const { - bool ret = filter->match(message); - if(ret) - callback(message); - return ret; - } - const MessageFilter& getFilter() const { return *filter; } - const fn_messageCallback& getCallback() const { return callback; } - -protected: - const fn_messageCallback callback; - const std::shared_ptr filter; -}; - -} - -#endif // __cplusplus - +#ifndef __MESSAGECALLBACK_H_ +#define __MESSAGECALLBACK_H_ + +#ifdef __cplusplus + +#include "icsneo/communication/message/message.h" +#include "icsneo/communication/message/filter/messagefilter.h" +#include +#include + +namespace icsneo { + +class MessageCallback { +public: + typedef std::function< void( std::shared_ptr ) > fn_messageCallback; + + MessageCallback(fn_messageCallback cb, std::shared_ptr f) + : callback(cb), filter(f ? f : std::make_shared()) { + if(!cb) + throw std::bad_function_call(); + } + + MessageCallback(fn_messageCallback cb, MessageFilter f = MessageFilter()) + : MessageCallback(cb, std::make_shared(f)) {} + + // Allow the filter to be placed first if the user wants (maybe in the case of a lambda) + MessageCallback(std::shared_ptr f, fn_messageCallback cb) + : MessageCallback(cb, f) {} + MessageCallback(MessageFilter f, fn_messageCallback cb) + : MessageCallback(cb, std::make_shared(f)) {} + + virtual bool callIfMatch(const std::shared_ptr& message) const { + bool ret = filter->match(message); + if(ret) + callback(message); + return ret; + } + const MessageFilter& getFilter() const { return *filter; } + const fn_messageCallback& getCallback() const { return callback; } + +protected: + const fn_messageCallback callback; + const std::shared_ptr filter; +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/communication/message/canmessage.h b/include/icsneo/communication/message/canmessage.h index c8703b0..76338fe 100644 --- a/include/icsneo/communication/message/canmessage.h +++ b/include/icsneo/communication/message/canmessage.h @@ -1,25 +1,25 @@ -#ifndef __CANMESSAGE_H_ -#define __CANMESSAGE_H_ - -#ifdef __cplusplus - -#include "icsneo/communication/message/message.h" - -namespace icsneo { - -class CANMessage : public Frame { -public: - uint32_t arbid; - uint8_t dlcOnWire; - bool isRemote = false; // Not allowed if CAN FD - bool isExtended = false; - bool isCANFD = false; - bool baudrateSwitch = false; // CAN FD only - bool errorStateIndicator = false; // CAN FD only -}; - -} - -#endif // __cplusplus - +#ifndef __CANMESSAGE_H_ +#define __CANMESSAGE_H_ + +#ifdef __cplusplus + +#include "icsneo/communication/message/message.h" + +namespace icsneo { + +class CANMessage : public Frame { +public: + uint32_t arbid; + uint8_t dlcOnWire; + bool isRemote = false; // Not allowed if CAN FD + bool isExtended = false; + bool isCANFD = false; + bool baudrateSwitch = false; // CAN FD only + bool errorStateIndicator = false; // CAN FD only +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/communication/message/filter/messagefilter.h b/include/icsneo/communication/message/filter/messagefilter.h index 51f3957..fd76ac3 100644 --- a/include/icsneo/communication/message/filter/messagefilter.h +++ b/include/icsneo/communication/message/filter/messagefilter.h @@ -1,68 +1,68 @@ -#ifndef __MESSAGEFILTER_H_ -#define __MESSAGEFILTER_H_ - -#ifdef __cplusplus - -#include "icsneo/communication/network.h" -#include "icsneo/communication/message/message.h" -#include - -namespace icsneo { - -class MessageFilter { -public: - MessageFilter() {} - MessageFilter(Message::Type type) : includeInternalInAny(neomessagetype_t(type) & 0x8000), messageType(type) {} - MessageFilter(Network::NetID netid) : MessageFilter(Network::GetTypeOfNetID(netid), netid) {} - 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 - // The NetID we want may be in there - includeInternalInAny = (networkType == Network::Type::Internal); - } - virtual ~MessageFilter() = default; - // When getting "all" types of messages, include the ones marked as "internal only" - bool includeInternalInAny = false; - - virtual bool match(const std::shared_ptr& message) const { - if(!matchMessageType(message->type)) - return false; - - if(message->type == Message::Type::Frame || message->type == Message::Type::Main51 || - message->type == Message::Type::RawMessage || message->type == Message::Type::ReadSettings) { - RawMessage& frame = *static_cast(message.get()); - if(!matchNetworkType(frame.network.getType())) - return false; - if(!matchNetID(frame.network.getNetID())) - return false; - } - return true; - } - -protected: - Message::Type messageType = Message::Type::Invalid; // Used here for "any" - bool matchMessageType(Message::Type mtype) const { - if(messageType == Message::Type::Invalid && ((neomessagetype_t(mtype) & 0x8000) == 0 || includeInternalInAny)) - return true; - return messageType == mtype; - } - - Network::Type networkType = Network::Type::Any; - bool matchNetworkType(Network::Type mtype) const { - if(networkType == Network::Type::Any && (mtype != Network::Type::Internal || includeInternalInAny)) - return true; - return networkType == mtype; - } - - Network::NetID netid = Network::NetID::Any; - bool matchNetID(Network::NetID mnetid) const { - if(netid == Network::NetID::Any) - return true; - return netid == mnetid; - } -}; - -} - -#endif // __cplusplus - +#ifndef __MESSAGEFILTER_H_ +#define __MESSAGEFILTER_H_ + +#ifdef __cplusplus + +#include "icsneo/communication/network.h" +#include "icsneo/communication/message/message.h" +#include + +namespace icsneo { + +class MessageFilter { +public: + MessageFilter() {} + MessageFilter(Message::Type type) : includeInternalInAny(neomessagetype_t(type) & 0x8000), messageType(type) {} + MessageFilter(Network::NetID netid) : MessageFilter(Network::GetTypeOfNetID(netid), netid) {} + 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 + // The NetID we want may be in there + includeInternalInAny = (networkType == Network::Type::Internal); + } + virtual ~MessageFilter() = default; + // When getting "all" types of messages, include the ones marked as "internal only" + bool includeInternalInAny = false; + + virtual bool match(const std::shared_ptr& message) const { + if(!matchMessageType(message->type)) + return false; + + if(message->type == Message::Type::Frame || message->type == Message::Type::Main51 || + message->type == Message::Type::RawMessage || message->type == Message::Type::ReadSettings) { + RawMessage& frame = *static_cast(message.get()); + if(!matchNetworkType(frame.network.getType())) + return false; + if(!matchNetID(frame.network.getNetID())) + return false; + } + return true; + } + +protected: + Message::Type messageType = Message::Type::Invalid; // Used here for "any" + bool matchMessageType(Message::Type mtype) const { + if(messageType == Message::Type::Invalid && ((neomessagetype_t(mtype) & 0x8000) == 0 || includeInternalInAny)) + return true; + return messageType == mtype; + } + + Network::Type networkType = Network::Type::Any; + bool matchNetworkType(Network::Type mtype) const { + if(networkType == Network::Type::Any && (mtype != Network::Type::Internal || includeInternalInAny)) + return true; + return networkType == mtype; + } + + Network::NetID netid = Network::NetID::Any; + bool matchNetID(Network::NetID mnetid) const { + if(netid == Network::NetID::Any) + return true; + return netid == mnetid; + } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/communication/message/iso9141message.h b/include/icsneo/communication/message/iso9141message.h index 0e35554..70b85ba 100644 --- a/include/icsneo/communication/message/iso9141message.h +++ b/include/icsneo/communication/message/iso9141message.h @@ -1,30 +1,30 @@ -#ifndef __ISO9141MESSAGE_H_ -#define __ISO9141MESSAGE_H_ - -#ifdef __cplusplus - -#include "icsneo/communication/message/message.h" -#include - -namespace icsneo { - -class ISO9141Message : public Frame { -public: - std::array header; - bool isInit = false; - bool isBreak = false; - bool framingError = false; - bool overflowError = false; - bool parityError = false; - bool rxTimeoutError = false; - // Checksum not yet implemted, it's just at the end of the data if enabled for now - // bool checksumError = false; - // bool hasChecksum = false; - // uint8_t checksum = 0; -}; - -} - -#endif // __cplusplus - +#ifndef __ISO9141MESSAGE_H_ +#define __ISO9141MESSAGE_H_ + +#ifdef __cplusplus + +#include "icsneo/communication/message/message.h" +#include + +namespace icsneo { + +class ISO9141Message : public Frame { +public: + std::array header; + bool isInit = false; + bool isBreak = false; + bool framingError = false; + bool overflowError = false; + bool parityError = false; + bool rxTimeoutError = false; + // Checksum not yet implemted, it's just at the end of the data if enabled for now + // bool checksumError = false; + // bool hasChecksum = false; + // uint8_t checksum = 0; +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/communication/message/message.h b/include/icsneo/communication/message/message.h index eb04658..e26a4dd 100644 --- a/include/icsneo/communication/message/message.h +++ b/include/icsneo/communication/message/message.h @@ -1,77 +1,77 @@ -#ifndef __MESSAGE_H_ -#define __MESSAGE_H_ - -#include -typedef uint16_t neomessagetype_t; - -#ifdef __cplusplus - -#include "icsneo/communication/network.h" -#include - -namespace icsneo { - -class Message { -public: - enum class Type : neomessagetype_t { - Frame = 0, - - CANErrorCount = 0x100, - - // Past 0x8000 are all for internal use only - Invalid = 0x8000, - RawMessage = 0x8001, - ReadSettings = 0x8002, - ResetStatus = 0x8003, - DeviceVersion = 0x8004, - Main51 = 0x8005, - FlexRayControl = 0x8006, - EthernetPhyRegister = 0x8007, - LogicalDiskInfo = 0x8008, - }; - - Message(Type t) : type(t) {} - virtual ~Message() = default; - const Type type; - uint64_t timestamp = 0; -}; - -class RawMessage : public Message { -public: - RawMessage(Message::Type type = Message::Type::RawMessage) : Message(type) {} - RawMessage(Message::Type type, Network net) : Message(type), network(net) {} - RawMessage(Network net) : Message(Message::Type::RawMessage), network(net) {} - RawMessage(Network net, std::vector d) : Message(Message::Type::RawMessage), network(net), data(d) {} - - Network network; - std::vector data; -}; - -class Frame : public RawMessage { -public: - Frame() : RawMessage(Message::Type::Frame) {} - - uint16_t description = 0; - bool transmitted = false; - bool error = false; -}; - -} - -#endif // __cplusplus - -#ifdef __ICSNEOC_H_ - -#define ICSNEO_MESSAGE_TYPE_FRAME (0x0) -#define ICSNEO_MESSAGE_TYPE_CAN_ERROR_COUNT (0x100) -#define ICSNEO_MESSAGE_TYPE_INVALID (0x8000) -#define ICSNEO_MESSAGE_TYPE_RAW_MESSAGE (0x8001) -#define ICSNEO_MESSAGE_TYPE_READ_SETTINGS (0x8002) -#define ICSNEO_MESSAGE_TYPE_RESET_STATUS (0x8003) -#define ICSNEO_MESSAGE_TYPE_DEVICE_VERSION (0x8004) -#define ICSNEO_MESSAGE_TYPE_MAIN51 (0x8005) -#define ICSNEO_MESSAGE_TYPE_FLEXRAY_CONTROL (0x8006) - -#endif // __ICSNEOC_H_ - +#ifndef __MESSAGE_H_ +#define __MESSAGE_H_ + +#include +typedef uint16_t neomessagetype_t; + +#ifdef __cplusplus + +#include "icsneo/communication/network.h" +#include + +namespace icsneo { + +class Message { +public: + enum class Type : neomessagetype_t { + Frame = 0, + + CANErrorCount = 0x100, + + // Past 0x8000 are all for internal use only + Invalid = 0x8000, + RawMessage = 0x8001, + ReadSettings = 0x8002, + ResetStatus = 0x8003, + DeviceVersion = 0x8004, + Main51 = 0x8005, + FlexRayControl = 0x8006, + EthernetPhyRegister = 0x8007, + LogicalDiskInfo = 0x8008, + }; + + Message(Type t) : type(t) {} + virtual ~Message() = default; + const Type type; + uint64_t timestamp = 0; +}; + +class RawMessage : public Message { +public: + RawMessage(Message::Type type = Message::Type::RawMessage) : Message(type) {} + RawMessage(Message::Type type, Network net) : Message(type), network(net) {} + RawMessage(Network net) : Message(Message::Type::RawMessage), network(net) {} + RawMessage(Network net, std::vector d) : Message(Message::Type::RawMessage), network(net), data(d) {} + + Network network; + std::vector data; +}; + +class Frame : public RawMessage { +public: + Frame() : RawMessage(Message::Type::Frame) {} + + uint16_t description = 0; + bool transmitted = false; + bool error = false; +}; + +} + +#endif // __cplusplus + +#ifdef __ICSNEOC_H_ + +#define ICSNEO_MESSAGE_TYPE_FRAME (0x0) +#define ICSNEO_MESSAGE_TYPE_CAN_ERROR_COUNT (0x100) +#define ICSNEO_MESSAGE_TYPE_INVALID (0x8000) +#define ICSNEO_MESSAGE_TYPE_RAW_MESSAGE (0x8001) +#define ICSNEO_MESSAGE_TYPE_READ_SETTINGS (0x8002) +#define ICSNEO_MESSAGE_TYPE_RESET_STATUS (0x8003) +#define ICSNEO_MESSAGE_TYPE_DEVICE_VERSION (0x8004) +#define ICSNEO_MESSAGE_TYPE_MAIN51 (0x8005) +#define ICSNEO_MESSAGE_TYPE_FLEXRAY_CONTROL (0x8006) + +#endif // __ICSNEOC_H_ + #endif \ No newline at end of file diff --git a/include/icsneo/communication/network.h b/include/icsneo/communication/network.h index 4b9868a..6c96b6a 100644 --- a/include/icsneo/communication/network.h +++ b/include/icsneo/communication/network.h @@ -1,944 +1,944 @@ -#ifndef __NETWORKID_H_ -#define __NETWORKID_H_ - -#include -typedef uint16_t neonetid_t; -typedef uint8_t neonettype_t; - -#ifdef __cplusplus - -#include -#include "icsneo/platform/optional.h" - -namespace icsneo { - -class Network { -public: - enum class NetID : neonetid_t { - Device = 0, - HSCAN = 1, - MSCAN = 2, - SWCAN = 3, - LSFTCAN = 4, - FordSCP = 5, - J1708 = 6, - Aux = 7, - J1850VPW = 8, - ISO9141 = 9, - ISOPIC = 10, - Main51 = 11, - RED = 12, - SCI = 13, - ISO9141_2 = 14, - ISO14230 = 15, - LIN = 16, - OP_Ethernet1 = 17, - OP_Ethernet2 = 18, - OP_Ethernet3 = 19, - - // START Device Command Returns - // When we send a command, the device returns on one of these, depending on command - RED_EXT_MEMORYREAD = 20, - RED_INT_MEMORYREAD = 21, - RED_DFLASH_READ = 22, - NeoMemorySDRead = 23, // Response from NeoMemory (MemoryTypeSD) - CAN_ERRBITS = 24, - NeoMemoryWriteDone = 25, - RED_WAVE_CAN1_LOGICAL = 26, - RED_WAVE_CAN2_LOGICAL = 27, - RED_WAVE_LIN1_LOGICAL = 28, - RED_WAVE_LIN2_LOGICAL = 29, - RED_WAVE_LIN1_ANALOG = 30, - RED_WAVE_LIN2_ANALOG = 31, - RED_WAVE_MISC_ANALOG = 32, - RED_WAVE_MISCDIO2_LOGICAL = 33, - RED_NETWORK_COM_ENABLE_EX = 34, - RED_NEOVI_NETWORK = 35, - RED_READ_BAUD_SETTINGS = 36, - RED_OLDFORMAT = 37, - RED_SCOPE_CAPTURE = 38, - RED_HARDWARE_EXCEP = 39, - RED_GET_RTC = 40, - // END Device Command Returns - - ISO9141_3 = 41, - HSCAN2 = 42, - HSCAN3 = 44, - OP_Ethernet4 = 45, - OP_Ethernet5 = 46, - ISO9141_4 = 47, - LIN2 = 48, - LIN3 = 49, - LIN4 = 50, - // MOST = 51, Old and unused - RED_App_Error = 52, - CGI = 53, - Reset_Status = 54, - FB_Status = 55, - App_Signal_Status = 56, - Read_Datalink_Cm_Tx_Msg = 57, - Read_Datalink_Cm_Rx_Msg = 58, - Logging_Overflow = 59, - ReadSettings = 60, - HSCAN4 = 61, - HSCAN5 = 62, - RS232 = 63, - UART = 64, - UART2 = 65, - UART3 = 66, - UART4 = 67, - SWCAN2 = 68, - Ethernet_DAQ = 69, - Data_To_Host = 70, - TextAPI_To_Host = 71, - OP_Ethernet6 = 73, - Red_VBat = 74, - OP_Ethernet7 = 75, - OP_Ethernet8 = 76, - OP_Ethernet9 = 77, - OP_Ethernet10 = 78, - OP_Ethernet11 = 79, - FlexRay1a = 80, - FlexRay1b = 81, - FlexRay2a = 82, - FlexRay2b = 83, - LIN5 = 84, - FlexRay = 85, - FlexRay2 = 86, - OP_Ethernet12 = 87, - I2C = 88, - MOST25 = 90, - MOST50 = 91, - MOST150 = 92, - Ethernet = 93, - GMFSA = 94, - TCP = 95, - HSCAN6 = 96, - HSCAN7 = 97, - LIN6 = 98, - LSFTCAN2 = 99, - LogicalDiskInfo = 187, - EthPHYControl = 239, - FlexRayControl = 243, - HW_COM_Latency_Test = 512, - DeviceStatus = 513, - UDP = 514, - ForwardedMessage = 516, - I2C2 = 517, - I2C3 = 518, - I2C4 = 519, - Ethernet2 = 520, - Any = 0xfffe, // Never actually set as type, but used as flag for filtering - Invalid = 0xffff - }; - enum class Type : neonettype_t { - Invalid = 0, - Internal = 1, // Used for statuses that don't actually need to be transferred to the client application - CAN = 2, - LIN = 3, - FlexRay = 4, - MOST = 5, - Ethernet = 6, - LSFTCAN = 7, - SWCAN = 8, - ISO9141 = 9, - I2C = 10, - Any = 0xFE, // Never actually set as type, but used as flag for filtering - Other = 0xFF - }; - enum class CoreMini : uint8_t { - HSCAN = 0, - MSCAN = 1, - LIN = 2, - LIN2 = 3, - Virtual = 4, - HSCAN2 = 5, - LSFTCAN = 6, - SWCAN = 7, - HSCAN3 = 8, - CGI = 9, - J1850VPW = 10, - LIN3 = 11, - LIN4 = 12, - J1708 = 13, - HSCAN4 = 14, - HSCAN5 = 15, - KLine1 = 16, - KLine2 = 17, - KLine3 = 18, - KLine4 = 19, - FlexRay1a = 20, - UART = 21, - UART2 = 22, - LIN5 = 23, - MOST25 = 24, - MOST50 = 25, - FlexRay1b = 26, - SWCAN2 = 27, - EthernetDAQ = 28, - Ethernet = 29, - FlexRay2a = 30, - FlexRay2b = 31, - HSCAN6 = 32, - HSCAN7 = 33, - LIN6 = 34, - LSFTCAN2 = 35, - OP_Ethernet1 = 36, - OP_Ethernet2 = 37, - OP_Ethernet3 = 38, - OP_Ethernet4 = 39, - OP_Ethernet5 = 40, - OP_Ethernet6 = 41, - OP_Ethernet7 = 42, - OP_Ethernet8 = 43, - OP_Ethernet9 = 44, - OP_Ethernet10 = 45, - OP_Ethernet11 = 46, - OP_Ethernet12 = 47, - TCPVirtual = 48, - UDPVirtual = 49, - FlexRay1 = 50, - FlexRay2 = 51, - ForwardedMessage = 52, - I2C1 = 53, - I2C2 = 54, - I2C3 = 55, - I2C4 = 56, - Ethernet2 = 57, - }; - static const char* GetTypeString(Type type) { - switch(type) { - case Type::CAN: - return "CAN"; - case Type::LIN: - return "LIN"; - case Type::FlexRay: - return "FlexRay"; - case Type::MOST: - return "MOST"; - case Type::Other: - return "Other"; - case Type::Internal: - return "Internal"; - case Type::ISO9141: - return "ISO 9141-2"; - case Type::Ethernet: - return "Ethernet"; - case Type::LSFTCAN: - return "Low Speed Fault Tolerant CAN"; - case Type::SWCAN: - return "Single Wire CAN"; - case Type::I2C: - return "I²C"; - case Type::Invalid: - default: - return "Invalid Type"; - } - } - static Type GetTypeOfNetID(NetID netid) { - switch(netid) { - case NetID::HSCAN: - case NetID::MSCAN: - case NetID::HSCAN2: - case NetID::HSCAN3: - case NetID::HSCAN4: - case NetID::HSCAN5: - case NetID::HSCAN6: - case NetID::HSCAN7: - return Type::CAN; - case NetID::LIN: - case NetID::LIN2: - case NetID::LIN3: - case NetID::LIN4: - case NetID::LIN5: - case NetID::LIN6: - return Type::LIN; - case NetID::FlexRay: - case NetID::FlexRay1a: - case NetID::FlexRay1b: - case NetID::FlexRay2: - case NetID::FlexRay2a: - case NetID::FlexRay2b: - return Type::FlexRay; - case NetID::MOST25: - case NetID::MOST50: - case NetID::MOST150: - return Type::MOST; - case NetID::RED: - case NetID::RED_OLDFORMAT: - case NetID::Device: - case NetID::Reset_Status: - case NetID::DeviceStatus: - case NetID::FlexRayControl: - case NetID::Main51: - case NetID::ReadSettings: - case NetID::LogicalDiskInfo: - case NetID::EthPHYControl: - case NetID::NeoMemorySDRead: - case NetID::NeoMemoryWriteDone: - return Type::Internal; - case NetID::Invalid: - case NetID::Any: - return Type::Invalid; - case NetID::Ethernet: - case NetID::Ethernet_DAQ: - case NetID::Ethernet2: - case NetID::OP_Ethernet1: - case NetID::OP_Ethernet2: - case NetID::OP_Ethernet3: - case NetID::OP_Ethernet4: - case NetID::OP_Ethernet5: - case NetID::OP_Ethernet6: - case NetID::OP_Ethernet7: - case NetID::OP_Ethernet8: - case NetID::OP_Ethernet9: - case NetID::OP_Ethernet10: - case NetID::OP_Ethernet11: - case NetID::OP_Ethernet12: - return Type::Ethernet; - case NetID::LSFTCAN: - case NetID::LSFTCAN2: - return Type::LSFTCAN; - case NetID::SWCAN: - case NetID::SWCAN2: - return Type::SWCAN; - case NetID::ISO9141: - case NetID::ISO9141_2: - case NetID::ISO9141_3: - case NetID::ISO9141_4: - return Type::ISO9141; - case NetID::I2C: - case NetID::I2C2: - case NetID::I2C3: - case NetID::I2C4: - return Type::I2C; - default: - return Type::Other; - } - } - static const char* GetNetIDString(NetID netid) { - switch(netid) { - case NetID::Device: - return "neoVI"; - case NetID::HSCAN: - return "HSCAN"; - case NetID::MSCAN: - return "MSCAN"; - case NetID::SWCAN: - return "SWCAN"; - case NetID::LSFTCAN: - return "LSFTCAN"; - case NetID::FordSCP: - return "FordSCP"; - case NetID::J1708: - return "J1708"; - case NetID::Aux: - return "Aux"; - case NetID::J1850VPW: - return "J1850 VPW"; - case NetID::ISO9141: - return "ISO 9141"; - case NetID::ISOPIC: - return "ISOPIC"; - case NetID::Main51: - return "Main51"; - case NetID::RED: - return "RED"; - case NetID::SCI: - return "SCI"; - case NetID::ISO9141_2: - return "ISO 9141 2"; - case NetID::ISO14230: - return "ISO 14230"; - case NetID::LIN: - return "LIN"; - case NetID::OP_Ethernet1: - return "OP (BR) Ethernet 1"; - case NetID::OP_Ethernet2: - return "OP (BR) Ethernet 2"; - case NetID::OP_Ethernet3: - return "OP (BR) Ethernet 3"; - case NetID::RED_EXT_MEMORYREAD: - return "RED_EXT_MEMORYREAD"; - case NetID::RED_INT_MEMORYREAD: - return "RED_INT_MEMORYREAD"; - case NetID::RED_DFLASH_READ: - return "RED_DFLASH_READ"; - case NetID::NeoMemorySDRead: - return "NeoMemorySDRead"; - case NetID::CAN_ERRBITS: - return "CAN_ERRBITS"; - case NetID::NeoMemoryWriteDone: - return "NeoMemoryWriteDone"; - case NetID::RED_WAVE_CAN1_LOGICAL: - return "RED_WAVE_CAN1_LOGICAL"; - case NetID::RED_WAVE_CAN2_LOGICAL: - return "RED_WAVE_CAN2_LOGICAL"; - case NetID::RED_WAVE_LIN1_LOGICAL: - return "RED_WAVE_LIN1_LOGICAL"; - case NetID::RED_WAVE_LIN2_LOGICAL: - return "RED_WAVE_LIN2_LOGICAL"; - case NetID::RED_WAVE_LIN1_ANALOG: - return "RED_WAVE_LIN1_ANALOG"; - case NetID::RED_WAVE_LIN2_ANALOG: - return "RED_WAVE_LIN2_ANALOG"; - case NetID::RED_WAVE_MISC_ANALOG: - return "RED_WAVE_MISC_ANALOG"; - case NetID::RED_WAVE_MISCDIO2_LOGICAL: - return "RED_WAVE_MISCDIO2_LOGICAL"; - case NetID::RED_NETWORK_COM_ENABLE_EX: - return "RED_NETWORK_COM_ENABLE_EX"; - case NetID::RED_NEOVI_NETWORK: - return "RED_NEOVI_NETWORK"; - case NetID::RED_READ_BAUD_SETTINGS: - return "RED_READ_BAUD_SETTINGS"; - case NetID::RED_OLDFORMAT: - return "RED_OLDFORMAT"; - case NetID::RED_SCOPE_CAPTURE: - return "RED_SCOPE_CAPTURE"; - case NetID::RED_HARDWARE_EXCEP: - return "RED_HARDWARE_EXCEP"; - case NetID::RED_GET_RTC: - return "RED_GET_RTC"; - case NetID::ISO9141_3: - return "ISO 9141 3"; - case NetID::HSCAN2: - return "HSCAN 2"; - case NetID::HSCAN3: - return "HSCAN 3"; - case NetID::OP_Ethernet4: - return "OP (BR) Ethernet 4"; - case NetID::OP_Ethernet5: - return "OP (BR) Ethernet 5"; - case NetID::ISO9141_4: - return "ISO 9141 4"; - case NetID::LIN2: - return "LIN 2"; - case NetID::LIN3: - return "LIN 3"; - case NetID::LIN4: - return "LIN 4"; - case NetID::RED_App_Error: - return "App Error"; - case NetID::CGI: - return "CGI"; - case NetID::Reset_Status: - return "Reset Status"; - case NetID::FB_Status: - return "FB Status"; - case NetID::App_Signal_Status: - return "App Signal Status"; - case NetID::Read_Datalink_Cm_Tx_Msg: - return "Read Datalink Cm Tx Msg"; - case NetID::Read_Datalink_Cm_Rx_Msg: - return "Read Datalink Cm Rx Msg"; - case NetID::Logging_Overflow: - return "Logging Overflow"; - case NetID::ReadSettings: - return "Read Settings"; - case NetID::HSCAN4: - return "HSCAN 4"; - case NetID::HSCAN5: - return "HSCAN 5"; - case NetID::RS232: - return "RS232"; - case NetID::UART: - return "UART"; - case NetID::UART2: - return "UART 2"; - case NetID::UART3: - return "UART 3"; - case NetID::UART4: - return "UART 4"; - case NetID::SWCAN2: - return "SWCAN 2"; - case NetID::Ethernet_DAQ: - return "Ethernet DAQ"; - case NetID::Data_To_Host: - return "Data To Host"; - case NetID::TextAPI_To_Host: - return "TextAPI To Host"; - case NetID::OP_Ethernet6: - return "OP (BR) Ethernet 6"; - case NetID::Red_VBat: - return "Red VBat"; - case NetID::OP_Ethernet7: - return "OP (BR) Ethernet 7"; - case NetID::OP_Ethernet8: - return "OP (BR) Ethernet 8"; - case NetID::OP_Ethernet9: - return "OP (BR) Ethernet 9"; - case NetID::OP_Ethernet10: - return "OP (BR) Ethernet 10"; - case NetID::OP_Ethernet11: - return "OP (BR) Ethernet 11"; - case NetID::FlexRay1a: - return "FlexRay 1a"; - case NetID::FlexRay1b: - return "FlexRay 1b"; - case NetID::FlexRay2a: - return "FlexRay 2a"; - case NetID::FlexRay2b: - return "FlexRay 2b"; - case NetID::LIN5: - return "LIN 5"; - case NetID::FlexRay: - return "FlexRay"; - case NetID::FlexRay2: - return "FlexRay 2"; - case NetID::OP_Ethernet12: - return "OP (BR) Ethernet 12"; - case NetID::I2C: - return "I2C"; - case NetID::MOST25: - return "MOST25"; - case NetID::MOST50: - return "MOST50"; - case NetID::MOST150: - return "MOST150"; - case NetID::Ethernet: - return "Ethernet"; - case NetID::GMFSA: - return "GMFSA"; - case NetID::TCP: - return "TCP"; - case NetID::HSCAN6: - return "HSCAN 6"; - case NetID::HSCAN7: - return "HSCAN 7"; - case NetID::LIN6: - return "LIN 6"; - case NetID::LSFTCAN2: - return "LSFTCAN 2"; - case NetID::LogicalDiskInfo: - return "Logical Disk Information"; - case NetID::EthPHYControl: - return "Ethernet PHY Register Control"; - case NetID::FlexRayControl: - return "FlexRay Control"; - case NetID::HW_COM_Latency_Test: - return "HW COM Latency Test"; - case NetID::DeviceStatus: - return "Device Status"; - case NetID::UDP: - return "UDP"; - case NetID::ForwardedMessage: - return "Forwarded Message"; - case NetID::I2C2: - return "I2C 2"; - case NetID::I2C3: - return "I2C 3"; - case NetID::I2C4: - return "I2C 4"; - case NetID::Ethernet2: - return "Ethernet 2"; - case NetID::Any: - case NetID::Invalid: - break; - } - return "Invalid Network"; - } - static optional GetCoreMiniNetworkFromNetID(NetID netid) { - switch(netid) { - case NetID::HSCAN: - return CoreMini::HSCAN; - case NetID::MSCAN: - return CoreMini::MSCAN; - case NetID::LIN: - return CoreMini::LIN; - case NetID::LIN2: - return CoreMini::LIN2; - case NetID::Device: - return CoreMini::Virtual; - case NetID::HSCAN2: - return CoreMini::HSCAN2; - case NetID::LSFTCAN: - return CoreMini::LSFTCAN; - case NetID::SWCAN: - return CoreMini::SWCAN; - case NetID::HSCAN3: - return CoreMini::HSCAN3; - case NetID::CGI: - return CoreMini::CGI; - case NetID::J1850VPW: - return CoreMini::J1850VPW; - case NetID::LIN3: - return CoreMini::LIN3; - case NetID::LIN4: - return CoreMini::LIN4; - case NetID::J1708: - return CoreMini::J1708; - case NetID::HSCAN4: - return CoreMini::HSCAN4; - case NetID::HSCAN5: - return CoreMini::HSCAN5; - case NetID::ISO9141: - return CoreMini::KLine1; - case NetID::ISO9141_2: - return CoreMini::KLine2; - case NetID::ISO9141_3: - return CoreMini::KLine3; - case NetID::ISO9141_4: - return CoreMini::KLine4; - case NetID::FlexRay1a: - return CoreMini::FlexRay1a; - case NetID::UART: - return CoreMini::UART; - case NetID::UART2: - return CoreMini::UART2; - case NetID::LIN5: - return CoreMini::LIN5; - case NetID::MOST25: - return CoreMini::MOST25; - case NetID::MOST50: - return CoreMini::MOST50; - case NetID::FlexRay1b: - return CoreMini::FlexRay1b; - case NetID::SWCAN2: - return CoreMini::SWCAN2; - case NetID::Ethernet_DAQ: - return CoreMini::EthernetDAQ; - case NetID::Ethernet: - return CoreMini::Ethernet; - case NetID::FlexRay2a: - return CoreMini::FlexRay2a; - case NetID::FlexRay2b: - return CoreMini::FlexRay2b; - case NetID::HSCAN6: - return CoreMini::HSCAN6; - case NetID::HSCAN7: - return CoreMini::HSCAN7; - case NetID::LIN6: - return CoreMini::LIN6; - case NetID::LSFTCAN2: - return CoreMini::LSFTCAN2; - case NetID::OP_Ethernet1: - return CoreMini::OP_Ethernet1; - case NetID::OP_Ethernet2: - return CoreMini::OP_Ethernet2; - case NetID::OP_Ethernet3: - return CoreMini::OP_Ethernet3; - case NetID::OP_Ethernet4: - return CoreMini::OP_Ethernet4; - case NetID::OP_Ethernet5: - return CoreMini::OP_Ethernet5; - case NetID::OP_Ethernet6: - return CoreMini::OP_Ethernet6; - case NetID::OP_Ethernet7: - return CoreMini::OP_Ethernet7; - case NetID::OP_Ethernet8: - return CoreMini::OP_Ethernet8; - case NetID::OP_Ethernet9: - return CoreMini::OP_Ethernet9; - case NetID::OP_Ethernet10: - return CoreMini::OP_Ethernet10; - case NetID::OP_Ethernet11: - return CoreMini::OP_Ethernet11; - case NetID::OP_Ethernet12: - return CoreMini::OP_Ethernet12; - case NetID::TCP: - return CoreMini::TCPVirtual; - case NetID::UDP: - return CoreMini::UDPVirtual; - case NetID::FlexRay: - return CoreMini::FlexRay1; - case NetID::FlexRay2: - return CoreMini::FlexRay2; - case NetID::ForwardedMessage: - return CoreMini::ForwardedMessage; - case NetID::I2C: - return CoreMini::I2C1; - case NetID::I2C2: - return CoreMini::I2C2; - case NetID::I2C3: - return CoreMini::I2C3; - case NetID::I2C4: - return CoreMini::I2C4; - case NetID::Ethernet2: - return CoreMini::Ethernet2; - default: - return nullopt; - } - } - static NetID GetNetIDFromCoreMiniNetwork(CoreMini cm) { - switch(cm) { - case CoreMini::HSCAN: - return NetID::HSCAN; - case CoreMini::MSCAN: - return NetID::MSCAN; - case CoreMini::LIN: - return NetID::LIN; - case CoreMini::LIN2: - return NetID::LIN2; - case CoreMini::Virtual: - return NetID::Device; - case CoreMini::HSCAN2: - return NetID::HSCAN2; - case CoreMini::LSFTCAN: - return NetID::LSFTCAN; - case CoreMini::SWCAN: - return NetID::SWCAN; - case CoreMini::HSCAN3: - return NetID::HSCAN3; - case CoreMini::CGI: - return NetID::CGI; - case CoreMini::J1850VPW: - return NetID::J1850VPW; - case CoreMini::LIN3: - return NetID::LIN3; - case CoreMini::LIN4: - return NetID::LIN4; - case CoreMini::J1708: - return NetID::J1708; - case CoreMini::HSCAN4: - return NetID::HSCAN4; - case CoreMini::HSCAN5: - return NetID::HSCAN5; - case CoreMini::KLine1: - return NetID::ISO9141; - case CoreMini::KLine2: - return NetID::ISO9141_2; - case CoreMini::KLine3: - return NetID::ISO9141_3; - case CoreMini::KLine4: - return NetID::ISO9141_4; - case CoreMini::FlexRay1a: - return NetID::FlexRay1a; - case CoreMini::UART: - return NetID::UART; - case CoreMini::UART2: - return NetID::UART2; - case CoreMini::LIN5: - return NetID::LIN5; - case CoreMini::MOST25: - return NetID::MOST25; - case CoreMini::MOST50: - return NetID::MOST50; - case CoreMini::FlexRay1b: - return NetID::FlexRay1b; - case CoreMini::SWCAN2: - return NetID::SWCAN2; - case CoreMini::EthernetDAQ: - return NetID::Ethernet_DAQ; - case CoreMini::Ethernet: - return NetID::Ethernet; - case CoreMini::FlexRay2a: - return NetID::FlexRay2a; - case CoreMini::FlexRay2b: - return NetID::FlexRay2b; - case CoreMini::HSCAN6: - return NetID::HSCAN6; - case CoreMini::HSCAN7: - return NetID::HSCAN7; - case CoreMini::LIN6: - return NetID::LIN6; - case CoreMini::LSFTCAN2: - return NetID::LSFTCAN2; - case CoreMini::OP_Ethernet1: - return NetID::OP_Ethernet1; - case CoreMini::OP_Ethernet2: - return NetID::OP_Ethernet2; - case CoreMini::OP_Ethernet3: - return NetID::OP_Ethernet3; - case CoreMini::OP_Ethernet4: - return NetID::OP_Ethernet4; - case CoreMini::OP_Ethernet5: - return NetID::OP_Ethernet5; - case CoreMini::OP_Ethernet6: - return NetID::OP_Ethernet6; - case CoreMini::OP_Ethernet7: - return NetID::OP_Ethernet7; - case CoreMini::OP_Ethernet8: - return NetID::OP_Ethernet8; - case CoreMini::OP_Ethernet9: - return NetID::OP_Ethernet9; - case CoreMini::OP_Ethernet10: - return NetID::OP_Ethernet10; - case CoreMini::OP_Ethernet11: - return NetID::OP_Ethernet11; - case CoreMini::OP_Ethernet12: - return NetID::OP_Ethernet12; - case CoreMini::TCPVirtual: - return NetID::TCP; - case CoreMini::UDPVirtual: - return NetID::UDP; - case CoreMini::FlexRay1: - return NetID::FlexRay; - case CoreMini::FlexRay2: - return NetID::FlexRay2; - case CoreMini::ForwardedMessage: - return NetID::ForwardedMessage; - case CoreMini::I2C1: - return NetID::I2C; - case CoreMini::I2C2: - return NetID::I2C2; - case CoreMini::I2C3: - return NetID::I2C3; - case CoreMini::I2C4: - return NetID::I2C4; - case CoreMini::Ethernet2: - return NetID::Ethernet2; - } - return NetID::Invalid; // Should be unreachable, the compiler should warn about new CoreMini IDs - } - - Network() { setValue(NetID::Invalid); } - Network(neonetid_t netid) { setValue((NetID)netid); } - Network(NetID netid) { setValue(netid); } - Network(CoreMini cm) { setValue(GetNetIDFromCoreMiniNetwork(cm)); } - NetID getNetID() const { return value; } - Type getType() const { return type; } - optional getCoreMini() const { return GetCoreMiniNetworkFromNetID(getNetID()); } - friend std::ostream& operator<<(std::ostream& os, const Network& network) { - os << GetNetIDString(network.getNetID()); - return os; - } - friend bool operator==(const Network& net1, const Network& net2) { return net1.getNetID() == net2.getNetID(); } - friend bool operator!=(const Network& net1, const Network& net2) { return !(net1 == net2); } - -private: - NetID value; // Always use setValue so that value and type stay in sync - Type type; - void setValue(NetID id) { - value = id; - type = GetTypeOfNetID(value); - } -}; - -} - -#endif // __cplusplus - -#ifdef __ICSNEOC_H_ -#define ICSNEO_NETID_DEVICE 0 -#define ICSNEO_NETID_HSCAN 1 -#define ICSNEO_NETID_MSCAN 2 -#define ICSNEO_NETID_SWCAN 3 -#define ICSNEO_NETID_LSFTCAN 4 -#define ICSNEO_NETID_FORDSCP 5 -#define ICSNEO_NETID_J1708 6 -#define ICSNEO_NETID_AUX 7 -#define ICSNEO_NETID_J1850VPW 8 -#define ICSNEO_NETID_ISO9141 9 -#define ICSNEO_NETID_ISOPIC 10 -#define ICSNEO_NETID_MAIN51 11 -#define ICSNEO_NETID_RED 12 -#define ICSNEO_NETID_SCI 13 -#define ICSNEO_NETID_ISO9141_2 14 -#define ICSNEO_NETID_ISO14230 15 -#define ICSNEO_NETID_LIN 16 -#define ICSNEO_NETID_OP_ETHERNET1 17 -#define ICSNEO_NETID_OP_ETHERNET2 18 -#define ICSNEO_NETID_OP_ETHERNET3 19 - -// START Device Command Returns -// When we send a command, the device returns on one of these, depending on command -#define ICSNEO_NETID_RED_EXT_MEMORYREAD 20 -#define ICSNEO_NETID_RED_INT_MEMORYREAD 21 -#define ICSNEO_NETID_RED_DFLASH_READ 22 -#define ICSNEO_NETID_NEOMEMORY_SD_READ 23 -#define ICSNEO_NETID_CAN_ERRBITS 24 -#define ICSNEO_NETID_NEOMEMORY_WRITE_DONE 25 -#define ICSNEO_NETID_RED_WAVE_CAN1_LOGICAL 26 -#define ICSNEO_NETID_RED_WAVE_CAN2_LOGICAL 27 -#define ICSNEO_NETID_RED_WAVE_LIN1_LOGICAL 28 -#define ICSNEO_NETID_RED_WAVE_LIN2_LOGICAL 29 -#define ICSNEO_NETID_RED_WAVE_LIN1_ANALOG 30 -#define ICSNEO_NETID_RED_WAVE_LIN2_ANALOG 31 -#define ICSNEO_NETID_RED_WAVE_MISC_ANALOG 32 -#define ICSNEO_NETID_RED_WAVE_MISCDIO2_LOGICAL 33 -#define ICSNEO_NETID_RED_NETWORK_COM_ENABLE_EX 34 -#define ICSNEO_NETID_RED_NEOVI_NETWORK 35 -#define ICSNEO_NETID_RED_READ_BAUD_SETTINGS 36 -#define ICSNEO_NETID_RED_OLDFORMAT 37 -#define ICSNEO_NETID_RED_SCOPE_CAPTURE 38 -#define ICSNEO_NETID_RED_HARDWARE_EXCEP 39 -#define ICSNEO_NETID_RED_GET_RTC 40 -// END Device Command Returns - -#define ICSNEO_NETID_ISO9141_3 41 -#define ICSNEO_NETID_HSCAN2 42 -#define ICSNEO_NETID_HSCAN3 44 -#define ICSNEO_NETID_OP_ETHERNET4 45 -#define ICSNEO_NETID_OP_ETHERNET5 46 -#define ICSNEO_NETID_ISO9141_4 47 -#define ICSNEO_NETID_LIN2 48 -#define ICSNEO_NETID_LIN3 49 -#define ICSNEO_NETID_LIN4 50 -//#define ICSNEO_NETID_MOST 51 Old and unused -#define ICSNEO_NETID_RED_APP_ERROR 52 -#define ICSNEO_NETID_CGI 53 -#define ICSNEO_NETID_RESET_STATUS 54 -#define ICSNEO_NETID_FB_STATUS 55 -#define ICSNEO_NETID_APP_SIGNAL_STATUS 56 -#define ICSNEO_NETID_READ_DATALINK_CM_TX_MSG 57 -#define ICSNEO_NETID_READ_DATALINK_CM_RX_MSG 58 -#define ICSNEO_NETID_LOGGING_OVERFLOW 59 -#define ICSNEO_NETID_READ_SETTINGS 60 -#define ICSNEO_NETID_HSCAN4 61 -#define ICSNEO_NETID_HSCAN5 62 -#define ICSNEO_NETID_RS232 63 -#define ICSNEO_NETID_UART 64 -#define ICSNEO_NETID_UART2 65 -#define ICSNEO_NETID_UART3 66 -#define ICSNEO_NETID_UART4 67 -#define ICSNEO_NETID_SWCAN2 68 -#define ICSNEO_NETID_ETHERNET_DAQ 69 -#define ICSNEO_NETID_DATA_TO_HOST 70 -#define ICSNEO_NETID_TEXTAPI_TO_HOST 71 -#define ICSNEO_NETID_OP_ETHERNET6 73 -#define ICSNEO_NETID_RED_VBAT 74 -#define ICSNEO_NETID_OP_ETHERNET7 75 -#define ICSNEO_NETID_OP_ETHERNET8 76 -#define ICSNEO_NETID_OP_ETHERNET9 77 -#define ICSNEO_NETID_OP_ETHERNET10 78 -#define ICSNEO_NETID_OP_ETHERNET11 79 -#define ICSNEO_NETID_FLEXRAY1A 80 -#define ICSNEO_NETID_FLEXRAY1B 81 -#define ICSNEO_NETID_FLEXRAY2A 82 -#define ICSNEO_NETID_FLEXRAY2B 83 -#define ICSNEO_NETID_LIN5 84 -#define ICSNEO_NETID_FLEXRAY 85 -#define ICSNEO_NETID_FLEXRAY2 86 -#define ICSNEO_NETID_OP_ETHERNET12 87 -#define ICSNEO_NETID_I2C 88 -#define ICSNEO_NETID_MOST25 90 -#define ICSNEO_NETID_MOST50 91 -#define ICSNEO_NETID_MOST150 92 -#define ICSNEO_NETID_ETHERNET 93 -#define ICSNEO_NETID_GMFSA 94 -#define ICSNEO_NETID_TCP 95 -#define ICSNEO_NETID_HSCAN6 96 -#define ICSNEO_NETID_HSCAN7 97 -#define ICSNEO_NETID_LIN6 98 -#define ICSNEO_NETID_LSFTCAN2 99 -#define ICSNEO_NETID_LOGICAL_DISK_INFO 187 -#define ICSNEO_NETID_ETH_PHY_CONTROL 239 -#define ICSNEO_NETID_FLEXRAY_CONTROL 243 -#define ICSNEO_NETID_HW_COM_LATENCY_TEST 512 -#define ICSNEO_NETID_DEVICE_STATUS 513 -#define ICSNEO_NETID_UDP 514 -#define ICSNEO_NETID_FORWARDED_MESSAGE 516 -#define ICSNEO_NETID_I2C2 517 -#define ICSNEO_NETID_I2C3 518 -#define ICSNEO_NETID_I2C4 519 -#define ICSNEO_NETID_ETHERNET2 520 -#define ICSNEO_NETID_ANY 0xfffe // Never actually set as type, but used as flag for filtering -#define ICSNEO_NETID_INVALID 0xffff - -#define ICSNEO_NETWORK_TYPE_INVALID 0 -#define ICSNEO_NETWORK_TYPE_INTERNAL 1 // Used for statuses that don't actually need to be transferred to the client application -#define ICSNEO_NETWORK_TYPE_CAN 2 -#define ICSNEO_NETWORK_TYPE_LIN 3 -#define ICSNEO_NETWORK_TYPE_FLEXRAY 4 -#define ICSNEO_NETWORK_TYPE_MOST 5 -#define ICSNEO_NETWORK_TYPE_ETHERNET 6 -#define ICSNEO_NETWORK_TYPE_LSFTCAN 7 -#define ICSNEO_NETWORK_TYPE_SWCAN 8 -#define ICSNEO_NETWORK_TYPE_ISO9141 9 -#define ICSNEO_NETWORK_TYPE_I2C 10 -#define ICSNEO_NETWORK_TYPE_ANY 0xFE // Never actually set as type, but used as flag for filtering -#define ICSNEO_NETWORK_TYPE_OTHER 0xFF -#endif - +#ifndef __NETWORKID_H_ +#define __NETWORKID_H_ + +#include +typedef uint16_t neonetid_t; +typedef uint8_t neonettype_t; + +#ifdef __cplusplus + +#include +#include "icsneo/platform/optional.h" + +namespace icsneo { + +class Network { +public: + enum class NetID : neonetid_t { + Device = 0, + HSCAN = 1, + MSCAN = 2, + SWCAN = 3, + LSFTCAN = 4, + FordSCP = 5, + J1708 = 6, + Aux = 7, + J1850VPW = 8, + ISO9141 = 9, + ISOPIC = 10, + Main51 = 11, + RED = 12, + SCI = 13, + ISO9141_2 = 14, + ISO14230 = 15, + LIN = 16, + OP_Ethernet1 = 17, + OP_Ethernet2 = 18, + OP_Ethernet3 = 19, + + // START Device Command Returns + // When we send a command, the device returns on one of these, depending on command + RED_EXT_MEMORYREAD = 20, + RED_INT_MEMORYREAD = 21, + RED_DFLASH_READ = 22, + NeoMemorySDRead = 23, // Response from NeoMemory (MemoryTypeSD) + CAN_ERRBITS = 24, + NeoMemoryWriteDone = 25, + RED_WAVE_CAN1_LOGICAL = 26, + RED_WAVE_CAN2_LOGICAL = 27, + RED_WAVE_LIN1_LOGICAL = 28, + RED_WAVE_LIN2_LOGICAL = 29, + RED_WAVE_LIN1_ANALOG = 30, + RED_WAVE_LIN2_ANALOG = 31, + RED_WAVE_MISC_ANALOG = 32, + RED_WAVE_MISCDIO2_LOGICAL = 33, + RED_NETWORK_COM_ENABLE_EX = 34, + RED_NEOVI_NETWORK = 35, + RED_READ_BAUD_SETTINGS = 36, + RED_OLDFORMAT = 37, + RED_SCOPE_CAPTURE = 38, + RED_HARDWARE_EXCEP = 39, + RED_GET_RTC = 40, + // END Device Command Returns + + ISO9141_3 = 41, + HSCAN2 = 42, + HSCAN3 = 44, + OP_Ethernet4 = 45, + OP_Ethernet5 = 46, + ISO9141_4 = 47, + LIN2 = 48, + LIN3 = 49, + LIN4 = 50, + // MOST = 51, Old and unused + RED_App_Error = 52, + CGI = 53, + Reset_Status = 54, + FB_Status = 55, + App_Signal_Status = 56, + Read_Datalink_Cm_Tx_Msg = 57, + Read_Datalink_Cm_Rx_Msg = 58, + Logging_Overflow = 59, + ReadSettings = 60, + HSCAN4 = 61, + HSCAN5 = 62, + RS232 = 63, + UART = 64, + UART2 = 65, + UART3 = 66, + UART4 = 67, + SWCAN2 = 68, + Ethernet_DAQ = 69, + Data_To_Host = 70, + TextAPI_To_Host = 71, + OP_Ethernet6 = 73, + Red_VBat = 74, + OP_Ethernet7 = 75, + OP_Ethernet8 = 76, + OP_Ethernet9 = 77, + OP_Ethernet10 = 78, + OP_Ethernet11 = 79, + FlexRay1a = 80, + FlexRay1b = 81, + FlexRay2a = 82, + FlexRay2b = 83, + LIN5 = 84, + FlexRay = 85, + FlexRay2 = 86, + OP_Ethernet12 = 87, + I2C = 88, + MOST25 = 90, + MOST50 = 91, + MOST150 = 92, + Ethernet = 93, + GMFSA = 94, + TCP = 95, + HSCAN6 = 96, + HSCAN7 = 97, + LIN6 = 98, + LSFTCAN2 = 99, + LogicalDiskInfo = 187, + EthPHYControl = 239, + FlexRayControl = 243, + HW_COM_Latency_Test = 512, + DeviceStatus = 513, + UDP = 514, + ForwardedMessage = 516, + I2C2 = 517, + I2C3 = 518, + I2C4 = 519, + Ethernet2 = 520, + Any = 0xfffe, // Never actually set as type, but used as flag for filtering + Invalid = 0xffff + }; + enum class Type : neonettype_t { + Invalid = 0, + Internal = 1, // Used for statuses that don't actually need to be transferred to the client application + CAN = 2, + LIN = 3, + FlexRay = 4, + MOST = 5, + Ethernet = 6, + LSFTCAN = 7, + SWCAN = 8, + ISO9141 = 9, + I2C = 10, + Any = 0xFE, // Never actually set as type, but used as flag for filtering + Other = 0xFF + }; + enum class CoreMini : uint8_t { + HSCAN = 0, + MSCAN = 1, + LIN = 2, + LIN2 = 3, + Virtual = 4, + HSCAN2 = 5, + LSFTCAN = 6, + SWCAN = 7, + HSCAN3 = 8, + CGI = 9, + J1850VPW = 10, + LIN3 = 11, + LIN4 = 12, + J1708 = 13, + HSCAN4 = 14, + HSCAN5 = 15, + KLine1 = 16, + KLine2 = 17, + KLine3 = 18, + KLine4 = 19, + FlexRay1a = 20, + UART = 21, + UART2 = 22, + LIN5 = 23, + MOST25 = 24, + MOST50 = 25, + FlexRay1b = 26, + SWCAN2 = 27, + EthernetDAQ = 28, + Ethernet = 29, + FlexRay2a = 30, + FlexRay2b = 31, + HSCAN6 = 32, + HSCAN7 = 33, + LIN6 = 34, + LSFTCAN2 = 35, + OP_Ethernet1 = 36, + OP_Ethernet2 = 37, + OP_Ethernet3 = 38, + OP_Ethernet4 = 39, + OP_Ethernet5 = 40, + OP_Ethernet6 = 41, + OP_Ethernet7 = 42, + OP_Ethernet8 = 43, + OP_Ethernet9 = 44, + OP_Ethernet10 = 45, + OP_Ethernet11 = 46, + OP_Ethernet12 = 47, + TCPVirtual = 48, + UDPVirtual = 49, + FlexRay1 = 50, + FlexRay2 = 51, + ForwardedMessage = 52, + I2C1 = 53, + I2C2 = 54, + I2C3 = 55, + I2C4 = 56, + Ethernet2 = 57, + }; + static const char* GetTypeString(Type type) { + switch(type) { + case Type::CAN: + return "CAN"; + case Type::LIN: + return "LIN"; + case Type::FlexRay: + return "FlexRay"; + case Type::MOST: + return "MOST"; + case Type::Other: + return "Other"; + case Type::Internal: + return "Internal"; + case Type::ISO9141: + return "ISO 9141-2"; + case Type::Ethernet: + return "Ethernet"; + case Type::LSFTCAN: + return "Low Speed Fault Tolerant CAN"; + case Type::SWCAN: + return "Single Wire CAN"; + case Type::I2C: + return "I²C"; + case Type::Invalid: + default: + return "Invalid Type"; + } + } + static Type GetTypeOfNetID(NetID netid) { + switch(netid) { + case NetID::HSCAN: + case NetID::MSCAN: + case NetID::HSCAN2: + case NetID::HSCAN3: + case NetID::HSCAN4: + case NetID::HSCAN5: + case NetID::HSCAN6: + case NetID::HSCAN7: + return Type::CAN; + case NetID::LIN: + case NetID::LIN2: + case NetID::LIN3: + case NetID::LIN4: + case NetID::LIN5: + case NetID::LIN6: + return Type::LIN; + case NetID::FlexRay: + case NetID::FlexRay1a: + case NetID::FlexRay1b: + case NetID::FlexRay2: + case NetID::FlexRay2a: + case NetID::FlexRay2b: + return Type::FlexRay; + case NetID::MOST25: + case NetID::MOST50: + case NetID::MOST150: + return Type::MOST; + case NetID::RED: + case NetID::RED_OLDFORMAT: + case NetID::Device: + case NetID::Reset_Status: + case NetID::DeviceStatus: + case NetID::FlexRayControl: + case NetID::Main51: + case NetID::ReadSettings: + case NetID::LogicalDiskInfo: + case NetID::EthPHYControl: + case NetID::NeoMemorySDRead: + case NetID::NeoMemoryWriteDone: + return Type::Internal; + case NetID::Invalid: + case NetID::Any: + return Type::Invalid; + case NetID::Ethernet: + case NetID::Ethernet_DAQ: + case NetID::Ethernet2: + case NetID::OP_Ethernet1: + case NetID::OP_Ethernet2: + case NetID::OP_Ethernet3: + case NetID::OP_Ethernet4: + case NetID::OP_Ethernet5: + case NetID::OP_Ethernet6: + case NetID::OP_Ethernet7: + case NetID::OP_Ethernet8: + case NetID::OP_Ethernet9: + case NetID::OP_Ethernet10: + case NetID::OP_Ethernet11: + case NetID::OP_Ethernet12: + return Type::Ethernet; + case NetID::LSFTCAN: + case NetID::LSFTCAN2: + return Type::LSFTCAN; + case NetID::SWCAN: + case NetID::SWCAN2: + return Type::SWCAN; + case NetID::ISO9141: + case NetID::ISO9141_2: + case NetID::ISO9141_3: + case NetID::ISO9141_4: + return Type::ISO9141; + case NetID::I2C: + case NetID::I2C2: + case NetID::I2C3: + case NetID::I2C4: + return Type::I2C; + default: + return Type::Other; + } + } + static const char* GetNetIDString(NetID netid) { + switch(netid) { + case NetID::Device: + return "neoVI"; + case NetID::HSCAN: + return "HSCAN"; + case NetID::MSCAN: + return "MSCAN"; + case NetID::SWCAN: + return "SWCAN"; + case NetID::LSFTCAN: + return "LSFTCAN"; + case NetID::FordSCP: + return "FordSCP"; + case NetID::J1708: + return "J1708"; + case NetID::Aux: + return "Aux"; + case NetID::J1850VPW: + return "J1850 VPW"; + case NetID::ISO9141: + return "ISO 9141"; + case NetID::ISOPIC: + return "ISOPIC"; + case NetID::Main51: + return "Main51"; + case NetID::RED: + return "RED"; + case NetID::SCI: + return "SCI"; + case NetID::ISO9141_2: + return "ISO 9141 2"; + case NetID::ISO14230: + return "ISO 14230"; + case NetID::LIN: + return "LIN"; + case NetID::OP_Ethernet1: + return "OP (BR) Ethernet 1"; + case NetID::OP_Ethernet2: + return "OP (BR) Ethernet 2"; + case NetID::OP_Ethernet3: + return "OP (BR) Ethernet 3"; + case NetID::RED_EXT_MEMORYREAD: + return "RED_EXT_MEMORYREAD"; + case NetID::RED_INT_MEMORYREAD: + return "RED_INT_MEMORYREAD"; + case NetID::RED_DFLASH_READ: + return "RED_DFLASH_READ"; + case NetID::NeoMemorySDRead: + return "NeoMemorySDRead"; + case NetID::CAN_ERRBITS: + return "CAN_ERRBITS"; + case NetID::NeoMemoryWriteDone: + return "NeoMemoryWriteDone"; + case NetID::RED_WAVE_CAN1_LOGICAL: + return "RED_WAVE_CAN1_LOGICAL"; + case NetID::RED_WAVE_CAN2_LOGICAL: + return "RED_WAVE_CAN2_LOGICAL"; + case NetID::RED_WAVE_LIN1_LOGICAL: + return "RED_WAVE_LIN1_LOGICAL"; + case NetID::RED_WAVE_LIN2_LOGICAL: + return "RED_WAVE_LIN2_LOGICAL"; + case NetID::RED_WAVE_LIN1_ANALOG: + return "RED_WAVE_LIN1_ANALOG"; + case NetID::RED_WAVE_LIN2_ANALOG: + return "RED_WAVE_LIN2_ANALOG"; + case NetID::RED_WAVE_MISC_ANALOG: + return "RED_WAVE_MISC_ANALOG"; + case NetID::RED_WAVE_MISCDIO2_LOGICAL: + return "RED_WAVE_MISCDIO2_LOGICAL"; + case NetID::RED_NETWORK_COM_ENABLE_EX: + return "RED_NETWORK_COM_ENABLE_EX"; + case NetID::RED_NEOVI_NETWORK: + return "RED_NEOVI_NETWORK"; + case NetID::RED_READ_BAUD_SETTINGS: + return "RED_READ_BAUD_SETTINGS"; + case NetID::RED_OLDFORMAT: + return "RED_OLDFORMAT"; + case NetID::RED_SCOPE_CAPTURE: + return "RED_SCOPE_CAPTURE"; + case NetID::RED_HARDWARE_EXCEP: + return "RED_HARDWARE_EXCEP"; + case NetID::RED_GET_RTC: + return "RED_GET_RTC"; + case NetID::ISO9141_3: + return "ISO 9141 3"; + case NetID::HSCAN2: + return "HSCAN 2"; + case NetID::HSCAN3: + return "HSCAN 3"; + case NetID::OP_Ethernet4: + return "OP (BR) Ethernet 4"; + case NetID::OP_Ethernet5: + return "OP (BR) Ethernet 5"; + case NetID::ISO9141_4: + return "ISO 9141 4"; + case NetID::LIN2: + return "LIN 2"; + case NetID::LIN3: + return "LIN 3"; + case NetID::LIN4: + return "LIN 4"; + case NetID::RED_App_Error: + return "App Error"; + case NetID::CGI: + return "CGI"; + case NetID::Reset_Status: + return "Reset Status"; + case NetID::FB_Status: + return "FB Status"; + case NetID::App_Signal_Status: + return "App Signal Status"; + case NetID::Read_Datalink_Cm_Tx_Msg: + return "Read Datalink Cm Tx Msg"; + case NetID::Read_Datalink_Cm_Rx_Msg: + return "Read Datalink Cm Rx Msg"; + case NetID::Logging_Overflow: + return "Logging Overflow"; + case NetID::ReadSettings: + return "Read Settings"; + case NetID::HSCAN4: + return "HSCAN 4"; + case NetID::HSCAN5: + return "HSCAN 5"; + case NetID::RS232: + return "RS232"; + case NetID::UART: + return "UART"; + case NetID::UART2: + return "UART 2"; + case NetID::UART3: + return "UART 3"; + case NetID::UART4: + return "UART 4"; + case NetID::SWCAN2: + return "SWCAN 2"; + case NetID::Ethernet_DAQ: + return "Ethernet DAQ"; + case NetID::Data_To_Host: + return "Data To Host"; + case NetID::TextAPI_To_Host: + return "TextAPI To Host"; + case NetID::OP_Ethernet6: + return "OP (BR) Ethernet 6"; + case NetID::Red_VBat: + return "Red VBat"; + case NetID::OP_Ethernet7: + return "OP (BR) Ethernet 7"; + case NetID::OP_Ethernet8: + return "OP (BR) Ethernet 8"; + case NetID::OP_Ethernet9: + return "OP (BR) Ethernet 9"; + case NetID::OP_Ethernet10: + return "OP (BR) Ethernet 10"; + case NetID::OP_Ethernet11: + return "OP (BR) Ethernet 11"; + case NetID::FlexRay1a: + return "FlexRay 1a"; + case NetID::FlexRay1b: + return "FlexRay 1b"; + case NetID::FlexRay2a: + return "FlexRay 2a"; + case NetID::FlexRay2b: + return "FlexRay 2b"; + case NetID::LIN5: + return "LIN 5"; + case NetID::FlexRay: + return "FlexRay"; + case NetID::FlexRay2: + return "FlexRay 2"; + case NetID::OP_Ethernet12: + return "OP (BR) Ethernet 12"; + case NetID::I2C: + return "I2C"; + case NetID::MOST25: + return "MOST25"; + case NetID::MOST50: + return "MOST50"; + case NetID::MOST150: + return "MOST150"; + case NetID::Ethernet: + return "Ethernet"; + case NetID::GMFSA: + return "GMFSA"; + case NetID::TCP: + return "TCP"; + case NetID::HSCAN6: + return "HSCAN 6"; + case NetID::HSCAN7: + return "HSCAN 7"; + case NetID::LIN6: + return "LIN 6"; + case NetID::LSFTCAN2: + return "LSFTCAN 2"; + case NetID::LogicalDiskInfo: + return "Logical Disk Information"; + case NetID::EthPHYControl: + return "Ethernet PHY Register Control"; + case NetID::FlexRayControl: + return "FlexRay Control"; + case NetID::HW_COM_Latency_Test: + return "HW COM Latency Test"; + case NetID::DeviceStatus: + return "Device Status"; + case NetID::UDP: + return "UDP"; + case NetID::ForwardedMessage: + return "Forwarded Message"; + case NetID::I2C2: + return "I2C 2"; + case NetID::I2C3: + return "I2C 3"; + case NetID::I2C4: + return "I2C 4"; + case NetID::Ethernet2: + return "Ethernet 2"; + case NetID::Any: + case NetID::Invalid: + break; + } + return "Invalid Network"; + } + static optional GetCoreMiniNetworkFromNetID(NetID netid) { + switch(netid) { + case NetID::HSCAN: + return CoreMini::HSCAN; + case NetID::MSCAN: + return CoreMini::MSCAN; + case NetID::LIN: + return CoreMini::LIN; + case NetID::LIN2: + return CoreMini::LIN2; + case NetID::Device: + return CoreMini::Virtual; + case NetID::HSCAN2: + return CoreMini::HSCAN2; + case NetID::LSFTCAN: + return CoreMini::LSFTCAN; + case NetID::SWCAN: + return CoreMini::SWCAN; + case NetID::HSCAN3: + return CoreMini::HSCAN3; + case NetID::CGI: + return CoreMini::CGI; + case NetID::J1850VPW: + return CoreMini::J1850VPW; + case NetID::LIN3: + return CoreMini::LIN3; + case NetID::LIN4: + return CoreMini::LIN4; + case NetID::J1708: + return CoreMini::J1708; + case NetID::HSCAN4: + return CoreMini::HSCAN4; + case NetID::HSCAN5: + return CoreMini::HSCAN5; + case NetID::ISO9141: + return CoreMini::KLine1; + case NetID::ISO9141_2: + return CoreMini::KLine2; + case NetID::ISO9141_3: + return CoreMini::KLine3; + case NetID::ISO9141_4: + return CoreMini::KLine4; + case NetID::FlexRay1a: + return CoreMini::FlexRay1a; + case NetID::UART: + return CoreMini::UART; + case NetID::UART2: + return CoreMini::UART2; + case NetID::LIN5: + return CoreMini::LIN5; + case NetID::MOST25: + return CoreMini::MOST25; + case NetID::MOST50: + return CoreMini::MOST50; + case NetID::FlexRay1b: + return CoreMini::FlexRay1b; + case NetID::SWCAN2: + return CoreMini::SWCAN2; + case NetID::Ethernet_DAQ: + return CoreMini::EthernetDAQ; + case NetID::Ethernet: + return CoreMini::Ethernet; + case NetID::FlexRay2a: + return CoreMini::FlexRay2a; + case NetID::FlexRay2b: + return CoreMini::FlexRay2b; + case NetID::HSCAN6: + return CoreMini::HSCAN6; + case NetID::HSCAN7: + return CoreMini::HSCAN7; + case NetID::LIN6: + return CoreMini::LIN6; + case NetID::LSFTCAN2: + return CoreMini::LSFTCAN2; + case NetID::OP_Ethernet1: + return CoreMini::OP_Ethernet1; + case NetID::OP_Ethernet2: + return CoreMini::OP_Ethernet2; + case NetID::OP_Ethernet3: + return CoreMini::OP_Ethernet3; + case NetID::OP_Ethernet4: + return CoreMini::OP_Ethernet4; + case NetID::OP_Ethernet5: + return CoreMini::OP_Ethernet5; + case NetID::OP_Ethernet6: + return CoreMini::OP_Ethernet6; + case NetID::OP_Ethernet7: + return CoreMini::OP_Ethernet7; + case NetID::OP_Ethernet8: + return CoreMini::OP_Ethernet8; + case NetID::OP_Ethernet9: + return CoreMini::OP_Ethernet9; + case NetID::OP_Ethernet10: + return CoreMini::OP_Ethernet10; + case NetID::OP_Ethernet11: + return CoreMini::OP_Ethernet11; + case NetID::OP_Ethernet12: + return CoreMini::OP_Ethernet12; + case NetID::TCP: + return CoreMini::TCPVirtual; + case NetID::UDP: + return CoreMini::UDPVirtual; + case NetID::FlexRay: + return CoreMini::FlexRay1; + case NetID::FlexRay2: + return CoreMini::FlexRay2; + case NetID::ForwardedMessage: + return CoreMini::ForwardedMessage; + case NetID::I2C: + return CoreMini::I2C1; + case NetID::I2C2: + return CoreMini::I2C2; + case NetID::I2C3: + return CoreMini::I2C3; + case NetID::I2C4: + return CoreMini::I2C4; + case NetID::Ethernet2: + return CoreMini::Ethernet2; + default: + return nullopt; + } + } + static NetID GetNetIDFromCoreMiniNetwork(CoreMini cm) { + switch(cm) { + case CoreMini::HSCAN: + return NetID::HSCAN; + case CoreMini::MSCAN: + return NetID::MSCAN; + case CoreMini::LIN: + return NetID::LIN; + case CoreMini::LIN2: + return NetID::LIN2; + case CoreMini::Virtual: + return NetID::Device; + case CoreMini::HSCAN2: + return NetID::HSCAN2; + case CoreMini::LSFTCAN: + return NetID::LSFTCAN; + case CoreMini::SWCAN: + return NetID::SWCAN; + case CoreMini::HSCAN3: + return NetID::HSCAN3; + case CoreMini::CGI: + return NetID::CGI; + case CoreMini::J1850VPW: + return NetID::J1850VPW; + case CoreMini::LIN3: + return NetID::LIN3; + case CoreMini::LIN4: + return NetID::LIN4; + case CoreMini::J1708: + return NetID::J1708; + case CoreMini::HSCAN4: + return NetID::HSCAN4; + case CoreMini::HSCAN5: + return NetID::HSCAN5; + case CoreMini::KLine1: + return NetID::ISO9141; + case CoreMini::KLine2: + return NetID::ISO9141_2; + case CoreMini::KLine3: + return NetID::ISO9141_3; + case CoreMini::KLine4: + return NetID::ISO9141_4; + case CoreMini::FlexRay1a: + return NetID::FlexRay1a; + case CoreMini::UART: + return NetID::UART; + case CoreMini::UART2: + return NetID::UART2; + case CoreMini::LIN5: + return NetID::LIN5; + case CoreMini::MOST25: + return NetID::MOST25; + case CoreMini::MOST50: + return NetID::MOST50; + case CoreMini::FlexRay1b: + return NetID::FlexRay1b; + case CoreMini::SWCAN2: + return NetID::SWCAN2; + case CoreMini::EthernetDAQ: + return NetID::Ethernet_DAQ; + case CoreMini::Ethernet: + return NetID::Ethernet; + case CoreMini::FlexRay2a: + return NetID::FlexRay2a; + case CoreMini::FlexRay2b: + return NetID::FlexRay2b; + case CoreMini::HSCAN6: + return NetID::HSCAN6; + case CoreMini::HSCAN7: + return NetID::HSCAN7; + case CoreMini::LIN6: + return NetID::LIN6; + case CoreMini::LSFTCAN2: + return NetID::LSFTCAN2; + case CoreMini::OP_Ethernet1: + return NetID::OP_Ethernet1; + case CoreMini::OP_Ethernet2: + return NetID::OP_Ethernet2; + case CoreMini::OP_Ethernet3: + return NetID::OP_Ethernet3; + case CoreMini::OP_Ethernet4: + return NetID::OP_Ethernet4; + case CoreMini::OP_Ethernet5: + return NetID::OP_Ethernet5; + case CoreMini::OP_Ethernet6: + return NetID::OP_Ethernet6; + case CoreMini::OP_Ethernet7: + return NetID::OP_Ethernet7; + case CoreMini::OP_Ethernet8: + return NetID::OP_Ethernet8; + case CoreMini::OP_Ethernet9: + return NetID::OP_Ethernet9; + case CoreMini::OP_Ethernet10: + return NetID::OP_Ethernet10; + case CoreMini::OP_Ethernet11: + return NetID::OP_Ethernet11; + case CoreMini::OP_Ethernet12: + return NetID::OP_Ethernet12; + case CoreMini::TCPVirtual: + return NetID::TCP; + case CoreMini::UDPVirtual: + return NetID::UDP; + case CoreMini::FlexRay1: + return NetID::FlexRay; + case CoreMini::FlexRay2: + return NetID::FlexRay2; + case CoreMini::ForwardedMessage: + return NetID::ForwardedMessage; + case CoreMini::I2C1: + return NetID::I2C; + case CoreMini::I2C2: + return NetID::I2C2; + case CoreMini::I2C3: + return NetID::I2C3; + case CoreMini::I2C4: + return NetID::I2C4; + case CoreMini::Ethernet2: + return NetID::Ethernet2; + } + return NetID::Invalid; // Should be unreachable, the compiler should warn about new CoreMini IDs + } + + Network() { setValue(NetID::Invalid); } + Network(neonetid_t netid) { setValue((NetID)netid); } + Network(NetID netid) { setValue(netid); } + Network(CoreMini cm) { setValue(GetNetIDFromCoreMiniNetwork(cm)); } + NetID getNetID() const { return value; } + Type getType() const { return type; } + optional getCoreMini() const { return GetCoreMiniNetworkFromNetID(getNetID()); } + friend std::ostream& operator<<(std::ostream& os, const Network& network) { + os << GetNetIDString(network.getNetID()); + return os; + } + friend bool operator==(const Network& net1, const Network& net2) { return net1.getNetID() == net2.getNetID(); } + friend bool operator!=(const Network& net1, const Network& net2) { return !(net1 == net2); } + +private: + NetID value; // Always use setValue so that value and type stay in sync + Type type; + void setValue(NetID id) { + value = id; + type = GetTypeOfNetID(value); + } +}; + +} + +#endif // __cplusplus + +#ifdef __ICSNEOC_H_ +#define ICSNEO_NETID_DEVICE 0 +#define ICSNEO_NETID_HSCAN 1 +#define ICSNEO_NETID_MSCAN 2 +#define ICSNEO_NETID_SWCAN 3 +#define ICSNEO_NETID_LSFTCAN 4 +#define ICSNEO_NETID_FORDSCP 5 +#define ICSNEO_NETID_J1708 6 +#define ICSNEO_NETID_AUX 7 +#define ICSNEO_NETID_J1850VPW 8 +#define ICSNEO_NETID_ISO9141 9 +#define ICSNEO_NETID_ISOPIC 10 +#define ICSNEO_NETID_MAIN51 11 +#define ICSNEO_NETID_RED 12 +#define ICSNEO_NETID_SCI 13 +#define ICSNEO_NETID_ISO9141_2 14 +#define ICSNEO_NETID_ISO14230 15 +#define ICSNEO_NETID_LIN 16 +#define ICSNEO_NETID_OP_ETHERNET1 17 +#define ICSNEO_NETID_OP_ETHERNET2 18 +#define ICSNEO_NETID_OP_ETHERNET3 19 + +// START Device Command Returns +// When we send a command, the device returns on one of these, depending on command +#define ICSNEO_NETID_RED_EXT_MEMORYREAD 20 +#define ICSNEO_NETID_RED_INT_MEMORYREAD 21 +#define ICSNEO_NETID_RED_DFLASH_READ 22 +#define ICSNEO_NETID_NEOMEMORY_SD_READ 23 +#define ICSNEO_NETID_CAN_ERRBITS 24 +#define ICSNEO_NETID_NEOMEMORY_WRITE_DONE 25 +#define ICSNEO_NETID_RED_WAVE_CAN1_LOGICAL 26 +#define ICSNEO_NETID_RED_WAVE_CAN2_LOGICAL 27 +#define ICSNEO_NETID_RED_WAVE_LIN1_LOGICAL 28 +#define ICSNEO_NETID_RED_WAVE_LIN2_LOGICAL 29 +#define ICSNEO_NETID_RED_WAVE_LIN1_ANALOG 30 +#define ICSNEO_NETID_RED_WAVE_LIN2_ANALOG 31 +#define ICSNEO_NETID_RED_WAVE_MISC_ANALOG 32 +#define ICSNEO_NETID_RED_WAVE_MISCDIO2_LOGICAL 33 +#define ICSNEO_NETID_RED_NETWORK_COM_ENABLE_EX 34 +#define ICSNEO_NETID_RED_NEOVI_NETWORK 35 +#define ICSNEO_NETID_RED_READ_BAUD_SETTINGS 36 +#define ICSNEO_NETID_RED_OLDFORMAT 37 +#define ICSNEO_NETID_RED_SCOPE_CAPTURE 38 +#define ICSNEO_NETID_RED_HARDWARE_EXCEP 39 +#define ICSNEO_NETID_RED_GET_RTC 40 +// END Device Command Returns + +#define ICSNEO_NETID_ISO9141_3 41 +#define ICSNEO_NETID_HSCAN2 42 +#define ICSNEO_NETID_HSCAN3 44 +#define ICSNEO_NETID_OP_ETHERNET4 45 +#define ICSNEO_NETID_OP_ETHERNET5 46 +#define ICSNEO_NETID_ISO9141_4 47 +#define ICSNEO_NETID_LIN2 48 +#define ICSNEO_NETID_LIN3 49 +#define ICSNEO_NETID_LIN4 50 +//#define ICSNEO_NETID_MOST 51 Old and unused +#define ICSNEO_NETID_RED_APP_ERROR 52 +#define ICSNEO_NETID_CGI 53 +#define ICSNEO_NETID_RESET_STATUS 54 +#define ICSNEO_NETID_FB_STATUS 55 +#define ICSNEO_NETID_APP_SIGNAL_STATUS 56 +#define ICSNEO_NETID_READ_DATALINK_CM_TX_MSG 57 +#define ICSNEO_NETID_READ_DATALINK_CM_RX_MSG 58 +#define ICSNEO_NETID_LOGGING_OVERFLOW 59 +#define ICSNEO_NETID_READ_SETTINGS 60 +#define ICSNEO_NETID_HSCAN4 61 +#define ICSNEO_NETID_HSCAN5 62 +#define ICSNEO_NETID_RS232 63 +#define ICSNEO_NETID_UART 64 +#define ICSNEO_NETID_UART2 65 +#define ICSNEO_NETID_UART3 66 +#define ICSNEO_NETID_UART4 67 +#define ICSNEO_NETID_SWCAN2 68 +#define ICSNEO_NETID_ETHERNET_DAQ 69 +#define ICSNEO_NETID_DATA_TO_HOST 70 +#define ICSNEO_NETID_TEXTAPI_TO_HOST 71 +#define ICSNEO_NETID_OP_ETHERNET6 73 +#define ICSNEO_NETID_RED_VBAT 74 +#define ICSNEO_NETID_OP_ETHERNET7 75 +#define ICSNEO_NETID_OP_ETHERNET8 76 +#define ICSNEO_NETID_OP_ETHERNET9 77 +#define ICSNEO_NETID_OP_ETHERNET10 78 +#define ICSNEO_NETID_OP_ETHERNET11 79 +#define ICSNEO_NETID_FLEXRAY1A 80 +#define ICSNEO_NETID_FLEXRAY1B 81 +#define ICSNEO_NETID_FLEXRAY2A 82 +#define ICSNEO_NETID_FLEXRAY2B 83 +#define ICSNEO_NETID_LIN5 84 +#define ICSNEO_NETID_FLEXRAY 85 +#define ICSNEO_NETID_FLEXRAY2 86 +#define ICSNEO_NETID_OP_ETHERNET12 87 +#define ICSNEO_NETID_I2C 88 +#define ICSNEO_NETID_MOST25 90 +#define ICSNEO_NETID_MOST50 91 +#define ICSNEO_NETID_MOST150 92 +#define ICSNEO_NETID_ETHERNET 93 +#define ICSNEO_NETID_GMFSA 94 +#define ICSNEO_NETID_TCP 95 +#define ICSNEO_NETID_HSCAN6 96 +#define ICSNEO_NETID_HSCAN7 97 +#define ICSNEO_NETID_LIN6 98 +#define ICSNEO_NETID_LSFTCAN2 99 +#define ICSNEO_NETID_LOGICAL_DISK_INFO 187 +#define ICSNEO_NETID_ETH_PHY_CONTROL 239 +#define ICSNEO_NETID_FLEXRAY_CONTROL 243 +#define ICSNEO_NETID_HW_COM_LATENCY_TEST 512 +#define ICSNEO_NETID_DEVICE_STATUS 513 +#define ICSNEO_NETID_UDP 514 +#define ICSNEO_NETID_FORWARDED_MESSAGE 516 +#define ICSNEO_NETID_I2C2 517 +#define ICSNEO_NETID_I2C3 518 +#define ICSNEO_NETID_I2C4 519 +#define ICSNEO_NETID_ETHERNET2 520 +#define ICSNEO_NETID_ANY 0xfffe // Never actually set as type, but used as flag for filtering +#define ICSNEO_NETID_INVALID 0xffff + +#define ICSNEO_NETWORK_TYPE_INVALID 0 +#define ICSNEO_NETWORK_TYPE_INTERNAL 1 // Used for statuses that don't actually need to be transferred to the client application +#define ICSNEO_NETWORK_TYPE_CAN 2 +#define ICSNEO_NETWORK_TYPE_LIN 3 +#define ICSNEO_NETWORK_TYPE_FLEXRAY 4 +#define ICSNEO_NETWORK_TYPE_MOST 5 +#define ICSNEO_NETWORK_TYPE_ETHERNET 6 +#define ICSNEO_NETWORK_TYPE_LSFTCAN 7 +#define ICSNEO_NETWORK_TYPE_SWCAN 8 +#define ICSNEO_NETWORK_TYPE_ISO9141 9 +#define ICSNEO_NETWORK_TYPE_I2C 10 +#define ICSNEO_NETWORK_TYPE_ANY 0xFE // Never actually set as type, but used as flag for filtering +#define ICSNEO_NETWORK_TYPE_OTHER 0xFF +#endif + #endif \ No newline at end of file diff --git a/include/icsneo/device/devicefinder.h b/include/icsneo/device/devicefinder.h index e4cea32..a5c0d4d 100644 --- a/include/icsneo/device/devicefinder.h +++ b/include/icsneo/device/devicefinder.h @@ -1,23 +1,23 @@ -#ifndef __DEVICEFINDER_H_ -#define __DEVICEFINDER_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" -#include -#include - -namespace icsneo { - -class DeviceFinder { -public: - static std::vector> FindAll(); - static const std::vector& GetSupportedDevices(); -}; - -} - -#endif // __cplusplus - +#ifndef __DEVICEFINDER_H_ +#define __DEVICEFINDER_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include +#include + +namespace icsneo { + +class DeviceFinder { +public: + static std::vector> FindAll(); + static const std::vector& GetSupportedDevices(); +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/radmoon2/radmoon2.h b/include/icsneo/device/tree/radmoon2/radmoon2.h index e996ed9..94f70c8 100644 --- a/include/icsneo/device/tree/radmoon2/radmoon2.h +++ b/include/icsneo/device/tree/radmoon2/radmoon2.h @@ -1,90 +1,90 @@ -#ifndef __RADMOON2_H_ -#define __RADMOON2_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" -#include "icsneo/device/tree/radmoon2/radmoon2settings.h" - -namespace icsneo { - -class RADMoon2 : public Device { -public: - // Serial numbers start with RM - // USB PID is 0x1202, standard driver is FTDI3 - ICSNEO_FINDABLE_DEVICE(RADMoon2, DeviceType::RADMoon2, "RM"); - - enum class SKU { - Standard, - APM1000E, // Keysight Branding - APM1000E_CLK, // Clock Option and Keysight Branding - }; - - SKU getSKU() const { - switch(getSerial().back()) { - case 'A': - case 'B': - return SKU::APM1000E; - case 'C': - case 'D': - return SKU::APM1000E_CLK; - default: - return SKU::Standard; - } - } - - std::string getProductName() const override { - switch(getSKU()) { - case SKU::Standard: break; - case SKU::APM1000E: - return "Keysight APM1000E"; - case SKU::APM1000E_CLK: - return "Keysight APM1000E-CLK"; - } - return Device::getProductName(); - } - - // RADMoon 2 does not go online, you can only set settings and - // view PHY information (when supported) - bool goOnline() override { - report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); - return false; - } - - bool goOffline() override { - report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); - return false; - } - - bool getEthPhyRegControlSupported() const override { return true; } - -protected: - RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { - initialize(makeDriver); - } - - void setupPacketizer(Packetizer& packetizer) override { - Device::setupPacketizer(packetizer); - packetizer.disableChecksum = true; - packetizer.align16bit = false; - } - - virtual void setupEncoder(Encoder& encoder) override { - Device::setupEncoder(encoder); - encoder.supportEthPhy = true; - } - - void setupDecoder(Decoder& decoder) override { - Device::setupDecoder(decoder); - decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns - } - - bool requiresVehiclePower() const override { return false; } -}; - -} - -#endif // __cplusplus - +#ifndef __RADMOON2_H_ +#define __RADMOON2_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include "icsneo/device/tree/radmoon2/radmoon2settings.h" + +namespace icsneo { + +class RADMoon2 : public Device { +public: + // Serial numbers start with RM + // USB PID is 0x1202, standard driver is FTDI3 + ICSNEO_FINDABLE_DEVICE(RADMoon2, DeviceType::RADMoon2, "RM"); + + enum class SKU { + Standard, + APM1000E, // Keysight Branding + APM1000E_CLK, // Clock Option and Keysight Branding + }; + + SKU getSKU() const { + switch(getSerial().back()) { + case 'A': + case 'B': + return SKU::APM1000E; + case 'C': + case 'D': + return SKU::APM1000E_CLK; + default: + return SKU::Standard; + } + } + + std::string getProductName() const override { + switch(getSKU()) { + case SKU::Standard: break; + case SKU::APM1000E: + return "Keysight APM1000E"; + case SKU::APM1000E_CLK: + return "Keysight APM1000E-CLK"; + } + return Device::getProductName(); + } + + // RADMoon 2 does not go online, you can only set settings and + // view PHY information (when supported) + bool goOnline() override { + report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); + return false; + } + + bool goOffline() override { + report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); + return false; + } + + bool getEthPhyRegControlSupported() const override { return true; } + +protected: + RADMoon2(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { + initialize(makeDriver); + } + + void setupPacketizer(Packetizer& packetizer) override { + Device::setupPacketizer(packetizer); + packetizer.disableChecksum = true; + packetizer.align16bit = false; + } + + virtual void setupEncoder(Encoder& encoder) override { + Device::setupEncoder(encoder); + encoder.supportEthPhy = true; + } + + void setupDecoder(Decoder& decoder) override { + Device::setupDecoder(decoder); + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns + } + + bool requiresVehiclePower() const override { return false; } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/radmoonduo/radmoonduo.h b/include/icsneo/device/tree/radmoonduo/radmoonduo.h index cfe7d84..3466cb3 100644 --- a/include/icsneo/device/tree/radmoonduo/radmoonduo.h +++ b/include/icsneo/device/tree/radmoonduo/radmoonduo.h @@ -1,54 +1,54 @@ -#ifndef __RADMOONDUO_H_ -#define __RADMOONDUO_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" -#include "icsneo/device/tree/radmoonduo/radmoonduosettings.h" - -namespace icsneo { - -class RADMoonDuo : public Device { -public: - // Serial numbers start with MD - // USB PID is 1106, standard driver is CDCACM - ICSNEO_FINDABLE_DEVICE(RADMoonDuo, DeviceType::RADMoonDuo, "MD"); - - static const std::vector& GetSupportedNetworks() { - // If Converter1 Target is set to USB/CM, OP_Ethernet2 will be exposed to the PC - static std::vector supportedNetworks = { - Network::NetID::OP_Ethernet2 - }; - return supportedNetworks; - } - - bool getEthPhyRegControlSupported() const override { return true; } - -protected: - RADMoonDuo(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { - initialize(makeDriver); - } - - virtual void setupEncoder(Encoder& encoder) override { - Device::setupEncoder(encoder); - encoder.supportEthPhy = true; - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } - - bool requiresVehiclePower() const override { return false; } - -}; - -} - -#endif // __cplusplus - +#ifndef __RADMOONDUO_H_ +#define __RADMOONDUO_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include "icsneo/device/tree/radmoonduo/radmoonduosettings.h" + +namespace icsneo { + +class RADMoonDuo : public Device { +public: + // Serial numbers start with MD + // USB PID is 1106, standard driver is CDCACM + ICSNEO_FINDABLE_DEVICE(RADMoonDuo, DeviceType::RADMoonDuo, "MD"); + + static const std::vector& GetSupportedNetworks() { + // If Converter1 Target is set to USB/CM, OP_Ethernet2 will be exposed to the PC + static std::vector supportedNetworks = { + Network::NetID::OP_Ethernet2 + }; + return supportedNetworks; + } + + bool getEthPhyRegControlSupported() const override { return true; } + +protected: + RADMoonDuo(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { + initialize(makeDriver); + } + + virtual void setupEncoder(Encoder& encoder) override { + Device::setupEncoder(encoder); + encoder.supportEthPhy = true; + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + bool requiresVehiclePower() const override { return false; } + +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/radsupermoon/radsupermoon.h b/include/icsneo/device/tree/radsupermoon/radsupermoon.h index f85e55e..d905f42 100644 --- a/include/icsneo/device/tree/radsupermoon/radsupermoon.h +++ b/include/icsneo/device/tree/radsupermoon/radsupermoon.h @@ -1,88 +1,88 @@ -#ifndef __RADSUPERMOON_H_ -#define __RADSUPERMOON_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" -#include "icsneo/device/tree/radsupermoon/radsupermoonsettings.h" - -namespace icsneo { - -class RADSupermoon : public Device { -public: - // Serial numbers start with SM - // USB PID is 0x1201, standard driver is FTDI3 - ICSNEO_FINDABLE_DEVICE(RADSupermoon, DeviceType::RADSupermoon, "SM"); - - enum class SKU { - Standard, - APM1000ET, // Keysight Branding - }; - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::Ethernet, - Network::NetID::OP_Ethernet1, - Network::NetID::OP_Ethernet2 - }; - return supportedNetworks; - } - - SKU getSKU() const { - switch(getSerial().back()) { - case 'A': - return SKU::APM1000ET; - default: - return SKU::Standard; - } - } - - std::string getProductName() const override { - switch(getSKU()) { - case SKU::Standard: break; - case SKU::APM1000ET: - return "Keysight APM1000ET"; - } - return Device::getProductName(); - } - - bool getEthPhyRegControlSupported() const override { return true; } - -protected: - RADSupermoon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { - initialize(makeDriver); - } - - void setupPacketizer(Packetizer& packetizer) override { - Device::setupPacketizer(packetizer); - packetizer.disableChecksum = true; - packetizer.align16bit = false; - } - - virtual void setupEncoder(Encoder& encoder) override { - Device::setupEncoder(encoder); - encoder.supportEthPhy = true; - } - - void setupDecoder(Decoder& decoder) override { - Device::setupDecoder(decoder); - decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } - - bool requiresVehiclePower() const override { return false; } -}; - -} - -#endif // __cplusplus - +#ifndef __RADSUPERMOON_H_ +#define __RADSUPERMOON_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include "icsneo/device/tree/radsupermoon/radsupermoonsettings.h" + +namespace icsneo { + +class RADSupermoon : public Device { +public: + // Serial numbers start with SM + // USB PID is 0x1201, standard driver is FTDI3 + ICSNEO_FINDABLE_DEVICE(RADSupermoon, DeviceType::RADSupermoon, "SM"); + + enum class SKU { + Standard, + APM1000ET, // Keysight Branding + }; + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::Ethernet, + Network::NetID::OP_Ethernet1, + Network::NetID::OP_Ethernet2 + }; + return supportedNetworks; + } + + SKU getSKU() const { + switch(getSerial().back()) { + case 'A': + return SKU::APM1000ET; + default: + return SKU::Standard; + } + } + + std::string getProductName() const override { + switch(getSKU()) { + case SKU::Standard: break; + case SKU::APM1000ET: + return "Keysight APM1000ET"; + } + return Device::getProductName(); + } + + bool getEthPhyRegControlSupported() const override { return true; } + +protected: + RADSupermoon(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { + initialize(makeDriver); + } + + void setupPacketizer(Packetizer& packetizer) override { + Device::setupPacketizer(packetizer); + packetizer.disableChecksum = true; + packetizer.align16bit = false; + } + + virtual void setupEncoder(Encoder& encoder) override { + Device::setupEncoder(encoder); + encoder.supportEthPhy = true; + } + + void setupDecoder(Decoder& decoder) override { + Device::setupDecoder(decoder); + decoder.timestampResolution = 10; // Timestamps are in 10ns increments instead of the usual 25ns + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + bool requiresVehiclePower() const override { return false; } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan3/valuecan3.h b/include/icsneo/device/tree/valuecan3/valuecan3.h index 3d58fbd..750f3d4 100644 --- a/include/icsneo/device/tree/valuecan3/valuecan3.h +++ b/include/icsneo/device/tree/valuecan3/valuecan3.h @@ -1,46 +1,46 @@ -#ifndef __VALUECAN3_H_ -#define __VALUECAN3_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" -#include "icsneo/platform/ftdi.h" -#include "icsneo/device/tree/valuecan3/valuecan3settings.h" - -namespace icsneo { - -class ValueCAN3 : public Device { -public: - // USB PID is 0x0601, standard driver is FTDI - ICSNEO_FINDABLE_DEVICE_BY_PID(ValueCAN3, DeviceType::VCAN3, 0x0701); - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::HSCAN, - Network::NetID::MSCAN - }; - return supportedNetworks; - } - -private: - ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { - initialize(makeDriver); - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } - - bool requiresVehiclePower() const override { return false; } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN3_H_ +#define __VALUECAN3_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include "icsneo/platform/ftdi.h" +#include "icsneo/device/tree/valuecan3/valuecan3settings.h" + +namespace icsneo { + +class ValueCAN3 : public Device { +public: + // USB PID is 0x0601, standard driver is FTDI + ICSNEO_FINDABLE_DEVICE_BY_PID(ValueCAN3, DeviceType::VCAN3, 0x0701); + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::MSCAN + }; + return supportedNetworks; + } + +private: + ValueCAN3(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { + initialize(makeDriver); + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + bool requiresVehiclePower() const override { return false; } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-1.h b/include/icsneo/device/tree/valuecan4/valuecan4-1.h index 8a89b89..713e391 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-1.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-1.h @@ -1,47 +1,47 @@ -#ifndef __VALUECAN4_1_H_ -#define __VALUECAN4_1_H_ - -#ifdef __cplusplus - -#include "icsneo/device/tree/valuecan4/valuecan4.h" -#include "icsneo/device/tree/valuecan4/settings/valuecan4-1settings.h" - -namespace icsneo { - -class ValueCAN4_1 : public ValueCAN4 { -public: - // Serial numbers start with V1 for 4-1 - // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM - ICSNEO_FINDABLE_DEVICE(ValueCAN4_1, DeviceType::VCAN4_1, "V1"); - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::HSCAN - }; - return supportedNetworks; - } - -protected: - ValueCAN4_1(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { - initialize(makeDriver); - } - - void setupEncoder(Encoder& encoder) override { - ValueCAN4::setupEncoder(encoder); - encoder.supportCANFD = false; // VCAN 4-1 does not support CAN FD - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN4_1_H_ +#define __VALUECAN4_1_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4-1settings.h" + +namespace icsneo { + +class ValueCAN4_1 : public ValueCAN4 { +public: + // Serial numbers start with V1 for 4-1 + // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM + ICSNEO_FINDABLE_DEVICE(ValueCAN4_1, DeviceType::VCAN4_1, "V1"); + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN + }; + return supportedNetworks; + } + +protected: + ValueCAN4_1(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { + initialize(makeDriver); + } + + void setupEncoder(Encoder& encoder) override { + ValueCAN4::setupEncoder(encoder); + encoder.supportCANFD = false; // VCAN 4-1 does not support CAN FD + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-2.h b/include/icsneo/device/tree/valuecan4/valuecan4-2.h index c2a062e..c3a29c2 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-2.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-2.h @@ -1,67 +1,67 @@ -#ifndef __VALUECAN4_2_H_ -#define __VALUECAN4_2_H_ - -#ifdef __cplusplus - -#include "icsneo/device/tree/valuecan4/valuecan4.h" -#include "icsneo/device/tree/valuecan4/settings/valuecan4-2settings.h" - -namespace icsneo { - -class ValueCAN4_2 : public ValueCAN4 { -public: - // Serial numbers start with V2 for 4-2 - // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM - ICSNEO_FINDABLE_DEVICE(ValueCAN4_2, DeviceType::VCAN4_2, "V2"); - - enum class SKU { - Standard, - AP0200A, // USB A and Keysight Branding - }; - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::HSCAN, - Network::NetID::HSCAN2 - }; - return supportedNetworks; - } - - SKU getSKU() const { - switch(getSerial().back()) { - case 'A': - case 'B': - return SKU::AP0200A; - default: - return SKU::Standard; - } - } - - std::string getProductName() const override { - switch(getSKU()) { - case SKU::Standard: break; - case SKU::AP0200A: - return "Keysight AP0200A"; - } - return Device::getProductName(); - } - -protected: - ValueCAN4_2(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { - initialize(makeDriver); - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN4_2_H_ +#define __VALUECAN4_2_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4-2settings.h" + +namespace icsneo { + +class ValueCAN4_2 : public ValueCAN4 { +public: + // Serial numbers start with V2 for 4-2 + // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM + ICSNEO_FINDABLE_DEVICE(ValueCAN4_2, DeviceType::VCAN4_2, "V2"); + + enum class SKU { + Standard, + AP0200A, // USB A and Keysight Branding + }; + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2 + }; + return supportedNetworks; + } + + SKU getSKU() const { + switch(getSerial().back()) { + case 'A': + case 'B': + return SKU::AP0200A; + default: + return SKU::Standard; + } + } + + std::string getProductName() const override { + switch(getSKU()) { + case SKU::Standard: break; + case SKU::AP0200A: + return "Keysight AP0200A"; + } + return Device::getProductName(); + } + +protected: + ValueCAN4_2(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { + initialize(makeDriver); + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-2el.h b/include/icsneo/device/tree/valuecan4/valuecan4-2el.h index c4eec65..0bda55b 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-2el.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-2el.h @@ -1,98 +1,98 @@ -#ifndef __VALUECAN4_2EL_H_ -#define __VALUECAN4_2EL_H_ - -#ifdef __cplusplus - -#include "icsneo/device/tree/valuecan4/valuecan4.h" -#include "icsneo/device/tree/valuecan4/settings/valuecan4-2elsettings.h" - -namespace icsneo { - -class ValueCAN4_2EL : public ValueCAN4 { -public: - // Serial numbers start with VE for 4-2EL - // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM - // Ethernet MAC allocation is 0x0B, standard driver is Raw - ICSNEO_FINDABLE_DEVICE(ValueCAN4_2EL, DeviceType::VCAN4_2EL, "VE"); - - enum class SKU { - Standard, - AP04E0A_D26, // HDB26, USB A, and Keysight Branding - AP04E0A_MUL, // Multi-connectors, USB A, and Keysight Branding - AP04E0A_OBD, // OBD, USB A, and Keysight Branding - }; - - SKU getSKU() const { - switch(getSerial().back()) { - case 'A': - return SKU::AP04E0A_D26; - case 'B': - return SKU::AP04E0A_MUL; - case 'C': - return SKU::AP04E0A_OBD; - default: - return SKU::Standard; - } - } - - std::string getProductName() const override { - switch(getSKU()) { - case SKU::Standard: break; - case SKU::AP04E0A_D26: - return "Keysight AP04E0A-D26"; - case SKU::AP04E0A_MUL: - return "Keysight AP04E0A-MUL"; - case SKU::AP04E0A_OBD: - return "Keysight AP04E0A-OBD"; - } - return Device::getProductName(); - } - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::HSCAN, - Network::NetID::HSCAN2, - - Network::NetID::Ethernet, - - Network::NetID::LIN - }; - return supportedNetworks; - } - -protected: - ValueCAN4_2EL(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { - initialize(makeDriver); - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } - - size_t getEthernetActivationLineCount() const override { return 1; } - - void handleDeviceStatus(const std::shared_ptr& message) override { - if(message->data.size() < sizeof(valuecan4_2el_status_t)) - return; - std::lock_guard lk(ioMutex); - const valuecan4_2el_status_t* status = reinterpret_cast(message->data.data()); - ethActivationStatus = status->ethernetActivationLineEnabled; - } - - bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); } - - void setupPacketizer(Packetizer& packetizer) override { - ValueCAN4::setupPacketizer(packetizer); - packetizer.align16bit = !com->driver->isEthernet(); - } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN4_2EL_H_ +#define __VALUECAN4_2EL_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4-2elsettings.h" + +namespace icsneo { + +class ValueCAN4_2EL : public ValueCAN4 { +public: + // Serial numbers start with VE for 4-2EL + // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM + // Ethernet MAC allocation is 0x0B, standard driver is Raw + ICSNEO_FINDABLE_DEVICE(ValueCAN4_2EL, DeviceType::VCAN4_2EL, "VE"); + + enum class SKU { + Standard, + AP04E0A_D26, // HDB26, USB A, and Keysight Branding + AP04E0A_MUL, // Multi-connectors, USB A, and Keysight Branding + AP04E0A_OBD, // OBD, USB A, and Keysight Branding + }; + + SKU getSKU() const { + switch(getSerial().back()) { + case 'A': + return SKU::AP04E0A_D26; + case 'B': + return SKU::AP04E0A_MUL; + case 'C': + return SKU::AP04E0A_OBD; + default: + return SKU::Standard; + } + } + + std::string getProductName() const override { + switch(getSKU()) { + case SKU::Standard: break; + case SKU::AP04E0A_D26: + return "Keysight AP04E0A-D26"; + case SKU::AP04E0A_MUL: + return "Keysight AP04E0A-MUL"; + case SKU::AP04E0A_OBD: + return "Keysight AP04E0A-OBD"; + } + return Device::getProductName(); + } + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2, + + Network::NetID::Ethernet, + + Network::NetID::LIN + }; + return supportedNetworks; + } + +protected: + ValueCAN4_2EL(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { + initialize(makeDriver); + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + size_t getEthernetActivationLineCount() const override { return 1; } + + void handleDeviceStatus(const std::shared_ptr& message) override { + if(message->data.size() < sizeof(valuecan4_2el_status_t)) + return; + std::lock_guard lk(ioMutex); + const valuecan4_2el_status_t* status = reinterpret_cast(message->data.data()); + ethActivationStatus = status->ethernetActivationLineEnabled; + } + + bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); } + + void setupPacketizer(Packetizer& packetizer) override { + ValueCAN4::setupPacketizer(packetizer); + packetizer.align16bit = !com->driver->isEthernet(); + } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4-4.h b/include/icsneo/device/tree/valuecan4/valuecan4-4.h index ee0e920..1e7da19 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4-4.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4-4.h @@ -1,78 +1,78 @@ -#ifndef __VALUECAN4_4_H_ -#define __VALUECAN4_4_H_ - -#ifdef __cplusplus - -#include "icsneo/device/tree/valuecan4/valuecan4.h" -#include "icsneo/device/tree/valuecan4/settings/valuecan4-4settings.h" - -namespace icsneo { - -class ValueCAN4_4 : public ValueCAN4 { -public: - // Serial numbers start with V4 for 4-4 - // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM - ICSNEO_FINDABLE_DEVICE(ValueCAN4_4, DeviceType::VCAN4_4, "V4"); - - enum class SKU { - Standard, - AP0400A_D26, // HDB26, USB A, and Keysight Branding - AP0400A_DB9, // 4xDB9, USB A, and Keysight Branding - AP0400A_OBD, // OBD, USB A, and Keysight Branding - }; - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::HSCAN, - Network::NetID::HSCAN2, - Network::NetID::HSCAN3, - Network::NetID::HSCAN4 - }; - return supportedNetworks; - } - - SKU getSKU() const { - switch(getSerial().back()) { - case 'A': - return SKU::AP0400A_D26; - case 'B': - return SKU::AP0400A_DB9; - case 'C': - return SKU::AP0400A_OBD; - default: - return SKU::Standard; - } - } - - std::string getProductName() const override { - switch(getSKU()) { - case SKU::Standard: break; - case SKU::AP0400A_D26: - return "Keysight AP0400A-D26"; - case SKU::AP0400A_DB9: - return "Keysight AP0400A-DB9"; - case SKU::AP0400A_OBD: - return "Keysight AP0400A-OBD"; - } - return Device::getProductName(); - } - -protected: - ValueCAN4_4(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { - initialize(makeDriver); - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN4_4_H_ +#define __VALUECAN4_4_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4-4settings.h" + +namespace icsneo { + +class ValueCAN4_4 : public ValueCAN4 { +public: + // Serial numbers start with V4 for 4-4 + // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM + ICSNEO_FINDABLE_DEVICE(ValueCAN4_4, DeviceType::VCAN4_4, "V4"); + + enum class SKU { + Standard, + AP0400A_D26, // HDB26, USB A, and Keysight Branding + AP0400A_DB9, // 4xDB9, USB A, and Keysight Branding + AP0400A_OBD, // OBD, USB A, and Keysight Branding + }; + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2, + Network::NetID::HSCAN3, + Network::NetID::HSCAN4 + }; + return supportedNetworks; + } + + SKU getSKU() const { + switch(getSerial().back()) { + case 'A': + return SKU::AP0400A_D26; + case 'B': + return SKU::AP0400A_DB9; + case 'C': + return SKU::AP0400A_OBD; + default: + return SKU::Standard; + } + } + + std::string getProductName() const override { + switch(getSKU()) { + case SKU::Standard: break; + case SKU::AP0400A_D26: + return "Keysight AP0400A-D26"; + case SKU::AP0400A_DB9: + return "Keysight AP0400A-DB9"; + case SKU::AP0400A_OBD: + return "Keysight AP0400A-OBD"; + } + return Device::getProductName(); + } + +protected: + ValueCAN4_4(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { + initialize(makeDriver); + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4.h b/include/icsneo/device/tree/valuecan4/valuecan4.h index d17520a..2d19a45 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4.h @@ -1,30 +1,30 @@ -#ifndef __VALUECAN4_H_ -#define __VALUECAN4_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" - -namespace icsneo { - -class ValueCAN4 : public Device { -public: - // All ValueCAN 4 devices share a USB PID of 0x1101 - -protected: - using Device::Device; - - virtual void setupEncoder(Encoder& encoder) override { - Device::setupEncoder(encoder); - encoder.supportCANFD = true; - } - - bool requiresVehiclePower() const override { return false; } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN4_H_ +#define __VALUECAN4_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" + +namespace icsneo { + +class ValueCAN4 : public Device { +public: + // All ValueCAN 4 devices share a USB PID of 0x1101 + +protected: + using Device::Device; + + virtual void setupEncoder(Encoder& encoder) override { + Device::setupEncoder(encoder); + encoder.supportCANFD = true; + } + + bool requiresVehiclePower() const override { return false; } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/valuecan4/valuecan4industrial.h b/include/icsneo/device/tree/valuecan4/valuecan4industrial.h index dc6288b..d906f58 100644 --- a/include/icsneo/device/tree/valuecan4/valuecan4industrial.h +++ b/include/icsneo/device/tree/valuecan4/valuecan4industrial.h @@ -1,55 +1,55 @@ -#ifndef __VALUECAN4INDUSTRIAL_H_ -#define __VALUECAN4INDUSTRIAL_H_ - -#ifdef __cplusplus - -#include "icsneo/device/tree/valuecan4/valuecan4.h" -#include "icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h" - -namespace icsneo { - -class ValueCAN4Industrial : public ValueCAN4 { -public: - // Serial numbers start with IV for Industrial - // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM - // Ethernet MAC allocation is 0x12, standard driver is Raw - ICSNEO_FINDABLE_DEVICE(ValueCAN4Industrial, DeviceType::VCAN4_IND, "IV"); - - static const std::vector& GetSupportedNetworks() { - static std::vector supportedNetworks = { - Network::NetID::HSCAN, - Network::NetID::HSCAN2, - - Network::NetID::Ethernet, - - Network::NetID::LIN - }; - return supportedNetworks; - } - -protected: - ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { - initialize(makeDriver); - } - - void setupSupportedRXNetworks(std::vector& rxNetworks) override { - for(auto& netid : GetSupportedNetworks()) - rxNetworks.emplace_back(netid); - } - - // The supported TX networks are the same as the supported RX networks for this device - void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } - - bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); } - - void setupPacketizer(Packetizer& packetizer) override { - ValueCAN4::setupPacketizer(packetizer); - packetizer.align16bit = !com->driver->isEthernet(); - } -}; - -} - -#endif // __cplusplus - +#ifndef __VALUECAN4INDUSTRIAL_H_ +#define __VALUECAN4INDUSTRIAL_H_ + +#ifdef __cplusplus + +#include "icsneo/device/tree/valuecan4/valuecan4.h" +#include "icsneo/device/tree/valuecan4/settings/valuecan4industrialsettings.h" + +namespace icsneo { + +class ValueCAN4Industrial : public ValueCAN4 { +public: + // Serial numbers start with IV for Industrial + // USB PID is 0x1101 (shared by all ValueCAN 4s), standard driver is CDCACM + // Ethernet MAC allocation is 0x12, standard driver is Raw + ICSNEO_FINDABLE_DEVICE(ValueCAN4Industrial, DeviceType::VCAN4_IND, "IV"); + + static const std::vector& GetSupportedNetworks() { + static std::vector supportedNetworks = { + Network::NetID::HSCAN, + Network::NetID::HSCAN2, + + Network::NetID::Ethernet, + + Network::NetID::LIN + }; + return supportedNetworks; + } + +protected: + ValueCAN4Industrial(neodevice_t neodevice, const driver_factory_t& makeDriver) : ValueCAN4(neodevice) { + initialize(makeDriver); + } + + void setupSupportedRXNetworks(std::vector& rxNetworks) override { + for(auto& netid : GetSupportedNetworks()) + rxNetworks.emplace_back(netid); + } + + // The supported TX networks are the same as the supported RX networks for this device + void setupSupportedTXNetworks(std::vector& txNetworks) override { setupSupportedRXNetworks(txNetworks); } + + bool currentDriverSupportsDFU() const override { return com->driver->isEthernet(); } + + void setupPacketizer(Packetizer& packetizer) override { + ValueCAN4::setupPacketizer(packetizer); + packetizer.align16bit = !com->driver->isEthernet(); + } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/device/tree/vividcan/vividcan.h b/include/icsneo/device/tree/vividcan/vividcan.h index 9e6a636..03db1fb 100644 --- a/include/icsneo/device/tree/vividcan/vividcan.h +++ b/include/icsneo/device/tree/vividcan/vividcan.h @@ -1,42 +1,42 @@ -#ifndef __VIVIDCAN_H_ -#define __VIVIDCAN_H_ - -#ifdef __cplusplus - -#include "icsneo/device/device.h" -#include "icsneo/device/devicetype.h" -#include "icsneo/platform/cdcacm.h" -#include "icsneo/device/tree/vividcan/vividcansettings.h" - -namespace icsneo { - -class VividCAN : public Device { -public: - // Serial numbers start with VV - // USB PID is 0x1102, standard driver is CDCACM - ICSNEO_FINDABLE_DEVICE(VividCAN, DeviceType::VividCAN, "VV"); - - // VividCAN does not go online, you can only set settings - bool goOnline() override { - report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); - return false; - } - - bool goOffline() override { - report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); - return false; - } - -protected: - VividCAN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { - initialize(makeDriver); - } - - bool requiresVehiclePower() const override { return false; } -}; - -} - -#endif // __cplusplus - +#ifndef __VIVIDCAN_H_ +#define __VIVIDCAN_H_ + +#ifdef __cplusplus + +#include "icsneo/device/device.h" +#include "icsneo/device/devicetype.h" +#include "icsneo/platform/cdcacm.h" +#include "icsneo/device/tree/vividcan/vividcansettings.h" + +namespace icsneo { + +class VividCAN : public Device { +public: + // Serial numbers start with VV + // USB PID is 0x1102, standard driver is CDCACM + ICSNEO_FINDABLE_DEVICE(VividCAN, DeviceType::VividCAN, "VV"); + + // VividCAN does not go online, you can only set settings + bool goOnline() override { + report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); + return false; + } + + bool goOffline() override { + report(APIEvent::Type::OnlineNotSupported, APIEvent::Severity::Error); + return false; + } + +protected: + VividCAN(neodevice_t neodevice, const driver_factory_t& makeDriver) : Device(neodevice) { + initialize(makeDriver); + } + + bool requiresVehiclePower() const override { return false; } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/icsneocpp.h b/include/icsneo/icsneocpp.h index b30f895..ed5636f 100644 --- a/include/icsneo/icsneocpp.h +++ b/include/icsneo/icsneocpp.h @@ -1,39 +1,39 @@ -#ifndef __ICSNEOCPP_H_ -#define __ICSNEOCPP_H_ - -#ifdef __cplusplus - -#include -#include - -#include "icsneo/device/device.h" -#include "icsneo/api/version.h" -#include "icsneo/api/eventmanager.h" - -#include "icsneo/communication/message/canmessage.h" -#include "icsneo/communication/message/ethernetmessage.h" -#include "icsneo/communication/message/flexray/flexraymessage.h" -#include "icsneo/communication/message/iso9141message.h" -#include "icsneo/communication/message/canerrorcountmessage.h" -#include "icsneo/communication/message/ethphymessage.h" - -namespace icsneo { - -std::vector> FindAllDevices(); -std::vector GetSupportedDevices(); - -size_t EventCount(EventFilter filter = EventFilter()); -std::vector GetEvents(EventFilter filter, size_t max = 0); -std::vector GetEvents(size_t max = 0, EventFilter filter = EventFilter()); -void GetEvents(std::vector& events, EventFilter filter, size_t max = 0); -void GetEvents(std::vector& events, size_t max = 0, EventFilter filter = EventFilter()); -APIEvent GetLastError(); -void DiscardEvents(EventFilter filter = EventFilter()); -void SetEventLimit(size_t newLimit); -size_t GetEventLimit(); - -} - -#endif // __cplusplus - +#ifndef __ICSNEOCPP_H_ +#define __ICSNEOCPP_H_ + +#ifdef __cplusplus + +#include +#include + +#include "icsneo/device/device.h" +#include "icsneo/api/version.h" +#include "icsneo/api/eventmanager.h" + +#include "icsneo/communication/message/canmessage.h" +#include "icsneo/communication/message/ethernetmessage.h" +#include "icsneo/communication/message/flexray/flexraymessage.h" +#include "icsneo/communication/message/iso9141message.h" +#include "icsneo/communication/message/canerrorcountmessage.h" +#include "icsneo/communication/message/ethphymessage.h" + +namespace icsneo { + +std::vector> FindAllDevices(); +std::vector GetSupportedDevices(); + +size_t EventCount(EventFilter filter = EventFilter()); +std::vector GetEvents(EventFilter filter, size_t max = 0); +std::vector GetEvents(size_t max = 0, EventFilter filter = EventFilter()); +void GetEvents(std::vector& events, EventFilter filter, size_t max = 0); +void GetEvents(std::vector& events, size_t max = 0, EventFilter filter = EventFilter()); +APIEvent GetLastError(); +void DiscardEvents(EventFilter filter = EventFilter()); +void SetEventLimit(size_t newLimit); +size_t GetEventLimit(); + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/platform/cdcacm.h b/include/icsneo/platform/cdcacm.h index e898fc8..addab1a 100644 --- a/include/icsneo/platform/cdcacm.h +++ b/include/icsneo/platform/cdcacm.h @@ -1,14 +1,14 @@ -#ifndef __CDCACM_H_ -#define __CDCACM_H_ - -#define INTREPID_USB_VENDOR_ID (0x093c) - -#if defined _WIN32 -#include "icsneo/platform/windows/cdcacm.h" -#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) -#include "icsneo/platform/posix/cdcacm.h" -#else -#warning "This platform is not supported by the CDC ACM driver" -#endif - +#ifndef __CDCACM_H_ +#define __CDCACM_H_ + +#define INTREPID_USB_VENDOR_ID (0x093c) + +#if defined _WIN32 +#include "icsneo/platform/windows/cdcacm.h" +#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) +#include "icsneo/platform/posix/cdcacm.h" +#else +#warning "This platform is not supported by the CDC ACM driver" +#endif + #endif \ No newline at end of file diff --git a/include/icsneo/platform/dynamiclib.h b/include/icsneo/platform/dynamiclib.h index 4f79b86..5a4e5ca 100644 --- a/include/icsneo/platform/dynamiclib.h +++ b/include/icsneo/platform/dynamiclib.h @@ -1,12 +1,12 @@ -#ifndef __DYNAMICLIB_H_ -#define __DYNAMICLIB_H_ - -#if defined _WIN32 -#include "icsneo/platform/windows/dynamiclib.h" -#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) -#include "icsneo/platform/posix/dynamiclib.h" -#else -#warning "This platform is not supported by the dynamic library driver" -#endif - +#ifndef __DYNAMICLIB_H_ +#define __DYNAMICLIB_H_ + +#if defined _WIN32 +#include "icsneo/platform/windows/dynamiclib.h" +#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) +#include "icsneo/platform/posix/dynamiclib.h" +#else +#warning "This platform is not supported by the dynamic library driver" +#endif + #endif \ No newline at end of file diff --git a/include/icsneo/platform/ftdi.h b/include/icsneo/platform/ftdi.h index e8a2669..b44a661 100644 --- a/include/icsneo/platform/ftdi.h +++ b/include/icsneo/platform/ftdi.h @@ -1,14 +1,14 @@ -#ifndef __FTDI_H_ -#define __FTDI_H_ - -#define INTREPID_USB_VENDOR_ID (0x093c) - -#if defined _WIN32 -#include "icsneo/platform/windows/ftdi.h" -#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) -#include "icsneo/platform/posix/ftdi.h" -#else -#warning "This platform is not supported by the FTDI driver" -#endif - +#ifndef __FTDI_H_ +#define __FTDI_H_ + +#define INTREPID_USB_VENDOR_ID (0x093c) + +#if defined _WIN32 +#include "icsneo/platform/windows/ftdi.h" +#elif defined (__unix__) || (defined (__APPLE__) && defined (__MACH__)) +#include "icsneo/platform/posix/ftdi.h" +#else +#warning "This platform is not supported by the FTDI driver" +#endif + #endif \ No newline at end of file diff --git a/include/icsneo/platform/posix/dynamiclib.h b/include/icsneo/platform/posix/dynamiclib.h index 6673b17..bec056c 100644 --- a/include/icsneo/platform/posix/dynamiclib.h +++ b/include/icsneo/platform/posix/dynamiclib.h @@ -1,24 +1,24 @@ -#ifndef __DYNAMICLIB_POSIX_H_ -#define __DYNAMICLIB_POSIX_H_ - -#include - -#ifdef __APPLE__ -#include "icsneo/platform/posix/darwin/dynamiclib.h" -#else -#include "icsneo/platform/posix/linux/dynamiclib.h" -#endif - -#define DLLExport __attribute__((visibility("default"))) -#define LegacyDLLExport DLLExport - -// #ifndef ICSNEO_NO_AUTO_DESTRUCT -// #define ICSNEO_DESTRUCTOR __attribute__((destructor)); -// #else -#define ICSNEO_DESTRUCTOR -// #endif - -#define icsneo_dynamicLibraryGetFunction(handle, func) dlsym(handle, func) -#define icsneo_dynamicLibraryClose(handle) (dlclose(handle) == 0) - +#ifndef __DYNAMICLIB_POSIX_H_ +#define __DYNAMICLIB_POSIX_H_ + +#include + +#ifdef __APPLE__ +#include "icsneo/platform/posix/darwin/dynamiclib.h" +#else +#include "icsneo/platform/posix/linux/dynamiclib.h" +#endif + +#define DLLExport __attribute__((visibility("default"))) +#define LegacyDLLExport DLLExport + +// #ifndef ICSNEO_NO_AUTO_DESTRUCT +// #define ICSNEO_DESTRUCTOR __attribute__((destructor)); +// #else +#define ICSNEO_DESTRUCTOR +// #endif + +#define icsneo_dynamicLibraryGetFunction(handle, func) dlsym(handle, func) +#define icsneo_dynamicLibraryClose(handle) (dlclose(handle) == 0) + #endif \ No newline at end of file diff --git a/include/icsneo/platform/posix/tchar.h b/include/icsneo/platform/posix/tchar.h index 0d4dd77..3d3f327 100644 --- a/include/icsneo/platform/posix/tchar.h +++ b/include/icsneo/platform/posix/tchar.h @@ -1,6 +1,6 @@ -#ifndef __TCHAR_POSIX_H_ -#define __TCHAR_POSIX_H_ - -typedef char TCHAR; - +#ifndef __TCHAR_POSIX_H_ +#define __TCHAR_POSIX_H_ + +typedef char TCHAR; + #endif \ No newline at end of file diff --git a/include/icsneo/platform/registry.h b/include/icsneo/platform/registry.h index 4805b93..5b6fa58 100644 --- a/include/icsneo/platform/registry.h +++ b/include/icsneo/platform/registry.h @@ -1,10 +1,10 @@ -#ifndef __REGISTRY_H_ -#define __REGISTRY_H_ - -#if defined _WIN32 -#include "icsneo/platform/windows/registry.h" -#else -#warning "This platform is not supported by the registry driver" -#endif - +#ifndef __REGISTRY_H_ +#define __REGISTRY_H_ + +#if defined _WIN32 +#include "icsneo/platform/windows/registry.h" +#else +#warning "This platform is not supported by the registry driver" +#endif + #endif \ No newline at end of file diff --git a/include/icsneo/platform/windows/cdcacm.h b/include/icsneo/platform/windows/cdcacm.h index 26a7ef6..11534ca 100644 --- a/include/icsneo/platform/windows/cdcacm.h +++ b/include/icsneo/platform/windows/cdcacm.h @@ -1,20 +1,20 @@ -#ifndef __CDCACM_WINDOWS_H_ -#define __CDCACM_WINDOWS_H_ - -#ifdef __cplusplus - -#include "icsneo/platform/windows/vcp.h" - -namespace icsneo { - -class CDCACM : public VCP { -public: - CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} - static void Find(std::vector& found) { return VCP::Find(found, { L"usbser" }); } -}; - -} - -#endif // __cplusplus - +#ifndef __CDCACM_WINDOWS_H_ +#define __CDCACM_WINDOWS_H_ + +#ifdef __cplusplus + +#include "icsneo/platform/windows/vcp.h" + +namespace icsneo { + +class CDCACM : public VCP { +public: + CDCACM(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} + static void Find(std::vector& found) { return VCP::Find(found, { L"usbser" }); } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/platform/windows/dynamiclib.h b/include/icsneo/platform/windows/dynamiclib.h index 8ada4d4..efd8a19 100644 --- a/include/icsneo/platform/windows/dynamiclib.h +++ b/include/icsneo/platform/windows/dynamiclib.h @@ -1,20 +1,20 @@ -#ifndef __DYNAMICLIB_WINDOWS_H_ -#define __DYNAMICLIB_WINDOWS_H_ - -#include "icsneo/platform/windows.h" - -#ifdef ICSNEOC_MAKEDLL -#define DLLExport __declspec(dllexport) -#else -#define DLLExport __declspec(dllimport) -#endif -#define LegacyDLLExport DLLExport _stdcall - -// MSVC does not have the ability to specify a destructor -#define ICSNEO_DESTRUCTOR - -#define icsneo_dynamicLibraryLoad() LoadLibrary(TEXT("icsneoc.dll")) -#define icsneo_dynamicLibraryGetFunction(handle, func) GetProcAddress((HMODULE) handle, func) -#define icsneo_dynamicLibraryClose(handle) FreeLibrary((HMODULE) handle) - +#ifndef __DYNAMICLIB_WINDOWS_H_ +#define __DYNAMICLIB_WINDOWS_H_ + +#include "icsneo/platform/windows.h" + +#ifdef ICSNEOC_MAKEDLL +#define DLLExport __declspec(dllexport) +#else +#define DLLExport __declspec(dllimport) +#endif +#define LegacyDLLExport DLLExport _stdcall + +// MSVC does not have the ability to specify a destructor +#define ICSNEO_DESTRUCTOR + +#define icsneo_dynamicLibraryLoad() LoadLibrary(TEXT("icsneoc.dll")) +#define icsneo_dynamicLibraryGetFunction(handle, func) GetProcAddress((HMODULE) handle, func) +#define icsneo_dynamicLibraryClose(handle) FreeLibrary((HMODULE) handle) + #endif \ No newline at end of file diff --git a/include/icsneo/platform/windows/ftdi.h b/include/icsneo/platform/windows/ftdi.h index d35b517..dd9d971 100644 --- a/include/icsneo/platform/windows/ftdi.h +++ b/include/icsneo/platform/windows/ftdi.h @@ -1,20 +1,20 @@ -#ifndef __FTDI_WINDOWS_H_ -#define __FTDI_WINDOWS_H_ - -#ifdef __cplusplus - -#include "icsneo/platform/windows/vcp.h" - -namespace icsneo { - -class FTDI : public VCP { -public: - FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} - static void Find(std::vector& found) { return VCP::Find(found, { L"serenum" /*, L"ftdibus" */ }); } -}; - -} - -#endif // __cplusplus - +#ifndef __FTDI_WINDOWS_H_ +#define __FTDI_WINDOWS_H_ + +#ifdef __cplusplus + +#include "icsneo/platform/windows/vcp.h" + +namespace icsneo { + +class FTDI : public VCP { +public: + FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} + static void Find(std::vector& found) { return VCP::Find(found, { L"serenum" /*, L"ftdibus" */ }); } +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/platform/windows/registry.h b/include/icsneo/platform/windows/registry.h index 38ffab0..1c64443 100644 --- a/include/icsneo/platform/windows/registry.h +++ b/include/icsneo/platform/windows/registry.h @@ -1,28 +1,28 @@ -#ifndef __REGISTRY_WINDOWS_H_ -#define __REGISTRY_WINDOWS_H_ - -#ifdef __cplusplus - -#include -#include - -namespace icsneo { - -class Registry { -public: - static bool EnumerateSubkeys(std::wstring path, std::vector& subkeys); - - // Get string 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); - - // Get DWORD 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); -}; - -} - -#endif // __cplusplus - +#ifndef __REGISTRY_WINDOWS_H_ +#define __REGISTRY_WINDOWS_H_ + +#ifdef __cplusplus + +#include +#include + +namespace icsneo { + +class Registry { +public: + static bool EnumerateSubkeys(std::wstring path, std::vector& subkeys); + + // Get string 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); + + // Get DWORD 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); +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/include/icsneo/platform/windows/vcp.h b/include/icsneo/platform/windows/vcp.h index e4d7e31..eedb736 100644 --- a/include/icsneo/platform/windows/vcp.h +++ b/include/icsneo/platform/windows/vcp.h @@ -1,48 +1,48 @@ -#ifndef __VCP_WINDOWS_H_ -#define __VCP_WINDOWS_H_ - -#ifdef __cplusplus - -#include -#include -#include -#include -#include -#include "icsneo/device/neodevice.h" -#include "icsneo/communication/driver.h" -#include "icsneo/api/eventmanager.h" - -namespace icsneo { - -// Virtual COM Port Communication -class VCP : public Driver { -public: - static void Find(std::vector& found, std::vector driverName); - static bool IsHandleValid(neodevice_handle_t handle); - typedef void(*fn_boolCallback)(bool success); - - VCP(const device_eventhandler_t& err, neodevice_t& forDevice); - ~VCP() { close(); } - bool open() { return open(false); } - void openAsync(fn_boolCallback callback); - bool close(); - bool isOpen(); - -private: - bool open(bool fromAsync); - bool opening = false; - neodevice_t& device; - - struct Detail; - std::shared_ptr detail; - - std::vector> threads; - void readTask(); - void writeTask(); -}; - -} - -#endif // __cplusplus - +#ifndef __VCP_WINDOWS_H_ +#define __VCP_WINDOWS_H_ + +#ifdef __cplusplus + +#include +#include +#include +#include +#include +#include "icsneo/device/neodevice.h" +#include "icsneo/communication/driver.h" +#include "icsneo/api/eventmanager.h" + +namespace icsneo { + +// Virtual COM Port Communication +class VCP : public Driver { +public: + static void Find(std::vector& found, std::vector driverName); + static bool IsHandleValid(neodevice_handle_t handle); + typedef void(*fn_boolCallback)(bool success); + + VCP(const device_eventhandler_t& err, neodevice_t& forDevice); + ~VCP() { close(); } + bool open() { return open(false); } + void openAsync(fn_boolCallback callback); + bool close(); + bool isOpen(); + +private: + bool open(bool fromAsync); + bool opening = false; + neodevice_t& device; + + struct Detail; + std::shared_ptr detail; + + std::vector> threads; + void readTask(); + void writeTask(); +}; + +} + +#endif // __cplusplus + #endif \ No newline at end of file diff --git a/platform/windows/registry.cpp b/platform/windows/registry.cpp index 2a37170..0656714 100644 --- a/platform/windows/registry.cpp +++ b/platform/windows/registry.cpp @@ -1,120 +1,120 @@ -#include "icsneo/platform/windows/registry.h" -#include "icsneo/platform/windows.h" -#include -#include -#include - -using namespace icsneo; - -static std::wstring_convert> converter; - -class Key { -public: - Key(std::wstring path, bool readwrite = false); - ~Key(); - HKEY GetKey() { return key; } - bool IsOpen() { return key != nullptr; } -private: - HKEY key; -}; - -Key::Key(std::wstring path, bool readwrite) { - DWORD dwDisposition; - if(readwrite) - RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition); - else - RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key); -} - -Key::~Key() { - if(IsOpen()) - RegCloseKey(key); -} - -bool Registry::EnumerateSubkeys(std::wstring path, std::vector& subkeys) { - Key regKey(path); - if(!regKey.IsOpen()) - return false; - - wchar_t className[MAX_PATH]; - memset(className, 0, sizeof(className)); - DWORD classNameLen = MAX_PATH; - DWORD subKeyCount = 0; - DWORD maxSubKeyLen, maxClassStringLen, valueCount, maxValueNameLen, maxValueDataLen, securityDescriptorLen; - FILETIME lastWriteTime; - auto ret = RegQueryInfoKeyW( - regKey.GetKey(), - className, - &classNameLen, - nullptr, - &subKeyCount, - &maxSubKeyLen, - &maxClassStringLen, - &valueCount, - &maxValueNameLen, - &maxValueDataLen, - &securityDescriptorLen, - &lastWriteTime); - - if(ret != ERROR_SUCCESS) - return false; - - subkeys.clear(); - for(DWORD i = 0; i < subKeyCount; i++) { - DWORD nameLen = MAX_PATH; - wchar_t name[MAX_PATH]; - memset(name, 0, sizeof(name)); - ret = RegEnumKeyExW(regKey.GetKey(), i, name, &nameLen, nullptr, nullptr, nullptr, &lastWriteTime); - if(ret == ERROR_SUCCESS) - subkeys.push_back(name); - } - return true; -} - -bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) { - Key regKey(path); - if(!regKey.IsOpen()) - return false; - - // Query for the type and size of the data - DWORD type, size; - auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)nullptr, &size); - if(ret != ERROR_SUCCESS) - return false; - - // Query for the data itself - std::vector data(size / 2 + 1); - 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); - if(ret != ERROR_SUCCESS) - return false; - - value = data.data(); - return true; -} - -bool Registry::Get(std::string path, std::string key, std::string& value) { - std::wstring wvalue; - bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue); - value = converter.to_bytes(wvalue); - return ret; -} - -bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) { - Key regKey(path); - if(!regKey.IsOpen()) - return false; - - // Query for the data - DWORD type, size = sizeof(DWORD), kvalue; - auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)&kvalue, &size); - if(ret != ERROR_SUCCESS || type != REG_DWORD) - return false; - - value = kvalue; - return true; -} - -bool Registry::Get(std::string path, std::string key, uint32_t& value) { - return Get(converter.from_bytes(path), converter.from_bytes(key), value); -} +#include "icsneo/platform/windows/registry.h" +#include "icsneo/platform/windows.h" +#include +#include +#include + +using namespace icsneo; + +static std::wstring_convert> converter; + +class Key { +public: + Key(std::wstring path, bool readwrite = false); + ~Key(); + HKEY GetKey() { return key; } + bool IsOpen() { return key != nullptr; } +private: + HKEY key; +}; + +Key::Key(std::wstring path, bool readwrite) { + DWORD dwDisposition; + if(readwrite) + RegCreateKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, nullptr, 0, KEY_QUERY_VALUE | KEY_WRITE, nullptr, &key, &dwDisposition); + else + RegOpenKeyExW(HKEY_LOCAL_MACHINE, path.c_str(), 0, KEY_READ, &key); +} + +Key::~Key() { + if(IsOpen()) + RegCloseKey(key); +} + +bool Registry::EnumerateSubkeys(std::wstring path, std::vector& subkeys) { + Key regKey(path); + if(!regKey.IsOpen()) + return false; + + wchar_t className[MAX_PATH]; + memset(className, 0, sizeof(className)); + DWORD classNameLen = MAX_PATH; + DWORD subKeyCount = 0; + DWORD maxSubKeyLen, maxClassStringLen, valueCount, maxValueNameLen, maxValueDataLen, securityDescriptorLen; + FILETIME lastWriteTime; + auto ret = RegQueryInfoKeyW( + regKey.GetKey(), + className, + &classNameLen, + nullptr, + &subKeyCount, + &maxSubKeyLen, + &maxClassStringLen, + &valueCount, + &maxValueNameLen, + &maxValueDataLen, + &securityDescriptorLen, + &lastWriteTime); + + if(ret != ERROR_SUCCESS) + return false; + + subkeys.clear(); + for(DWORD i = 0; i < subKeyCount; i++) { + DWORD nameLen = MAX_PATH; + wchar_t name[MAX_PATH]; + memset(name, 0, sizeof(name)); + ret = RegEnumKeyExW(regKey.GetKey(), i, name, &nameLen, nullptr, nullptr, nullptr, &lastWriteTime); + if(ret == ERROR_SUCCESS) + subkeys.push_back(name); + } + return true; +} + +bool Registry::Get(std::wstring path, std::wstring key, std::wstring& value) { + Key regKey(path); + if(!regKey.IsOpen()) + return false; + + // Query for the type and size of the data + DWORD type, size; + auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)nullptr, &size); + if(ret != ERROR_SUCCESS) + return false; + + // Query for the data itself + std::vector data(size / 2 + 1); + 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); + if(ret != ERROR_SUCCESS) + return false; + + value = data.data(); + return true; +} + +bool Registry::Get(std::string path, std::string key, std::string& value) { + std::wstring wvalue; + bool ret = Get(converter.from_bytes(path), converter.from_bytes(key), wvalue); + value = converter.to_bytes(wvalue); + return ret; +} + +bool Registry::Get(std::wstring path, std::wstring key, uint32_t& value) { + Key regKey(path); + if(!regKey.IsOpen()) + return false; + + // Query for the data + DWORD type, size = sizeof(DWORD), kvalue; + auto ret = RegQueryValueExW(regKey.GetKey(), key.c_str(), nullptr, &type, (LPBYTE)&kvalue, &size); + if(ret != ERROR_SUCCESS || type != REG_DWORD) + return false; + + value = kvalue; + return true; +} + +bool Registry::Get(std::string path, std::string key, uint32_t& value) { + return Get(converter.from_bytes(path), converter.from_bytes(key), value); +} diff --git a/platform/windows/vcp.cpp b/platform/windows/vcp.cpp index 90784c8..57c1f0b 100644 --- a/platform/windows/vcp.cpp +++ b/platform/windows/vcp.cpp @@ -1,466 +1,466 @@ -#include "icsneo/platform/windows/ftdi.h" -#include "icsneo/platform/ftdi.h" -#include "icsneo/platform/registry.h" -#include "icsneo/device/founddevice.h" -#include -#include -#include -#include -#include -#include -#include -#include -#include - -using namespace icsneo; - -static std::wstring_convert> converter; -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 constexpr unsigned int RETRY_TIMES = 5; -static constexpr unsigned int RETRY_DELAY = 50; - -struct VCP::Detail { - Detail() { - overlappedRead.hEvent = INVALID_HANDLE_VALUE; - overlappedWrite.hEvent = INVALID_HANDLE_VALUE; - overlappedWait.hEvent = INVALID_HANDLE_VALUE; - } - HANDLE handle = INVALID_HANDLE_VALUE; - OVERLAPPED overlappedRead = {}; - OVERLAPPED overlappedWrite = {}; - OVERLAPPED overlappedWait = {}; -}; - -void VCP::Find(std::vector& found, std::vector driverNames) { - for(auto& driverName : driverNames) { - std::wstringstream regss; - regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\"; - std::wstring driverEnumRegKey = regss.str(); - - uint32_t deviceCount = 0; - if(!Registry::Get(driverEnumRegKey, L"Count", deviceCount)) - continue; - - for(uint32_t i = 0; i < deviceCount; i++) { - FoundDevice device; - - device.makeDriver = [](const device_eventhandler_t& reportFn, neodevice_t& device) { - return std::unique_ptr(new VCP(reportFn, device)); - }; - - // First we want to look at what devices FTDI is enumerating (inside driverEnumRegKey) - // The entry for a ValueCAN 3 with SN 138635 looks like "FTDIBUS\VID_093C+PID_0601+138635A\0000" - // The entry for a ValueCAN 4 with SN V20227 looks like "USB\VID_093C&PID_1101\V20227" - std::wstringstream ss; - ss << i; - std::wstring entry; - if(!Registry::Get(driverEnumRegKey, ss.str(), entry)) - continue; - - std::transform(entry.begin(), entry.end(), entry.begin(), std::towupper); - - std::wstringstream vss; - 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) - continue; - - auto pidpos = entry.find(L"PID_"); - if(pidpos == std::wstring::npos) - continue; - // We will later use this and startchar to parse the PID - - // Okay, this is a device we want - // Get the serial number - auto startchar = entry.find(L"+", pidpos + 1); - if(startchar == std::wstring::npos) - startchar = entry.find(L"\\", pidpos + 1); - bool conversionError = false; - int sn = 0; - try { - sn = std::stoi(entry.substr(startchar + 1)); - } - catch(...) { - conversionError = true; - } - - std::wstringstream oss; - if(!sn || conversionError) - oss << entry.substr(startchar + 1, 6); // This is a device with characters in the serial number - else - oss << sn; - - device.productId = uint16_t(std::wcstol(entry.c_str() + pidpos + 4, nullptr, 16)); - if(!device.productId) - continue; - - std::string serial = converter.to_bytes(oss.str()); - // The serial number should not have a path slash in it. If it does, that means we don't have the real serial. - if(serial.find_first_of('\\') != std::string::npos) { - // The serial number was not in the first serenum key where we expected it. - // We can try to match the ContainerID with the one in ALL_ENUM\USB and get a serial that way - std::wstringstream uess; - uess << ALL_ENUM_REG_KEY << L"\\USB\\" << vss.str() << L"&PID_" << std::setfill(L'0') << std::setw(4) - << std::uppercase << std::hex << device.productId << L'\\'; - std::wstringstream ciss; - ciss << ALL_ENUM_REG_KEY << entry; - std::wstring containerIDFromEntry, containerIDFromEnum; - if(!Registry::Get(ciss.str(), L"ContainerID", containerIDFromEntry)) - continue; // We did not get a container ID. This can happen on Windows XP and before. - if(containerIDFromEntry.empty()) - continue; // The container ID was empty? - std::vector subkeys; - if(!Registry::EnumerateSubkeys(uess.str(), subkeys)) - continue; // VID/PID combo was not present at all. - if(subkeys.empty()) - continue; // No devices for VID/PID. - std::wstring correctSerial; - for(auto& subkey : subkeys) { - std::wstringstream skss; - skss << uess.str() << L'\\' << subkey; - if(!Registry::Get(skss.str(), L"ContainerID", containerIDFromEnum)) - continue; - if(containerIDFromEntry != containerIDFromEnum) - continue; - correctSerial = subkey; - break; - } - if(correctSerial.empty()) - continue; // Didn't find the device within the subkeys of the enumeration - - sn = 0; - conversionError = false; - try { - sn = std::stoi(correctSerial); - } - catch(...) { - conversionError = true; - } - - if(!sn || conversionError) { - // This is a device with characters in the serial number - if(correctSerial.size() != 6) - continue; - serial = converter.to_bytes(correctSerial); - } - else { - std::wstringstream soss; - soss << sn; - serial = converter.to_bytes(soss.str()); - } - - if(serial.find_first_of('\\') != std::string::npos) - continue; - } - strcpy_s(device.serial, sizeof(device.serial), serial.c_str()); - - // 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) - std::wstringstream dpss; - dpss << ALL_ENUM_REG_KEY << entry << L"\\Device Parameters"; - std::wstring port; - 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); - auto compos = port.find(L"COM"); - device.handle = 0; - if(compos != std::wstring::npos) { - try { - device.handle = std::stoi(port.substr(compos + 3)); - } - catch(...) {} // In case of this, or any other error, handle has already been initialized to 0 - } - - bool alreadyFound = false; - FoundDevice* shouldReplace = nullptr; - for(auto& foundDev : found) { - if((foundDev.handle == device.handle || foundDev.handle == 0 || device.handle == 0) && serial == foundDev.serial) { - alreadyFound = true; - if(foundDev.handle == 0) - shouldReplace = &foundDev; - break; - } - } - - if(!alreadyFound) - found.push_back(device); - else if(shouldReplace != nullptr) - *shouldReplace = device; - } - } -} - -VCP::VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) { - detail = std::make_shared(); -} - -bool VCP::IsHandleValid(neodevice_handle_t handle) { - if(handle < 1) - return false; - - 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 true; -} - -bool VCP::open(bool fromAsync) { - if(isOpen() || (!fromAsync && opening)) { - report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); - return false; - } - - if(!IsHandleValid(device.handle)) { - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - opening = true; - - std::wstringstream comss; - comss << L"\\\\.\\COM" << device.handle; - - // We're going to attempt to open 5 (RETRY_TIMES) times in a row - for(int i = 0; !isOpen() && i < RETRY_TIMES; i++) { - detail->handle = CreateFileW(comss.str().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, - OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr); - if(GetLastError() == ERROR_SUCCESS) - break; // We have the file handle - - std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_DELAY)); - } - - opening = false; - - if(!isOpen()) { - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - // Set the timeouts - COMMTIMEOUTS timeouts; - if(!GetCommTimeouts(detail->handle, &timeouts)) { - close(); - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - // See https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_commtimeouts#remarks - timeouts.ReadIntervalTimeout = MAXDWORD; - timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; - timeouts.ReadTotalTimeoutConstant = 100; - timeouts.WriteTotalTimeoutConstant = 10000; - timeouts.WriteTotalTimeoutMultiplier = 0; - - if(!SetCommTimeouts(detail->handle, &timeouts)) { - close(); - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - // Set the COM state - DCB comstate; - if(!GetCommState(detail->handle, &comstate)) { - close(); - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - comstate.BaudRate = 115200; - comstate.ByteSize = 8; - comstate.Parity = NOPARITY; - comstate.StopBits = 0; - comstate.fDtrControl = DTR_CONTROL_ENABLE; - comstate.fRtsControl = RTS_CONTROL_ENABLE; - - if(!SetCommState(detail->handle, &comstate)) { - close(); - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - PurgeComm(detail->handle, PURGE_RXCLEAR); - - // Set up events so that overlapped IO can work with them - detail->overlappedRead.hEvent = CreateEvent(nullptr, false, false, nullptr); - detail->overlappedWrite.hEvent = CreateEvent(nullptr, false, false, nullptr); - detail->overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr); - if (detail->overlappedRead.hEvent == nullptr || detail->overlappedWrite.hEvent == nullptr || detail->overlappedWait.hEvent == nullptr) { - close(); - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - return false; - } - - // Set up event so that we will satisfy overlappedWait when a character comes in - if(!SetCommMask(detail->handle, EV_RXCHAR)) { - close(); - report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); - 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 - - // Create threads - readThread = std::thread(&VCP::readTask, this); - writeThread = std::thread(&VCP::writeTask, this); - - return true; -} - -void VCP::openAsync(fn_boolCallback callback) { - threads.push_back(std::make_shared([&]() { - callback(open(true)); - })); -} - -bool VCP::close() { - if(!isOpen()) { - report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); - return false; - } - - closing = true; // Signal the threads that we are closing - for(auto& t : threads) - t->join(); // Wait for the threads to close - readThread.join(); - writeThread.join(); - closing = false; - - if(!CloseHandle(detail->handle)) { - report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); - return false; - } - - 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 - if(detail->overlappedRead.hEvent != INVALID_HANDLE_VALUE) { - if(!CloseHandle(detail->overlappedRead.hEvent)) - ret = false; - detail->overlappedRead.hEvent = INVALID_HANDLE_VALUE; - } - if(detail->overlappedWrite.hEvent != INVALID_HANDLE_VALUE) { - if(!CloseHandle(detail->overlappedWrite.hEvent)) - ret = false; - detail->overlappedWrite.hEvent = INVALID_HANDLE_VALUE; - } - if(detail->overlappedWait.hEvent != INVALID_HANDLE_VALUE) { - if(!CloseHandle(detail->overlappedWait.hEvent)) - ret = false; - detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE; - } - - uint8_t flush; - WriteOperation flushop; - while(readQueue.try_dequeue(flush)) {} - while(writeQueue.try_dequeue(flushop)) {} - - if(!ret) - 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 - - return ret; -} - -bool VCP::isOpen() { - return detail->handle != INVALID_HANDLE_VALUE; -} - -void VCP::readTask() { - constexpr size_t READ_BUFFER_SIZE = 10240; - uint8_t readbuf[READ_BUFFER_SIZE]; - IOTaskState state = LAUNCH; - DWORD bytesRead = 0; - EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { - switch(state) { - case LAUNCH: { - COMSTAT comStatus; - unsigned long errorCodes; - ClearCommError(detail->handle, &errorCodes, &comStatus); - - bytesRead = 0; - if(ReadFile(detail->handle, readbuf, READ_BUFFER_SIZE, nullptr, &detail->overlappedRead)) { - if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) { - if(bytesRead) - readQueue.enqueue_bulk(readbuf, bytesRead); - } - continue; - } - - auto lastError = GetLastError(); - if(lastError == ERROR_IO_PENDING) - state = WAIT; - else if(lastError != ERROR_SUCCESS) { - if(lastError == ERROR_ACCESS_DENIED) { - if(!isDisconnected()) { - disconnected = true; - report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); - } - } else - report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); - } - } - break; - case WAIT: { - auto ret = WaitForSingleObject(detail->overlappedRead.hEvent, 100); - if(ret == WAIT_OBJECT_0) { - if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) { - readQueue.enqueue_bulk(readbuf, bytesRead); - state = LAUNCH; - } else - report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); - } - if(ret == WAIT_ABANDONED || ret == WAIT_FAILED) { - state = LAUNCH; - report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); - } - } - } - } -} - -void VCP::writeTask() { - IOTaskState state = LAUNCH; - VCP::WriteOperation writeOp; - DWORD bytesWritten = 0; - EventManager::GetInstance().downgradeErrorsOnCurrentThread(); - while(!closing && !isDisconnected()) { - switch(state) { - case LAUNCH: { - if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) - continue; - - bytesWritten = 0; - if(WriteFile(detail->handle, writeOp.bytes.data(), (DWORD)writeOp.bytes.size(), nullptr, &detail->overlappedWrite)) - continue; - - auto winerr = GetLastError(); - if(winerr == ERROR_IO_PENDING) { - state = WAIT; - } - else if(winerr == ERROR_ACCESS_DENIED) { - if(!isDisconnected()) { - disconnected = true; - report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); - } - } else - report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); - } - break; - case WAIT: { - auto ret = WaitForSingleObject(detail->overlappedWrite.hEvent, 50); - if(ret == WAIT_OBJECT_0) { - if(!GetOverlappedResult(detail->handle, &detail->overlappedWrite, &bytesWritten, FALSE)) - report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); - state = LAUNCH; - } - - if(ret == WAIT_ABANDONED) { - report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); - state = LAUNCH; - } - } - } - } +#include "icsneo/platform/windows/ftdi.h" +#include "icsneo/platform/ftdi.h" +#include "icsneo/platform/registry.h" +#include "icsneo/device/founddevice.h" +#include +#include +#include +#include +#include +#include +#include +#include +#include + +using namespace icsneo; + +static std::wstring_convert> converter; +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 constexpr unsigned int RETRY_TIMES = 5; +static constexpr unsigned int RETRY_DELAY = 50; + +struct VCP::Detail { + Detail() { + overlappedRead.hEvent = INVALID_HANDLE_VALUE; + overlappedWrite.hEvent = INVALID_HANDLE_VALUE; + overlappedWait.hEvent = INVALID_HANDLE_VALUE; + } + HANDLE handle = INVALID_HANDLE_VALUE; + OVERLAPPED overlappedRead = {}; + OVERLAPPED overlappedWrite = {}; + OVERLAPPED overlappedWait = {}; +}; + +void VCP::Find(std::vector& found, std::vector driverNames) { + for(auto& driverName : driverNames) { + std::wstringstream regss; + regss << DRIVER_SERVICES_REG_KEY << driverName << L"\\Enum\\"; + std::wstring driverEnumRegKey = regss.str(); + + uint32_t deviceCount = 0; + if(!Registry::Get(driverEnumRegKey, L"Count", deviceCount)) + continue; + + for(uint32_t i = 0; i < deviceCount; i++) { + FoundDevice device; + + device.makeDriver = [](const device_eventhandler_t& reportFn, neodevice_t& device) { + return std::unique_ptr(new VCP(reportFn, device)); + }; + + // First we want to look at what devices FTDI is enumerating (inside driverEnumRegKey) + // The entry for a ValueCAN 3 with SN 138635 looks like "FTDIBUS\VID_093C+PID_0601+138635A\0000" + // The entry for a ValueCAN 4 with SN V20227 looks like "USB\VID_093C&PID_1101\V20227" + std::wstringstream ss; + ss << i; + std::wstring entry; + if(!Registry::Get(driverEnumRegKey, ss.str(), entry)) + continue; + + std::transform(entry.begin(), entry.end(), entry.begin(), std::towupper); + + std::wstringstream vss; + 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) + continue; + + auto pidpos = entry.find(L"PID_"); + if(pidpos == std::wstring::npos) + continue; + // We will later use this and startchar to parse the PID + + // Okay, this is a device we want + // Get the serial number + auto startchar = entry.find(L"+", pidpos + 1); + if(startchar == std::wstring::npos) + startchar = entry.find(L"\\", pidpos + 1); + bool conversionError = false; + int sn = 0; + try { + sn = std::stoi(entry.substr(startchar + 1)); + } + catch(...) { + conversionError = true; + } + + std::wstringstream oss; + if(!sn || conversionError) + oss << entry.substr(startchar + 1, 6); // This is a device with characters in the serial number + else + oss << sn; + + device.productId = uint16_t(std::wcstol(entry.c_str() + pidpos + 4, nullptr, 16)); + if(!device.productId) + continue; + + std::string serial = converter.to_bytes(oss.str()); + // The serial number should not have a path slash in it. If it does, that means we don't have the real serial. + if(serial.find_first_of('\\') != std::string::npos) { + // The serial number was not in the first serenum key where we expected it. + // We can try to match the ContainerID with the one in ALL_ENUM\USB and get a serial that way + std::wstringstream uess; + uess << ALL_ENUM_REG_KEY << L"\\USB\\" << vss.str() << L"&PID_" << std::setfill(L'0') << std::setw(4) + << std::uppercase << std::hex << device.productId << L'\\'; + std::wstringstream ciss; + ciss << ALL_ENUM_REG_KEY << entry; + std::wstring containerIDFromEntry, containerIDFromEnum; + if(!Registry::Get(ciss.str(), L"ContainerID", containerIDFromEntry)) + continue; // We did not get a container ID. This can happen on Windows XP and before. + if(containerIDFromEntry.empty()) + continue; // The container ID was empty? + std::vector subkeys; + if(!Registry::EnumerateSubkeys(uess.str(), subkeys)) + continue; // VID/PID combo was not present at all. + if(subkeys.empty()) + continue; // No devices for VID/PID. + std::wstring correctSerial; + for(auto& subkey : subkeys) { + std::wstringstream skss; + skss << uess.str() << L'\\' << subkey; + if(!Registry::Get(skss.str(), L"ContainerID", containerIDFromEnum)) + continue; + if(containerIDFromEntry != containerIDFromEnum) + continue; + correctSerial = subkey; + break; + } + if(correctSerial.empty()) + continue; // Didn't find the device within the subkeys of the enumeration + + sn = 0; + conversionError = false; + try { + sn = std::stoi(correctSerial); + } + catch(...) { + conversionError = true; + } + + if(!sn || conversionError) { + // This is a device with characters in the serial number + if(correctSerial.size() != 6) + continue; + serial = converter.to_bytes(correctSerial); + } + else { + std::wstringstream soss; + soss << sn; + serial = converter.to_bytes(soss.str()); + } + + if(serial.find_first_of('\\') != std::string::npos) + continue; + } + strcpy_s(device.serial, sizeof(device.serial), serial.c_str()); + + // 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) + std::wstringstream dpss; + dpss << ALL_ENUM_REG_KEY << entry << L"\\Device Parameters"; + std::wstring port; + 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); + auto compos = port.find(L"COM"); + device.handle = 0; + if(compos != std::wstring::npos) { + try { + device.handle = std::stoi(port.substr(compos + 3)); + } + catch(...) {} // In case of this, or any other error, handle has already been initialized to 0 + } + + bool alreadyFound = false; + FoundDevice* shouldReplace = nullptr; + for(auto& foundDev : found) { + if((foundDev.handle == device.handle || foundDev.handle == 0 || device.handle == 0) && serial == foundDev.serial) { + alreadyFound = true; + if(foundDev.handle == 0) + shouldReplace = &foundDev; + break; + } + } + + if(!alreadyFound) + found.push_back(device); + else if(shouldReplace != nullptr) + *shouldReplace = device; + } + } +} + +VCP::VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : Driver(err), device(forDevice) { + detail = std::make_shared(); +} + +bool VCP::IsHandleValid(neodevice_handle_t handle) { + if(handle < 1) + return false; + + 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 true; +} + +bool VCP::open(bool fromAsync) { + if(isOpen() || (!fromAsync && opening)) { + report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); + return false; + } + + if(!IsHandleValid(device.handle)) { + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + opening = true; + + std::wstringstream comss; + comss << L"\\\\.\\COM" << device.handle; + + // We're going to attempt to open 5 (RETRY_TIMES) times in a row + for(int i = 0; !isOpen() && i < RETRY_TIMES; i++) { + detail->handle = CreateFileW(comss.str().c_str(), GENERIC_READ | GENERIC_WRITE, 0, nullptr, + OPEN_EXISTING, FILE_FLAG_OVERLAPPED, nullptr); + if(GetLastError() == ERROR_SUCCESS) + break; // We have the file handle + + std::this_thread::sleep_for(std::chrono::milliseconds(RETRY_DELAY)); + } + + opening = false; + + if(!isOpen()) { + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + // Set the timeouts + COMMTIMEOUTS timeouts; + if(!GetCommTimeouts(detail->handle, &timeouts)) { + close(); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + // See https://docs.microsoft.com/en-us/windows/desktop/api/winbase/ns-winbase-_commtimeouts#remarks + timeouts.ReadIntervalTimeout = MAXDWORD; + timeouts.ReadTotalTimeoutMultiplier = MAXDWORD; + timeouts.ReadTotalTimeoutConstant = 100; + timeouts.WriteTotalTimeoutConstant = 10000; + timeouts.WriteTotalTimeoutMultiplier = 0; + + if(!SetCommTimeouts(detail->handle, &timeouts)) { + close(); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + // Set the COM state + DCB comstate; + if(!GetCommState(detail->handle, &comstate)) { + close(); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + comstate.BaudRate = 115200; + comstate.ByteSize = 8; + comstate.Parity = NOPARITY; + comstate.StopBits = 0; + comstate.fDtrControl = DTR_CONTROL_ENABLE; + comstate.fRtsControl = RTS_CONTROL_ENABLE; + + if(!SetCommState(detail->handle, &comstate)) { + close(); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + PurgeComm(detail->handle, PURGE_RXCLEAR); + + // Set up events so that overlapped IO can work with them + detail->overlappedRead.hEvent = CreateEvent(nullptr, false, false, nullptr); + detail->overlappedWrite.hEvent = CreateEvent(nullptr, false, false, nullptr); + detail->overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr); + if (detail->overlappedRead.hEvent == nullptr || detail->overlappedWrite.hEvent == nullptr || detail->overlappedWait.hEvent == nullptr) { + close(); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + return false; + } + + // Set up event so that we will satisfy overlappedWait when a character comes in + if(!SetCommMask(detail->handle, EV_RXCHAR)) { + close(); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); + 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 + + // Create threads + readThread = std::thread(&VCP::readTask, this); + writeThread = std::thread(&VCP::writeTask, this); + + return true; +} + +void VCP::openAsync(fn_boolCallback callback) { + threads.push_back(std::make_shared([&]() { + callback(open(true)); + })); +} + +bool VCP::close() { + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return false; + } + + closing = true; // Signal the threads that we are closing + for(auto& t : threads) + t->join(); // Wait for the threads to close + readThread.join(); + writeThread.join(); + closing = false; + + if(!CloseHandle(detail->handle)) { + report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); + return false; + } + + 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 + if(detail->overlappedRead.hEvent != INVALID_HANDLE_VALUE) { + if(!CloseHandle(detail->overlappedRead.hEvent)) + ret = false; + detail->overlappedRead.hEvent = INVALID_HANDLE_VALUE; + } + if(detail->overlappedWrite.hEvent != INVALID_HANDLE_VALUE) { + if(!CloseHandle(detail->overlappedWrite.hEvent)) + ret = false; + detail->overlappedWrite.hEvent = INVALID_HANDLE_VALUE; + } + if(detail->overlappedWait.hEvent != INVALID_HANDLE_VALUE) { + if(!CloseHandle(detail->overlappedWait.hEvent)) + ret = false; + detail->overlappedWait.hEvent = INVALID_HANDLE_VALUE; + } + + uint8_t flush; + WriteOperation flushop; + while(readQueue.try_dequeue(flush)) {} + while(writeQueue.try_dequeue(flushop)) {} + + if(!ret) + 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 + + return ret; +} + +bool VCP::isOpen() { + return detail->handle != INVALID_HANDLE_VALUE; +} + +void VCP::readTask() { + constexpr size_t READ_BUFFER_SIZE = 10240; + uint8_t readbuf[READ_BUFFER_SIZE]; + IOTaskState state = LAUNCH; + DWORD bytesRead = 0; + EventManager::GetInstance().downgradeErrorsOnCurrentThread(); + while(!closing && !isDisconnected()) { + switch(state) { + case LAUNCH: { + COMSTAT comStatus; + unsigned long errorCodes; + ClearCommError(detail->handle, &errorCodes, &comStatus); + + bytesRead = 0; + if(ReadFile(detail->handle, readbuf, READ_BUFFER_SIZE, nullptr, &detail->overlappedRead)) { + if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) { + if(bytesRead) + readQueue.enqueue_bulk(readbuf, bytesRead); + } + continue; + } + + auto lastError = GetLastError(); + if(lastError == ERROR_IO_PENDING) + state = WAIT; + else if(lastError != ERROR_SUCCESS) { + if(lastError == ERROR_ACCESS_DENIED) { + if(!isDisconnected()) { + disconnected = true; + report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); + } + } else + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); + } + } + break; + case WAIT: { + auto ret = WaitForSingleObject(detail->overlappedRead.hEvent, 100); + if(ret == WAIT_OBJECT_0) { + if(GetOverlappedResult(detail->handle, &detail->overlappedRead, &bytesRead, FALSE)) { + readQueue.enqueue_bulk(readbuf, bytesRead); + state = LAUNCH; + } else + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); + } + if(ret == WAIT_ABANDONED || ret == WAIT_FAILED) { + state = LAUNCH; + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); + } + } + } + } +} + +void VCP::writeTask() { + IOTaskState state = LAUNCH; + VCP::WriteOperation writeOp; + DWORD bytesWritten = 0; + EventManager::GetInstance().downgradeErrorsOnCurrentThread(); + while(!closing && !isDisconnected()) { + switch(state) { + case LAUNCH: { + if(!writeQueue.wait_dequeue_timed(writeOp, std::chrono::milliseconds(100))) + continue; + + bytesWritten = 0; + if(WriteFile(detail->handle, writeOp.bytes.data(), (DWORD)writeOp.bytes.size(), nullptr, &detail->overlappedWrite)) + continue; + + auto winerr = GetLastError(); + if(winerr == ERROR_IO_PENDING) { + state = WAIT; + } + else if(winerr == ERROR_ACCESS_DENIED) { + if(!isDisconnected()) { + disconnected = true; + report(APIEvent::Type::DeviceDisconnected, APIEvent::Severity::Error); + } + } else + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); + } + break; + case WAIT: { + auto ret = WaitForSingleObject(detail->overlappedWrite.hEvent, 50); + if(ret == WAIT_OBJECT_0) { + if(!GetOverlappedResult(detail->handle, &detail->overlappedWrite, &bytesWritten, FALSE)) + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); + state = LAUNCH; + } + + if(ret == WAIT_ABANDONED) { + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); + state = LAUNCH; + } + } + } + } } \ No newline at end of file