Added error reporting to idevicesettings
parent
965679c370
commit
a16f2843d8
|
|
@ -59,6 +59,17 @@ static constexpr const char* ERROR_SETTINGS_VERSION = "The settings version is i
|
|||
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_BAD_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.";
|
||||
|
||||
// Transport Errors
|
||||
static constexpr const char* ERROR_FAILED_TO_READ = "A read operation failed.";
|
||||
|
|
@ -108,6 +119,26 @@ const char* APIError::DescriptionForType(ErrorType type) {
|
|||
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 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;
|
||||
|
||||
// Transport Errors
|
||||
case FailedToRead:
|
||||
|
|
@ -145,6 +176,8 @@ APIError::Severity APIError::SeverityForType(ErrorType type) {
|
|||
case DeviceCurrentlyClosed:
|
||||
// Device Warnings
|
||||
case PollingMessageOverflow:
|
||||
case DeviceFirmwareOutOfDate:
|
||||
case SettingsStructureTruncated:
|
||||
// Transport Warnings
|
||||
case PCAPCouldNotStart:
|
||||
case PCAPCouldNotFindDevices:
|
||||
|
|
@ -164,6 +197,14 @@ APIError::Severity APIError::SeverityForType(ErrorType type) {
|
|||
case SettingsLengthError:
|
||||
case SettingsChecksumError:
|
||||
case SettingsNotAvailable:
|
||||
case SettingsReadOnly:
|
||||
case CANSettingsNotAvailable:
|
||||
case CANFDSettingsNotAvailable:
|
||||
case LSFTCANSettingsNotAvailable:
|
||||
case SWCANSettingsNotAvailable:
|
||||
case BaudrateNotFound:
|
||||
case SettingsStructureMismatch:
|
||||
case NoDeviceResponse:
|
||||
// Transport Errors
|
||||
case FailedToRead:
|
||||
case FailedToWrite:
|
||||
|
|
|
|||
|
|
@ -183,8 +183,20 @@ bool IDeviceSettings::refresh(bool ignoreChecksum) {
|
|||
}
|
||||
|
||||
bool IDeviceSettings::apply(bool temporary) {
|
||||
if(!settingsLoaded || disabled || readonly)
|
||||
if(readonly) {
|
||||
err(APIError::SettingsReadOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
err(APIError::SettingsReadError);
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<uint8_t> bytestream;
|
||||
bytestream.resize(7 + settings.size());
|
||||
|
|
@ -202,7 +214,11 @@ bool IDeviceSettings::apply(bool temporary) {
|
|||
std::shared_ptr<Message> msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
||||
|
||||
if(!msg || msg->data[0] != 1) { // We did not receive a response
|
||||
refresh(); // Attempt to get the settings from the device so we're up to date if possible
|
||||
// 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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -217,7 +233,11 @@ bool IDeviceSettings::apply(bool temporary) {
|
|||
com->sendCommand(Command::SetSettings, bytestream);
|
||||
msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
refresh();
|
||||
// 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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -228,17 +248,32 @@ bool IDeviceSettings::apply(bool temporary) {
|
|||
|
||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||
|
||||
return (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||
bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||
if(!ret) {
|
||||
err(APIError::FailedToWrite);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool IDeviceSettings::applyDefaults(bool temporary) {
|
||||
if(disabled || readonly)
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
err(APIError::SettingsReadOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
com->sendCommand(Command::SetDefaultSettings);
|
||||
std::shared_ptr<Message> msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetDefaultSettings), std::chrono::milliseconds(1000));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
refresh();
|
||||
// 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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -263,7 +298,11 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
|||
com->sendCommand(Command::SetSettings, bytestream);
|
||||
msg = com->waitForMessageSync(std::make_shared<Main51MessageFilter>(Command::SetSettings), std::chrono::milliseconds(1000));
|
||||
if(!msg || msg->data[0] != 1) {
|
||||
refresh();
|
||||
// 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);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -274,45 +313,79 @@ bool IDeviceSettings::applyDefaults(bool temporary) {
|
|||
|
||||
refresh(); // Refresh our buffer with what the device has, whether we were successful or not
|
||||
|
||||
return (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||
bool ret = (msg && msg->data[0] == 1); // Device sends 0x01 for success
|
||||
if(!ret) {
|
||||
err(APIError::FailedToWrite);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int64_t IDeviceSettings::getBaudrateFor(Network net) const {
|
||||
if(!settingsLoaded || disabled)
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
err(APIError::SettingsReadError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::CAN: {
|
||||
const CAN_SETTINGS* cfg = getCANSettingsFor(net);
|
||||
if(cfg == nullptr)
|
||||
if(cfg == nullptr) {
|
||||
err(APIError::CANFDSettingsNotAvailable);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->Baudrate);
|
||||
if(baudrate == -1)
|
||||
if(baudrate == -1) {
|
||||
err(APIError::BaudrateNotFound);
|
||||
return -1;
|
||||
}
|
||||
return baudrate;
|
||||
}
|
||||
default:
|
||||
err(APIError::BadNetworkType);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
||||
if(!settingsLoaded || disabled || readonly)
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
err(APIError::SettingsReadError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
err(APIError::SettingsReadOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::CAN: {
|
||||
if(baudrate > 1000000) // This is an FD baudrate. Use setFDBaudrateFor instead.
|
||||
if(baudrate > 1000000) { // This is an FD baudrate. Use setFDBaudrateFor instead.
|
||||
err(APIError::CANFDSettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
CAN_SETTINGS* cfg = getMutableCANSettingsFor(net);
|
||||
if(cfg == nullptr)
|
||||
if(cfg == nullptr) {
|
||||
err(APIError::CANSettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||
if(newBaud == (CANBaudrate)-1)
|
||||
if(newBaud == (CANBaudrate)-1) {
|
||||
err(APIError::BaudrateNotFound);
|
||||
return false;
|
||||
}
|
||||
cfg->Baudrate = (uint8_t)newBaud;
|
||||
cfg->auto_baud = false;
|
||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
|
|
@ -320,12 +393,16 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||
}
|
||||
case Network::Type::LSFTCAN: {
|
||||
CAN_SETTINGS* cfg = getMutableLSFTCANSettingsFor(net);
|
||||
if(cfg == nullptr)
|
||||
if(cfg == nullptr) {
|
||||
err(APIError::LSFTCANSettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||
if(newBaud == (CANBaudrate)-1)
|
||||
if(newBaud == (CANBaudrate)-1) {
|
||||
err(APIError::BaudrateNotFound);
|
||||
return false;
|
||||
}
|
||||
cfg->Baudrate = (uint8_t)newBaud;
|
||||
cfg->auto_baud = false;
|
||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
|
|
@ -333,77 +410,126 @@ bool IDeviceSettings::setBaudrateFor(Network net, int64_t baudrate) {
|
|||
}
|
||||
case Network::Type::SWCAN: {
|
||||
SWCAN_SETTINGS* cfg = getMutableSWCANSettingsFor(net);
|
||||
if(cfg == nullptr)
|
||||
if(cfg == nullptr) {
|
||||
err(APIError::SWCANSettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||
if(newBaud == (CANBaudrate)-1)
|
||||
if(newBaud == (CANBaudrate)-1) {
|
||||
err(APIError::BaudrateNotFound);
|
||||
return false;
|
||||
}
|
||||
cfg->Baudrate = (uint8_t)newBaud;
|
||||
cfg->auto_baud = false;
|
||||
cfg->SetBaudrate = AUTO; // Device will use the baudrate value to set the TQ values
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
err(APIError::BadNetworkType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
int64_t IDeviceSettings::getFDBaudrateFor(Network net) const {
|
||||
if(!settingsLoaded || disabled)
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
}
|
||||
|
||||
if(!settingsLoaded) {
|
||||
err(APIError::SettingsReadError);
|
||||
return -1;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::CAN: {
|
||||
const CANFD_SETTINGS* cfg = getCANFDSettingsFor(net);
|
||||
if(cfg == nullptr)
|
||||
if(cfg == nullptr) {
|
||||
err(APIError::CANFDSettingsNotAvailable);
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t baudrate = GetBaudrateValueForEnum((CANBaudrate)cfg->FDBaudrate);
|
||||
if(baudrate == -1)
|
||||
if(baudrate == -1) {
|
||||
err(APIError::BaudrateNotFound);
|
||||
return -1;
|
||||
}
|
||||
|
||||
return baudrate;
|
||||
}
|
||||
default:
|
||||
err(APIError::BadNetworkType);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
bool IDeviceSettings::setFDBaudrateFor(Network net, int64_t baudrate) {
|
||||
if(!settingsLoaded || disabled || readonly)
|
||||
if(!settingsLoaded) {
|
||||
err(APIError::SettingsReadError);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
err(APIError::SettingsReadOnly);
|
||||
return false;
|
||||
}
|
||||
|
||||
switch(net.getType()) {
|
||||
case Network::Type::CAN: {
|
||||
CANFD_SETTINGS* cfg = getMutableCANFDSettingsFor(net);
|
||||
if(cfg == nullptr)
|
||||
if(cfg == nullptr) {
|
||||
err(APIError::CANFDSettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
CANBaudrate newBaud = GetEnumValueForBaudrate(baudrate);
|
||||
if(newBaud == (CANBaudrate)-1)
|
||||
if(newBaud == (CANBaudrate)-1) {
|
||||
err(APIError::BaudrateNotFound);
|
||||
return false;
|
||||
}
|
||||
cfg->FDBaudrate = (uint8_t)newBaud;
|
||||
return true;
|
||||
}
|
||||
default:
|
||||
err(APIError::BadNetworkType);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
template<typename T> bool IDeviceSettings::applyStructure(const T& newStructure) {
|
||||
if(!settingsLoaded || disabled || readonly)
|
||||
if(!settingsLoaded) {
|
||||
err(APIError::SettingsReadError);
|
||||
return false;
|
||||
}
|
||||
|
||||
// This function is only called from C++ so the callers structure size and ours should never differ
|
||||
if(sizeof(T) != structSize)
|
||||
if(disabled) {
|
||||
err(APIError::SettingsNotAvailable);
|
||||
return false;
|
||||
}
|
||||
|
||||
if(readonly) {
|
||||
err(APIError::SettingsReadOnly);
|
||||
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);
|
||||
return false; // The wrong structure was passed in for the current device
|
||||
|
||||
}
|
||||
size_t copySize = sizeof(T);
|
||||
if(copySize > settings.size())
|
||||
if(copySize > settings.size()) {
|
||||
err(APIError::SettingsStructureTruncated);
|
||||
copySize = settings.size(); // TODO Warn user that their structure is truncated
|
||||
|
||||
// TODO Warn user that the device firmware doesn't support all the settings in the current API
|
||||
//if(copySize < settings.size())
|
||||
}
|
||||
// Warn user that the device firmware doesn't support all the settings in the current API
|
||||
if(copySize < settings.size())
|
||||
err(APIError::DeviceFirmwareOutOfDate);
|
||||
|
||||
memcpy(settings.data(), &newStructure, structSize);
|
||||
return apply();
|
||||
|
|
|
|||
|
|
@ -50,6 +50,17 @@ public:
|
|||
SettingsLengthError = 0x2005,
|
||||
SettingsChecksumError = 0x2006,
|
||||
SettingsNotAvailable = 0x2007,
|
||||
SettingsReadOnly = 0x2008,
|
||||
CANSettingsNotAvailable = 0x2009,
|
||||
CANFDSettingsNotAvailable = 0x2010,
|
||||
LSFTCANSettingsNotAvailable = 0x2011,
|
||||
SWCANSettingsNotAvailable = 0x2012,
|
||||
BaudrateNotFound = 0x2013,
|
||||
BadNetworkType = 0x2014,
|
||||
DeviceFirmwareOutOfDate = 0x2015,
|
||||
SettingsStructureMismatch = 0x2016,
|
||||
SettingsStructureTruncated = 0x2017,
|
||||
NoDeviceResponse = 0x2018,
|
||||
|
||||
// Transport Errors
|
||||
FailedToRead = 0x3000,
|
||||
|
|
|
|||
|
|
@ -399,13 +399,17 @@ public:
|
|||
|
||||
const size_t& getSize() const { return structSize; }
|
||||
|
||||
// if settings are disabled for this device. always false unless constructed null
|
||||
bool disabled = false;
|
||||
|
||||
bool readonly = false;
|
||||
bool disableGSChecksumming = false;
|
||||
protected:
|
||||
std::shared_ptr<Communication> com;
|
||||
device_errorhandler_t err;
|
||||
size_t structSize;
|
||||
|
||||
// if we hold any local copies of the device settings
|
||||
bool settingsLoaded = false;
|
||||
|
||||
std::vector<uint8_t> settings; // For writing settings to, calling apply() should copy over to device RAM (and EEPROM)
|
||||
|
|
|
|||
Loading…
Reference in New Issue