diff --git a/CMakeLists.txt b/CMakeLists.txt index 18fb4df..dbab50c 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -121,8 +121,8 @@ include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}) add_library(icsneocpp api/icsneocpp/icsneocpp.cpp - api/icsneocpp/error.cpp - api/icsneocpp/errormanager.cpp + api/icsneocpp/event.cpp + api/icsneocpp/eventmanager.cpp api/icsneocpp/version.cpp ${SRC_FILES} ) diff --git a/README.md b/README.md index dbe458e..9325d2c 100644 --- a/README.md +++ b/README.md @@ -88,7 +88,7 @@ for(size_t i = 0; i < deviceCount; i++) { neodevice_t* myDevice = &devices[0]; if(!icsneo_openDevice(myDevice)) { - neoerror_t error; + neoevent_t error; if(icsneo_getLastError(&error)) printf("Error! %s\n", error.description); } diff --git a/api/icsneoc/icsneoc.cpp b/api/icsneoc/icsneoc.cpp index 4bf7d92..c83a127 100644 --- a/api/icsneoc/icsneoc.cpp +++ b/api/icsneoc/icsneoc.cpp @@ -7,7 +7,7 @@ #include "icsneo/icsneoc.h" #include "icsneo/icsneocpp.h" #include "icsneo/platform/dynamiclib.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include "icsneo/device/devicefinder.h" #include #include @@ -28,7 +28,7 @@ void icsneo_findAllDevices(neodevice_t* devices, size_t* count) { std::vector> foundDevices = icsneo::FindAllDevices(); if(count == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return; } @@ -43,7 +43,7 @@ void icsneo_findAllDevices(neodevice_t* devices, size_t* count) { *count = foundDevices.size(); size_t outputSize = *count; if(outputSize > inputSize) { - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); outputSize = inputSize; } @@ -60,7 +60,7 @@ void icsneo_freeUnconnectedDevices() { bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) { // TAG String copy function if(count == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } @@ -73,7 +73,7 @@ bool icsneo_serialNumToString(uint32_t num, char* str, size_t* count) { if(*count < result.length()) { *count = result.length() + 1; // This is how big of a buffer we need - ErrorManager::GetInstance().add(APIError::BufferInsufficient); + EventManager::GetInstance().add(APIEvent::Type::BufferInsufficient, APIEvent::Severity::Error); return false; } @@ -89,7 +89,7 @@ uint32_t icsneo_serialStringToNum(const char* str) { bool icsneo_isValidNeoDevice(const neodevice_t* device) { // return false on nullptr if(!device) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + 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) @@ -102,7 +102,7 @@ bool icsneo_isValidNeoDevice(const neodevice_t* device) { return true; } - ErrorManager::GetInstance().add(APIError::InvalidNeoDevice); + EventManager::GetInstance().add(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error); return false; } @@ -200,7 +200,7 @@ bool icsneo_getMessages(const neodevice_t* device, neomessage_t* messages, size_ return false; if(items == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } @@ -245,7 +245,7 @@ bool icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit) { bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength) { // TAG String copy function if(maxLength == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } @@ -263,7 +263,7 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng str[*maxLength] = '\0'; if(output.length() > *maxLength) - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); return true; } @@ -271,7 +271,7 @@ bool icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLeng bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength) { // TAG String copy function if(maxLength == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } @@ -286,7 +286,7 @@ bool icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLengt str[*maxLength] = '\0'; if(output.length() > *maxLength) - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); return true; } @@ -336,13 +336,13 @@ size_t icsneo_settingsReadStructure(const neodevice_t* device, void* structure, if(readSize > structureSize) { // Client application has a smaller structure than we do // It is probably built against an older version of the API - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); readSize = structureSize; } const void* deviceStructure = device->device->settings->getRawStructurePointer(); if(deviceStructure == nullptr) { - ErrorManager::GetInstance().add(APIError::SettingsNotAvailable); + EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return 0; } @@ -360,19 +360,19 @@ static bool icsneo_settingsWriteStructure(const neodevice_t* device, const void* return false; if(structure == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } size_t writeSize = device->device->settings->getSize(); if(writeSize < structureSize) { - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); structureSize = writeSize; } void* deviceStructure = device->device->settings->getMutableRawStructurePointer(); if(deviceStructure == nullptr) { - ErrorManager::GetInstance().add(APIError::SettingsNotAvailable); + EventManager::GetInstance().add(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } @@ -440,7 +440,7 @@ bool icsneo_transmitMessages(const neodevice_t* device, const neomessage_t* mess bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength) { // TAG String copy function if(maxLength == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } @@ -453,7 +453,7 @@ bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLeng str[*maxLength] = '\0'; if(output.length() > *maxLength) - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); return true; } @@ -462,88 +462,88 @@ neoversion_t icsneo_getVersion(void) { return icsneo::GetVersion(); } -bool icsneo_getErrors(neoerror_t* errors, size_t* size) { +bool icsneo_getEvents(neoevent_t* events, size_t* size) { if(size == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } - if(errors == nullptr) { - *size = icsneo::ErrorCount(); + if(events == nullptr) { + *size = icsneo::EventCount(); return false; } - auto cppErrors = icsneo::GetErrors(*size); + auto cppErrors = icsneo::GetEvents(*size); for(size_t i = 0; i < cppErrors.size(); i++) - memcpy(&errors[i], cppErrors[i].getNeoError(), sizeof(neoerror_t)); + memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t)); *size = cppErrors.size(); return true; } -bool icsneo_getDeviceErrors(const neodevice_t* device, neoerror_t* errors, size_t* size) { +bool icsneo_getDeviceEvents(const neodevice_t* device, neoevent_t* events, size_t* size) { if(!icsneo_isValidNeoDevice(device)) return false; if(size == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } - // Creating the filter will nullptr is okay! It will find any errors not associated with a device. - ErrorFilter filter = (device != nullptr ? device->device : nullptr); + // 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(errors == nullptr) { - *size = icsneo::ErrorCount(filter); + if(events == nullptr) { + *size = icsneo::EventCount(filter); return false; } - auto cppErrors = icsneo::GetErrors(*size, filter); + auto cppErrors = icsneo::GetEvents(*size, filter); for(size_t i = 0; i < cppErrors.size(); i++) - memcpy(&errors[i], cppErrors[i].getNeoError(), sizeof(neoerror_t)); + memcpy(&events[i], cppErrors[i].getNeoEvent(), sizeof(neoevent_t)); *size = cppErrors.size(); return true; } -bool icsneo_getLastError(neoerror_t* error) { +bool icsneo_getLastError(neoevent_t* error) { if(error == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } - APIError cppErr; - if(!icsneo::GetLastError(cppErr)) + APIEvent cppErr = icsneo::GetLastError(); + if(cppErr.getType() == icsneo::APIEvent::Type::NoErrorFound) return false; - memcpy(error, cppErr.getNeoError(), sizeof(neoerror_t)); + memcpy(error, cppErr.getNeoEvent(), sizeof(neoevent_t)); return true; } -void icsneo_discardAllErrors(void) { - icsneo::DiscardErrors(); +void icsneo_discardAllEvents(void) { + icsneo::DiscardEvents(); } -void icsneo_discardDeviceErrors(const neodevice_t* device) { +void icsneo_discardDeviceEvents(const neodevice_t* device) { if(!icsneo_isValidNeoDevice(device)) return; if(device == nullptr) - icsneo::DiscardErrors(nullptr); // Discard errors not associated with a device + icsneo::DiscardEvents(nullptr); // Discard events not associated with a device else - icsneo::DiscardErrors(device->device); + icsneo::DiscardEvents(device->device); } -void icsneo_setErrorLimit(size_t newLimit) { - icsneo::SetErrorLimit(newLimit); +void icsneo_setEventLimit(size_t newLimit) { + icsneo::SetEventLimit(newLimit); } -size_t icsneo_getErrorLimit(void) { - return icsneo::GetErrorLimit(); +size_t icsneo_getEventLimit(void) { + return icsneo::GetEventLimit(); } bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) { if(count == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } @@ -557,7 +557,7 @@ bool icsneo_getSupportedDevices(devicetype_t* devices, size_t* count) { if(*count < len) { len = *count; - ErrorManager::GetInstance().add(APIError::OutputTruncated); + EventManager::GetInstance().add(APIEvent::Type::OutputTruncated, APIEvent::Severity::EventWarning); } for(size_t i = 0; i < len; i++) @@ -572,7 +572,7 @@ extern bool DLLExport icsneo_getTimestampResolution(const neodevice_t* device, u return false; if(resolution == nullptr) { - ErrorManager::GetInstance().add(APIError::RequiredParameterNull); + EventManager::GetInstance().add(APIEvent::Type::RequiredParameterNull, APIEvent::Severity::Error); return false; } diff --git a/api/icsneocpp/error.cpp b/api/icsneocpp/error.cpp deleted file mode 100644 index 8f906ab..0000000 --- a/api/icsneocpp/error.cpp +++ /dev/null @@ -1,294 +0,0 @@ -#include "icsneo/api/error.h" -#include "icsneo/device/device.h" -#include - -using namespace icsneo; - -APIError::APIError(ErrorType error) : errorStruct({}) { - init(error); -} - -APIError::APIError(ErrorType error, const Device* forDevice) : errorStruct({}) { - device = forDevice; - serial = device->getSerial(); - errorStruct.serial[serial.copy(errorStruct.serial, sizeof(errorStruct.serial))] = '\0'; - - init(error); -} - -void APIError::init(ErrorType error) { - timepoint = ErrorClock::now(); - errorStruct.description = DescriptionForType(error); - errorStruct.errorNumber = (uint32_t)error; - errorStruct.severity = (uint8_t)SeverityForType(error); - errorStruct.timestamp = ErrorClock::to_time_t(timepoint); -} - -std::string APIError::describe() const noexcept { - std::stringstream ss; - if(device) - ss << *device; // Makes use of device.describe() - else - ss << "API"; - - Severity severity = getSeverity(); - if(severity == Severity::Info) { - ss << " Info: "; - } else if(severity == Severity::Warning) { - ss << " Warning: "; - } else if(severity == Severity::Error) { - ss << " Error: "; - } else { - // Should never get here, since Severity::Any should only be used for filtering - ss << " Any: "; - } - - ss << getDescription(); - return ss.str(); -} - -bool APIError::isForDevice(std::string filterSerial) const noexcept { - if(!device || filterSerial.length() == 0) - return false; - return device->getSerial() == filterSerial; -} - -// API Errors -static constexpr const char* ERROR_INVALID_NEODEVICE = "The provided neodevice_t object was invalid."; -static constexpr const char* ERROR_REQUIRED_PARAMETER_NULL = "A required parameter was NULL."; -static constexpr const char* ERROR_BUFFER_INSUFFICIENT = "The provided buffer was insufficient. No data was written."; -static constexpr const char* ERROR_OUTPUT_TRUNCATED = "The output was too large for the provided buffer and has been truncated."; -static constexpr const char* ERROR_PARAMETER_OUT_OF_RANGE = "A parameter was out of range."; -static constexpr const char* ERROR_DEVICE_CURRENTLY_OPEN = "The device is currently open. Perhaps a different device state is required."; -static constexpr const char* ERROR_DEVICE_CURRENTLY_CLOSED = "The device is currently closed. Perhaps a different device state is required."; -static constexpr const char* ERROR_DEVICE_CURRENTLY_ONLINE = "The device is currently online. Perhaps a different device state is required."; -static constexpr const char* ERROR_DEVICE_CURRENTLY_OFFLINE = "The device is currently offline. Perhaps a different device state is required."; -static constexpr const char* ERROR_DEVICE_CURRENTLY_POLLING = "The device is currently polling for messages. Perhaps a different device state is required."; -static constexpr const char* ERROR_DEVICE_NOT_CURRENTLY_POLLING = "The device is not currently polling for messages. Perhaps a different device state is required."; -static constexpr const char* ERROR_UNSUPPORTED_TX_NETWORK = "Message network is not a supported TX network."; -static constexpr const char* ERROR_MESSAGE_MAX_LENGTH_EXCEEDED = "The message was too long."; - -// Device Errors -static constexpr const char* ERROR_POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!"; -static constexpr const char* ERROR_NO_SERIAL_NUMBER = "Communication could not be established with the device. Perhaps it is not powered with 12 volts?"; -static constexpr const char* ERROR_INCORRECT_SERIAL_NUMBER = "The device did not return the expected serial number!"; -static constexpr const char* ERROR_SETTINGS_READ = "The device settings could not be read."; -static constexpr const char* ERROR_SETTINGS_VERSION = "The settings version is incorrect, please update your firmware with neoVI Explorer."; -static constexpr const char* ERROR_SETTINGS_LENGTH = "The settings length is incorrect, please update your firmware with neoVI Explorer."; -static constexpr const char* ERROR_SETTINGS_CHECKSUM = "The settings checksum is incorrect, attempting to set defaults may remedy this issue."; -static constexpr const char* ERROR_SETTINGS_NOT_AVAILABLE = "Settings are not available for this device."; -static constexpr const char* ERROR_SETTINGS_READONLY = "Settings are read-only for this device."; -static constexpr const char* ERROR_CAN_SETTINGS_NOT_AVAILABLE = "CAN settings are not available for this device."; -static constexpr const char* ERROR_CANFD_SETTINGS_NOT_AVAILABLE = "CANFD settings are not available for this device."; -static constexpr const char* ERROR_LSFTCAN_SETTINGS_NOT_AVAILABLE = "LSFTCAN settings are not available for this device."; -static constexpr const char* ERROR_SWCAN_SETTINGS_NOT_AVAILABLE = "SWCAN settings are not available for this device."; -static constexpr const char* ERROR_BAUDRATE_NOT_FOUND = "The baudrate was not found."; -static constexpr const char* ERROR_UNEXPECTED_NETWORK_TYPE = "The network type was not found."; -static constexpr const char* ERROR_DEVICE_FIRMWARE_OUT_OF_DATE = "The device firmware is out of date. New API functionality may not be supported."; -static constexpr const char* ERROR_SETTINGS_STRUCTURE_MISMATCH = "Unexpected settings structure for this device."; -static constexpr const char* ERROR_SETTINGS_STRUCTURE_TRUNCATED = "Settings structure is longer than the device supports and will be truncated."; -static constexpr const char* ERROR_NO_DEVICE_RESPONSE = "Expected a response from the device but none were found."; -static constexpr const char* ERROR_MESSAGE_FORMATTING = "The message was not properly formed."; -static constexpr const char* ERROR_CANFD_NOT_SUPPORTED = "This device does not support CANFD."; -static constexpr const char* ERROR_RTR_NOT_SUPPORTED = "RTR is not supported with CANFD."; - -// Transport Errors -static constexpr const char* ERROR_FAILED_TO_READ = "A read operation failed."; -static constexpr const char* ERROR_FAILED_TO_WRITE = "A write operation failed."; -static constexpr const char* ERROR_DRIVER_FAILED_TO_OPEN = "The device driver encountered a low-level error while opening the device."; -static constexpr const char* ERROR_DRIVER_FAILED_TO_CLOSE = "The device driver encountered a low-level error while closing the device."; -static constexpr const char* ERROR_PACKET_CHECKSUM_ERROR = "There was a checksum error while decoding a packet. The packet was dropped."; -static constexpr const char* ERROR_TRANSMIT_BUFFER_FULL = "The transmit buffer is full and the device is set to non-blocking."; -static constexpr const char* ERROR_PCAP_COULD_NOT_START = "The PCAP driver could not be started. Ethernet devices will not be found."; -static constexpr const char* ERROR_PCAP_COULD_NOT_FIND_DEVICES = "The PCAP driver failed to find devices. Ethernet devices will not be found."; -static constexpr const char* ERROR_PACKET_DECODING = "The packet could not be decoded."; - -static constexpr const char* ERROR_TOO_MANY_ERRORS = "Too many errors have occurred. The list has been truncated."; -static constexpr const char* ERROR_UNKNOWN = "An unknown internal error occurred."; -static constexpr const char* ERROR_INVALID = "An invalid internal error occurred."; -const char* APIError::DescriptionForType(ErrorType type) { - switch(type) { - // API Errors - case InvalidNeoDevice: - return ERROR_INVALID_NEODEVICE; - case RequiredParameterNull: - return ERROR_REQUIRED_PARAMETER_NULL; - case BufferInsufficient: - return ERROR_BUFFER_INSUFFICIENT; - case OutputTruncated: - return ERROR_OUTPUT_TRUNCATED; - case ParameterOutOfRange: - return ERROR_PARAMETER_OUT_OF_RANGE; - case DeviceCurrentlyOpen: - return ERROR_DEVICE_CURRENTLY_OPEN; - case DeviceCurrentlyClosed: - return ERROR_DEVICE_CURRENTLY_CLOSED; - case DeviceCurrentlyOnline: - return ERROR_DEVICE_CURRENTLY_ONLINE; - case DeviceCurrentlyOffline: - return ERROR_DEVICE_CURRENTLY_OFFLINE; - case DeviceCurrentlyPolling: - return ERROR_DEVICE_CURRENTLY_POLLING; - case DeviceNotCurrentlyPolling: - return ERROR_DEVICE_NOT_CURRENTLY_POLLING; - case UnsupportedTXNetwork: - return ERROR_UNSUPPORTED_TX_NETWORK; - case MessageMaxLengthExceeded: - return ERROR_MESSAGE_MAX_LENGTH_EXCEEDED; - - // Device Errors - case PollingMessageOverflow: - return ERROR_POLLING_MESSAGE_OVERFLOW; - case NoSerialNumber: - return ERROR_NO_SERIAL_NUMBER; - case IncorrectSerialNumber: - return ERROR_INCORRECT_SERIAL_NUMBER; - case SettingsReadError: - return ERROR_SETTINGS_READ; - case SettingsVersionError: - return ERROR_SETTINGS_VERSION; - case SettingsLengthError: - return ERROR_SETTINGS_LENGTH; - case SettingsChecksumError: - return ERROR_SETTINGS_CHECKSUM; - case SettingsNotAvailable: - return ERROR_SETTINGS_NOT_AVAILABLE; - case SettingsReadOnly: - return ERROR_SETTINGS_READONLY; - case CANSettingsNotAvailable: - return ERROR_CAN_SETTINGS_NOT_AVAILABLE; - case CANFDSettingsNotAvailable: - return ERROR_CANFD_SETTINGS_NOT_AVAILABLE; - case LSFTCANSettingsNotAvailable: - return ERROR_LSFTCAN_SETTINGS_NOT_AVAILABLE; - case SWCANSettingsNotAvailable: - return ERROR_SWCAN_SETTINGS_NOT_AVAILABLE; - case BaudrateNotFound: - return ERROR_BAUDRATE_NOT_FOUND; - case UnexpectedNetworkType: - return ERROR_UNEXPECTED_NETWORK_TYPE; - case DeviceFirmwareOutOfDate: - return ERROR_DEVICE_FIRMWARE_OUT_OF_DATE; - case SettingsStructureMismatch: - return ERROR_SETTINGS_STRUCTURE_MISMATCH; - case SettingsStructureTruncated: - return ERROR_SETTINGS_STRUCTURE_TRUNCATED; - case NoDeviceResponse: - return ERROR_NO_DEVICE_RESPONSE; - case MessageFormattingError: - return ERROR_MESSAGE_FORMATTING; - case CANFDNotSupported: - return ERROR_CANFD_NOT_SUPPORTED; - case RTRNotSupported: - return ERROR_RTR_NOT_SUPPORTED; - - // Transport Errors - case FailedToRead: - return ERROR_FAILED_TO_READ; - case FailedToWrite: - return ERROR_FAILED_TO_WRITE; - case DriverFailedToOpen: - return ERROR_DRIVER_FAILED_TO_OPEN; - case DriverFailedToClose: - return ERROR_DRIVER_FAILED_TO_CLOSE; - case PacketChecksumError: - return ERROR_PACKET_CHECKSUM_ERROR; - case TransmitBufferFull: - return ERROR_TRANSMIT_BUFFER_FULL; - case PCAPCouldNotStart: - return ERROR_PCAP_COULD_NOT_START; - case PCAPCouldNotFindDevices: - return ERROR_PCAP_COULD_NOT_FIND_DEVICES; - case PacketDecodingError: - return ERROR_PACKET_DECODING; - - // Other Errors - case TooManyErrors: - return ERROR_TOO_MANY_ERRORS; - case Unknown: - return ERROR_UNKNOWN; - default: - return ERROR_INVALID; - } -} - -APIError::Severity APIError::SeverityForType(ErrorType type) { - switch(type) { - // API Warnings - case OutputTruncated: - - // Device Warnings - case PollingMessageOverflow: - case DeviceFirmwareOutOfDate: - case SettingsStructureTruncated: - // Transport Warnings - case PCAPCouldNotStart: - case PCAPCouldNotFindDevices: - return Severity::Warning; - - // API Errors - case InvalidNeoDevice: - case RequiredParameterNull: - case BufferInsufficient: - case ParameterOutOfRange: - case UnsupportedTXNetwork: - case MessageMaxLengthExceeded: - - // Device Errors - case DeviceCurrentlyOpen: - case DeviceCurrentlyClosed: - case DeviceCurrentlyOnline: - case DeviceCurrentlyOffline: - case DeviceCurrentlyPolling: - case DeviceNotCurrentlyPolling: - case NoSerialNumber: - case IncorrectSerialNumber: - case SettingsReadError: - case SettingsVersionError: - case SettingsLengthError: - case SettingsChecksumError: - case SettingsNotAvailable: - case SettingsReadOnly: - case CANSettingsNotAvailable: - case CANFDSettingsNotAvailable: - case LSFTCANSettingsNotAvailable: - case SWCANSettingsNotAvailable: - case BaudrateNotFound: - case UnexpectedNetworkType: - case SettingsStructureMismatch: - case NoDeviceResponse: - case MessageFormattingError: - case CANFDNotSupported: - case RTRNotSupported: - - // Transport Errors - case FailedToRead: - case FailedToWrite: - case DriverFailedToOpen: - case DriverFailedToClose: - case PacketChecksumError: - case TransmitBufferFull: - case PacketDecodingError: - // Other Errors - case TooManyErrors: - case Unknown: - default: - return Severity::Error; - } -} - -bool ErrorFilter::match(const APIError& error) const noexcept { - if(type != APIError::Any && type != error.getType()) - return false; - - if(matchOnDevicePtr && !error.isForDevice(device)) - return false; - - if(severity != APIError::Severity::Any && severity != error.getSeverity()) - return false; - - if(serial.length() != 0 && !error.isForDevice(serial)) - return false; - - return true; -} \ No newline at end of file diff --git a/api/icsneocpp/errormanager.cpp b/api/icsneocpp/errormanager.cpp deleted file mode 100644 index 2745ccb..0000000 --- a/api/icsneocpp/errormanager.cpp +++ /dev/null @@ -1,155 +0,0 @@ -#include "icsneo/api/errormanager.h" -#include - -using namespace icsneo; - -static std::unique_ptr singleton; - -ErrorManager& ErrorManager::GetInstance() { - if(!singleton) - singleton = std::unique_ptr(new ErrorManager()); - return *singleton.get(); -} - -void ErrorManager::get(std::vector& errorOutput, size_t max, ErrorFilter filter) { - std::lock_guard lk(mutex); - - if(max == 0) // A limit of 0 indicates no limit - max = (size_t)-1; - - size_t count = 0; - errorOutput.clear(); - auto it = errors.begin(); - while(it != errors.end()) { - if(filter.match(*it)) { - errorOutput.push_back(*it); - errors.erase(it++); - if(count++ >= max) - break; // We now have as many written to output as we can - } else { - std::advance(it, 1); - } - } -} - -bool ErrorManager::getLastError(APIError& errorOutput, ErrorFilter filter) { - std::lock_guard lk(mutex); - - auto it = errors.rbegin(); - while(it != errors.rend()) { - if(filter.match(*it)) { - errorOutput = *it; - errors.erase(std::next(it).base()); - return true; - } - std::advance(it, 1); - } - - return false; -} - -bool ErrorManager::getLastError(APIError& errorOutput, std::thread::id id) { - auto iter = lastUserErrors.find(id); - if(iter == lastUserErrors.end()) { - return false; - } else { - errorOutput = iter->second; - return true; - } -} - -void ErrorManager::discard(ErrorFilter filter) { - std::lock_guard lk(mutex); - errors.remove_if([&filter](const APIError& error) { - return filter.match(error); - }); -} - -size_t ErrorManager::count_internal(ErrorFilter filter) const { - size_t ret = 0; - for(auto& error : errors) - if(filter.match(error)) - ret++; - return ret; -} - -/** - * Ensures errors is always at most errorLimit - 1 in size. - * Returns true if any errors were removed in the process of doing so. - */ -bool ErrorManager::enforceLimit() { - // Remove all TooManyErrors before checking - errors.remove_if([](icsneo::APIError err){ return err.getType() == icsneo::APIError::TooManyErrors; }); - - // We are not overflowing - if(errors.size() < errorLimit) - return false; - - size_t amountToRemove = errors.size() + 1 - errorLimit; - - discardLeastSevere(amountToRemove); - - return true; -} - -APIError::Severity ErrorManager::lowestCurrentSeverity() { - if(errors.empty()) - return APIError::Severity(0); - - APIError::Severity lowest = APIError::Severity::Error; - auto it = errors.begin(); - while(it != errors.end()) { - if((*it).getSeverity() < lowest) - lowest = (*it).getSeverity(); - it++; - } - return lowest; -} - -void ErrorManager::discardLeastSevere(size_t count) { - if(count == 0) - return; - - // Erase needed Info level errors, starting from the beginning - ErrorFilter infoFilter(APIError::Severity::Info); - auto it = errors.begin(); - while(it != errors.end()) { - if(infoFilter.match(*it)) { - errors.erase(it++); - if(--count == 0) - break; - } else { - it++; - } - } - - // Erase needed Warning level errors, starting from the beginning - if(count != 0) { - ErrorFilter warningFilter(APIError::Severity::Warning); - it = errors.begin(); - while(it != errors.end()) { - if(warningFilter.match(*it)) { - errors.erase(it++); - if(--count == 0) - break; - } else { - it++; - } - } - } - - // Erase needed Error level errors, starting from the beginning - if(count != 0) { - ErrorFilter errorFilter(APIError::Severity::Error); - it = errors.begin(); - while(it != errors.end()) { - if(errorFilter.match(*it)) { - errors.erase(it++); - if(--count == 0) - break; - } else { - it++; - } - } - } -} \ No newline at end of file diff --git a/api/icsneocpp/event.cpp b/api/icsneocpp/event.cpp new file mode 100644 index 0000000..9d14fa4 --- /dev/null +++ b/api/icsneocpp/event.cpp @@ -0,0 +1,227 @@ +#include "icsneo/api/event.h" +#include "icsneo/device/device.h" +#include + +using namespace icsneo; + +APIEvent::APIEvent(Type type, APIEvent::Severity severity, const Device* device) : eventStruct({}) { + this->device = device; + if(!device) { + serial = device->getSerial(); + eventStruct.serial[serial.copy(eventStruct.serial, sizeof(eventStruct.serial))] = '\0'; + } + + init(type, severity); +} + +void APIEvent::init(Type event, APIEvent::Severity severity) { + timepoint = EventClock::now(); + eventStruct.description = DescriptionForType(event); + eventStruct.eventNumber = (uint32_t)event; + eventStruct.severity = (uint8_t) severity; + eventStruct.timestamp = EventClock::to_time_t(timepoint); +} + +std::string APIEvent::describe() const noexcept { + std::stringstream ss; + if(device) + ss << *device; // Makes use of device.describe() + else + ss << "API"; + + Severity severity = getSeverity(); + if(severity == Severity::EventInfo) { + ss << " Info: "; + } else if(severity == Severity::EventWarning) { + ss << " Warning: "; + } else if(severity == Severity::Error) { + ss << " Error: "; + } else { + // Should never get here, since Severity::Any should only be used for filtering + ss << " Any: "; + } + + ss << getDescription(); + return ss.str(); +} + +bool APIEvent::isForDevice(std::string filterSerial) const noexcept { + if(!device || filterSerial.length() == 0) + return false; + return device->getSerial() == filterSerial; +} + +// API Errors +static constexpr const char* INVALID_NEODEVICE = "The provided neodevice_t object was invalid."; +static constexpr const char* REQUIRED_PARAMETER_NULL = "A required parameter was NULL."; +static constexpr const char* OUTPUT_TRUNCATED = "The output was too large for the provided buffer and has been truncated."; +static constexpr const char* BUFFER_INSUFFICIENT = "The provided buffer was insufficient. No data was written."; +static constexpr const char* PARAMETER_OUT_OF_RANGE = "A parameter was out of range."; +static constexpr const char* DEVICE_CURRENTLY_OPEN = "The device is currently open."; +static constexpr const char* DEVICE_CURRENTLY_CLOSED = "The device is currently closed."; +static constexpr const char* DEVICE_CURRENTLY_ONLINE = "The device is currently online."; +static constexpr const char* DEVICE_CURRENTLY_OFFLINE = "The device is currently offline."; +static constexpr const char* DEVICE_CURRENTLY_POLLING = "The device is currently polling for messages."; +static constexpr const char* DEVICE_NOT_CURRENTLY_POLLING = "The device is not currently polling for messages."; +static constexpr const char* UNSUPPORTED_TX_NETWORK = "Message network is not a supported TX network."; +static constexpr const char* MESSAGE_MAX_LENGTH_EXCEEDED = "The message was too long."; + +// Device Errors +static constexpr const char* POLLING_MESSAGE_OVERFLOW = "Too many messages have been recieved for the polling message buffer, some have been lost!"; +static constexpr const char* NO_SERIAL_NUMBER = "Communication could not be established with the device. Perhaps it is not powered with 12 volts?"; +static constexpr const char* INCORRECT_SERIAL_NUMBER = "The device did not return the expected serial number!"; +static constexpr const char* SETTINGS_READ = "The device settings could not be read."; +static constexpr const char* SETTINGS_VERSION = "The settings version is incorrect, please update your firmware with neoVI Explorer."; +static constexpr const char* SETTINGS_LENGTH = "The settings length is incorrect, please update your firmware with neoVI Explorer."; +static constexpr const char* SETTINGS_CHECKSUM = "The settings checksum is incorrect, attempting to set defaults may remedy this issue."; +static constexpr const char* SETTINGS_NOT_AVAILABLE = "Settings are not available for this device."; +static constexpr const char* SETTINGS_READONLY = "Settings are read-only for this device."; +static constexpr const char* CAN_SETTINGS_NOT_AVAILABLE = "CAN settings are not available for this device."; +static constexpr const char* CANFD_SETTINGS_NOT_AVAILABLE = "CANFD settings are not available for this device."; +static constexpr const char* LSFTCAN_SETTINGS_NOT_AVAILABLE = "LSFTCAN settings are not available for this device."; +static constexpr const char* SWCAN_SETTINGS_NOT_AVAILABLE = "SWCAN settings are not available for this device."; +static constexpr const char* BAUDRATE_NOT_FOUND = "The baudrate was not found."; +static constexpr const char* UNEXPECTED_NETWORK_TYPE = "The network type was not found."; +static constexpr const char* DEVICE_FIRMWARE_OUT_OF_DATE = "The device firmware is out of date. New API functionality may not be supported."; +static constexpr const char* SETTINGS_STRUCTURE_MISMATCH = "Unexpected settings structure for this device."; +static constexpr const char* SETTINGS_STRUCTURE_TRUNCATED = "Settings structure is longer than the device supports and will be truncated."; +static constexpr const char* NO_DEVICE_RESPONSE = "Expected a response from the device but none were found."; +static constexpr const char* MESSAGE_FORMATTING = "The message was not properly formed."; +static constexpr const char* CANFD_NOT_SUPPORTED = "This device does not support CANFD."; +static constexpr const char* RTR_NOT_SUPPORTED = "RTR is not supported with CANFD."; + +// Transport Errors +static constexpr const char* FAILED_TO_READ = "A read operation failed."; +static constexpr const char* FAILED_TO_WRITE = "A write operation failed."; +static constexpr const char* DRIVER_FAILED_TO_OPEN = "The device driver encountered a low-level error while opening the device."; +static constexpr const char* DRIVER_FAILED_TO_CLOSE = "The device driver encountered a low-level error while closing the device."; +static constexpr const char* PACKET_CHECKSUM_ERROR = "There was a checksum error while decoding a packet. The packet was dropped."; +static constexpr const char* TRANSMIT_BUFFER_FULL = "The transmit buffer is full and the device is set to non-blocking."; +static constexpr const char* PCAP_COULD_NOT_START = "The PCAP driver could not be started. Ethernet devices will not be found."; +static constexpr const char* PCAP_COULD_NOT_FIND_DEVICES = "The PCAP driver failed to find devices. Ethernet devices will not be found."; +static constexpr const char* PACKET_DECODING = "The packet could not be decoded."; + +static constexpr const char* TOO_MANY_EVENTS = "Too many events have occurred. The list has been truncated."; +static constexpr const char* UNKNOWN = "An unknown internal error occurred."; +static constexpr const char* INVALID = "An invalid internal error occurred."; +const char* APIEvent::DescriptionForType(Type type) { + switch(type) { + // API Errors + case Type::InvalidNeoDevice: + return INVALID_NEODEVICE; + case Type::RequiredParameterNull: + return REQUIRED_PARAMETER_NULL; + case Type::BufferInsufficient: + return BUFFER_INSUFFICIENT; + case Type::OutputTruncated: + return OUTPUT_TRUNCATED; + case Type::ParameterOutOfRange: + return PARAMETER_OUT_OF_RANGE; + case Type::DeviceCurrentlyOpen: + return DEVICE_CURRENTLY_OPEN; + case Type::DeviceCurrentlyClosed: + return DEVICE_CURRENTLY_CLOSED; + case Type::DeviceCurrentlyOnline: + return DEVICE_CURRENTLY_ONLINE; + case Type::DeviceCurrentlyOffline: + return DEVICE_CURRENTLY_OFFLINE; + case Type::DeviceCurrentlyPolling: + return DEVICE_CURRENTLY_POLLING; + case Type::DeviceNotCurrentlyPolling: + return DEVICE_NOT_CURRENTLY_POLLING; + case Type::UnsupportedTXNetwork: + return UNSUPPORTED_TX_NETWORK; + case Type::MessageMaxLengthExceeded: + return MESSAGE_MAX_LENGTH_EXCEEDED; + + // Device Errors + case Type::PollingMessageOverflow: + return POLLING_MESSAGE_OVERFLOW; + case Type::NoSerialNumber: + return NO_SERIAL_NUMBER; + case Type::IncorrectSerialNumber: + return INCORRECT_SERIAL_NUMBER; + case Type::SettingsReadError: + return SETTINGS_READ; + case Type::SettingsVersionError: + return SETTINGS_VERSION; + case Type::SettingsLengthError: + return SETTINGS_LENGTH; + case Type::SettingsChecksumError: + return SETTINGS_CHECKSUM; + case Type::SettingsNotAvailable: + return SETTINGS_NOT_AVAILABLE; + case Type::SettingsReadOnly: + return SETTINGS_READONLY; + case Type::CANSettingsNotAvailable: + return CAN_SETTINGS_NOT_AVAILABLE; + case Type::CANFDSettingsNotAvailable: + return CANFD_SETTINGS_NOT_AVAILABLE; + case Type::LSFTCANSettingsNotAvailable: + return LSFTCAN_SETTINGS_NOT_AVAILABLE; + case Type::SWCANSettingsNotAvailable: + return SWCAN_SETTINGS_NOT_AVAILABLE; + case Type::BaudrateNotFound: + return BAUDRATE_NOT_FOUND; + case Type::UnexpectedNetworkType: + return UNEXPECTED_NETWORK_TYPE; + case Type::DeviceFirmwareOutOfDate: + return DEVICE_FIRMWARE_OUT_OF_DATE; + case Type::SettingsStructureMismatch: + return SETTINGS_STRUCTURE_MISMATCH; + case Type::SettingsStructureTruncated: + return SETTINGS_STRUCTURE_TRUNCATED; + case Type::NoDeviceResponse: + return NO_DEVICE_RESPONSE; + case Type::MessageFormattingError: + return MESSAGE_FORMATTING; + case Type::CANFDNotSupported: + return CANFD_NOT_SUPPORTED; + case Type::RTRNotSupported: + return RTR_NOT_SUPPORTED; + + // Transport Errors + case Type::FailedToRead: + return FAILED_TO_READ; + case Type::FailedToWrite: + return FAILED_TO_WRITE; + case Type::DriverFailedToOpen: + return DRIVER_FAILED_TO_OPEN; + case Type::DriverFailedToClose: + return DRIVER_FAILED_TO_CLOSE; + case Type::PacketChecksumError: + return PACKET_CHECKSUM_ERROR; + case Type::TransmitBufferFull: + return TRANSMIT_BUFFER_FULL; + case Type::PCAPCouldNotStart: + return PCAP_COULD_NOT_START; + case Type::PCAPCouldNotFindDevices: + return PCAP_COULD_NOT_FIND_DEVICES; + case Type::PacketDecodingError: + return PACKET_DECODING; + + // Other Errors + case Type::TooManyEvents: + return TOO_MANY_EVENTS; + case Type::Unknown: + return UNKNOWN; + default: + return INVALID; + } +} + +bool EventFilter::match(const APIEvent& event) const noexcept { + if(type != APIEvent::Type::Any && type != event.getType()) + return false; + + if(matchOnDevicePtr && !event.isForDevice(device)) + return false; + + if(severity != APIEvent::Severity::Any && severity != event.getSeverity()) + return false; + + if(serial.length() != 0 && !event.isForDevice(serial)) + return false; + + return true; +} \ No newline at end of file diff --git a/api/icsneocpp/eventmanager.cpp b/api/icsneocpp/eventmanager.cpp new file mode 100644 index 0000000..e38930c --- /dev/null +++ b/api/icsneocpp/eventmanager.cpp @@ -0,0 +1,133 @@ +#include "icsneo/api/eventmanager.h" +#include + +using namespace icsneo; + +static std::unique_ptr singleton; + +EventManager& EventManager::GetInstance() { + if(!singleton) + singleton = std::unique_ptr(new EventManager()); + return *singleton.get(); +} + +void EventManager::get(std::vector& eventOutput, size_t max, EventFilter filter) { + std::lock_guard lk(mutex); + + if(max == 0) // A limit of 0 indicates no limit + max = (size_t)-1; + + size_t count = 0; + eventOutput.clear(); + auto it = events.begin(); + while(it != events.end()) { + if(filter.match(*it)) { + eventOutput.push_back(*it); + events.erase(it++); + if(count++ >= max) + break; // We now have as many written to output as we can + } else { + std::advance(it, 1); + } + } +} + +/** + * Removes the returned error from the map + * If no error was found, return a default-constructed event + */ +APIEvent EventManager::getLastError() { + std::lock_guard lk(mutex); + + auto it = lastUserErrors.find(std::this_thread::get_id()); + if(it == lastUserErrors.end()) { + return APIEvent(APIEvent::Type::NoErrorFound, APIEvent::Severity::EventInfo); + } else { + APIEvent ret = it->second; + lastUserErrors.erase(it); + return ret; + } +} + +void EventManager::discard(EventFilter filter) { + std::lock_guard lk(mutex); + events.remove_if([&filter](const APIEvent& event) { + return filter.match(event); + }); +} + +size_t EventManager::count_internal(EventFilter filter) const { + size_t ret = 0; + for(auto& event : events) + if(filter.match(event)) + ret++; + return ret; +} + +/** + * Ensures events is always at most eventLimit - 1 in size. + * Returns true if any events were removed in the process of doing so. + */ +bool EventManager::enforceLimit() { + // Remove all TooManyEvents before checking + events.remove_if([](icsneo::APIEvent err){ return err.getType() == APIEvent::Type::TooManyEvents; }); + + // We are not overflowing + if(events.size() < eventLimit) + return false; + + size_t amountToRemove = events.size() + 1 - eventLimit; + + discardLeastSevere(amountToRemove); + + return true; +} + +APIEvent::Severity EventManager::lowestCurrentSeverity() { + if(events.empty()) + return APIEvent::Severity(0); + + APIEvent::Severity lowest = APIEvent::Severity::Error; + auto it = events.begin(); + while(it != events.end()) { + if((*it).getSeverity() < lowest) + lowest = (*it).getSeverity(); + it++; + } + return lowest; +} + +void EventManager::discardLeastSevere(size_t count) { + if(count == 0) + return; + + // Erase needed Info level events, starting from the beginning + EventFilter infoFilter(APIEvent::Severity::EventInfo); + auto it = events.begin(); + while(it != events.end()) { + if(infoFilter.match(*it)) { + events.erase(it++); + if(--count == 0) + break; + } else { + it++; + } + } + + // Erase needed Warning level events, starting from the beginning + if(count != 0) { + EventFilter warningFilter(APIEvent::Severity::EventWarning); + it = events.begin(); + while(it != events.end()) { + if(warningFilter.match(*it)) { + events.erase(it++); + if(--count == 0) + break; + } else { + it++; + } + } + } + + // No need to check for Error level events, as they are not stored in the list of events. +} \ No newline at end of file diff --git a/api/icsneocpp/icsneocpp.cpp b/api/icsneocpp/icsneocpp.cpp index 139f5c8..4734f33 100644 --- a/api/icsneocpp/icsneocpp.cpp +++ b/api/icsneocpp/icsneocpp.cpp @@ -11,38 +11,38 @@ std::vector icsneo::GetSupportedDevices() { return DeviceFinder::GetSupportedDevices(); } -size_t icsneo::ErrorCount(ErrorFilter filter) { - return ErrorManager::GetInstance().count(filter); +size_t icsneo::EventCount(EventFilter filter) { + return EventManager::GetInstance().count(filter); } -std::vector icsneo::GetErrors(ErrorFilter filter, size_t max) { - return ErrorManager::GetInstance().get(filter, max); +std::vector icsneo::GetEvents(EventFilter filter, size_t max) { + return EventManager::GetInstance().get(filter, max); } -std::vector icsneo::GetErrors(size_t max, ErrorFilter filter) { - return ErrorManager::GetInstance().get(max, filter); +std::vector icsneo::GetEvents(size_t max, EventFilter filter) { + return EventManager::GetInstance().get(max, filter); } -void icsneo::GetErrors(std::vector& errors, ErrorFilter filter, size_t max) { - ErrorManager::GetInstance().get(errors, filter, max); +void icsneo::GetEvents(std::vector& events, EventFilter filter, size_t max) { + EventManager::GetInstance().get(events, filter, max); } -void icsneo::GetErrors(std::vector& errors, size_t max, ErrorFilter filter) { - ErrorManager::GetInstance().get(errors, max, filter); +void icsneo::GetEvents(std::vector& events, size_t max, EventFilter filter) { + EventManager::GetInstance().get(events, max, filter); } -bool icsneo::GetLastError(APIError& error, ErrorFilter filter) { - return ErrorManager::GetInstance().getLastError(error, filter); +APIEvent icsneo::GetLastError() { + return EventManager::GetInstance().getLastError(); } -void icsneo::DiscardErrors(ErrorFilter filter) { - ErrorManager::GetInstance().discard(filter); +void icsneo::DiscardEvents(EventFilter filter) { + EventManager::GetInstance().discard(filter); } -void icsneo::SetErrorLimit(size_t newLimit) { - ErrorManager::GetInstance().setErrorLimit(newLimit); +void icsneo::SetEventLimit(size_t newLimit) { + EventManager::GetInstance().setEventLimit(newLimit); } -size_t icsneo::GetErrorLimit() { - return ErrorManager::GetInstance().getErrorLimit(); +size_t icsneo::GetEventLimit() { + return EventManager::GetInstance().getEventLimit(); } \ No newline at end of file diff --git a/communication/communication.cpp b/communication/communication.cpp index bfc8521..4071d7f 100644 --- a/communication/communication.cpp +++ b/communication/communication.cpp @@ -19,7 +19,7 @@ int Communication::messageCallbackIDCounter = 1; bool Communication::open() { if(isOpen()) { - err(APIError::DeviceCurrentlyOpen); + report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); return false; } @@ -40,7 +40,7 @@ void Communication::joinThreads() { bool Communication::close() { if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } @@ -74,12 +74,12 @@ bool Communication::getSettingsSync(std::vector& data, std::chrono::mil std::shared_ptr gsmsg = std::dynamic_pointer_cast(msg); if(!gsmsg) { - err(APIError::Unknown); + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return false; } if(gsmsg->response != ReadSettingsMessage::Response::OK) { - err(APIError::Unknown); + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return false; } @@ -112,7 +112,7 @@ bool Communication::removeMessageCallback(int id) { messageCallbacks.erase(id); return true; } catch(...) { - err(APIError::Unknown); + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return false; } } diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 05aa600..396e588 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -23,7 +23,7 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrdata); if(!result) { - err(APIError::PacketDecodingError); + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return false; // A nullptr was returned, the packet was not long enough to decode } @@ -36,13 +36,13 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrdata.size() < 24) { - err(APIError::PacketDecodingError); + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return false; } result = HardwareCANPacket::DecodeToMessage(packet->data); if(!result) { - err(APIError::PacketDecodingError); + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return false; // A nullptr was returned, the packet was malformed } // Timestamps are in (resolution) ns increments since 1/1/2007 GMT 00:00:00.0000 @@ -55,7 +55,7 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrnetwork.getNetID()) { case Network::NetID::Reset_Status: { if(packet->data.size() < sizeof(HardwareResetStatusPacket)) { - err(APIError::PacketDecodingError); + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); return false; } diff --git a/communication/encoder.cpp b/communication/encoder.cpp index a5c14ef..5418f1b 100644 --- a/communication/encoder.cpp +++ b/communication/encoder.cpp @@ -14,12 +14,12 @@ bool Encoder::encode(std::vector& result, const std::shared_ptr(message); if(!ethmsg) { - err(APIError::MessageFormattingError); + report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error); return false; // The message was not a properly formed EthernetMessage } useResultAsBuffer = true; - if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, err)) + if(!HardwareEthernetPacket::EncodeFromMessage(*ethmsg, result, report)) return false; break; @@ -29,17 +29,17 @@ bool Encoder::encode(std::vector& result, const std::shared_ptr(message); if(!canmsg) { - err(APIError::MessageFormattingError); + report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error); return false; // The message was not a properly formed CANMessage } if(!supportCANFD && canmsg->isCANFD) { - err(APIError::CANFDNotSupported); + report(APIEvent::Type::CANFDNotSupported, APIEvent::Severity::Error); return false; // This device does not support CAN FD } useResultAsBuffer = true; - if(!HardwareCANPacket::EncodeFromMessage(*canmsg, result, err)) + if(!HardwareCANPacket::EncodeFromMessage(*canmsg, result, report)) return false; // The CANMessage was malformed break; @@ -75,7 +75,7 @@ bool Encoder::encode(std::vector& result, const std::shared_ptr& bytes, std::chrono::millisec bool ICommunication::write(const std::vector& bytes) { if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } @@ -50,14 +50,14 @@ bool ICommunication::write(const std::vector& bytes) { writeCV.wait(lk); } else { if(writeQueue.size_approx() > writeQueueSize) { - err(APIError::TransmitBufferFull); + report(APIEvent::Type::TransmitBufferFull, APIEvent::Severity::Error); return false; } } bool ret = writeQueue.enqueue(WriteOperation(bytes)); if(!ret) - err(APIError::Unknown); + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return ret; } \ No newline at end of file diff --git a/communication/multichannelcommunication.cpp b/communication/multichannelcommunication.cpp index aa4c920..bb41569 100644 --- a/communication/multichannelcommunication.cpp +++ b/communication/multichannelcommunication.cpp @@ -107,7 +107,7 @@ void MultiChannelCommunication::readTask() { for(auto& packet : packetizer->output()) { std::shared_ptr msg; if(!decoder->decode(msg, packet)) { - err(APIError::Unknown); // TODO Use specific error + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); // TODO Use specific error continue; } diff --git a/communication/packet/canpacket.cpp b/communication/packet/canpacket.cpp index 53d325f..41c38d4 100644 --- a/communication/packet/canpacket.cpp +++ b/communication/packet/canpacket.cpp @@ -79,15 +79,15 @@ std::shared_ptr HardwareCANPacket::DecodeToMessage(const std::vector return msg; } -bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector& result, const device_errorhandler_t& err) { +bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector& result, const device_eventhandler_t& report) { if(message.isCANFD && message.isRemote) { - err(APIError::RTRNotSupported); + report(APIEvent::Type::RTRNotSupported, APIEvent::Severity::Error); return false; // RTR frames can not be used with CAN FD } const size_t dataSize = message.data.size(); if(dataSize > 64 || (dataSize > 8 && !message.isCANFD)) { - err(APIError::MessageMaxLengthExceeded); + report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error); return false; // Too much data for the protocol } @@ -166,7 +166,7 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector lengthNibble = 0xF; break; default: - err(APIError::MessageMaxLengthExceeded); + report(APIEvent::Type::MessageMaxLengthExceeded, APIEvent::Severity::Error); return false; // CAN FD frame may have had an incorrect byte count } } @@ -182,7 +182,7 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector // Next 2-4 bytes are ArbID if(message.isExtended) { if(message.arbid >= 0x20000000) {// Extended messages use 29-bit arb IDs - err(APIError::MessageFormattingError); + report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error); return false; } @@ -194,7 +194,7 @@ bool HardwareCANPacket::EncodeFromMessage(const CANMessage& message, std::vector }); } else { if(message.arbid >= 0x800) {// Standard messages use 11-bit arb IDs - err(APIError::MessageFormattingError); + report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error); return false; } diff --git a/communication/packet/ethernetpacket.cpp b/communication/packet/ethernetpacket.cpp index 0061315..de3410e 100644 --- a/communication/packet/ethernetpacket.cpp +++ b/communication/packet/ethernetpacket.cpp @@ -53,7 +53,7 @@ std::shared_ptr HardwareEthernetPacket::DecodeToMessage(const s return messagePtr; } -bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector& bytestream, const device_errorhandler_t&) { +bool HardwareEthernetPacket::EncodeFromMessage(const EthernetMessage& message, std::vector& bytestream, const device_eventhandler_t&) { const size_t unpaddedSize = message.data.size(); size_t paddedSize = unpaddedSize; diff --git a/communication/packetizer.cpp b/communication/packetizer.cpp index d839db8..040db94 100644 --- a/communication/packetizer.cpp +++ b/communication/packetizer.cpp @@ -111,7 +111,7 @@ bool Packetizer::input(const std::vector& inputBytes) { bytes.pop_front(); } else { if(gotGoodPackets) // Don't complain unless we've already gotten a good packet, in case we started in the middle of a stream - err(APIError::PacketChecksumError); + report(APIEvent::Type::PacketChecksumError, APIEvent::Severity::Error); bytes.pop_front(); // Drop the first byte so it doesn't get picked up again } diff --git a/device/device.cpp b/device/device.cpp index 2e2472d..e0cc1db 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -79,7 +79,7 @@ std::string Device::describe() const { bool Device::enableMessagePolling() { if(isMessagePollingEnabled()) {// We are already polling - err(APIError::DeviceCurrentlyPolling); + report(APIEvent::Type::DeviceCurrentlyPolling, APIEvent::Severity::Error); return false; } messagePollingCallbackID = com->addMessageCallback(MessageCallback([this](std::shared_ptr message) { @@ -91,7 +91,7 @@ bool Device::enableMessagePolling() { bool Device::disableMessagePolling() { if(!isMessagePollingEnabled()) { - err(APIError::DeviceNotCurrentlyPolling); + report(APIEvent::Type::DeviceNotCurrentlyPolling, APIEvent::Severity::Error); return false; // Not currently polling } auto ret = com->removeMessageCallback(messagePollingCallbackID); @@ -117,19 +117,19 @@ std::vector> Device::getMessages() { bool Device::getMessages(std::vector>& container, size_t limit, std::chrono::milliseconds timeout) { // not open if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } // not online if(!isOnline()) { - err(APIError::DeviceCurrentlyOffline); + report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error); return false; } // not currently polling, throw error if(!isMessagePollingEnabled()) { - err(APIError::DeviceNotCurrentlyPolling); + report(APIEvent::Type::DeviceNotCurrentlyPolling, APIEvent::Severity::Error); return false; } @@ -159,13 +159,13 @@ void Device::enforcePollingMessageLimit() { while(pollingContainer.size_approx() > pollingMessageLimit) { std::shared_ptr throwAway; pollingContainer.try_dequeue(throwAway); - err(APIError::PollingMessageOverflow); + report(APIEvent::Type::PollingMessageOverflow, APIEvent::Severity::EventWarning); } } bool Device::open() { if(!com) { - err(APIError::Unknown); + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return false; } @@ -181,14 +181,14 @@ bool Device::open() { break; } if(!serial) { - err(APIError::NoSerialNumber); // Communication could not be established with the device. Perhaps it is not powered with 12 volts? + report(APIEvent::Type::NoSerialNumber, APIEvent::Severity::Error); // Communication could not be established with the device. Perhaps it is not powered with 12 volts? com->close(); return false; } std::string currentSerial = getNeoDevice().serial; if(currentSerial != serial->deviceSerial) { - err(APIError::IncorrectSerialNumber); + report(APIEvent::Type::IncorrectSerialNumber, APIEvent::Severity::Error); com->close(); return false; } @@ -205,7 +205,7 @@ bool Device::open() { bool Device::close() { if(!com) { - err(APIError::Unknown); + report(APIEvent::Type::Unknown, APIEvent::Severity::Error); return false; } @@ -247,18 +247,18 @@ bool Device::goOffline() { bool Device::transmit(std::shared_ptr message) { // not open if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } // not online if(!isOnline()) { - err(APIError::DeviceCurrentlyOffline); + report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error); return false; } if(!isSupportedTXNetwork(message->network)) { - err(APIError::UnsupportedTXNetwork); + report(APIEvent::Type::UnsupportedTXNetwork, APIEvent::Severity::Error); return false; } diff --git a/device/idevicesettings.cpp b/device/idevicesettings.cpp index c26bef9..3bcafb0 100644 --- a/device/idevicesettings.cpp +++ b/device/idevicesettings.cpp @@ -130,7 +130,7 @@ int64_t IDeviceSettings::GetBaudrateValueForEnum(CANBaudrate enumValue) { bool IDeviceSettings::refresh(bool ignoreChecksum) { if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } @@ -140,12 +140,12 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) { std::vector rxSettings; bool ret = com->getSettingsSync(rxSettings); if(!ret) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return false; } if(rxSettings.size() < 6) { // We need to at least have the header of GLOBAL_SETTINGS - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return false; } @@ -158,17 +158,17 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) { rxSettings.erase(rxSettings.begin(), rxSettings.begin() + gs_size); if(gs_version != 5) { - err(APIError::SettingsVersionError); + report(APIEvent::Type::SettingsVersionError, APIEvent::Severity::Error); return false; } if(rxLen != gs_len) { - err(APIError::SettingsLengthError); + report(APIEvent::Type::SettingsLengthError, APIEvent::Severity::Error); return false; } if(!ignoreChecksum && gs_chksum != CalculateGSChecksum(rxSettings)) { - err(APIError::SettingsChecksumError); + report(APIEvent::Type::SettingsChecksumError, APIEvent::Severity::Error); return false; } @@ -184,17 +184,17 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) { bool IDeviceSettings::apply(bool temporary) { if(readonly) { - err(APIError::SettingsReadOnly); + report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error); return false; } if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } if(!settingsLoaded) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return false; } @@ -217,7 +217,7 @@ bool IDeviceSettings::apply(bool temporary) { // Attempt to get the settings from the device so we're up to date if possible if(refresh()) { // refresh succeeded but previously there was an error - err(APIError::NoDeviceResponse); + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); } return false; } @@ -236,7 +236,7 @@ bool IDeviceSettings::apply(bool temporary) { // Attempt to get the settings from the device so we're up to date if possible if(refresh()) { // refresh succeeded but previously there was an error - err(APIError::NoDeviceResponse); + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); } return false; } @@ -250,19 +250,19 @@ bool IDeviceSettings::apply(bool temporary) { bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success if(!ret) { - err(APIError::FailedToWrite); + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); } return ret; } bool IDeviceSettings::applyDefaults(bool temporary) { if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } if(readonly) { - err(APIError::SettingsReadOnly); + report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error); return false; } @@ -272,7 +272,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) { // Attempt to get the settings from the device so we're up to date if possible if(refresh()) { // refresh succeeded but previously there was an error - err(APIError::NoDeviceResponse); + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); } return false; } @@ -301,7 +301,7 @@ bool IDeviceSettings::applyDefaults(bool temporary) { // Attempt to get the settings from the device so we're up to date if possible if(refresh()) { // refresh succeeded but previously there was an error - err(APIError::NoDeviceResponse); + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); } return false; } @@ -315,19 +315,19 @@ bool IDeviceSettings::applyDefaults(bool temporary) { bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success if(!ret) { - err(APIError::FailedToWrite); + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); } return ret; } int64_t IDeviceSettings::getBaudrateFor(Network net) const { if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return -1; } if(!settingsLoaded) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return -1; } @@ -335,55 +335,55 @@ int64_t IDeviceSettings::getBaudrateFor(Network net) const { case Network::Type::CAN: { const CAN_SETTINGS* cfg = getCANSettingsFor(net); if(cfg == nullptr) { - err(APIError::CANFDSettingsNotAvailable); + report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error); return -1; } int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->Baudrate); if(baudrate == -1) { - err(APIError::BaudrateNotFound); + report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error); return -1; } return baudrate; } default: - err(APIError::UnexpectedNetworkType); + report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error); return -1; } } bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) { if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } if(!settingsLoaded) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return false; } if(readonly) { - err(APIError::SettingsReadOnly); + report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error); return false; } switch(net.getType()) { case Network::Type::CAN: { if(baudrate > 1000000) { // This is an FD baudrate. Use setFDBaudrateFor instead. - err(APIError::CANFDSettingsNotAvailable); + report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error); return false; } CAN_SETTINGS* cfg = getMutableCANSettingsFor(net); if(cfg == nullptr) { - err(APIError::CANSettingsNotAvailable); + report(APIEvent::Type::CANSettingsNotAvailable, APIEvent::Severity::Error); return false; } CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate); if(newBaud == (CANBaudrate)-1) { - err(APIError::BaudrateNotFound); + report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error); return false; } cfg->Baudrate = (uint8_t)newBaud; @@ -394,13 +394,13 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) { case Network::Type::LSFTCAN: { CAN_SETTINGS* cfg = getMutableLSFTCANSettingsFor(net); if(cfg == nullptr) { - err(APIError::LSFTCANSettingsNotAvailable); + report(APIEvent::Type::LSFTCANSettingsNotAvailable, APIEvent::Severity::Error); return false; } CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate); if(newBaud == (CANBaudrate)-1) { - err(APIError::BaudrateNotFound); + report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error); return false; } cfg->Baudrate = (uint8_t)newBaud; @@ -411,13 +411,13 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) { case Network::Type::SWCAN: { SWCAN_SETTINGS* cfg = getMutableSWCANSettingsFor(net); if(cfg == nullptr) { - err(APIError::SWCANSettingsNotAvailable); + report(APIEvent::Type::SWCANSettingsNotAvailable, APIEvent::Severity::Error); return false; } CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate); if(newBaud == (CANBaudrate)-1) { - err(APIError::BaudrateNotFound); + report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error); return false; } cfg->Baudrate = (uint8_t)newBaud; @@ -426,18 +426,18 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) { return true; } default: - err(APIError::UnexpectedNetworkType); + report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error); return false; } } int64_t IDeviceSettings::getFDBaudrateFor(Network net) const { if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); } if(!settingsLoaded) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return -1; } @@ -445,37 +445,37 @@ int64_t IDeviceSettings::getFDBaudrateFor(Network net) const { case Network::Type::CAN: { const CANFD_SETTINGS* cfg = getCANFDSettingsFor(net); if(cfg == nullptr) { - err(APIError::CANFDSettingsNotAvailable); + report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error); return -1; } int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->FDBaudrate); if(baudrate == -1) { - err(APIError::BaudrateNotFound); + report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error); return -1; } return baudrate; } default: - err(APIError::UnexpectedNetworkType); + report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error); return -1; } } bool IDeviceSettings::setFDBaudrateFor(Network net, int64_t baudrate) { if(!settingsLoaded) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return false; } if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } if(readonly) { - err(APIError::SettingsReadOnly); + report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error); return false; } @@ -483,53 +483,53 @@ bool IDeviceSettings::setFDBaudrateFor(Network net, int64_t baudrate) { case Network::Type::CAN: { CANFD_SETTINGS* cfg = getMutableCANFDSettingsFor(net); if(cfg == nullptr) { - err(APIError::CANFDSettingsNotAvailable); + report(APIEvent::Type::CANFDSettingsNotAvailable, APIEvent::Severity::Error); return false; } CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate); if(newBaud == (CANBaudrate)-1) { - err(APIError::BaudrateNotFound); + report(APIEvent::Type::BaudrateNotFound, APIEvent::Severity::Error); return false; } cfg->FDBaudrate = (uint8_t)newBaud; return true; } default: - err(APIError::UnexpectedNetworkType); + report(APIEvent::Type::UnexpectedNetworkType, APIEvent::Severity::Error); return false; } } template bool IDeviceSettings::applyStructure(const T& newStructure) { if(!settingsLoaded) { - err(APIError::SettingsReadError); + report(APIEvent::Type::SettingsReadError, APIEvent::Severity::Error); return false; } if(disabled) { - err(APIError::SettingsNotAvailable); + report(APIEvent::Type::SettingsNotAvailable, APIEvent::Severity::Error); return false; } if(readonly) { - err(APIError::SettingsReadOnly); + report(APIEvent::Type::SettingsReadOnly, APIEvent::Severity::Error); return false; } // This function is only called from C++ so the caller's structure size and ours should never differ if(sizeof(T) != structSize) { - err(APIError::SettingsStructureMismatch); + report(APIEvent::Type::SettingsStructureMismatch, APIEvent::Severity::Error); return false; // The wrong structure was passed in for the current device } size_t copySize = sizeof(T); if(copySize > settings.size()) { - err(APIError::SettingsStructureTruncated); + report(APIEvent::Type::SettingsStructureTruncated, APIEvent::Severity::EventWarning); copySize = settings.size(); // TODO Warn user that their structure is truncated } // Warn user that the device firmware doesn't support all the settings in the current API if(copySize < settings.size()) - err(APIError::DeviceFirmwareOutOfDate); + report(APIEvent::Type::DeviceFirmwareOutOfDate, APIEvent::Severity::EventWarning); memcpy(settings.data(), &newStructure, structSize); return apply(); diff --git a/include/icsneo/api/errormanager.h b/include/icsneo/api/errormanager.h deleted file mode 100644 index a30acaa..0000000 --- a/include/icsneo/api/errormanager.h +++ /dev/null @@ -1,145 +0,0 @@ -#ifndef __ICSNEO_API_ERRORMANAGER_H_ -#define __ICSNEO_API_ERRORMANAGER_H_ - -#include -#include -#include -#include -#include -#include -#include "icsneo/api/error.h" - -namespace icsneo { - -typedef std::function device_errorhandler_t; - -class ErrorManager { -public: - static ErrorManager& GetInstance(); - - size_t count(ErrorFilter filter = ErrorFilter()) const { - std::lock_guard lk(mutex); - return count_internal(filter); - }; - - std::vector get(ErrorFilter filter, size_t max = 0) { return get(max, filter); } - std::vector get(size_t max = 0, ErrorFilter filter = ErrorFilter()) { - std::vector ret; - get(ret, filter, max); - return ret; - } - void get(std::vector& outErrors, ErrorFilter filter, size_t max = 0) { get(outErrors, max, filter); } - void get(std::vector& outErrors, size_t max = 0, ErrorFilter filter = ErrorFilter()); - bool getLastError(APIError& outErrors, ErrorFilter filter = ErrorFilter()); - bool getLastError(APIError& errorOutput, std::thread::id id); - - void add(APIError error) { - std::lock_guard lk(mutex); - add_internal(error); - } - void add(APIError error, std::thread::id id) { - std::lock_guard lk(mutex); - if(id == std::thread::id()) - add_internal(error); - else - add_internal_threaded(error, id); - } - void add(APIError::ErrorType type) { - std::lock_guard lk(mutex); - add_internal(APIError::APIError(type)); - } - void add(APIError::ErrorType type, std::thread::id id) { - std::lock_guard lk(mutex); - if(id == std::thread::id()) - add_internal(APIError::APIError(type)); - else - add_internal_threaded(APIError::APIError(type), id); - - } - void add(APIError::ErrorType type, const Device* forDevice) { - std::lock_guard lk(mutex); - add_internal(APIError::APIError(type, forDevice)); - } - void add(APIError::ErrorType type, const Device* forDevice, std::thread::id id) { - std::lock_guard lk(mutex); - if(id == std::thread::id()) - add_internal(APIError::APIError(type, forDevice)); - else - add_internal_threaded(APIError::APIError(type, forDevice), id); - } - - void discard(ErrorFilter filter = ErrorFilter()); - - void setErrorLimit(size_t newLimit) { - if(newLimit == errorLimit) - return; - - if(newLimit < 10) { - add(APIError::ParameterOutOfRange); - return; - } - - std::lock_guard lk(mutex); - errorLimit = newLimit; - if(enforceLimit()) - add(APIError::TooManyErrors); - } - - size_t getErrorLimit() const { return errorLimit; } - -private: - ErrorManager() {} - // Used by functions for threadsafety - mutable std::mutex mutex; - - // Stores all errors - std::list errors; - std::unordered_map lastUserErrors; - size_t errorLimit = 10000; - - size_t count_internal(ErrorFilter filter = ErrorFilter()) const; - - /** - * Places a {id, error} pair into the lastUserErrors - * If the key id already exists in the map, replace the error of that pair with the new one - */ - void add_internal_threaded(APIError error, std::thread::id id) { - auto iter = lastUserErrors.find(id); - if(iter == lastUserErrors.end()) { - lastUserErrors.insert(std::make_pair(id, error)); - } else { - iter->second = error; - } - } - - /** - * If errors is not full, add the error at the end - * Otherwise, remove the least significant errors, push the error to the back and push a APIError::TooManyErrors to the back (in that order) - */ - void add_internal(APIError error) { - // Ensure the error list is at most exactly full (size of errorLimit - 1, leaving room for a potential APIError::TooManyErrors) - enforceLimit(); - - // We are exactly full, either because the list was truncated or because we were simply full before - if(errors.size() == errorLimit - 1) { - // If the error is worth adding - if(APIError::SeverityForType(error.getType()) >= lowestCurrentSeverity()) { - discardLeastSevere(1); - errors.push_back(error); - } - - errors.push_back(APIError(APIError::TooManyErrors)); - } else { - errors.push_back(error); - } - } - - bool enforceLimit(); // Returns whether the limit enforcement resulted in an overflow - - APIError::Severity lowestCurrentSeverity(); - void discardLeastSevere(size_t count = 1); -}; - -} - -#endif \ No newline at end of file diff --git a/include/icsneo/api/error.h b/include/icsneo/api/event.h similarity index 56% rename from include/icsneo/api/error.h rename to include/icsneo/api/event.h index f04288e..5e5722e 100644 --- a/include/icsneo/api/error.h +++ b/include/icsneo/api/event.h @@ -1,5 +1,5 @@ -#ifndef __ICSNEO_API_ERROR_H_ -#define __ICSNEO_API_ERROR_H_ +#ifndef __ICSNEO_API_EVENT_H_ +#define __ICSNEO_API_EVENT_H_ #include #include @@ -7,11 +7,11 @@ typedef struct { const char* description; time_t timestamp; - uint32_t errorNumber; + uint32_t eventNumber; uint8_t severity; char serial[7]; uint8_t reserved[16]; -} neoerror_t; +} neoevent_t; #ifdef __cplusplus @@ -24,19 +24,19 @@ namespace icsneo { class Device; -class APIError { +class APIEvent { public: - typedef std::chrono::system_clock ErrorClock; - typedef std::chrono::time_point ErrorTimePoint; + typedef std::chrono::system_clock EventClock; + typedef std::chrono::time_point EventTimePoint; - enum ErrorType : uint32_t { + enum class Type : uint32_t { Any = 0, // Used for filtering, should not appear in data - // API Errors - InvalidNeoDevice = 0x1000, + // API Events + InvalidNeoDevice = 0x1000, // api RequiredParameterNull = 0x1001, BufferInsufficient = 0x1002, - OutputTruncated = 0x1003, + OutputTruncated = 0x1003, // just a warning ParameterOutOfRange = 0x1004, DeviceCurrentlyOpen = 0x1005, DeviceCurrentlyClosed = 0x1006, @@ -47,10 +47,10 @@ public: UnsupportedTXNetwork = 0x1011, MessageMaxLengthExceeded = 0x1012, - // Device Errors + // Device Events PollingMessageOverflow = 0x2000, - NoSerialNumber = 0x2001, - IncorrectSerialNumber = 0x2002, + NoSerialNumber = 0x2001, // api + IncorrectSerialNumber = 0x2002, // api SettingsReadError = 0x2003, SettingsVersionError = 0x2004, SettingsLengthError = 0x2005, @@ -71,7 +71,7 @@ public: CANFDNotSupported = 0x2020, RTRNotSupported = 0x2021, - // Transport Errors + // Transport Events FailedToRead = 0x3000, FailedToWrite = 0x3001, DriverFailedToOpen = 0x3002, @@ -81,66 +81,65 @@ public: PCAPCouldNotStart = 0x3102, PCAPCouldNotFindDevices = 0x3103, PacketDecodingError = 0x3104, - - TooManyErrors = 0xFFFFFFFE, + + NoErrorFound = 0xFFFFFFFD, + TooManyEvents = 0xFFFFFFFE, Unknown = 0xFFFFFFFF }; enum class Severity : uint8_t { Any = 0, // Used for filtering, should not appear in data - Info = 0x10, - Warning = 0x20, + EventInfo = 0x10, + EventWarning = 0x20, Error = 0x30 }; - APIError() : errorStruct({}), device(nullptr) {} - APIError(ErrorType error); - APIError(ErrorType error, const Device* device); - - const neoerror_t* getNeoError() const noexcept { return &errorStruct; } - ErrorType getType() const noexcept { return ErrorType(errorStruct.errorNumber); } - Severity getSeverity() const noexcept { return Severity(errorStruct.severity); } - std::string getDescription() const noexcept { return std::string(errorStruct.description); } - const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide error - ErrorTimePoint getTimestamp() const noexcept { return timepoint; } + APIEvent() : eventStruct({}), device(nullptr), serial(), timepoint() {} + APIEvent(APIEvent::Type event, APIEvent::Severity severity, const Device* device = nullptr); + + const neoevent_t* getNeoEvent() const noexcept { return &eventStruct; } + Type getType() const noexcept { return Type(eventStruct.eventNumber); } + Severity getSeverity() const noexcept { return Severity(eventStruct.severity); } + std::string getDescription() const noexcept { return std::string(eventStruct.description); } + const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide event + EventTimePoint getTimestamp() const noexcept { return timepoint; } bool isForDevice(const Device* forDevice) const noexcept { return forDevice == device; } bool isForDevice(std::string serial) const noexcept; // As opposed to getDescription, this will also add text such as "neoVI FIRE 2 CY2468 Error: " to fully describe the problem std::string describe() const noexcept; - friend std::ostream& operator<<(std::ostream& os, const APIError& error) { - os << error.describe(); + friend std::ostream& operator<<(std::ostream& os, const APIEvent& event) { + os << event.describe(); return os; } - static const char* DescriptionForType(ErrorType type); - static Severity SeverityForType(ErrorType type); + static const char* DescriptionForType(Type type); private: - neoerror_t errorStruct; + neoevent_t eventStruct; std::string serial; - ErrorTimePoint timepoint; + EventTimePoint timepoint; const Device* device; - void init(ErrorType error); + void init(Type event, APIEvent::Severity); }; -class ErrorFilter { +class EventFilter { public: - ErrorFilter() {} // Empty filter matches anything - ErrorFilter(APIError::ErrorType error) : type(error) {} - ErrorFilter(APIError::Severity severity) : severity(severity) {} - ErrorFilter(const Device* device, APIError::ErrorType error = APIError::Any) : type(error), matchOnDevicePtr(true), device(device) {} - ErrorFilter(const Device* device, APIError::Severity severity) : severity(severity), matchOnDevicePtr(true), device(device) {} - ErrorFilter(std::string serial, APIError::ErrorType error = APIError::Any) : type(error), serial(serial) {} - ErrorFilter(std::string serial, APIError::Severity severity) : severity(severity), serial(serial) {} + EventFilter() {} // Empty filter matches anything + EventFilter(APIEvent::Type type) : type(type) {} + EventFilter(APIEvent::Severity severity) : severity(severity) {} + EventFilter(const Device* device, APIEvent::Type type = APIEvent::Type::Any) : type(type), matchOnDevicePtr(true), device(device) {} + EventFilter(const Device* device, APIEvent::Severity severity) : severity(severity), matchOnDevicePtr(true), device(device) {} + EventFilter(std::string serial, APIEvent::Type type = APIEvent::Type::Any) : type(type), serial(serial) {} + EventFilter(std::string serial, APIEvent::Severity severity) : severity(severity), serial(serial) {} - bool match(const APIError& error) const noexcept; + bool match(const APIEvent& event) const noexcept; - APIError::Severity severity = APIError::Severity::Any; - APIError::ErrorType type = APIError::Any; + APIEvent::Type type = APIEvent::Type::Any; + APIEvent::Severity severity = APIEvent::Severity::Any; bool matchOnDevicePtr = false; - const Device* device = nullptr; // nullptr will match on "no device, generic API error" + const Device* device = nullptr; // nullptr will match on "no device, generic API event" std::string serial; // Empty serial will match any, including no device. Not affected by matchOnDevicePtr }; diff --git a/include/icsneo/api/eventmanager.h b/include/icsneo/api/eventmanager.h new file mode 100644 index 0000000..ad66727 --- /dev/null +++ b/include/icsneo/api/eventmanager.h @@ -0,0 +1,125 @@ +#ifndef __ICSNEO_API_EVENTMANAGER_H_ +#define __ICSNEO_API_EVENTMANAGER_H_ + +#include +#include +#include +#include +#include +#include +#include "icsneo/api/event.h" + +namespace icsneo { + +typedef std::function device_eventhandler_t; + +class EventManager { +public: + static EventManager& GetInstance(); + + size_t count(EventFilter filter = EventFilter()) const { + std::lock_guard lk(mutex); + return count_internal(filter); + }; + + std::vector get(EventFilter filter, size_t max = 0) { return get(max, filter); } + std::vector get(size_t max = 0, EventFilter filter = EventFilter()) { + std::vector ret; + get(ret, filter, max); + return ret; + } + void get(std::vector& outEvents, EventFilter filter, size_t max = 0) { get(outEvents, max, filter); } + void get(std::vector& outEvents, size_t max = 0, EventFilter filter = EventFilter()); + + APIEvent getLastError(); + + void add(APIEvent event) { + std::lock_guard lk(mutex); + add_internal(event); + } + void add(APIEvent::Type type, APIEvent::Severity severity, const Device* forDevice = nullptr) { + std::lock_guard lk(mutex); + add_internal(APIEvent::APIEvent(type, severity, forDevice)); + } + + void discard(EventFilter filter = EventFilter()); + + void setEventLimit(size_t newLimit) { + if(newLimit == eventLimit) + return; + + if(newLimit < 10) { + add(APIEvent::Type::ParameterOutOfRange, APIEvent::Severity::EventWarning); + return; + } + + std::lock_guard lk(mutex); + eventLimit = newLimit; + if(enforceLimit()) + add(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning); + } + + size_t getEventLimit() const { return eventLimit; } + +private: + EventManager() {} + // Used by functions for threadsafety + mutable std::mutex mutex; + + // Stores all events + std::list events; + std::unordered_map lastUserErrors; + size_t eventLimit = 10000; + + size_t count_internal(EventFilter filter = EventFilter()) const; + + void add_internal(APIEvent event) { + if(event.getSeverity() == APIEvent::Severity::Error) + add_internal_error(event); + else + add_internal_event(event); + } + + /** + * Places a {id, event} pair into the lastUserErrors + * If the key id already exists in the map, replace the event of that pair with the new one + */ + void add_internal_error(APIEvent event) { + auto iter = lastUserErrors.find(std::this_thread::get_id()); + if(iter == lastUserErrors.end()) + lastUserErrors.insert(std::make_pair(std::this_thread::get_id(), event)); + else + iter->second = event; + } + + /** + * If events is not full, add the event at the end + * Otherwise, remove the least significant events, push the event to the back and push a APIEvent::TooManyEvents to the back (in that order) + */ + void add_internal_event(APIEvent event) { + // Ensure the event list is at most exactly full (size of eventLimit - 1, leaving room for a potential APIEvent::TooManyEvents) + enforceLimit(); + + // We are exactly full, either because the list was truncated or because we were simply full before + if(events.size() == eventLimit - 1) { + // If the event is worth adding + if(event.getSeverity() >= lowestCurrentSeverity()) { + discardLeastSevere(1); + events.push_back(event); + } + + events.push_back(APIEvent(APIEvent::Type::TooManyEvents, APIEvent::Severity::EventWarning)); + } else { + events.push_back(event); + } + } + + bool enforceLimit(); // Returns whether the limit enforcement resulted in an overflow + + APIEvent::Severity lowestCurrentSeverity(); + void discardLeastSevere(size_t count = 1); +}; + +} + +#endif \ No newline at end of file diff --git a/include/icsneo/communication/communication.h b/include/icsneo/communication/communication.h index 583dbb8..7f502bb 100644 --- a/include/icsneo/communication/communication.h +++ b/include/icsneo/communication/communication.h @@ -7,7 +7,7 @@ #include "icsneo/communication/packet.h" #include "icsneo/communication/message/callback/messagecallback.h" #include "icsneo/communication/message/serialnumbermessage.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include "icsneo/communication/packetizer.h" #include "icsneo/communication/encoder.h" #include "icsneo/communication/decoder.h" @@ -23,11 +23,11 @@ namespace icsneo { class Communication { public: Communication( - device_errorhandler_t err, + device_eventhandler_t report, std::unique_ptr com, std::shared_ptr p, std::unique_ptr e, - std::unique_ptr md) : packetizer(p), encoder(std::move(e)), decoder(std::move(md)), err(err), impl(std::move(com)) {} + std::unique_ptr md) : packetizer(p), encoder(std::move(e)), decoder(std::move(md)), report(report), impl(std::move(com)) {} virtual ~Communication() { close(); } bool open(); @@ -53,7 +53,7 @@ public: std::shared_ptr packetizer; // Ownership is shared with the encoder std::unique_ptr encoder; std::unique_ptr decoder; - device_errorhandler_t err; + device_eventhandler_t report; protected: std::unique_ptr impl; diff --git a/include/icsneo/communication/decoder.h b/include/icsneo/communication/decoder.h index bdeab9d..0b0a988 100644 --- a/include/icsneo/communication/decoder.h +++ b/include/icsneo/communication/decoder.h @@ -5,7 +5,7 @@ #include "icsneo/communication/message/canmessage.h" #include "icsneo/communication/packet.h" #include "icsneo/communication/network.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include #include #include @@ -16,13 +16,13 @@ class Decoder { public: static uint64_t GetUInt64FromLEBytes(uint8_t* bytes); - Decoder(device_errorhandler_t err) : err(err) {} + Decoder(device_eventhandler_t report) : report(report) {} bool decode(std::shared_ptr& result, const std::shared_ptr& packet); uint16_t timestampResolution = 25; private: - device_errorhandler_t err; + device_eventhandler_t report; #pragma pack(push, 1) diff --git a/include/icsneo/communication/encoder.h b/include/icsneo/communication/encoder.h index 46cfc1a..3562678 100644 --- a/include/icsneo/communication/encoder.h +++ b/include/icsneo/communication/encoder.h @@ -15,7 +15,7 @@ namespace icsneo { class Encoder { public: - Encoder(device_errorhandler_t err, std::shared_ptr p) : packetizer(p), err(err) {} + Encoder(device_eventhandler_t report, std::shared_ptr p) : packetizer(p), report(report) {} bool encode(std::vector& result, const std::shared_ptr& message); bool encode(std::vector& result, Command cmd, bool boolean) { return encode(result, cmd, std::vector({ (uint8_t)boolean })); } bool encode(std::vector& result, Command cmd, std::vector arguments = {}); @@ -23,7 +23,7 @@ public: bool supportCANFD = false; private: std::shared_ptr packetizer; - device_errorhandler_t err; + device_eventhandler_t report; }; } diff --git a/include/icsneo/communication/icommunication.h b/include/icsneo/communication/icommunication.h index bb17445..b6aeaf7 100644 --- a/include/icsneo/communication/icommunication.h +++ b/include/icsneo/communication/icommunication.h @@ -7,14 +7,14 @@ #include #include #include -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h" namespace icsneo { class ICommunication { public: - ICommunication(const device_errorhandler_t& handler) : err(handler) {} + ICommunication(const device_eventhandler_t& handler) : report(handler) {} virtual ~ICommunication() {} virtual bool open() = 0; virtual bool isOpen() = 0; @@ -27,7 +27,7 @@ public: writeCV.notify_one(); } - device_errorhandler_t err; + device_eventhandler_t report; size_t writeQueueSize = 50; bool writeBlocks = true; // Otherwise it just fails when the queue is full diff --git a/include/icsneo/communication/multichannelcommunication.h b/include/icsneo/communication/multichannelcommunication.h index 4f7e81a..66851a8 100644 --- a/include/icsneo/communication/multichannelcommunication.h +++ b/include/icsneo/communication/multichannelcommunication.h @@ -11,7 +11,7 @@ namespace icsneo { class MultiChannelCommunication : public Communication { public: MultiChannelCommunication( - device_errorhandler_t err, + device_eventhandler_t err, std::unique_ptr com, std::shared_ptr p, std::unique_ptr e, diff --git a/include/icsneo/communication/packet/canpacket.h b/include/icsneo/communication/packet/canpacket.h index b41c4b1..1d863a5 100644 --- a/include/icsneo/communication/packet/canpacket.h +++ b/include/icsneo/communication/packet/canpacket.h @@ -2,7 +2,7 @@ #define __CANPACKET_H__ #include "icsneo/communication/message/canmessage.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include #include @@ -12,7 +12,7 @@ typedef uint16_t icscm_bitfield; struct HardwareCANPacket { static std::shared_ptr DecodeToMessage(const std::vector& bytestream); - static bool EncodeFromMessage(const CANMessage& message, std::vector& bytestream, const device_errorhandler_t& err); + static bool EncodeFromMessage(const CANMessage& message, std::vector& bytestream, const device_eventhandler_t& report); struct { icscm_bitfield IDE : 1; diff --git a/include/icsneo/communication/packet/ethernetpacket.h b/include/icsneo/communication/packet/ethernetpacket.h index dcb64a8..0126ca7 100644 --- a/include/icsneo/communication/packet/ethernetpacket.h +++ b/include/icsneo/communication/packet/ethernetpacket.h @@ -2,7 +2,7 @@ #define __ETHERNETPACKET_H__ #include "icsneo/communication/message/ethernetmessage.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include #include @@ -12,7 +12,7 @@ typedef uint16_t icscm_bitfield; struct HardwareEthernetPacket { static std::shared_ptr DecodeToMessage(const std::vector& bytestream); - static bool EncodeFromMessage(const EthernetMessage& message, std::vector& bytestream, const device_errorhandler_t& err); + static bool EncodeFromMessage(const EthernetMessage& message, std::vector& bytestream, const device_eventhandler_t& err); struct { icscm_bitfield FCS_AVAIL : 1; diff --git a/include/icsneo/communication/packetizer.h b/include/icsneo/communication/packetizer.h index 2307297..9cea2a9 100644 --- a/include/icsneo/communication/packetizer.h +++ b/include/icsneo/communication/packetizer.h @@ -2,7 +2,7 @@ #define __PACKETIZER_H_ #include "icsneo/communication/packet.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include #include #include @@ -13,7 +13,7 @@ class Packetizer { public: static uint8_t ICSChecksum(const std::vector& data); - Packetizer(device_errorhandler_t err) : err(err) {} + Packetizer(device_eventhandler_t report) : report(report) {} std::vector& packetWrap(std::vector& data, bool shortFormat); @@ -42,7 +42,7 @@ private: std::vector> processedPackets; - device_errorhandler_t err; + device_eventhandler_t report; }; } diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index f874d7a..ace97df 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -4,7 +4,7 @@ #include #include #include -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include "icsneo/device/neodevice.h" #include "icsneo/device/idevicesettings.h" #include "icsneo/device/nullsettings.h" @@ -88,7 +88,7 @@ protected: bool online = false; int messagePollingCallbackID = 0; int internalHandlerCallbackID = 0; - device_errorhandler_t err; + device_eventhandler_t report; // START Initialization Functions Device(neodevice_t neodevice = { 0 }) { @@ -98,7 +98,7 @@ protected: template void initialize() { - err = makeErrorHandler(); + report = makeEventHandler(); auto transport = makeTransport(); setupTransport(*transport); auto packetizer = makePacketizer(); @@ -115,31 +115,31 @@ protected: setupSupportedTXNetworks(supportedTXNetworks); } - virtual device_errorhandler_t makeErrorHandler() { - return [this](APIError::ErrorType type) { + virtual device_eventhandler_t makeEventHandler() { + return [this](APIEvent::Type type, APIEvent::Severity severity) { if(!destructing) - ErrorManager::GetInstance().add(type, this); + EventManager::GetInstance().add(type, severity, this); }; } template - std::unique_ptr makeTransport() { return std::unique_ptr(new Transport(err, getWritableNeoDevice())); } + std::unique_ptr makeTransport() { return std::unique_ptr(new Transport(report, getWritableNeoDevice())); } virtual void setupTransport(ICommunication&) {} - virtual std::shared_ptr makePacketizer() { return std::make_shared(err); } + virtual std::shared_ptr makePacketizer() { return std::make_shared(report); } virtual void setupPacketizer(Packetizer&) {} - virtual std::unique_ptr makeEncoder(std::shared_ptr p) { return std::unique_ptr(new Encoder(err, p)); } + virtual std::unique_ptr makeEncoder(std::shared_ptr p) { return std::unique_ptr(new Encoder(report, p)); } virtual void setupEncoder(Encoder&) {} - virtual std::unique_ptr makeDecoder() { return std::unique_ptr(new Decoder(err)); } + virtual std::unique_ptr makeDecoder() { return std::unique_ptr(new Decoder(report)); } virtual void setupDecoder(Decoder&) {} virtual std::shared_ptr makeCommunication( std::unique_ptr t, std::shared_ptr p, std::unique_ptr e, - std::unique_ptr d) { return std::make_shared(err, std::move(t), p, std::move(e), std::move(d)); } + std::unique_ptr d) { return std::make_shared(report, std::move(t), p, std::move(e), std::move(d)); } virtual void setupCommunication(Communication&) {} template diff --git a/include/icsneo/device/idevicesettings.h b/include/icsneo/device/idevicesettings.h index 08abce3..d9bc026 100644 --- a/include/icsneo/device/idevicesettings.h +++ b/include/icsneo/device/idevicesettings.h @@ -334,7 +334,7 @@ public: static CANBaudrate GetEnumValueForBaudrate(int64_t baudrate); static int64_t GetBaudrateValueForEnum(CANBaudrate enumValue); - IDeviceSettings(std::shared_ptr com, size_t size) : com(com), err(com->err), structSize(size) {} + IDeviceSettings(std::shared_ptr com, size_t size) : com(com), report(com->report), structSize(size) {} virtual ~IDeviceSettings() {} bool ok() { return !disabled && settingsLoaded; } @@ -406,7 +406,7 @@ public: bool disableGSChecksumming = false; protected: std::shared_ptr com; - device_errorhandler_t err; + device_eventhandler_t report; size_t structSize; // if we hold any local copies of the device settings @@ -418,7 +418,7 @@ protected: // Parameter createInoperableSettings exists because it is serving as a warning that you probably don't want to do this typedef void* warn_t; IDeviceSettings(warn_t createInoperableSettings, std::shared_ptr com) - : disabled(true), readonly(true), err(com->err), structSize(0) { (void)createInoperableSettings; } + : disabled(true), readonly(true), report(com->report), structSize(0) { (void)createInoperableSettings; } }; } diff --git a/include/icsneo/device/plasion/plasion.h b/include/icsneo/device/plasion/plasion.h index 7968ae8..1bd138f 100644 --- a/include/icsneo/device/plasion/plasion.h +++ b/include/icsneo/device/plasion/plasion.h @@ -14,7 +14,7 @@ protected: std::shared_ptr packetizer, std::unique_ptr encoder, std::unique_ptr decoder - ) override { return std::make_shared(err, std::move(transport), packetizer, std::move(encoder), std::move(decoder)); } + ) override { return std::make_shared(report, std::move(transport), packetizer, std::move(encoder), std::move(decoder)); } // TODO: This is done so that Plasion can still transmit it's basic networks, awaiting VLAN support virtual bool isSupportedRXNetwork(const Network&) const override { return true; } diff --git a/include/icsneo/icsneoc.h b/include/icsneo/icsneoc.h index eba9fd5..4bf9c24 100644 --- a/include/icsneo/icsneoc.h +++ b/include/icsneo/icsneoc.h @@ -9,7 +9,7 @@ #include "icsneo/platform/dynamiclib.h" // Dynamic library loading and exporting #include "icsneo/communication/network.h" // Network type and netID defines #include "icsneo/api/version.h" // For version info -#include "icsneo/api/error.h" // For error info +#include "icsneo/api/event.h" // For error info #ifndef ICSNEOC_DYNAMICLOAD @@ -33,7 +33,7 @@ extern "C" { * To invoke this behavior without finding devices again, call icsneo_freeUnconnectedDevices(). * * If the size provided is not large enough, the output will be truncated. - * An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case. + * An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case. */ extern void DLLExport icsneo_findAllDevices(neodevice_t* devices, size_t* count); @@ -64,7 +64,7 @@ extern void DLLExport icsneo_freeUnconnectedDevices(); * * If the size provided is not large enough, the output will be **NOT** be truncated. * Nothing will be written to the output. - * Instead, an icsneo::APIError::BufferInsufficient will be available in icsneo_getLastError(). + * Instead, an icsneo::APIEvent::BufferInsufficient will be available in icsneo_getLastError(). * False will be returned, and `count` will now contain the number of *bytes* necessary to store the full string. */ extern bool DLLExport icsneo_serialNumToString(uint32_t num, char* str, size_t* count); @@ -86,7 +86,7 @@ extern uint32_t DLLExport icsneo_serialStringToNum(const char* str); * \returns True if the neodevice_t is valid. * * This check is automatically performed at the beginning of any API function that operates on a device. - * If there is a failure, an icsneo::APIError::InvalidNeoDevice will be available in icsneo_getLastError(). + * If there is a failure, an icsneo::APIEvent::InvalidNeoDevice will be available in icsneo_getLastError(). * * See icsneo_findAllDevices() for information regarding the neodevice_t validity contract. */ @@ -103,7 +103,7 @@ extern bool DLLExport icsneo_isValidNeoDevice(const neodevice_t* device); * * If the open did not succeed, icsneo_getLastError() should provide more information about why. * - * If the device was already open, an icsneo::APIError::DeviceCurrentlyOpen will be available in icsneo_getLastError(). + * If the device was already open, an icsneo::APIEvent::DeviceCurrentlyOpen will be available in icsneo_getLastError(). */ extern bool DLLExport icsneo_openDevice(const neodevice_t* device); @@ -182,7 +182,7 @@ extern bool DLLExport icsneo_isOnline(const neodevice_t* device); * The client application will have to call icsneo_getMessages() very often to avoid losing messages, or change the limit. * * If the message limit is exceeded before a call to icsneo_getMessages() takes ownership of the messages, - * the oldest message will be dropped (**LOST**) and an icsneo::APIError::PollingMessageOverflow will be flagged for the device. + * the oldest message will be dropped (**LOST**) and an icsneo::APIEvent::PollingMessageOverflow will be flagged for the device. * * This function will succeed even if the device is not open. */ @@ -280,7 +280,7 @@ extern size_t DLLExport icsneo_getPollingMessageLimit(const neodevice_t* device) * See icsneo_enableMessagePolling() for more information about the message polling system. * * Setting the maximum lower than the current number of stored messages will cause the oldest messages - * to be dropped (**LOST**) and an icsneo::APIError::PollingMessageOverflow to be flagged for the device. + * to be dropped (**LOST**) and an icsneo::APIEvent::PollingMessageOverflow to be flagged for the device. */ extern bool DLLExport icsneo_setPollingMessageLimit(const neodevice_t* device, size_t newLimit); @@ -303,7 +303,7 @@ extern bool DLLExport icsneo_setPollingMessageLimit(const neodevice_t* device, s * icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid. * * If the size provided is not large enough, the output will be truncated. - * An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case. + * An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case. * True will still be returned. */ extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str, size_t* maxLength); @@ -327,7 +327,7 @@ extern bool DLLExport icsneo_getProductName(const neodevice_t* device, char* str * icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid. * * If the size provided is not large enough, the output will be truncated. - * An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case. + * An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case. * True will still be returned. */ extern bool DLLExport icsneo_getProductNameForType(devicetype_t type, char* str, size_t* maxLength); @@ -551,7 +551,7 @@ extern bool DLLExport icsneo_transmitMessages(const neodevice_t* device, const n * icsneo_getLastError() should be checked to verify that the neodevice_t provided was valid. * * If the size provided is not large enough, the output will be truncated. - * An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case. + * An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case. * True will still be returned. */ extern bool DLLExport icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLength); @@ -563,75 +563,82 @@ extern bool DLLExport icsneo_describeDevice(const neodevice_t* device, char* str extern neoversion_t DLLExport icsneo_getVersion(void); /** - * \brief Read out errors which have occurred in API operation - * \param[out] errors A pointer to a buffer which neoerror_t structures will be written to. NULL can be passed, which will write the current error count to size. + * \brief Read out events which have occurred in API operation + * \param[out] events A pointer to a buffer which neoevent_t structures will be written to. NULL can be passed, which will write the current event count to size. * \param[inout] size A pointer to a size_t which, prior to the call, - * holds the maximum number of errors to be written, and after the call holds the number of errors written. - * \returns True if the errors were read out successfully (even if there were no errors to report). + * holds the maximum number of events to be written, and after the call holds the number of events written. + * \returns True if the events were read out successfully (even if there were no events to report). * - * Errors can be caused by API usage, such as bad input or operating on a closed neodevice_t. + * Events contain INFO and WARNINGS, and may potentially contain one TooManyEvents ERROR at the end. No other ERRORS are found in Events, see icsneo_getLastError() instead. * - * Errors can also occur asynchronously to the client application threads, in the case of a device communication error or similar. + * Events can be caused by API usage, such as providing too small of a buffer or disconnecting from a device. * - * Errors are read out of the API managed buffer in order of oldest to newest. + * Events can also occur asynchronously to the client application threads, in the case of a device communication event or similar. + * + * Events are read out of the API managed buffer in order of oldest to newest. * As they are read out, they are removed from the API managed buffer. * - * If size is too small to contain all errors, as many errors as will fit will be read out. - * Subsequent calls to icsneo_getErrors() can retrieve any errors which were not read out. + * If size is too small to contain all events, as many events as will fit will be read out. + * Subsequent calls to icsneo_getErrors() can retrieve any events which were not read out. */ -extern bool DLLExport icsneo_getErrors(neoerror_t* errors, size_t* size); +extern bool DLLExport icsneo_getEvents(neoevent_t* events, size_t* size); /** - * \brief Read out errors which have occurred in API operation for a specific device - * \param[in] device A pointer to the neodevice_t structure specifying the device to read out errors for. NULL can be passed, which indicates that **ONLY** errors *not* associated with a device are desired (API errors). - * \param[out] errors A pointer to a buffer which neoerror_t structures will be written to. NULL can be passed, which will write the current error count to size. + * \brief Read out events which have occurred in API operation for a specific device + * \param[in] device A pointer to the neodevice_t structure specifying the device to read out events for. NULL can be passed, which indicates that **ONLY** events *not* associated with a device are desired (API events). + * \param[out] events A pointer to a buffer which neoevent_t structures will be written to. NULL can be passed, which will write the current event count to size. * \param[inout] size A pointer to a size_t which, prior to the call, - * holds the maximum number of errors to be written, and after the call holds the number of errors written. - * \returns True if the errors were read out successfully (even if there were no errors to report). + * holds the maximum number of events to be written, and after the call holds the number of events written. + * \returns True if the events were read out successfully (even if there were no events to report). * - * See icsneo_getErrors() for more information about the error system. + * See icsneo_getEvents() for more information about the event system. */ -extern bool DLLExport icsneo_getDeviceErrors(const neodevice_t* device, neoerror_t* errors, size_t* size); +extern bool DLLExport icsneo_getDeviceEvents(const neodevice_t* device, neoevent_t* events, size_t* size); /** - * \brief Read out the last error which occurred in API operation. - * \param[out] error A pointer to a buffer which a neoerror_t structure will be written to. + * \brief Read out the last error which occurred in API operation on this thread. + * \param[out] error A pointer to a buffer which a neoevent_t structure will be written to. * \returns True if an error was read out. * - * See icsneo_getErrors() for more information about the error system. + * All errors are stored on a per-thread basis, meaning that calling icsneo_getLastError() will return the last error that occured on the calling thread. + * Any errors can only be retrieved through this function, and NOT ics_neo_getEvents() or similar! Only INFO and WARNING level events are accessible through those, with the exception of the + * Only the last error is stored, so call this function often! + * Calling icsneo_getLastError() will remove the returned error, meaning that subsequent calls to icsneo_getLastError() on the same thread will return false (barring any additional errors) + * + * See icsneo_getEvents() for more information about the event system. * * This operation removes the returned error from the buffer, so subsequent calls to error functions will not include the error. */ -extern bool DLLExport icsneo_getLastError(neoerror_t* error); +extern bool DLLExport icsneo_getLastError(neoevent_t* error); /** * \brief Discard all errors which have occurred in API operation. */ -extern void DLLExport icsneo_discardAllErrors(void); +extern void DLLExport icsneo_discardAllEvents(void); /** * \brief Discard all errors which have occurred in API operation. * \param[in] device A pointer to the neodevice_t structure specifying the device to discard errors for. NULL can be passed, which indicates that **ONLY** errors *not* associated with a device are desired (API errors). */ -extern void DLLExport icsneo_discardDeviceErrors(const neodevice_t* device); +extern void DLLExport icsneo_discardDeviceEvents(const neodevice_t* device); /** - * \brief Set the number of errors which will be held in the API managed buffer before icsneo::APIError::TooManyErrors - * \param[in] newLimit The new limit. Must be >10. 1 error slot is always reserved for a potential icsneo::APIError::TooManyErrors, so (newLimit - 1) other errors can be stored. + * \brief Set the number of errors which will be held in the API managed buffer before icsneo::APIEvent::TooManyEvents + * \param[in] newLimit The new limit. Must be >10. 1 error slot is always reserved for a potential icsneo::APIEvent::TooManyEvents, so (newLimit - 1) other errors can be stored. * - * If the error limit is reached, an icsneo::APIError::TooManyErrors will be flagged. + * If the error limit is reached, an icsneo::APIEvent::TooManyEvents will be flagged. * * If the `newLimit` is smaller than the current error count, * errors will be removed in order of increasing severity and decreasing age. - * This will also flag an icsneo::APIError::TooManyErrors. + * This will also flag an icsneo::APIEvent::TooManyEvents. */ -extern void DLLExport icsneo_setErrorLimit(size_t newLimit); +extern void DLLExport icsneo_setEventLimit(size_t newLimit); /** * \brief Get the number of errors which can be held in the API managed buffer * \returns The current limit. */ -extern size_t DLLExport icsneo_getErrorLimit(void); +extern size_t DLLExport icsneo_getEventLimit(void); /** * \brief Get the devices supported by the current version of the API @@ -647,7 +654,7 @@ extern size_t DLLExport icsneo_getErrorLimit(void); * A query for length (`devices == NULL`) will return false. * * If the count provided is not large enough, the output will be truncated. - * An icsneo::APIError::OutputTruncatedError will be available in icsneo_getLastError() in this case. + * An icsneo::APIEvent::OutputTruncatedError will be available in icsneo_getLastError() in this case. * True will still be returned. */ extern bool DLLExport icsneo_getSupportedDevices(devicetype_t* devices, size_t* count); @@ -772,13 +779,13 @@ fn_icsneo_describeDevice icsneo_describeDevice; typedef neoversion_t(*fn_icsneo_getVersion)(void); fn_icsneo_getVersion icsneo_getVersion; -typedef bool(*fn_icsneo_getErrors)(neoerror_t* errors, size_t* size); +typedef bool(*fn_icsneo_getErrors)(neoevent_t* errors, size_t* size); fn_icsneo_getErrors icsneo_getErrors; -typedef bool(*fn_icsneo_getDeviceErrors)(const neodevice_t* device, neoerror_t* errors, size_t* size); +typedef bool(*fn_icsneo_getDeviceErrors)(const neodevice_t* device, neoevent_t* errors, size_t* size); fn_icsneo_getDeviceErrors icsneo_getDeviceErrors; -typedef bool(*fn_icsneo_getLastError)(neoerror_t* error); +typedef bool(*fn_icsneo_getLastError)(neoevent_t* error); fn_icsneo_getLastError icsneo_getLastError; typedef void(*fn_icsneo_discardAllErrors)(void); diff --git a/include/icsneo/icsneocpp.h b/include/icsneo/icsneocpp.h index b071b0b..cd9d38d 100644 --- a/include/icsneo/icsneocpp.h +++ b/include/icsneo/icsneocpp.h @@ -6,7 +6,7 @@ #include "icsneo/device/device.h" #include "icsneo/api/version.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include "icsneo/communication/message/canmessage.h" #include "icsneo/communication/message/ethernetmessage.h" @@ -16,15 +16,15 @@ namespace icsneo { std::vector> FindAllDevices(); std::vector GetSupportedDevices(); -size_t ErrorCount(ErrorFilter filter = ErrorFilter()); -std::vector GetErrors(ErrorFilter filter, size_t max = 0); -std::vector GetErrors(size_t max = 0, ErrorFilter filter = ErrorFilter()); -void GetErrors(std::vector& errors, ErrorFilter filter, size_t max = 0); -void GetErrors(std::vector& errors, size_t max = 0, ErrorFilter filter = ErrorFilter()); -bool GetLastError(APIError& error, ErrorFilter filter = ErrorFilter()); -void DiscardErrors(ErrorFilter filter = ErrorFilter()); -void SetErrorLimit(size_t newLimit); -size_t GetErrorLimit(); +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(); } diff --git a/include/icsneo/icsneolegacy.h b/include/icsneo/icsneolegacy.h index a0d554c..e6e9c2b 100644 --- a/include/icsneo/icsneolegacy.h +++ b/include/icsneo/icsneolegacy.h @@ -60,9 +60,9 @@ extern int DLLExport icsneoGetDeviceParameters(void* hObject, char* pParameter, extern int DLLExport icsneoSetDeviceParameters(void* hObject, char* pParmValue, int* pErrorIndex, int bSaveToEEPROM); //Error Functions -extern int DLLExport icsneoGetLastAPIError(void* hObject, unsigned long* pErrorNumber); +extern int DLLExport icsneoGetLastAPIEvent(void* hObject, unsigned long* peventNumber); extern int DLLExport icsneoGetErrorMessages(void* hObject, int* pErrorMsgs, int* pNumberOfErrors); -extern int DLLExport icsneoGetErrorInfo(int lErrorNumber, TCHAR*szErrorDescriptionShort, TCHAR*szErrorDescriptionLong, int* lMaxLengthShort, int* lMaxLengthLong,int* lErrorSeverity,int* lRestartNeeded); +extern int DLLExport icsneoGetErrorInfo(int leventNumber, TCHAR*szErrorDescriptionShort, TCHAR*szErrorDescriptionLong, int* lMaxLengthShort, int* lMaxLengthLong,int* lErrorSeverity,int* lRestartNeeded); //ISO15765-2 Functions extern int DLLExport icsneoISO15765_EnableNetworks(void* hObject, unsigned long ulNetworks); diff --git a/include/icsneo/platform/posix/ftdi.h b/include/icsneo/platform/posix/ftdi.h index 1bb7672..9fc2195 100644 --- a/include/icsneo/platform/posix/ftdi.h +++ b/include/icsneo/platform/posix/ftdi.h @@ -8,7 +8,7 @@ #include "icsneo/device/neodevice.h" #include "icsneo/communication/icommunication.h" #include "icsneo/third-party/concurrentqueue/blockingconcurrentqueue.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" namespace icsneo { @@ -16,7 +16,7 @@ class FTDI : public ICommunication { public: static std::vector FindByProduct(int product); - FTDI(const device_errorhandler_t& err, neodevice_t& forDevice); + FTDI(const device_eventhandler_t& err, neodevice_t& forDevice); ~FTDI() { close(); } bool open(); bool close(); diff --git a/include/icsneo/platform/posix/pcap.h b/include/icsneo/platform/posix/pcap.h index 233502a..0bf3ed3 100644 --- a/include/icsneo/platform/posix/pcap.h +++ b/include/icsneo/platform/posix/pcap.h @@ -3,7 +3,7 @@ #include "icsneo/device/neodevice.h" #include "icsneo/communication/icommunication.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include #include @@ -21,7 +21,7 @@ public: static std::string GetEthDevSerialFromMacAddress(uint8_t product, uint16_t macSerial); static bool IsHandleValid(neodevice_handle_t handle); - PCAP(device_errorhandler_t err, neodevice_t& forDevice); + PCAP(device_eventhandler_t err, neodevice_t& forDevice); bool open(); bool isOpen(); bool close(); diff --git a/include/icsneo/platform/posix/stm32.h b/include/icsneo/platform/posix/stm32.h index e9e2d8a..4be0567 100644 --- a/include/icsneo/platform/posix/stm32.h +++ b/include/icsneo/platform/posix/stm32.h @@ -3,7 +3,7 @@ #include "icsneo/communication/icommunication.h" #include "icsneo/device/neodevice.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include #include @@ -11,7 +11,7 @@ namespace icsneo { class STM32 : public ICommunication { public: - STM32(const device_errorhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) {} + STM32(const device_eventhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) {} static std::vector FindByProduct(int product); bool open(); diff --git a/include/icsneo/platform/windows/ftdi.h b/include/icsneo/platform/windows/ftdi.h index e3e91c4..90effd1 100644 --- a/include/icsneo/platform/windows/ftdi.h +++ b/include/icsneo/platform/windows/ftdi.h @@ -7,7 +7,7 @@ namespace icsneo { class FTDI : public VCP { public: - FTDI(const device_errorhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} + FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} static std::vector FindByProduct(int product) { return VCP::FindByProduct(product, { L"serenum" /*, L"ftdibus" */ }); } }; diff --git a/include/icsneo/platform/windows/pcap.h b/include/icsneo/platform/windows/pcap.h index e3b4565..66de9f3 100644 --- a/include/icsneo/platform/windows/pcap.h +++ b/include/icsneo/platform/windows/pcap.h @@ -4,7 +4,7 @@ #include "icsneo/platform/windows/internal/pcapdll.h" #include "icsneo/device/neodevice.h" #include "icsneo/communication/icommunication.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" #include namespace icsneo { @@ -21,7 +21,7 @@ public: static std::string GetEthDevSerialFromMacAddress(uint8_t product, uint16_t macSerial); static bool IsHandleValid(neodevice_handle_t handle); - PCAP(const device_errorhandler_t& err, neodevice_t& forDevice); + PCAP(const device_eventhandler_t& err, neodevice_t& forDevice); bool open(); bool isOpen(); bool close(); diff --git a/include/icsneo/platform/windows/stm32.h b/include/icsneo/platform/windows/stm32.h index ca7680e..e5f67f6 100644 --- a/include/icsneo/platform/windows/stm32.h +++ b/include/icsneo/platform/windows/stm32.h @@ -7,7 +7,7 @@ namespace icsneo { class STM32 : public VCP { public: - STM32(const device_errorhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} + STM32(const device_eventhandler_t& err, neodevice_t& forDevice) : VCP(err, forDevice) {} static std::vector FindByProduct(int product) { return VCP::FindByProduct(product, { L"usbser" }); } }; diff --git a/include/icsneo/platform/windows/vcp.h b/include/icsneo/platform/windows/vcp.h index d2af74e..7a909e3 100644 --- a/include/icsneo/platform/windows/vcp.h +++ b/include/icsneo/platform/windows/vcp.h @@ -9,7 +9,7 @@ #include #include "icsneo/device/neodevice.h" #include "icsneo/communication/icommunication.h" -#include "icsneo/api/errormanager.h" +#include "icsneo/api/eventmanager.h" namespace icsneo { @@ -20,7 +20,7 @@ public: static bool IsHandleValid(neodevice_handle_t handle); typedef void(*fn_boolCallback)(bool success); - VCP(const device_errorhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { + VCP(const device_eventhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { overlappedRead.hEvent = INVALID_HANDLE_VALUE; overlappedWrite.hEvent = INVALID_HANDLE_VALUE; overlappedWait.hEvent = INVALID_HANDLE_VALUE; diff --git a/platform/posix/ftdi.cpp b/platform/posix/ftdi.cpp index b381391..7c4e061 100644 --- a/platform/posix/ftdi.cpp +++ b/platform/posix/ftdi.cpp @@ -39,25 +39,25 @@ std::vector FTDI::FindByProduct(int product) { return found; } -FTDI::FTDI(const device_errorhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { +FTDI::FTDI(const device_eventhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { openable = strlen(forDevice.serial) > 0 && device.handle >= 0 && device.handle < (neodevice_handle_t)handles.size(); } bool FTDI::open() { if(isOpen()) { - err(APIError::DeviceCurrentlyOpen); + report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); return false; } if(!openable) { - err(APIError::InvalidNeoDevice); + report(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error); return false; } // At this point the handle has been checked to be within the bounds of the handles array std::tuple& handle = handles[device.handle]; if(ftdi.openDevice(std::get<0>(handle), std::get<1>(handle).c_str()) != 0) { - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -77,7 +77,7 @@ bool FTDI::open() { bool FTDI::close() { if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } @@ -91,7 +91,7 @@ bool FTDI::close() { bool ret = ftdi.closeDevice(); if(ret != 0) - err(APIError::DriverFailedToClose); + report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); uint8_t flush; WriteOperation flushop; diff --git a/platform/posix/pcap.cpp b/platform/posix/pcap.cpp index 301be50..f40bb4c 100644 --- a/platform/posix/pcap.cpp +++ b/platform/posix/pcap.cpp @@ -33,7 +33,7 @@ std::vector PCAP::FindAll() { } if(!success) { - ErrorManager::GetInstance().add(APIError::PCAPCouldNotFindDevices); + EventManager::GetInstance().add(APIEvent::PCAPCouldNotFindDevices); return std::vector(); } @@ -167,7 +167,7 @@ bool PCAP::IsHandleValid(neodevice_handle_t handle) { return (netifIndex < knownInterfaces.size()); } -PCAP::PCAP(device_errorhandler_t err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { +PCAP::PCAP(device_eventhandler_t err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { if(IsHandleValid(device.handle)) { interface = knownInterfaces[(device.handle >> 24) & 0xFF]; interface.fp = nullptr; // We're going to open our own connection to the interface. This should already be nullptr but just in case. @@ -193,7 +193,7 @@ bool PCAP::open() { // Open the interface interface.fp = pcap_open_live(interface.nameFromWinPCAP.c_str(), INT16_MAX, 1, 0, errbuf); if(interface.fp == nullptr) { - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -236,7 +236,7 @@ void PCAP::readTask() { while(!closing) { auto readBytes = pcap_next_ex(interface.fp, &header, &data); if(readBytes < 0) { - err(APIError::FailedToRead); + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); break; } if(readBytes == 0) diff --git a/platform/posix/stm32.cpp b/platform/posix/stm32.cpp index 4cae1e9..c597bce 100644 --- a/platform/posix/stm32.cpp +++ b/platform/posix/stm32.cpp @@ -192,7 +192,7 @@ std::vector STM32::FindByProduct(int product) { bool STM32::open() { if(isOpen()) { - err(APIError::DeviceCurrentlyOpen); + report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); return false; } std::stringstream ss; @@ -200,7 +200,7 @@ bool STM32::open() { fd = ::open(ss.str().c_str(), O_RDWR | O_NOCTTY | O_SYNC); if(!isOpen()) { //std::cout << "Open of " << ss.str().c_str() << " failed with " << strerror(errno) << ' '; - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -209,7 +209,7 @@ bool STM32::open() { if(tcgetattr(fd, &tty) != 0) { close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -232,7 +232,7 @@ bool STM32::open() { if(tcsetattr(fd, TCSAFLUSH, &tty) != 0) { // Flushes input and output buffers as well as setting settings close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -254,7 +254,7 @@ bool STM32::isOpen() { bool STM32::close() { if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } @@ -279,7 +279,7 @@ bool STM32::close() { if(ret == 0) { return true; } else { - err(APIError::DriverFailedToClose); + report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); return false; } } @@ -303,7 +303,7 @@ void STM32::writeTask() { const ssize_t writeSize = (ssize_t)writeOp.bytes.size(); ssize_t actualWritten = ::write(fd, writeOp.bytes.data(), writeSize); if(actualWritten != writeSize) - err(APIError::FailedToWrite); + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); onWrite(); } } \ No newline at end of file diff --git a/platform/windows/pcap.cpp b/platform/windows/pcap.cpp index 6daf26c..b3a4cfc 100644 --- a/platform/windows/pcap.cpp +++ b/platform/windows/pcap.cpp @@ -20,7 +20,7 @@ std::vector PCAP::FindAll() { std::vector foundDevices; PCAPDLL pcap; if(!pcap.ok()) { - ErrorManager::GetInstance().add(APIError::PCAPCouldNotStart); + EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotStart, APIEvent::Severity::Error); return std::vector(); } @@ -38,7 +38,7 @@ std::vector PCAP::FindAll() { } if(!success) { - ErrorManager::GetInstance().add(APIError::PCAPCouldNotFindDevices); + EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error); return std::vector(); } @@ -55,13 +55,13 @@ std::vector PCAP::FindAll() { // Now we're going to ask Win32 for the information as well ULONG size = 0; if(GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, nullptr, &size) != ERROR_BUFFER_OVERFLOW) { - ErrorManager::GetInstance().add(APIError::PCAPCouldNotFindDevices); + EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error); return std::vector(); } std::vector adapterAddressBuffer; adapterAddressBuffer.resize(size); if(GetAdaptersAddresses(AF_UNSPEC, GAA_FLAG_INCLUDE_PREFIX, nullptr, (IP_ADAPTER_ADDRESSES*)adapterAddressBuffer.data(), &size) != ERROR_SUCCESS) { - ErrorManager::GetInstance().add(APIError::PCAPCouldNotFindDevices); + EventManager::GetInstance().add(APIEvent::Type::PCAPCouldNotFindDevices, APIEvent::Severity::Error); return std::vector(); } @@ -177,7 +177,7 @@ bool PCAP::IsHandleValid(neodevice_handle_t handle) { return (netifIndex < knownInterfaces.size()); } -PCAP::PCAP(const device_errorhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { +PCAP::PCAP(const device_eventhandler_t& err, neodevice_t& forDevice) : ICommunication(err), device(forDevice) { if(IsHandleValid(device.handle)) { interface = knownInterfaces[(device.handle >> 24) & 0xFF]; interface.fp = nullptr; // We're going to open our own connection to the interface. This should already be nullptr but just in case. @@ -195,24 +195,24 @@ PCAP::PCAP(const device_errorhandler_t& err, neodevice_t& forDevice) : ICommunic bool PCAP::open() { if(!openable) { - err(APIError::InvalidNeoDevice); + report(APIEvent::Type::InvalidNeoDevice, APIEvent::Severity::Error); return false; } if(!pcap.ok()) { - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } if(isOpen()) { - err(APIError::DeviceCurrentlyOpen); + report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); return false; } // Open the interface interface.fp = pcap.open(interface.nameFromWinPCAP.c_str(), 100, PCAP_OPENFLAG_PROMISCUOUS | PCAP_OPENFLAG_MAX_RESPONSIVENESS, 1, nullptr, errbuf); if(interface.fp == nullptr) { - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -229,7 +229,7 @@ bool PCAP::isOpen() { bool PCAP::close() { if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } @@ -255,7 +255,7 @@ void PCAP::readTask() { while(!closing) { auto readBytes = pcap.next_ex(interface.fp, &header, &data); if(readBytes < 0) { - err(APIError::FailedToRead); + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); break; } if(readBytes == 0) diff --git a/platform/windows/vcp.cpp b/platform/windows/vcp.cpp index d8a10ad..fc7ae98 100644 --- a/platform/windows/vcp.cpp +++ b/platform/windows/vcp.cpp @@ -184,12 +184,12 @@ bool VCP::IsHandleValid(neodevice_handle_t handle) { bool VCP::open(bool fromAsync) { if(isOpen() || (!fromAsync && opening)) { - err(APIError::DeviceCurrentlyOpen); + report(APIEvent::Type::DeviceCurrentlyOpen, APIEvent::Severity::Error); return false; } if(!IsHandleValid(device.handle)) { - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -210,7 +210,7 @@ bool VCP::open(bool fromAsync) { opening = false; if(!isOpen()) { - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -218,7 +218,7 @@ bool VCP::open(bool fromAsync) { COMMTIMEOUTS timeouts; if(!GetCommTimeouts(handle, &timeouts)) { close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -231,7 +231,7 @@ bool VCP::open(bool fromAsync) { if(!SetCommTimeouts(handle, &timeouts)) { close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -239,7 +239,7 @@ bool VCP::open(bool fromAsync) { DCB comstate; if(!GetCommState(handle, &comstate)) { close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -252,7 +252,7 @@ bool VCP::open(bool fromAsync) { if(!SetCommState(handle, &comstate)) { close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -264,14 +264,14 @@ bool VCP::open(bool fromAsync) { overlappedWait.hEvent = CreateEvent(nullptr, true, false, nullptr); if (overlappedRead.hEvent == nullptr || overlappedWrite.hEvent == nullptr || overlappedWait.hEvent == nullptr) { close(); - err(APIError::DriverFailedToOpen); + 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(handle, EV_RXCHAR)) { close(); - err(APIError::DriverFailedToOpen); + report(APIEvent::Type::DriverFailedToOpen, APIEvent::Severity::Error); return false; } @@ -292,7 +292,7 @@ void VCP::openAsync(fn_boolCallback callback) { bool VCP::close() { if(!isOpen()) { - err(APIError::DeviceCurrentlyClosed); + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); return false; } @@ -304,7 +304,7 @@ bool VCP::close() { closing = false; if(!CloseHandle(handle)) { - err(APIError::DriverFailedToClose); + report(APIEvent::Type::DriverFailedToClose, APIEvent::Severity::Error); return false; } @@ -333,7 +333,7 @@ bool VCP::close() { while(writeQueue.try_dequeue(flushop)) {} if(!ret) - err(APIError::DriverFailedToClose); + 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 @@ -365,7 +365,7 @@ void VCP::readTask() { if(lastError == ERROR_IO_PENDING) state = WAIT; else if(lastError != ERROR_SUCCESS) - err(APIError::FailedToRead); + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); } break; case WAIT: { @@ -375,11 +375,11 @@ void VCP::readTask() { readQueue.enqueue_bulk(readbuf, bytesRead); state = LAUNCH; } else - err(APIError::FailedToRead); + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); } if(ret == WAIT_ABANDONED) { state = LAUNCH; - err(APIError::FailedToRead); + report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error); } } } @@ -407,19 +407,19 @@ void VCP::writeTask() { state = WAIT; } else - err(APIError::FailedToWrite); + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); } break; case WAIT: { auto ret = WaitForSingleObject(overlappedWrite.hEvent, 50); if(ret == WAIT_OBJECT_0) { if(!GetOverlappedResult(handle, &overlappedWrite, &bytesWritten, FALSE)) - err(APIError::FailedToWrite); + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); state = LAUNCH; } if(ret == WAIT_ABANDONED) { - err(APIError::FailedToWrite); + report(APIEvent::Type::FailedToWrite, APIEvent::Severity::Error); state = LAUNCH; } }