Compare commits
2 Commits
75af3220b0
...
564933cb41
| Author | SHA1 | Date |
|---|---|---|
|
|
564933cb41 | |
|
|
cac8d760b0 |
|
|
@ -238,6 +238,7 @@ set(SRC_FILES
|
|||
communication/message/flexray/control/flexraycontrolmessage.cpp
|
||||
communication/message/callback/streamoutput/a2bwavoutput.cpp
|
||||
communication/message/a2bmessage.cpp
|
||||
communication/message/apperrormessage.cpp
|
||||
communication/message/neomessage.cpp
|
||||
communication/message/ethphymessage.cpp
|
||||
communication/message/linmessage.cpp
|
||||
|
|
@ -519,6 +520,7 @@ if(LIBICSNEO_BUILD_UNIT_TESTS)
|
|||
test/unit/mdioencoderdecodertest.cpp
|
||||
test/unit/livedataencoderdecodertest.cpp
|
||||
test/unit/ringbuffertest.cpp
|
||||
test/unit/apperrordecodertest.cpp
|
||||
)
|
||||
|
||||
target_link_libraries(libicsneo-unit-tests gtest gtest_main)
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@
|
|||
#include "icsneo/communication/message/readsettingsmessage.h"
|
||||
#include "icsneo/communication/message/canerrorcountmessage.h"
|
||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||
#include "icsneo/communication/message/flashmemorymessage.h"
|
||||
#include "icsneo/communication/message/extendedresponsemessage.h"
|
||||
#include "icsneo/communication/message/wiviresponsemessage.h"
|
||||
#include "icsneo/communication/message/scriptstatusmessage.h"
|
||||
|
|
@ -18,6 +19,7 @@
|
|||
#include "icsneo/communication/message/diskdatamessage.h"
|
||||
#include "icsneo/communication/message/hardwareinfo.h"
|
||||
#include "icsneo/communication/message/tc10statusmessage.h"
|
||||
#include "icsneo/communication/message/apperrormessage.h"
|
||||
#include "icsneo/communication/command.h"
|
||||
#include "icsneo/device/device.h"
|
||||
#include "icsneo/communication/packet/canpacket.h"
|
||||
|
|
@ -256,6 +258,18 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
result = std::make_shared<RawMessage>(packet->network, packet->data);
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::RED_INT_MEMORYREAD: {
|
||||
if(packet->data.size() != 512 + sizeof(uint16_t)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return false; // Should get enough data for a start address and sector
|
||||
}
|
||||
|
||||
const auto msg = std::make_shared<FlashMemoryMessage>();
|
||||
result = msg;
|
||||
msg->startAddress = *reinterpret_cast<uint16_t*>(packet->data.data());
|
||||
msg->data.insert(msg->data.end(), packet->data.begin() + 2, packet->data.end());
|
||||
return true;
|
||||
}
|
||||
case Network::NetID::NeoMemorySDRead: {
|
||||
if(packet->data.size() != 512 + sizeof(uint32_t)) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
|
|
@ -398,6 +412,14 @@ bool Decoder::decode(std::shared_ptr<Message>& result, const std::shared_ptr<Pac
|
|||
packet->data.resize(length);
|
||||
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: {
|
||||
auto msg = std::make_shared<ReadSettingsMessage>();
|
||||
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
|
||||
|
|
@ -656,6 +656,85 @@ bool Device::clearScript(Disk::MemoryType memType)
|
|||
return true;
|
||||
}
|
||||
|
||||
std::optional<CoreminiHeader> Device::readCoreminiHeader(Disk::MemoryType memType) {
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto startAddress = getCoreminiStartAddress(memType);
|
||||
if(!startAddress) {
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
auto connected = isLogicalDiskConnected();
|
||||
|
||||
if(!connected) {
|
||||
return std::nullopt; // Already added an API error
|
||||
}
|
||||
|
||||
#pragma pack(push, 2)
|
||||
struct RawCoreminiHeader {
|
||||
uint16_t fileType;
|
||||
uint16_t fileVersion;
|
||||
uint32_t storedFileSize;
|
||||
uint32_t fileChecksum;
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t skipDecompression : 1;
|
||||
uint32_t encryptedMode : 1;
|
||||
uint32_t reserved : 30;
|
||||
} bits;
|
||||
uint32_t word;
|
||||
} flags;
|
||||
uint8_t fileHash[32];
|
||||
union
|
||||
{
|
||||
struct
|
||||
{
|
||||
uint32_t lsb;
|
||||
uint32_t msb;
|
||||
} words;
|
||||
uint64_t time64;
|
||||
} createTime;
|
||||
uint8_t reserved[8];
|
||||
};
|
||||
#pragma pack(pop)
|
||||
|
||||
RawCoreminiHeader header = {};
|
||||
auto numRead = readLogicalDisk(*startAddress, (uint8_t*)&header, sizeof(header), std::chrono::milliseconds(2000), memType);
|
||||
|
||||
if(!numRead) {
|
||||
return std::nullopt; // Already added an API error
|
||||
}
|
||||
|
||||
if(*numRead != sizeof(header)) {
|
||||
report(APIEvent::Type::FailedToRead, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
if(header.fileType != 0x0907) {
|
||||
report(APIEvent::Type::MessageFormattingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
std::optional<CoreminiHeader> ret;
|
||||
ret.emplace();
|
||||
ret->coreminiVersion = header.fileVersion;
|
||||
ret->storedFileSize = header.storedFileSize;
|
||||
ret->fileChecksum = header.fileChecksum;
|
||||
ret->skipDecompression = static_cast<bool>(header.flags.bits.skipDecompression);
|
||||
ret->encryptedMode = static_cast<bool>(header.flags.bits.encryptedMode);
|
||||
std::copy(std::begin(header.fileHash), std::end(header.fileHash), ret->fileHash.begin());
|
||||
static constexpr std::chrono::seconds icsEpochDelta(1167609600);
|
||||
static constexpr uint8_t timestampResolution = 25;
|
||||
static constexpr uint16_t nsInUs = 1'000;
|
||||
ret->timestamp += icsEpochDelta + std::chrono::microseconds(header.createTime.time64 * timestampResolution / nsInUs);
|
||||
return ret;
|
||||
}
|
||||
|
||||
bool Device::transmit(std::shared_ptr<Frame> frame) {
|
||||
if(!isOpen()) {
|
||||
report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error);
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
#include "icsneo/disk/neomemorydiskdriver.h"
|
||||
#include "icsneo/communication/message/neoreadmemorysdmessage.h"
|
||||
#include "icsneo/communication/message/flashmemorymessage.h"
|
||||
#include <cstring>
|
||||
#include <iostream>
|
||||
|
||||
|
|
@ -8,7 +9,8 @@ using namespace icsneo::Disk;
|
|||
|
||||
std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communication& com, device_eventhandler_t report,
|
||||
uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, MemoryType memType) {
|
||||
static std::shared_ptr<MessageFilter> NeoMemorySDRead = std::make_shared<MessageFilter>(Network::NetID::NeoMemorySDRead);
|
||||
const auto filter = std::make_shared<MessageFilter>((memType == MemoryType::SD ? Network::NetID::NeoMemorySDRead : Network::NetID::RED_INT_MEMORYREAD));
|
||||
filter->includeInternalInAny = true;
|
||||
|
||||
if(pos % SectorSize != 0)
|
||||
return std::nullopt;
|
||||
|
|
@ -20,7 +22,7 @@ std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio
|
|||
const uint8_t memLocation = (uint8_t)memType;
|
||||
|
||||
uint64_t numWords = amount / 2;
|
||||
|
||||
|
||||
auto msg = com.waitForMessageSync([¤tSector, &memLocation, &com, &numWords] {
|
||||
return com.sendCommand(Command::NeoReadMemory, {
|
||||
memLocation,
|
||||
|
|
@ -33,18 +35,26 @@ std::optional<uint64_t> NeoMemoryDiskDriver::readLogicalDiskAligned(Communicatio
|
|||
uint8_t((numWords >> 16) & 0xFF),
|
||||
uint8_t((numWords >> 24) & 0xFF)
|
||||
});
|
||||
}, NeoMemorySDRead, timeout);
|
||||
}, filter, timeout);
|
||||
|
||||
if(!msg)
|
||||
return 0;
|
||||
|
||||
const auto sdmsg = std::dynamic_pointer_cast<NeoReadMemorySDMessage>(msg);
|
||||
if(!sdmsg || sdmsg->data.size() != SectorSize) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
if(memType == MemoryType::SD) {
|
||||
const auto mem = std::dynamic_pointer_cast<NeoReadMemorySDMessage>(msg);
|
||||
if(!mem || mem->data.size() != SectorSize) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
memcpy(into, mem->data.data(), SectorSize);
|
||||
} else { // flash
|
||||
const auto mem = std::dynamic_pointer_cast<FlashMemoryMessage>(msg);
|
||||
if(!mem || mem->data.size() != SectorSize) {
|
||||
report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error);
|
||||
return std::nullopt;
|
||||
}
|
||||
memcpy(into, mem->data.data(), SectorSize);
|
||||
}
|
||||
|
||||
memcpy(into, sdmsg->data.data(), SectorSize);
|
||||
return SectorSize;
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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_MDIO_EXAMPLE "Build the MDIO 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
|
||||
# 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)
|
||||
endif()
|
||||
|
||||
if(LIBICSNEO_BUILD_CPP_APP_ERROR_EXAMPLE)
|
||||
add_subdirectory(cpp/apperror)
|
||||
endif()
|
||||
|
||||
# if(LIBICSNEO_BUILD_CSHARP_INTERACTIVE_EXAMPLE)
|
||||
# add_subdirectory(csharp)
|
||||
# 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,
|
||||
LINSettingsNotAvailable = 0x2053,
|
||||
ModeNotFound = 0x2054,
|
||||
AppErrorParsingFailed = 0x2055,
|
||||
|
||||
// Transport Events
|
||||
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
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
#ifndef __FLASHMEMORYMESSAGE_H_
|
||||
#define __FLASHMEMORYMESSAGE_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include "icsneo/communication/message/message.h"
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
class FlashMemoryMessage : public RawMessage {
|
||||
public:
|
||||
FlashMemoryMessage() : RawMessage(Message::Type::RawMessage, Network::NetID::RED_INT_MEMORYREAD) {}
|
||||
uint16_t startAddress = 0;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -40,6 +40,7 @@ public:
|
|||
LiveData = 0x800f,
|
||||
HardwareInfo = 0x8010,
|
||||
TC10Status = 0x8011,
|
||||
AppError = 0x8012,
|
||||
};
|
||||
|
||||
Message(Type t) : type(t) {}
|
||||
|
|
|
|||
|
|
@ -533,10 +533,12 @@ public:
|
|||
case NetID::CoreMiniPreLoad:
|
||||
case NetID::ExtendedCommand:
|
||||
case NetID::ExtendedData:
|
||||
case NetID::RED_INT_MEMORYREAD:
|
||||
case NetID::NeoMemorySDRead:
|
||||
case NetID::NeoMemoryWriteDone:
|
||||
case NetID::RED_GET_RTC:
|
||||
case NetID::DiskData:
|
||||
case NetID::RED_App_Error:
|
||||
return Type::Internal;
|
||||
case NetID::Invalid:
|
||||
case NetID::Any:
|
||||
|
|
|
|||
|
|
@ -0,0 +1,28 @@
|
|||
#ifndef __COREMINI_H_
|
||||
#define __COREMINI_H_
|
||||
|
||||
#ifdef __cplusplus
|
||||
|
||||
#include <cstdint>
|
||||
#include <array>
|
||||
#include <chrono>
|
||||
|
||||
namespace icsneo {
|
||||
|
||||
struct CoreminiHeader {
|
||||
uint16_t coreminiVersion;
|
||||
uint32_t storedFileSize;
|
||||
// 32-bit word checksum on the entire (decompressed) binary, with the checksum and hash fields set to 0
|
||||
uint32_t fileChecksum;
|
||||
// SHA256 hash of the entire (decompressed) binary, with the checksum, hash, and create time fields set to 0
|
||||
bool skipDecompression;
|
||||
bool encryptedMode;
|
||||
std::array<uint8_t, 32> fileHash;
|
||||
std::chrono::time_point<std::chrono::system_clock> timestamp;
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
#endif // __cplusplus
|
||||
|
||||
#endif
|
||||
|
|
@ -13,6 +13,7 @@
|
|||
#include <optional>
|
||||
#include <unordered_map>
|
||||
#include <set>
|
||||
#include <chrono>
|
||||
#include "icsneo/api/eventmanager.h"
|
||||
#include "icsneo/api/lifetime.h"
|
||||
#include "icsneo/device/neodevice.h"
|
||||
|
|
@ -21,6 +22,7 @@
|
|||
#include "icsneo/device/devicetype.h"
|
||||
#include "icsneo/device/deviceversion.h"
|
||||
#include "icsneo/device/founddevice.h"
|
||||
#include "icsneo/device/coremini.h"
|
||||
#include "icsneo/disk/diskreaddriver.h"
|
||||
#include "icsneo/disk/diskwritedriver.h"
|
||||
#include "icsneo/disk/nulldiskdriver.h"
|
||||
|
|
@ -163,6 +165,7 @@ public:
|
|||
bool stopScript();
|
||||
bool clearScript(Disk::MemoryType memType = Disk::MemoryType::SD);
|
||||
bool uploadCoremini(std::istream& stream, Disk::MemoryType memType = Disk::MemoryType::SD);
|
||||
std::optional<CoreminiHeader> readCoreminiHeader(Disk::MemoryType memType = Disk::MemoryType::SD);
|
||||
|
||||
bool eraseScriptMemory(Disk::MemoryType memType, uint64_t amount);
|
||||
|
||||
|
|
|
|||
|
|
@ -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