diff --git a/CMakeLists.txt b/CMakeLists.txt index aad5af1..3ad118a 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -182,6 +182,7 @@ set(SRC_FILES communication/packet/ethphyregpacket.cpp communication/packet/logicaldiskinfopacket.cpp communication/packet/wivicommandpacket.cpp + communication/packet/scriptstatuspacket.cpp communication/decoder.cpp communication/encoder.cpp communication/ethernetpacketizer.cpp diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 138a0e9..ba2bfef 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -7,6 +7,7 @@ #include "icsneo/communication/message/neoreadmemorysdmessage.h" #include "icsneo/communication/message/extendedresponsemessage.h" #include "icsneo/communication/message/wiviresponsemessage.h" +#include "icsneo/communication/message/scriptstatusmessage.h" #include "icsneo/communication/message/a2bmessage.h" #include "icsneo/communication/message/flexray/control/flexraycontrolmessage.h" #include "icsneo/communication/command.h" @@ -20,6 +21,7 @@ #include "icsneo/communication/packet/ethphyregpacket.h" #include "icsneo/communication/packet/logicaldiskinfopacket.h" #include "icsneo/communication/packet/wivicommandpacket.h" +#include "icsneo/communication/packet/scriptstatuspacket.h" #include using namespace icsneo; @@ -319,6 +321,14 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrdata); + if(!result) { + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::EventWarning); + return false; + } + return true; + } default: break; } diff --git a/communication/packet/scriptstatuspacket.cpp b/communication/packet/scriptstatuspacket.cpp new file mode 100644 index 0000000..e94f7f7 --- /dev/null +++ b/communication/packet/scriptstatuspacket.cpp @@ -0,0 +1,30 @@ +#include +#include "icsneo/communication/packet/scriptstatuspacket.h" +#include "icsneo/communication/message/scriptstatusmessage.h" + +using namespace icsneo; + +std::shared_ptr ScriptStatus::DecodeToMessage(const std::vector& bytestream){ + if(bytestream.size() != sizeof(ScriptStatus)) + return {}; + + auto msg = std::make_shared(); + const auto& decoded = *reinterpret_cast(bytestream.data()); + msg->isCoreminiRunning = decoded.status.isRunning; + msg->sectorOverflows = decoded.sectorOverflows; + msg->numRemainingSectorBuffers = decoded.numRemainingSectorBuffers; + msg->lastSector = decoded.lastSector; + msg->readBinSize = decoded.readBinSize; + msg->minSector = decoded.minSector; + msg->maxSector = decoded.maxSector; + msg->currentSector = decoded.currentSector; + msg->coreminiCreateTime = ((uint64_t)decoded.coreminiCreateTimeMsb << 32) | decoded.coreminiCreateTimeLsb; + msg->fileChecksum = decoded.fileChecksum; + msg->coreminiVersion = decoded.coreminiVersion; + msg->coreminiHeaderSize = decoded.coreminiHeaderSize; + msg->diagnosticErrorCode = decoded.diagErrCode; + msg->diagnosticErrorCodeCount = decoded.diagErrCodeCount; + msg->maxCoreminiSizeKB = decoded.maxCoreminiSizeKB; + + return msg; +} \ No newline at end of file diff --git a/device/device.cpp b/device/device.cpp index 092f221..a023afa 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -6,6 +6,7 @@ #include "icsneo/disk/fat.h" #include "icsneo/communication/packet/wivicommandpacket.h" #include "icsneo/communication/message/wiviresponsemessage.h" +#include "icsneo/communication/message/scriptstatusmessage.h" #include #include #include @@ -410,6 +411,104 @@ bool Device::goOffline() { return true; } +int8_t Device::prepareScriptLoad() { + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return false; + } + + static std::shared_ptr filter = std::make_shared(Network::NetID::CoreMiniPreLoad); + + if(!com->sendCommand(Command::CoreMiniPreload)) + return false; + + int8_t retVal = 0; + while(retVal == 0) + { + auto generic = com->waitForMessageSync(filter, std::chrono::milliseconds(1000)); + + if(!generic) { + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); + return false; + } + + const auto resp = std::static_pointer_cast(generic); + retVal = (int8_t)resp->data[0]; + } + + return retVal; +} + +bool Device::startScript() +{ + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return false; + } + + uint8_t LocationSdCard = 1; //Only support starting a coremini in an SDCard + auto generic = com->sendCommand(Command::LoadCoreMini, LocationSdCard); + + if(!generic) + { + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); + return false; + } + + return true; +} + +bool Device::stopScript() +{ + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return false; + } + + auto generic = com->sendCommand(Command::ClearCoreMini); + + if(!generic) + { + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); + return false; + } + + return true; +} + +bool Device::clearScript() +{ + if(!stopScript()) + return false; + + std::vector clearData(512, 0xCD); + uint64_t ScriptLocation = 0; //We only support a coremini in an SDCard, which is at the very beginning of the card + auto written = writeLogicalDisk(ScriptLocation, clearData.data(), clearData.size()); + + return written > 0; +} + +std::optional Device::getCoreMiniVersion() +{ + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return std::nullopt; + } + + static std::shared_ptr filter = std::make_shared(Message::Type::ScriptStatus); + const auto generic = com->waitForMessageSync([this]() { + return com->sendCommand(Command::ScriptStatus); + }, filter); + + if (!generic || generic->type != Message::Type::ScriptStatus) { + report(APIEvent::Type::NoDeviceResponse, APIEvent::Severity::Error); + return std::nullopt; + } + + const auto resp = std::static_pointer_cast(generic); + return resp->coreminiVersion; +} + bool Device::transmit(std::shared_ptr frame) { if(!isOpen()) { report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); diff --git a/include/icsneo/communication/command.h b/include/icsneo/communication/command.h index 568db33..b671b93 100644 --- a/include/icsneo/communication/command.h +++ b/include/icsneo/communication/command.h @@ -10,6 +10,8 @@ enum class Command : uint8_t { EnableNetworkCommunicationEx = 0x08, NeoReadMemory = 0x40, NeoWriteMemory = 0x41, + ClearCoreMini = 0x42, + LoadCoreMini = 0x43, RequestSerialNumber = 0xA1, GetMainVersion = 0xA3, // Previously known as RED_CMD_APP_VERSION_REQ SetSettings = 0xA4, // Previously known as RED_CMD_SET_BAUD_REQ, follow up with SaveSettings to write to EEPROM @@ -25,9 +27,11 @@ enum class Command : uint8_t { RequestBitSmash = 0xDC, // Previously known as RED_CMD_CM_BITSMASH WiVICommand = 0xDD, // Previously known as RED_CMD_WIVI_COMM GetVBattReq = 0xDF, // Previously known as RED_CMD_VBATT_REQUEST + ScriptStatus = 0xE0, // Previously known as RED_CMD_SCRIPT_STATUS MiscControl = 0xE7, Extended = 0xF0, FlexRayControl = 0xF3, + CoreMiniPreload = 0xF4, // Previously known as RED_CMD_COREMINI_PRELOAD PHYControlRegisters = 0xEF }; diff --git a/include/icsneo/communication/message/message.h b/include/icsneo/communication/message/message.h index 13ac397..592025c 100644 --- a/include/icsneo/communication/message/message.h +++ b/include/icsneo/communication/message/message.h @@ -30,6 +30,7 @@ public: LogicalDiskInfo = 0x8008, ExtendedResponse = 0x8009, WiVICommandResponse = 0x800a, + ScriptStatus = 0x800b, }; Message(Type t) : type(t) {} diff --git a/include/icsneo/communication/message/scriptstatusmessage.h b/include/icsneo/communication/message/scriptstatusmessage.h new file mode 100644 index 0000000..0a3adbf --- /dev/null +++ b/include/icsneo/communication/message/scriptstatusmessage.h @@ -0,0 +1,36 @@ +#ifndef __SCRIPTSTATUSMESSAGE_H +#define __SCRIPTSTATUSMESSAGE_H + +#ifdef __cplusplus + +#include "icsneo/communication/message/message.h" +#include "icsneo/communication/packet/scriptstatuspacket.h" + +namespace icsneo +{ +//Response to Command::ScriptStatus +class ScriptStatusMessage : public Message { +public: + ScriptStatusMessage() : Message( Message::Type::ScriptStatus ) {} + + bool isCoreminiRunning; + uint32_t sectorOverflows; + uint32_t numRemainingSectorBuffers; + int32_t lastSector; + int32_t readBinSize; + int32_t minSector; + int32_t maxSector; + int32_t currentSector; + uint64_t coreminiCreateTime; + uint16_t fileChecksum; + uint16_t coreminiVersion; + uint16_t coreminiHeaderSize; + uint8_t diagnosticErrorCode; + uint8_t diagnosticErrorCodeCount; + uint16_t maxCoreminiSizeKB; +}; +} + +#endif // __cplusplus + +#endif //__SCRIPTSTATUSMESSAGE_H diff --git a/include/icsneo/communication/network.h b/include/icsneo/communication/network.h index a3c7f81..655b00c 100644 --- a/include/icsneo/communication/network.h +++ b/include/icsneo/communication/network.h @@ -119,9 +119,11 @@ public: LSFTCAN2 = 99, LogicalDiskInfo = 187, WiVICommand = 221, + ScriptStatus = 224, EthPHYControl = 239, ExtendedCommand = 240, FlexRayControl = 243, + CoreMiniPreLoad = 244, HW_COM_Latency_Test = 512, DeviceStatus = 513, UDP = 514, @@ -281,7 +283,9 @@ public: case NetID::ReadSettings: case NetID::LogicalDiskInfo: case NetID::WiVICommand: + case NetID::ScriptStatus: case NetID::EthPHYControl: + case NetID::CoreMiniPreLoad: case NetID::ExtendedCommand: case NetID::NeoMemorySDRead: case NetID::NeoMemoryWriteDone: @@ -526,6 +530,10 @@ public: return "Logical Disk Information"; case NetID::WiVICommand: return "WiVI Command"; + case NetID::ScriptStatus: + return "Script Status"; + case NetID::CoreMiniPreLoad: + return "CoreMini PreLoad"; case NetID::EthPHYControl: return "Ethernet PHY Register Control"; case NetID::ExtendedCommand: @@ -934,9 +942,11 @@ private: #define ICSNEO_NETID_LSFTCAN2 99 #define ICSNEO_NETID_LOGICAL_DISK_INFO 187 #define ICSNEO_NETID_WIVI_COMMAND 221 +#define ICSNEO_NETID_SCRIPT_STATUS 224 #define ICSNEO_NETID_ETH_PHY_CONTROL 239 #define ICSNEO_NETID_EXTENDED_COMMAND 240 #define ICSNEO_NETID_FLEXRAY_CONTROL 243 +#define ICSNEO_NETID_COREMINI_PRELOAD 244 #define ICSNEO_NETID_HW_COM_LATENCY_TEST 512 #define ICSNEO_NETID_DEVICE_STATUS 513 #define ICSNEO_NETID_UDP 514 diff --git a/include/icsneo/communication/packet/scriptstatuspacket.h b/include/icsneo/communication/packet/scriptstatuspacket.h new file mode 100644 index 0000000..921f50f --- /dev/null +++ b/include/icsneo/communication/packet/scriptstatuspacket.h @@ -0,0 +1,86 @@ +#ifndef __SCRIPTSTATUSPACKET_H +#define __SCRIPTSTATUSPACKET_H + +#ifdef __cplusplus + +#include "icsneo/communication/packet.h" +#include +#include + +#pragma pack(push,2) +#ifdef _MSC_VER +#pragma warning(push) +#pragma warning(disable: 4201) // nonstandard extension used: nameless struct/union +#pragma warning(disable: 4200) // nonstandard extension used: zero-sized array in struct/union +#endif // _MSC_VER + +namespace icsneo +{ + +class ScriptStatusMessage; + +struct CoreMiniStatus +{ + uint32_t justReset : 1; + uint32_t communicationEnabled : 1; + uint32_t isRunning : 1; + uint32_t checksumFailed : 1; + uint32_t licenseFailed : 1; + uint32_t versionMismatch : 1; + uint32_t bootOff : 1; + uint32_t hardwareFailure : 1; // To check SRAM failure (for now) + uint32_t isPassiveConnect : 1; // Always zero. Set to one when neoVI connection is passive,i.e. no async traffic + uint32_t usbCommunicationEnabled : 1; // Set to one when USB Host PC has enabled communication. + uint32_t linuxCommunicationEnabled : 1; // Set to one when Android (Linux) has enabled communication. + uint32_t tooBig : 1; + uint32_t hidUsbState : 1; + uint32_t fpgaUsbState : 1; + uint32_t filesystem : 1; + uint32_t isEncrypted : 1; + uint32_t reserved : 16; +}; + +struct ScriptStatus +{ + static std::shared_ptr DecodeToMessage(const std::vector& bytestream); + + CoreMiniStatus status; + uint32_t sectorOverflows; + uint32_t numRemainingSectorBuffers; + int32_t lastSector; + int32_t readBinSize; + int32_t minSector; + int32_t maxSector; + int32_t currentSector; + uint32_t coreminiCreateTimeMsb; + uint32_t coreminiCreateTimeLsb; + uint16_t zero2; + uint16_t zero3; + uint16_t fileChecksum; + uint16_t coreminiVersion; + uint16_t coreminiHeaderSize; + uint16_t coreminiEngineMinVersion; // This firmware min version + uint16_t coreminiScriptMinEngineVers; // Current loaded script's min engine requirements. + uint8_t eolResults1; + uint8_t eolResults2; + uint8_t eolResults3; + uint8_t zero6; + uint8_t diagErrCode; + uint8_t diagErrCodeCount; + /* FPGA version Fpga reports to HID over SPI */ + uint8_t spiFpgaVers1; + uint8_t spiFpgaVers2; + uint16_t maxCoreminiSizeKB; + uint16_t maxCoreminiFlashSizeKB; +}; + +} // namespace icsneo + +#ifdef _MSC_VER +#pragma warning(pop) +#endif // _MSC_VER +#pragma pack(pop) + +#endif // __cplusplus + +#endif //__SCRIPTSTATUSPACKET_H diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 7eebf50..733d739 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -125,6 +125,21 @@ public: virtual bool goOnline(); virtual bool goOffline(); + enum class PreloadReturn : uint8_t + { + Pending, + Ok, + OKEncrypted, + NoScript, + }; + + int8_t prepareScriptLoad(); + bool startScript(); + bool stopScript(); + bool clearScript(); + + std::optional getCoreMiniVersion(); + // Message polling related functions bool enableMessagePolling(); bool disableMessagePolling();