mirror of
https://github.com/intrepidcs/libicsneo.git
synced 2026-08-05 01:18:36 +02:00
Event refactor builds on Windows
This commit is contained in:
+50
-50
@@ -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 <string>
|
||||
#include <vector>
|
||||
@@ -28,7 +28,7 @@ void icsneo_findAllDevices(neodevice_t* devices, size_t* count) {
|
||||
std::vector<std::shared_ptr<Device>> 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;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,294 +0,0 @@
|
||||
#include "icsneo/api/error.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include <sstream>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -1,155 +0,0 @@
|
||||
#include "icsneo/api/errormanager.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static std::unique_ptr<ErrorManager> singleton;
|
||||
|
||||
ErrorManager& ErrorManager::GetInstance() {
|
||||
if(!singleton)
|
||||
singleton = std::unique_ptr<ErrorManager>(new ErrorManager());
|
||||
return *singleton.get();
|
||||
}
|
||||
|
||||
void ErrorManager::get(std::vector<APIError>& errorOutput, size_t max, ErrorFilter filter) {
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,227 @@
|
||||
#include "icsneo/api/event.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include <sstream>
|
||||
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include <memory>
|
||||
|
||||
using namespace icsneo;
|
||||
|
||||
static std::unique_ptr<EventManager> singleton;
|
||||
|
||||
EventManager& EventManager::GetInstance() {
|
||||
if(!singleton)
|
||||
singleton = std::unique_ptr<EventManager>(new EventManager());
|
||||
return *singleton.get();
|
||||
}
|
||||
|
||||
void EventManager::get(std::vector<APIEvent>& eventOutput, size_t max, EventFilter filter) {
|
||||
std::lock_guard<std::mutex> 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<std::mutex> 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<std::mutex> 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.
|
||||
}
|
||||
+18
-18
@@ -11,38 +11,38 @@ std::vector<DeviceType> 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<APIError> icsneo::GetErrors(ErrorFilter filter, size_t max) {
|
||||
return ErrorManager::GetInstance().get(filter, max);
|
||||
std::vector<APIEvent> icsneo::GetEvents(EventFilter filter, size_t max) {
|
||||
return EventManager::GetInstance().get(filter, max);
|
||||
}
|
||||
|
||||
std::vector<APIError> icsneo::GetErrors(size_t max, ErrorFilter filter) {
|
||||
return ErrorManager::GetInstance().get(max, filter);
|
||||
std::vector<APIEvent> icsneo::GetEvents(size_t max, EventFilter filter) {
|
||||
return EventManager::GetInstance().get(max, filter);
|
||||
}
|
||||
|
||||
void icsneo::GetErrors(std::vector<APIError>& errors, ErrorFilter filter, size_t max) {
|
||||
ErrorManager::GetInstance().get(errors, filter, max);
|
||||
void icsneo::GetEvents(std::vector<APIEvent>& events, EventFilter filter, size_t max) {
|
||||
EventManager::GetInstance().get(events, filter, max);
|
||||
}
|
||||
|
||||
void icsneo::GetErrors(std::vector<APIError>& errors, size_t max, ErrorFilter filter) {
|
||||
ErrorManager::GetInstance().get(errors, max, filter);
|
||||
void icsneo::GetEvents(std::vector<APIEvent>& 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();
|
||||
}
|
||||
Reference in New Issue
Block a user