Error system now functional in C and C++ APIs
parent
a295713c50
commit
5bc65554f9
|
|
@ -376,4 +376,83 @@ bool icsneo_describeDevice(const neodevice_t* device, char* str, size_t* maxLeng
|
||||||
|
|
||||||
neoversion_t icsneo_getVersion(void) {
|
neoversion_t icsneo_getVersion(void) {
|
||||||
return icsneo::GetVersion();
|
return icsneo::GetVersion();
|
||||||
|
}
|
||||||
|
|
||||||
|
bool icsneo_getErrors(neoerror_t* errors, size_t* size) {
|
||||||
|
if(size == nullptr) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(errors == nullptr) {
|
||||||
|
*size = icsneo::ErrorCount();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cppErrors = icsneo::GetErrors(*size);
|
||||||
|
for(size_t i = 0; i < cppErrors.size(); i++)
|
||||||
|
memcpy(&errors[i], cppErrors[i].getNeoError(), sizeof(neoerror_t));
|
||||||
|
*size = cppErrors.size();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool icsneo_getDeviceErrors(const neodevice_t* device, neoerror_t* errors, size_t* size) {
|
||||||
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(size == nullptr) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
ErrorFilter filter = (icsneo::Device*)device->device;
|
||||||
|
|
||||||
|
if(errors == nullptr) {
|
||||||
|
*size = icsneo::ErrorCount(filter);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto cppErrors = icsneo::GetErrors(*size, filter);
|
||||||
|
for(size_t i = 0; i < cppErrors.size(); i++)
|
||||||
|
memcpy(&errors[i], cppErrors[i].getNeoError(), sizeof(neoerror_t));
|
||||||
|
*size = cppErrors.size();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool icsneo_getLastError(neoerror_t* error) {
|
||||||
|
if(error == nullptr) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::RequiredParameterNull);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
APIError cppErr;
|
||||||
|
if(!icsneo::GetLastError(cppErr))
|
||||||
|
return false;
|
||||||
|
memcpy(error, cppErr.getNeoError(), sizeof(neoerror_t));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo_discardAllErrors(void) {
|
||||||
|
icsneo::DiscardErrors();
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo_discardDeviceErrors(const neodevice_t* device) {
|
||||||
|
if(!icsneo_isValidNeoDevice(device)) {
|
||||||
|
ErrorManager::GetInstance().add(APIError::InvalidNeoDevice);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
icsneo::DiscardErrors(icsneo::ErrorFilter((icsneo::Device*)device->device));
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo_setErrorLimit(size_t newLimit) {
|
||||||
|
icsneo::SetErrorLimit(newLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t icsneo_getErrorLimit(void) {
|
||||||
|
return icsneo::GetErrorLimit();
|
||||||
}
|
}
|
||||||
|
|
@ -27,20 +27,25 @@ void ErrorManager::get(std::vector<APIError>& errorOutput, size_t max, ErrorFilt
|
||||||
if(count++ >= max)
|
if(count++ >= max)
|
||||||
break; // We now have as many written to output as we can
|
break; // We now have as many written to output as we can
|
||||||
} else {
|
} else {
|
||||||
it++;
|
std::advance(it, 1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bool ErrorManager::getOne(APIError& errorOutput, ErrorFilter filter) {
|
bool ErrorManager::getLastError(APIError& errorOutput, ErrorFilter filter) {
|
||||||
std::vector<APIError> output;
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
get(output, filter, 1);
|
|
||||||
|
|
||||||
if(output.size() == 0)
|
auto it = errors.rbegin();
|
||||||
return false;
|
while(it != errors.rend()) {
|
||||||
|
if(filter.match(*it)) {
|
||||||
errorOutput = output[0];
|
errorOutput = *it;
|
||||||
return true;
|
errors.erase(std::next(it).base());
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
std::advance(it, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void ErrorManager::discard(ErrorFilter filter) {
|
void ErrorManager::discard(ErrorFilter filter) {
|
||||||
|
|
|
||||||
|
|
@ -5,4 +5,40 @@ using namespace icsneo;
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Device>> icsneo::FindAllDevices() {
|
std::vector<std::shared_ptr<Device>> icsneo::FindAllDevices() {
|
||||||
return DeviceFinder::FindAll();
|
return DeviceFinder::FindAll();
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t icsneo::ErrorCount(ErrorFilter filter) {
|
||||||
|
return ErrorManager::GetInstance().count(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<APIError> icsneo::GetErrors(ErrorFilter filter, size_t max) {
|
||||||
|
return ErrorManager::GetInstance().get(filter, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<APIError> icsneo::GetErrors(size_t max, ErrorFilter filter) {
|
||||||
|
return ErrorManager::GetInstance().get(max, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo::GetErrors(std::vector<APIError>& errors, ErrorFilter filter, size_t max) {
|
||||||
|
ErrorManager::GetInstance().get(errors, filter, max);
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo::GetErrors(std::vector<APIError>& errors, size_t max, ErrorFilter filter) {
|
||||||
|
ErrorManager::GetInstance().get(errors, max, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool icsneo::GetLastError(APIError& error, ErrorFilter filter) {
|
||||||
|
return ErrorManager::GetInstance().getLastError(error, filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo::DiscardErrors(ErrorFilter filter) {
|
||||||
|
ErrorManager::GetInstance().discard(filter);
|
||||||
|
}
|
||||||
|
|
||||||
|
void icsneo::SetErrorLimit(size_t newLimit) {
|
||||||
|
ErrorManager::GetInstance().setErrorLimit(newLimit);
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t icsneo::GetErrorLimit() {
|
||||||
|
return ErrorManager::GetInstance().getErrorLimit();
|
||||||
}
|
}
|
||||||
|
|
@ -19,6 +19,8 @@ typedef struct {
|
||||||
uint8_t reserved[16];
|
uint8_t reserved[16];
|
||||||
} neoerror_t;
|
} neoerror_t;
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <chrono>
|
#include <chrono>
|
||||||
#include <string>
|
#include <string>
|
||||||
|
|
@ -68,16 +70,18 @@ public:
|
||||||
Error = 0x30
|
Error = 0x30
|
||||||
};
|
};
|
||||||
|
|
||||||
|
APIError() : errorStruct({}), device(nullptr) {}
|
||||||
APIError(ErrorType error);
|
APIError(ErrorType error);
|
||||||
APIError(ErrorType error, const Device* device);
|
APIError(ErrorType error, const Device* device);
|
||||||
|
|
||||||
|
const neoerror_t* getNeoError() const noexcept { return &errorStruct; }
|
||||||
ErrorType getType() const noexcept { return ErrorType(errorStruct.errorNumber); }
|
ErrorType getType() const noexcept { return ErrorType(errorStruct.errorNumber); }
|
||||||
Severity getSeverity() const noexcept { return Severity(errorStruct.severity); }
|
Severity getSeverity() const noexcept { return Severity(errorStruct.severity); }
|
||||||
std::string getDescription() const noexcept { return std::string(errorStruct.description); }
|
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
|
const Device* getDevice() const noexcept { return device; } // Will return nullptr if this is an API-wide error
|
||||||
std::chrono::time_point<std::chrono::high_resolution_clock> getTimestamp() const noexcept { return timepoint; }
|
std::chrono::time_point<std::chrono::high_resolution_clock> getTimestamp() const noexcept { return timepoint; }
|
||||||
|
|
||||||
bool isForDevice(Device* forDevice) const noexcept { return forDevice == device; }
|
bool isForDevice(const Device* forDevice) const noexcept { return forDevice == device; }
|
||||||
bool isForDevice(std::string serial) const noexcept;
|
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
|
// As opposed to getDescription, this will also add text such as "neoVI FIRE 2 CY2468 Error: " to fully describe the problem
|
||||||
|
|
@ -104,20 +108,22 @@ public:
|
||||||
ErrorFilter() {} // Empty filter matches anything
|
ErrorFilter() {} // Empty filter matches anything
|
||||||
ErrorFilter(APIError::ErrorType error) : type(error) {}
|
ErrorFilter(APIError::ErrorType error) : type(error) {}
|
||||||
ErrorFilter(APIError::Severity severity) : severity(severity) {}
|
ErrorFilter(APIError::Severity severity) : severity(severity) {}
|
||||||
ErrorFilter(Device* device, APIError::ErrorType error = APIError::Any) : type(error), matchOnDevicePtr(true), device(device) {}
|
ErrorFilter(const Device* device, APIError::ErrorType error = APIError::Any) : type(error), matchOnDevicePtr(true), device(device) {}
|
||||||
ErrorFilter(Device* device, APIError::Severity severity = APIError::Severity::Any) : severity(severity), 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::ErrorType error = APIError::Any) : type(error), serial(serial) {}
|
||||||
ErrorFilter(std::string serial, APIError::Severity severity = APIError::Severity::Any) : severity(severity), serial(serial) {}
|
ErrorFilter(std::string serial, APIError::Severity severity) : severity(severity), serial(serial) {}
|
||||||
|
|
||||||
bool match(const APIError& error) const noexcept;
|
bool match(const APIError& error) const noexcept;
|
||||||
|
|
||||||
APIError::Severity severity = APIError::Severity::Any;
|
APIError::Severity severity = APIError::Severity::Any;
|
||||||
APIError::ErrorType type = APIError::Any;
|
APIError::ErrorType type = APIError::Any;
|
||||||
bool matchOnDevicePtr = false;
|
bool matchOnDevicePtr = false;
|
||||||
Device* device = nullptr; // nullptr will match on "no device, generic API error"
|
const Device* device = nullptr; // nullptr will match on "no device, generic API error"
|
||||||
std::string serial; // Empty serial will match any, including no device. Not affected by matchOnDevicePtr
|
std::string serial; // Empty serial will match any, including no device. Not affected by matchOnDevicePtr
|
||||||
};
|
};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -28,7 +28,7 @@ public:
|
||||||
}
|
}
|
||||||
void get(std::vector<APIError>& errors, ErrorFilter filter, size_t max = 0) { get(errors, max, filter); }
|
void get(std::vector<APIError>& errors, ErrorFilter filter, size_t max = 0) { get(errors, max, filter); }
|
||||||
void get(std::vector<APIError>& errors, size_t max = 0, ErrorFilter filter = ErrorFilter());
|
void get(std::vector<APIError>& errors, size_t max = 0, ErrorFilter filter = ErrorFilter());
|
||||||
bool getOne(APIError& error, ErrorFilter filter = ErrorFilter());
|
bool getLastError(APIError& error, ErrorFilter filter = ErrorFilter());
|
||||||
|
|
||||||
void add(APIError error) {
|
void add(APIError error) {
|
||||||
std::lock_guard<std::mutex> lk(mutex);
|
std::lock_guard<std::mutex> lk(mutex);
|
||||||
|
|
|
||||||
|
|
@ -7,6 +7,7 @@
|
||||||
#include "icsneo/platform/dynamiclib.h" // Dynamic library loading and exporting
|
#include "icsneo/platform/dynamiclib.h" // Dynamic library loading and exporting
|
||||||
#include "icsneo/communication/network.h" // Network type and netID defines
|
#include "icsneo/communication/network.h" // Network type and netID defines
|
||||||
#include "icsneo/api/version.h" // For version info
|
#include "icsneo/api/version.h" // For version info
|
||||||
|
#include "icsneo/api/error.h" // For error info
|
||||||
|
|
||||||
#ifndef ICSNEOC_DYNAMICLOAD
|
#ifndef ICSNEOC_DYNAMICLOAD
|
||||||
|
|
||||||
|
|
@ -68,6 +69,20 @@ extern bool DLLExport icsneo_describeDevice(const neodevice_t* device, char* str
|
||||||
|
|
||||||
extern neoversion_t DLLExport icsneo_getVersion(void);
|
extern neoversion_t DLLExport icsneo_getVersion(void);
|
||||||
|
|
||||||
|
extern bool DLLExport icsneo_getErrors(neoerror_t* errors, size_t* size);
|
||||||
|
|
||||||
|
extern bool DLLExport icsneo_getDeviceErrors(const neodevice_t* device, neoerror_t* errors, size_t* size);
|
||||||
|
|
||||||
|
extern bool DLLExport icsneo_getLastError(neoerror_t* error);
|
||||||
|
|
||||||
|
extern void DLLExport icsneo_discardAllErrors(void);
|
||||||
|
|
||||||
|
extern void DLLExport icsneo_discardDeviceErrors(const neodevice_t* device);
|
||||||
|
|
||||||
|
extern void DLLExport icsneo_setErrorLimit(size_t newLimit);
|
||||||
|
|
||||||
|
extern size_t DLLExport icsneo_getErrorLimit(void);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
} // extern "C"
|
} // extern "C"
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -155,6 +170,27 @@ fn_icsneo_describeDevice icsneo_describeDevice;
|
||||||
typedef neoversion_t(*fn_icsneo_getVersion)(void);
|
typedef neoversion_t(*fn_icsneo_getVersion)(void);
|
||||||
fn_icsneo_getVersion icsneo_getVersion;
|
fn_icsneo_getVersion icsneo_getVersion;
|
||||||
|
|
||||||
|
typedef bool(*fn_icsneo_getErrors)(neoerror_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);
|
||||||
|
fn_icsneo_getDeviceErrors icsneo_getDeviceErrors;
|
||||||
|
|
||||||
|
typedef bool(*fn_icsneo_getLastError)(neoerror_t* error);
|
||||||
|
fn_icsneo_getLastError icsneo_getLastError;
|
||||||
|
|
||||||
|
typedef void(*fn_icsneo_discardAllErrors)(void);
|
||||||
|
fn_icsneo_discardAllErrors icsneo_discardAllErrors;
|
||||||
|
|
||||||
|
typedef void(*fn_icsneo_discardDeviceErrors)(const neodevice_t* device);
|
||||||
|
fn_icsneo_discardDeviceErrors icsneo_discardDeviceErrors;
|
||||||
|
|
||||||
|
typedef void(*fn_icsneo_setErrorLimit)(size_t newLimit);
|
||||||
|
fn_icsneo_setErrorLimit icsneo_setErrorLimit;
|
||||||
|
|
||||||
|
typedef size_t(*fn_icsneo_getErrorLimit)(void);
|
||||||
|
fn_icsneo_getErrorLimit icsneo_getErrorLimit;
|
||||||
|
|
||||||
#define ICSNEO_IMPORT(func) func = (fn_##func)icsneo_dynamicLibraryGetFunction(icsneo_libraryHandle, #func)
|
#define ICSNEO_IMPORT(func) func = (fn_##func)icsneo_dynamicLibraryGetFunction(icsneo_libraryHandle, #func)
|
||||||
#define ICSNEO_IMPORTASSERT(func) if((ICSNEO_IMPORT(func)) == NULL) return 3
|
#define ICSNEO_IMPORTASSERT(func) if((ICSNEO_IMPORT(func)) == NULL) return 3
|
||||||
void* icsneo_libraryHandle = NULL;
|
void* icsneo_libraryHandle = NULL;
|
||||||
|
|
@ -196,6 +232,13 @@ int icsneo_init() {
|
||||||
ICSNEO_IMPORTASSERT(icsneo_transmitMessages);
|
ICSNEO_IMPORTASSERT(icsneo_transmitMessages);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_describeDevice);
|
ICSNEO_IMPORTASSERT(icsneo_describeDevice);
|
||||||
ICSNEO_IMPORTASSERT(icsneo_getVersion);
|
ICSNEO_IMPORTASSERT(icsneo_getVersion);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_getErrors);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_getDeviceErrors);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_getLastError);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_discardAllErrors);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_discardDeviceErrors);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_setErrorLimit);
|
||||||
|
ICSNEO_IMPORTASSERT(icsneo_getErrorLimit);
|
||||||
|
|
||||||
icsneo_initialized = true;
|
icsneo_initialized = true;
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
||||||
|
|
@ -6,11 +6,22 @@
|
||||||
|
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/api/version.h"
|
#include "icsneo/api/version.h"
|
||||||
|
#include "icsneo/api/errormanager.h"
|
||||||
|
|
||||||
namespace icsneo {
|
namespace icsneo {
|
||||||
|
|
||||||
std::vector<std::shared_ptr<Device>> FindAllDevices();
|
std::vector<std::shared_ptr<Device>> FindAllDevices();
|
||||||
|
|
||||||
|
size_t ErrorCount(ErrorFilter filter = ErrorFilter());
|
||||||
|
std::vector<APIError> GetErrors(ErrorFilter filter, size_t max = 0);
|
||||||
|
std::vector<APIError> GetErrors(size_t max = 0, ErrorFilter filter = ErrorFilter());
|
||||||
|
void GetErrors(std::vector<APIError>& errors, ErrorFilter filter, size_t max = 0);
|
||||||
|
void GetErrors(std::vector<APIError>& 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();
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
Loading…
Reference in New Issue