Communication: Add AppErrorMessage support
App errors are responses from the device indicating internal runtime errors.ks-refactor-docs
parent
75af3220b0
commit
cac8d760b0
|
|
@ -238,6 +238,7 @@ set(SRC_FILES
|
||||||
communication/message/flexray/control/flexraycontrolmessage.cpp
|
communication/message/flexray/control/flexraycontrolmessage.cpp
|
||||||
communication/message/callback/streamoutput/a2bwavoutput.cpp
|
communication/message/callback/streamoutput/a2bwavoutput.cpp
|
||||||
communication/message/a2bmessage.cpp
|
communication/message/a2bmessage.cpp
|
||||||
|
communication/message/apperrormessage.cpp
|
||||||
communication/message/neomessage.cpp
|
communication/message/neomessage.cpp
|
||||||
communication/message/ethphymessage.cpp
|
communication/message/ethphymessage.cpp
|
||||||
communication/message/linmessage.cpp
|
communication/message/linmessage.cpp
|
||||||
|
|
@ -519,6 +520,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
||||||
test/unit/mdioencoderdecodertest.cpp
|
test/unit/mdioencoderdecodertest.cpp
|
||||||
test/unit/livedataencoderdecodertest.cpp
|
test/unit/livedataencoderdecodertest.cpp
|
||||||
test/unit/ringbuffertest.cpp
|
test/unit/ringbuffertest.cpp
|
||||||
|
test/unit/apperrordecodertest.cpp
|
||||||
)
|
)
|
||||||
|
|
||||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,7 @@
|
||||||
#include "icsneo/communication/message/diskdatamessage.h"
|
#include "icsneo/communication/message/diskdatamessage.h"
|
||||||
#include "icsneo/communication/message/hardwareinfo.h"
|
#include "icsneo/communication/message/hardwareinfo.h"
|
||||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||||
|
#include "icsneo/communication/message/apperrormessage.h"
|
||||||
#include "icsneo/communication/command.h"
|
#include "icsneo/communication/command.h"
|
||||||
#include "icsneo/device/device.h"
|
#include "icsneo/device/device.h"
|
||||||
#include "icsneo/communication/packet/canpacket.h"
|
#include "icsneo/communication/packet/canpacket.h"
|
||||||
|
|
@ -398,6 +399,14 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
||||||
packet->data.resize(length);
|
packet->data.resize(length);
|
||||||
return decode(result, packet);
|
return decode(result, packet);
|
||||||
}
|
}
|
||||||
|
case Network::NetID::RED_App_Error: {
|
||||||
|
result = AppErrorMessage::DecodeToMessage(packet->data, report);
|
||||||
|
if(!result) {
|
||||||
|
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
case Network::NetID::ReadSettings: {
|
case Network::NetID::ReadSettings: {
|
||||||
auto msg = std::make_shared<ReadSettingsMessage>();
|
auto msg = std::make_shared<ReadSettingsMessage>();
|
||||||
msg->response = ReadSettingsMessage::Response(packet->data[0]);
|
msg->response = ReadSettingsMessage::Response(packet->data[0]);
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,143 @@
|
||||||
|
#include <icsneo/communication/message/apperrormessage.h>
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
#pragma pack(push, 2)
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
uint16_t error_type;
|
||||||
|
uint16_t network_id;
|
||||||
|
uint32_t uiTimeStamp10uS;
|
||||||
|
uint32_t uiTimeStamp10uSMSB;
|
||||||
|
} AppErrorData;
|
||||||
|
|
||||||
|
#pragma pack(pop)
|
||||||
|
|
||||||
|
std::shared_ptr<Message> AppErrorMessage::DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report) {
|
||||||
|
const AppErrorData* data = reinterpret_cast<const AppErrorData*>(bytestream.data());
|
||||||
|
if(!data) {
|
||||||
|
report(APIEvent::Type::AppErrorParsingFailed, APIEvent::Severity::Error);
|
||||||
|
return nullptr;
|
||||||
|
}
|
||||||
|
auto appErr = std::make_shared<AppErrorMessage>();
|
||||||
|
appErr->errorType = data->error_type;
|
||||||
|
appErr->errorNetID = static_cast<Network::NetID>(data->network_id);
|
||||||
|
appErr->timestamp10us = data->uiTimeStamp10uS;
|
||||||
|
appErr->timestamp10usMSB = data->uiTimeStamp10uSMSB;
|
||||||
|
appErr->network = Network::NetID::RED_App_Error;
|
||||||
|
return appErr;
|
||||||
|
}
|
||||||
|
|
||||||
|
AppErrorType AppErrorMessage::getAppErrorType() {
|
||||||
|
AppErrorType errType = static_cast<AppErrorType>(errorType);
|
||||||
|
if(errType > AppErrorType::AppNoError) {
|
||||||
|
return AppErrorType::AppNoError;
|
||||||
|
}
|
||||||
|
return errType;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string AppErrorMessage::getAppErrorString() {
|
||||||
|
auto netIDString = Network::GetNetIDString(errorNetID);
|
||||||
|
AppErrorType errType = static_cast<AppErrorType>(errorType);
|
||||||
|
switch (errType) {
|
||||||
|
case AppErrorType::AppErrorRxMessagesFull:
|
||||||
|
return std::string(netIDString) + ": RX message buffer full";
|
||||||
|
case AppErrorType::AppErrorTxMessagesFull:
|
||||||
|
return std::string(netIDString) + ": TX message buffer full";
|
||||||
|
case AppErrorType::AppErrorTxReportMessagesFull:
|
||||||
|
return std::string(netIDString) + ": TX report buffer full";
|
||||||
|
case AppErrorType::AppErrorBadCommWithDspIC:
|
||||||
|
return "Received bad packet from DSP IC";
|
||||||
|
case AppErrorType::AppErrorDriverOverflow:
|
||||||
|
return std::string(netIDString) + ": Driver overflow";
|
||||||
|
case AppErrorType::AppErrorPCBuffOverflow:
|
||||||
|
return "PC buffer overflow";
|
||||||
|
case AppErrorType::AppErrorPCChksumError:
|
||||||
|
return "PC checksum error";
|
||||||
|
case AppErrorType::AppErrorPCMissedByte:
|
||||||
|
return "PC missed byte";
|
||||||
|
case AppErrorType::AppErrorPCOverrunError:
|
||||||
|
return "PC overrun error";
|
||||||
|
case AppErrorType::AppErrorSettingFailure:
|
||||||
|
return std::string(netIDString) + ": Settings incorrectly set";
|
||||||
|
case AppErrorType::AppErrorTooManySelectedNetworks:
|
||||||
|
return "Too many selected networks";
|
||||||
|
case AppErrorType::AppErrorNetworkNotEnabled:
|
||||||
|
return std::string(netIDString) + ": Network not enabled";
|
||||||
|
case AppErrorType::AppErrorRtcNotCorrect:
|
||||||
|
return "RTC not correct";
|
||||||
|
case AppErrorType::AppErrorLoadedDefaultSettings:
|
||||||
|
return "Loaded default settings";
|
||||||
|
case AppErrorType::AppErrorFeatureNotUnlocked:
|
||||||
|
return "Feature not unlocked";
|
||||||
|
case AppErrorType::AppErrorFeatureRtcCmdDropped:
|
||||||
|
return "RTC command dropped";
|
||||||
|
case AppErrorType::AppErrorTxMessagesFlushed:
|
||||||
|
return "TX message buffer flushed";
|
||||||
|
case AppErrorType::AppErrorTxMessagesHalfFull:
|
||||||
|
return "TX message buffer half full";
|
||||||
|
case AppErrorType::AppErrorNetworkNotValid:
|
||||||
|
return "Network is not valid";
|
||||||
|
case AppErrorType::AppErrorTxInterfaceNotImplemented:
|
||||||
|
return "TX interface is not implemented";
|
||||||
|
case AppErrorType::AppErrorTxMessagesCommEnableIsOff:
|
||||||
|
return "TX message communication is disabled";
|
||||||
|
case AppErrorType::AppErrorRxFilterMatchCountExceeded:
|
||||||
|
return "RX filter match count exceeded";
|
||||||
|
case AppErrorType::AppErrorEthPreemptionNotEnabled:
|
||||||
|
return std::string(netIDString) + ": Ethernet preemption not enabled";
|
||||||
|
case AppErrorType::AppErrorTxNotSupportedInMode:
|
||||||
|
return std::string(netIDString) + ": Transmit is not supported in this mode";
|
||||||
|
case AppErrorType::AppErrorJumboFramesNotSupported:
|
||||||
|
return std::string(netIDString) + ": Jumbo frames not supported";
|
||||||
|
case AppErrorType::AppErrorEthernetIpFragment:
|
||||||
|
return "Ethernet IP fragment received";
|
||||||
|
case AppErrorType::AppErrorTxMessagesUnderrun:
|
||||||
|
return std::string(netIDString) + ": Transmit buffer underrun";
|
||||||
|
case AppErrorType::AppErrorDeviceFanFailure:
|
||||||
|
return "Device fan failure";
|
||||||
|
case AppErrorType::AppErrorDeviceOvertemperature:
|
||||||
|
return "Device overtemperature";
|
||||||
|
case AppErrorType::AppErrorTxMessageIndexOutOfRange:
|
||||||
|
return "Transmit message index out of range";
|
||||||
|
case AppErrorType::AppErrorUndersizedFrameDropped:
|
||||||
|
return std::string(netIDString) + ": Undersized frame dropped";
|
||||||
|
case AppErrorType::AppErrorOversizedFrameDropped:
|
||||||
|
return std::string(netIDString) + ": Oversized frame dropped";
|
||||||
|
case AppErrorType::AppErrorWatchdogEvent:
|
||||||
|
return "Watchdog event occured";
|
||||||
|
case AppErrorType::AppErrorSystemClockFailure:
|
||||||
|
return "Device clock failed";
|
||||||
|
case AppErrorType::AppErrorSystemClockRecovered:
|
||||||
|
return "Device clock recovered";
|
||||||
|
case AppErrorType::AppErrorSystemPeripheralReset:
|
||||||
|
return "Device peripheral reset";
|
||||||
|
case AppErrorType::AppErrorSystemCommunicationFailure:
|
||||||
|
return "Device communication failure";
|
||||||
|
case AppErrorType::AppErrorTxMessagesUnsupportedSourceOrPacketId:
|
||||||
|
return std::string(netIDString) + ": Transmit unsupported source or packet ID";
|
||||||
|
case AppErrorType::AppErrorWbmsManagerConnectFailed:
|
||||||
|
return std::string(netIDString) + ": Failed to connect to managers with settings";
|
||||||
|
case AppErrorType::AppErrorWbmsManagerConnectBadState:
|
||||||
|
return std::string(netIDString) + ": Connected to managers in a invalid state";
|
||||||
|
case AppErrorType::AppErrorWbmsManagerConnectTimeout:
|
||||||
|
return std::string(netIDString) + ": Timeout while attempting to connect to managers";
|
||||||
|
case AppErrorType::AppErrorFailedToInitializeLoggerDisk:
|
||||||
|
return "Device failed to initialize storage disk";
|
||||||
|
case AppErrorType::AppErrorInvalidSetting:
|
||||||
|
return std::string(netIDString) + ": Invalid settings";
|
||||||
|
case AppErrorType::AppErrorSystemFailureRequestedReset:
|
||||||
|
return "Device rebooted to recover from an unexpected error condition";
|
||||||
|
case AppErrorType::AppErrorPortKeyMistmatch:
|
||||||
|
return std::string(netIDString) + ": Mismatch between key in manager and stored key";
|
||||||
|
case AppErrorType::AppErrorErrorBufferOverflow:
|
||||||
|
return "Device error buffer overflow";
|
||||||
|
case AppErrorType::AppNoError:
|
||||||
|
return "No error";
|
||||||
|
default:
|
||||||
|
return "Unknown error";
|
||||||
|
}
|
||||||
|
return "Unknown error";
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace icsneo
|
||||||
|
|
@ -9,6 +9,7 @@ option(LIBICSNEO_BUILD_CPP_LIVEDATA_EXAMPLE "Build the Live Data example." ON)
|
||||||
option(LIBICSNEO_BUILD_CPP_COREMINI_EXAMPLE "Build the Coremini example." ON)
|
option(LIBICSNEO_BUILD_CPP_COREMINI_EXAMPLE "Build the Coremini example." ON)
|
||||||
option(LIBICSNEO_BUILD_CPP_MDIO_EXAMPLE "Build the MDIO example." ON)
|
option(LIBICSNEO_BUILD_CPP_MDIO_EXAMPLE "Build the MDIO example." ON)
|
||||||
option(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE "Build the VSA example." ON)
|
option(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE "Build the VSA example." ON)
|
||||||
|
option(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE "Build the app error example." ON)
|
||||||
|
|
||||||
# Disabled until we properly build these in-tree
|
# Disabled until we properly build these in-tree
|
||||||
# option(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE "Build the command-line interactive C# example." OFF)
|
# option(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE "Build the command-line interactive C# example." OFF)
|
||||||
|
|
@ -58,6 +59,10 @@ if(LIBICSNEO_BUILD_CPP_VSA_EXAMPLE)
|
||||||
add_subdirectory(cpp/vsa)
|
add_subdirectory(cpp/vsa)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
|
if(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE)
|
||||||
|
add_subdirectory(cpp/apperror)
|
||||||
|
endif()
|
||||||
|
|
||||||
# if(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE)
|
# if(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE)
|
||||||
# add_subdirectory(csharp)
|
# add_subdirectory(csharp)
|
||||||
# endif()
|
# endif()
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,2 @@
|
||||||
|
add_executable(libicsneocpp-app-error src/AppErrorExample.cpp)
|
||||||
|
target_link_libraries(libicsneocpp-app-error icsneocpp)
|
||||||
|
|
@ -0,0 +1,85 @@
|
||||||
|
#include <iostream>
|
||||||
|
#include <iomanip>
|
||||||
|
#include <thread>
|
||||||
|
#include <chrono>
|
||||||
|
|
||||||
|
#include "icsneo/icsneocpp.h"
|
||||||
|
#include "icsneo/communication/message/apperrormessage.h"
|
||||||
|
#include "icsneo/communication/message/message.h"
|
||||||
|
/*
|
||||||
|
* App errors are responses from the device indicating internal runtime errors
|
||||||
|
* NOTE: To trigger the app error in this example, disable the HSCAN network on the device
|
||||||
|
* (e.g. with neoVI Explorer)
|
||||||
|
*/
|
||||||
|
int main() {
|
||||||
|
std::cout << "Running libicsneo " << icsneo::GetVersion() << std::endl;
|
||||||
|
std::cout << "\nFinding devices... " << std::flush;
|
||||||
|
auto devices = icsneo::FindAllDevices();
|
||||||
|
std::cout << "OK, " << devices.size() << " device" << (devices.size() == 1 ? "" : "s") << " found" << std::endl;
|
||||||
|
|
||||||
|
// List off the devices
|
||||||
|
for(auto& device : devices)
|
||||||
|
std::cout << '\t' << device->describe() << " @ Handle " << device->getNeoDevice().handle << std::endl;
|
||||||
|
std::cout << std::endl;
|
||||||
|
|
||||||
|
for(auto device : devices) {
|
||||||
|
std::cout << "Connecting to " << device->describe() << "... ";
|
||||||
|
bool ret = device->open();
|
||||||
|
if(!ret) { // Failed to open
|
||||||
|
std::cout << "FAIL" << std::endl;
|
||||||
|
std::cout << icsneo::GetLastError() << std::endl << std::endl;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << "OK" << std::endl << std::endl;
|
||||||
|
|
||||||
|
// Create an app error message filter, including "internal" messages
|
||||||
|
auto filter = std::make_shared<icsneo::MessageFilter>(icsneo::Message::Type::AppError);
|
||||||
|
filter->includeInternalInAny = true;
|
||||||
|
|
||||||
|
// ...and register a callback with it.
|
||||||
|
// Add your error handling here
|
||||||
|
auto handler = device->addMessageCallback(std::make_shared<icsneo::MessageCallback>(filter, [](std::shared_ptr<icsneo::Message> message) {
|
||||||
|
auto msg = std::static_pointer_cast<icsneo::AppErrorMessage>(message);
|
||||||
|
if(icsneo::Network::NetID::RED_App_Error == msg->network.getNetID()) {
|
||||||
|
std::cout << std::endl << "App error reported:" << std::endl;
|
||||||
|
std::cout << msg->getAppErrorString() << std::endl << std::endl;
|
||||||
|
}
|
||||||
|
}));
|
||||||
|
|
||||||
|
std::cout << "Going online... ";
|
||||||
|
ret = device->goOnline();
|
||||||
|
if(!ret) {
|
||||||
|
std::cout << "FAIL" << std::endl;
|
||||||
|
device->close();
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
std::cout << "OK" << std::endl;
|
||||||
|
|
||||||
|
// Prepare a CAN message
|
||||||
|
std::cout << std::endl << "Transmitting a CAN frame... ";
|
||||||
|
auto txMessage = std::make_shared<icsneo::CANMessage>();
|
||||||
|
txMessage->network = icsneo::Network::NetID::HSCAN;
|
||||||
|
txMessage->arbid = 0x22;
|
||||||
|
txMessage->data.insert(txMessage->data.end(), {0xaa, 0xbb, 0xcc});
|
||||||
|
// The DLC will come from the length of the data vector
|
||||||
|
txMessage->isExtended = false;
|
||||||
|
txMessage->isCANFD = false;
|
||||||
|
|
||||||
|
// Transmit a CAN message on HSCAN, even though HSCAN is disabled on the device!
|
||||||
|
// Expect to see an app error caught in the callback defined above
|
||||||
|
ret = device->transmit(txMessage);
|
||||||
|
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||||
|
|
||||||
|
std::this_thread::sleep_for(std::chrono::milliseconds(1000));
|
||||||
|
|
||||||
|
// Go offline, stop sending and receiving traffic
|
||||||
|
device->removeMessageCallback(handler);
|
||||||
|
std::cout << "Going offline... ";
|
||||||
|
ret = device->goOffline();
|
||||||
|
std::cout << (ret ? "OK" : "FAIL") << std::endl;
|
||||||
|
std::cout << "Disconnecting... ";
|
||||||
|
ret = device->close();
|
||||||
|
std::cout << (ret ? "OK\n" : "FAIL\n") << std::endl;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
@ -108,6 +108,7 @@ public:
|
||||||
LiveDataNotSupported = 0x2052,
|
LiveDataNotSupported = 0x2052,
|
||||||
LINSettingsNotAvailable = 0x2053,
|
LINSettingsNotAvailable = 0x2053,
|
||||||
ModeNotFound = 0x2054,
|
ModeNotFound = 0x2054,
|
||||||
|
AppErrorParsingFailed = 0x2055,
|
||||||
|
|
||||||
// Transport Events
|
// Transport Events
|
||||||
FailedToRead = 0x3000,
|
FailedToRead = 0x3000,
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,80 @@
|
||||||
|
#ifndef __APPERRORMESSAGE_H_
|
||||||
|
#define __APPERRORMESSAGE_H_
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
|
||||||
|
#include "icsneo/communication/message/message.h"
|
||||||
|
#include <unordered_set>
|
||||||
|
#include <memory>
|
||||||
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
|
||||||
|
|
||||||
|
namespace icsneo {
|
||||||
|
|
||||||
|
enum class AppErrorType : uint16_t {
|
||||||
|
AppErrorRxMessagesFull = 0,
|
||||||
|
AppErrorTxMessagesFull = 1,
|
||||||
|
AppErrorTxReportMessagesFull = 2,
|
||||||
|
AppErrorBadCommWithDspIC = 3,
|
||||||
|
AppErrorDriverOverflow = 4,
|
||||||
|
AppErrorPCBuffOverflow = 5,
|
||||||
|
AppErrorPCChksumError = 6,
|
||||||
|
AppErrorPCMissedByte = 7,
|
||||||
|
AppErrorPCOverrunError = 8,
|
||||||
|
AppErrorSettingFailure = 9,
|
||||||
|
AppErrorTooManySelectedNetworks = 10,
|
||||||
|
AppErrorNetworkNotEnabled = 11,
|
||||||
|
AppErrorRtcNotCorrect = 12,
|
||||||
|
AppErrorLoadedDefaultSettings = 13,
|
||||||
|
AppErrorFeatureNotUnlocked = 14,
|
||||||
|
AppErrorFeatureRtcCmdDropped = 15,
|
||||||
|
AppErrorTxMessagesFlushed = 16,
|
||||||
|
AppErrorTxMessagesHalfFull = 17,
|
||||||
|
AppErrorNetworkNotValid = 18,
|
||||||
|
AppErrorTxInterfaceNotImplemented = 19,
|
||||||
|
AppErrorTxMessagesCommEnableIsOff = 20,
|
||||||
|
AppErrorRxFilterMatchCountExceeded = 21,
|
||||||
|
AppErrorEthPreemptionNotEnabled = 22,
|
||||||
|
AppErrorTxNotSupportedInMode = 23,
|
||||||
|
AppErrorJumboFramesNotSupported = 24,
|
||||||
|
AppErrorEthernetIpFragment = 25,
|
||||||
|
AppErrorTxMessagesUnderrun = 26,
|
||||||
|
AppErrorDeviceFanFailure = 27,
|
||||||
|
AppErrorDeviceOvertemperature = 28,
|
||||||
|
AppErrorTxMessageIndexOutOfRange = 29,
|
||||||
|
AppErrorUndersizedFrameDropped = 30,
|
||||||
|
AppErrorOversizedFrameDropped = 31,
|
||||||
|
AppErrorWatchdogEvent = 32,
|
||||||
|
AppErrorSystemClockFailure = 33,
|
||||||
|
AppErrorSystemClockRecovered = 34,
|
||||||
|
AppErrorSystemPeripheralReset = 35,
|
||||||
|
AppErrorSystemCommunicationFailure = 36,
|
||||||
|
AppErrorTxMessagesUnsupportedSourceOrPacketId = 37,
|
||||||
|
AppErrorWbmsManagerConnectFailed = 38,
|
||||||
|
AppErrorWbmsManagerConnectBadState = 39,
|
||||||
|
AppErrorWbmsManagerConnectTimeout = 40,
|
||||||
|
AppErrorFailedToInitializeLoggerDisk = 41,
|
||||||
|
AppErrorInvalidSetting = 42,
|
||||||
|
AppErrorSystemFailureRequestedReset = 43,
|
||||||
|
AppErrorPortKeyMistmatch = 45,
|
||||||
|
AppErrorErrorBufferOverflow = 254,
|
||||||
|
AppNoError = 255
|
||||||
|
};
|
||||||
|
|
||||||
|
class AppErrorMessage : public RawMessage {
|
||||||
|
public:
|
||||||
|
AppErrorMessage() : RawMessage(Message::Type::AppError, Network::NetID::RED_App_Error) {}
|
||||||
|
uint16_t errorType;
|
||||||
|
Network::NetID errorNetID;
|
||||||
|
uint32_t timestamp10us;
|
||||||
|
uint32_t timestamp10usMSB;
|
||||||
|
|
||||||
|
static std::shared_ptr<Message> DecodeToMessage(const std::vector<uint8_t>& bytestream, const device_eventhandler_t& report);
|
||||||
|
AppErrorType getAppErrorType();
|
||||||
|
std::string getAppErrorString();
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace icsneo
|
||||||
|
|
||||||
|
#endif // __cplusplus
|
||||||
|
#endif
|
||||||
|
|
@ -40,6 +40,7 @@ public:
|
||||||
LiveData = 0x800f,
|
LiveData = 0x800f,
|
||||||
HardwareInfo = 0x8010,
|
HardwareInfo = 0x8010,
|
||||||
TC10Status = 0x8011,
|
TC10Status = 0x8011,
|
||||||
|
AppError = 0x8012,
|
||||||
};
|
};
|
||||||
|
|
||||||
Message(Type t) : type(t) {}
|
Message(Type t) : type(t) {}
|
||||||
|
|
|
||||||
|
|
@ -537,6 +537,7 @@ public:
|
||||||
case NetID::NeoMemoryWriteDone:
|
case NetID::NeoMemoryWriteDone:
|
||||||
case NetID::RED_GET_RTC:
|
case NetID::RED_GET_RTC:
|
||||||
case NetID::DiskData:
|
case NetID::DiskData:
|
||||||
|
case NetID::RED_App_Error:
|
||||||
return Type::Internal;
|
return Type::Internal;
|
||||||
case NetID::Invalid:
|
case NetID::Invalid:
|
||||||
case NetID::Any:
|
case NetID::Any:
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,101 @@
|
||||||
|
#include "icsneo/icsneocpp.h"
|
||||||
|
#include "icsneo/communication/encoder.h"
|
||||||
|
#include "icsneo/communication/message/apperrormessage.h"
|
||||||
|
#include "icsneo/communication/packetizer.h"
|
||||||
|
#include "icsneo/device/tree/neovired2/neovired2.h"
|
||||||
|
#include "icsneo/api/eventmanager.h"
|
||||||
|
#include "gtest/gtest.h"
|
||||||
|
#include <vector>
|
||||||
|
#include <iostream>
|
||||||
|
|
||||||
|
using namespace icsneo;
|
||||||
|
|
||||||
|
class REDAppErrorDecoderTest : public ::testing::Test {
|
||||||
|
protected:
|
||||||
|
void SetUp() override {
|
||||||
|
report = [](APIEvent::Type, APIEvent::Severity) {
|
||||||
|
// Unless caught by the test, the packetizer should not throw errors
|
||||||
|
EXPECT_TRUE(false);
|
||||||
|
};
|
||||||
|
|
||||||
|
packetizer.emplace([this](APIEvent::Type t, APIEvent::Severity s) { report(t, s); });
|
||||||
|
packetEncoder.emplace([this](APIEvent::Type t, APIEvent::Severity s) { report(t, s); });
|
||||||
|
packetDecoder.emplace([this](APIEvent::Type t, APIEvent::Severity s) { report(t, s); });
|
||||||
|
}
|
||||||
|
|
||||||
|
device_eventhandler_t report;
|
||||||
|
std::optional<Encoder> packetEncoder;
|
||||||
|
std::optional<Packetizer> packetizer;
|
||||||
|
std::optional<Decoder> packetDecoder;
|
||||||
|
|
||||||
|
RingBuffer ringBuffer = RingBuffer(128);
|
||||||
|
|
||||||
|
std::vector<uint8_t> testErrorData =
|
||||||
|
{0xaa, 0x0c,
|
||||||
|
0x12, 0x00, //size
|
||||||
|
0x34, 0x00, //netID
|
||||||
|
0x0b, 0x00, //error_type
|
||||||
|
0x01, 0x00, //network_id
|
||||||
|
0x33, 0x44, 0x55, 0x66, //uiTime10us
|
||||||
|
0x77, 0x88, 0x99, 0xAA, //uiTime10usMSB
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
TEST_F(REDAppErrorDecoderTest, PacketDecoderTest) {
|
||||||
|
std::shared_ptr<icsneo::Message> decodeMsg;
|
||||||
|
|
||||||
|
auto msg1 = std::make_shared<icsneo::AppErrorMessage>();
|
||||||
|
msg1->errorType = static_cast<uint16_t>(AppErrorType::AppErrorNetworkNotEnabled);
|
||||||
|
msg1->errorNetID = Network::NetID::HSCAN;
|
||||||
|
msg1->timestamp10us = 0x66554433;
|
||||||
|
msg1->timestamp10usMSB = 0xAA998877;
|
||||||
|
msg1->network = icsneo::Network::NetID::RED_App_Error;
|
||||||
|
|
||||||
|
ringBuffer.clear();
|
||||||
|
ringBuffer.write(testErrorData);
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||||
|
auto packets = packetizer->output();
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||||
|
EXPECT_NE(decodeMsg, nullptr);
|
||||||
|
auto testMessage = std::dynamic_pointer_cast<icsneo::AppErrorMessage>(decodeMsg);
|
||||||
|
EXPECT_EQ(msg1->network, testMessage->network);
|
||||||
|
EXPECT_EQ(msg1->errorType, testMessage->errorType);
|
||||||
|
EXPECT_EQ(msg1->errorNetID, testMessage->errorNetID);
|
||||||
|
EXPECT_EQ(msg1->timestamp10us, testMessage->timestamp10us);
|
||||||
|
EXPECT_EQ(msg1->timestamp10usMSB, testMessage->timestamp10usMSB);
|
||||||
|
packets.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(REDAppErrorDecoderTest, GetErrorStringTest) {
|
||||||
|
std::shared_ptr<icsneo::Message> decodeMsg;
|
||||||
|
|
||||||
|
ringBuffer.clear();
|
||||||
|
ringBuffer.write(testErrorData);
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||||
|
auto packets = packetizer->output();
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||||
|
EXPECT_NE(decodeMsg, nullptr);
|
||||||
|
auto testMessage = std::dynamic_pointer_cast<icsneo::AppErrorMessage>(decodeMsg);
|
||||||
|
EXPECT_EQ("HSCAN: Network not enabled", testMessage->getAppErrorString());
|
||||||
|
packets.pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_F(REDAppErrorDecoderTest, GetTypeTest) {
|
||||||
|
std::shared_ptr<icsneo::Message> decodeMsg;
|
||||||
|
|
||||||
|
ringBuffer.clear();
|
||||||
|
ringBuffer.write(testErrorData);
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetizer->input(ringBuffer));
|
||||||
|
auto packets = packetizer->output();
|
||||||
|
|
||||||
|
EXPECT_TRUE(packetDecoder->decode(decodeMsg, packets.back()));
|
||||||
|
EXPECT_NE(decodeMsg, nullptr);
|
||||||
|
auto testMessage = std::dynamic_pointer_cast<icsneo::AppErrorMessage>(decodeMsg);
|
||||||
|
EXPECT_EQ(AppErrorType::AppErrorNetworkNotEnabled, testMessage->getAppErrorType());
|
||||||
|
packets.pop_back();
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue