libicsneo/api/icsneocpp/event.cpp

237 lines
10 KiB
C++

#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();
}
void APIEvent::downgradeFromError() noexcept {
eventStruct.severity = (uint8_t) APIEvent::Severity::EventWarning;
}
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.";
static constexpr const char* DEVICE_DISCONNECTED = "The device was disconnected.";
// 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* DEVICE_IN_USE = "The device is currently in use by another program.";
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;
case Type::DeviceDisconnected:
return DEVICE_DISCONNECTED;
// 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::DeviceInUse:
return DEVICE_IN_USE;
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;
}