From 9a1cd1124d95cf42b0c385661e4c49bf9087b27c Mon Sep 17 00:00:00 2001 From: Yasser Yassine Date: Tue, 14 May 2024 19:52:00 +0000 Subject: [PATCH] Device: Add device hardware info retrieval support --- CMakeLists.txt | 1 + communication/decoder.cpp | 13 +++++ communication/packet/hardwareinfopacket.cpp | 50 +++++++++++++++++++ device/device.cpp | 31 ++++++++++++ include/icsneo/communication/command.h | 1 + .../message/componentversionsmessage.h | 14 ++++++ .../communication/message/hardwareinfo.h | 32 ++++++++++++ .../icsneo/communication/message/message.h | 1 + .../communication/packet/hardwareinfopacket.h | 22 ++++++++ include/icsneo/device/device.h | 7 ++- 10 files changed, 170 insertions(+), 2 deletions(-) create mode 100644 communication/packet/hardwareinfopacket.cpp create mode 100644 include/icsneo/communication/message/hardwareinfo.h create mode 100644 include/icsneo/communication/packet/hardwareinfopacket.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 4c2e98e..3c1ee2b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -259,6 +259,7 @@ set(SRC_FILES communication/packet/componentversionpacket.cpp communication/packet/supportedfeaturespacket.cpp communication/packet/genericbinarystatuspacket.cpp + communication/packet/hardwareinfopacket.cpp communication/decoder.cpp communication/encoder.cpp communication/ethernetpacketizer.cpp diff --git a/communication/decoder.cpp b/communication/decoder.cpp index 65ba809..f0c4241 100644 --- a/communication/decoder.cpp +++ b/communication/decoder.cpp @@ -16,6 +16,7 @@ #include "icsneo/communication/message/extendeddatamessage.h" #include "icsneo/communication/message/livedatamessage.h" #include "icsneo/communication/message/diskdatamessage.h" +#include "icsneo/communication/message/hardwareinfo.h" #include "icsneo/communication/command.h" #include "icsneo/device/device.h" #include "icsneo/communication/packet/canpacket.h" @@ -35,6 +36,8 @@ #include "icsneo/communication/packet/mdiopacket.h" #include "icsneo/communication/packet/genericbinarystatuspacket.h" #include "icsneo/communication/packet/livedatapacket.h" +#include "icsneo/communication/packet/hardwareinfopacket.h" + #include using namespace icsneo; @@ -358,6 +361,16 @@ bool Decoder::decode(std::shared_ptr& result, const std::shared_ptrdata); + + if(!result) { + report(APIEvent::Type::PacketDecodingError, APIEvent::Severity::Error); + return false; + } + + return true; + } default: auto msg = std::make_shared(); msg->command = Command(packet->data[0]); diff --git a/communication/packet/hardwareinfopacket.cpp b/communication/packet/hardwareinfopacket.cpp new file mode 100644 index 0000000..d6a5e22 --- /dev/null +++ b/communication/packet/hardwareinfopacket.cpp @@ -0,0 +1,50 @@ +#include "icsneo/communication/packet/hardwareinfopacket.h" +#include "icsneo/communication/message/hardwareinfo.h" +#include +using namespace icsneo; + +#pragma pack(push, 1) +typedef struct +{ + uint8_t valid; + struct + { + uint8_t day; + uint8_t month; + uint16_t year; + } manufactureDate; + struct + { + uint8_t major; + uint8_t minor; + } hwRev; + uint8_t deviceId; + struct + { + uint8_t major; + uint8_t minor; + } blVersion; +} HardwareInfoFrame; +#pragma pack(pop) + +std::shared_ptr HardwareInfoPacket::DecodeToMessage(const std::vector& bytes) { + if(bytes.size() < (sizeof(HardwareInfoFrame) + 1)) { + return nullptr; + } + + const auto* frame = reinterpret_cast(&bytes[1]); + + auto msg = std::make_shared(); + + msg->manufactureDate.day = frame->manufactureDate.day; + msg->manufactureDate.year = frame->manufactureDate.year; + msg->manufactureDate.month = frame->manufactureDate.month; + + msg->hardwareRevision.major = frame->hwRev.major; + msg->hardwareRevision.minor = frame->hwRev.minor; + + msg->bootloaderVersion.major = frame->blVersion.major; + msg->bootloaderVersion.minor = frame->blVersion.minor; + + return msg; +} diff --git a/device/device.cpp b/device/device.cpp index 4dc688f..57d0677 100644 --- a/device/device.cpp +++ b/device/device.cpp @@ -722,6 +722,37 @@ Network Device::getNetworkByNumber(Network::Type type, size_t index) const { return Network::NetID::Invalid; } +std::shared_ptr Device::getHardwareInfo(std::chrono::milliseconds timeout) { + if(!isOpen()) { + report(APIEvent::Type::DeviceCurrentlyClosed, APIEvent::Severity::Error); + return nullptr; + } + + if(!isOnline()) { + report(APIEvent::Type::DeviceCurrentlyOffline, APIEvent::Severity::Error); + return nullptr; + } + + auto filter = std::make_shared(Message::Type::HardwareInfo); + + auto response = com->waitForMessageSync([this]() { + return com->sendCommand(Command::GetHardwareInfo); + }, filter, timeout); + + if(!response) { + report(APIEvent::Type::Timeout, APIEvent::Severity::Error); + return nullptr; + } + + auto hardwareInfo = std::dynamic_pointer_cast(response); + if(!hardwareInfo) { + report(APIEvent::Type::UnexpectedResponse, APIEvent::Severity::Error); + return nullptr; + } + + return hardwareInfo; +} + std::optional Device::readLogicalDisk(uint64_t pos, uint8_t* into, uint64_t amount, std::chrono::milliseconds timeout, Disk::MemoryType memType) { if(!into || timeout <= std::chrono::milliseconds(0)) { diff --git a/include/icsneo/communication/command.h b/include/icsneo/communication/command.h index c13700d..3f985ba 100644 --- a/include/icsneo/communication/command.h +++ b/include/icsneo/communication/command.h @@ -22,6 +22,7 @@ enum class Command : uint8_t { UpdateLEDState = 0xA7, SetDefaultSettings = 0xA8, // Follow up with SaveSettings to write to EEPROM GetSecondaryVersions = 0xA9, // Previously known as RED_CMD_PERIPHERALS_APP_VERSION_REQ, versions other than the main chip + GetHardwareInfo = 0xB7, // Previously known as RED_CMD_HARDWARE_VERSION_REQ GetLogicalDiskInfo = 0xBB, // Previously known as RED_CMD_GET_SDCARD_INFO RequestStatusUpdate = 0xBC, ReadSettings = 0xC7, // Previously known as 3G_READ_SETTINGS_EX diff --git a/include/icsneo/communication/message/componentversionsmessage.h b/include/icsneo/communication/message/componentversionsmessage.h index fc39233..0a7c245 100644 --- a/include/icsneo/communication/message/componentversionsmessage.h +++ b/include/icsneo/communication/message/componentversionsmessage.h @@ -9,6 +9,20 @@ class ComponentVersion { public: ComponentVersion(uint8_t valid, uint8_t componentInfo, uint32_t identifier, uint32_t dotVersion, uint32_t commitHash) : valid(valid), componentInfo(componentInfo), identifier(identifier), dotVersion(dotVersion), commitHash(commitHash) {} + + static ComponentVersion FromAppVersion(uint32_t identifier, uint8_t appMajor, uint8_t appMinor) { + uint32_t dotVersion = (appMajor << 24) | (appMinor << 16); + + + return ComponentVersion( + static_cast(1u), + static_cast(0u), + identifier, + dotVersion, + static_cast(0u) + ); + } + const bool valid; const uint8_t componentInfo; const uint32_t identifier; diff --git a/include/icsneo/communication/message/hardwareinfo.h b/include/icsneo/communication/message/hardwareinfo.h new file mode 100644 index 0000000..b9e17d9 --- /dev/null +++ b/include/icsneo/communication/message/hardwareinfo.h @@ -0,0 +1,32 @@ +#ifndef _HARDWARE_INFO_MESSAGE_H_ +#define _HARDWARE_INFO_MESSAGE_H_ + +#ifdef __cplusplus +#include "icsneo/communication/message/message.h" + +namespace icsneo { + +class HardwareInfo : public Message { +public: + HardwareInfo() : Message(Message::Type::HardwareInfo) {} + struct Version { + uint8_t major; + uint8_t minor; + }; + + struct Date { + uint8_t day; + uint8_t month; + uint16_t year; + }; + + Date manufactureDate; + Version hardwareRevision; + Version bootloaderVersion; +}; + +} + +#endif // __cplusplus + +#endif \ No newline at end of file diff --git a/include/icsneo/communication/message/message.h b/include/icsneo/communication/message/message.h index bba8cde..f5ff894 100644 --- a/include/icsneo/communication/message/message.h +++ b/include/icsneo/communication/message/message.h @@ -38,6 +38,7 @@ public: SupportedFeatures = 0x800d, GenericBinaryStatus = 0x800e, LiveData = 0x800f, + HardwareInfo = 0x8010 }; Message(Type t) : type(t) {} diff --git a/include/icsneo/communication/packet/hardwareinfopacket.h b/include/icsneo/communication/packet/hardwareinfopacket.h new file mode 100644 index 0000000..0103ac9 --- /dev/null +++ b/include/icsneo/communication/packet/hardwareinfopacket.h @@ -0,0 +1,22 @@ +#ifndef __HARDWAREINFOPACKET_H__ +#define __HARDWAREINFOPACKET_H__ + +#ifdef __cplusplus + +#include +#include +#include + +namespace icsneo { + +class HardwareInfo; + +struct HardwareInfoPacket { + static std::shared_ptr DecodeToMessage(const std::vector& bytes); +}; + +} + +#endif // __cplusplus + +#endif // __DEVICECOMPONENTVERSIONPACKET_H__ diff --git a/include/icsneo/device/device.h b/include/icsneo/device/device.h index 2b37057..e0f326e 100644 --- a/include/icsneo/device/device.h +++ b/include/icsneo/device/device.h @@ -34,6 +34,7 @@ #include "icsneo/communication/message/scriptstatusmessage.h" #include "icsneo/communication/message/supportedfeaturesmessage.h" #include "icsneo/communication/message/genericbinarystatusmessage.h" +#include "icsneo/communication/message/hardwareinfo.h" #include "icsneo/communication/message/extendeddatamessage.h" #include "icsneo/communication/message/livedatamessage.h" #include "icsneo/communication/packet/genericbinarystatuspacket.h" @@ -45,6 +46,8 @@ #include "icsneo/platform/nodiscard.h" #include "icsneo/disk/vsa/vsa.h" #include "icsneo/disk/vsa/vsaparser.h" +#include "icsneo/communication/message/versionmessage.h" + #define ICSNEO_FINDABLE_DEVICE_BASE(className, type) \ static constexpr DeviceType::Enum DEVICE_TYPE = type; \ @@ -222,6 +225,7 @@ public: virtual size_t getNetworkCountByType(Network::Type) const; virtual Network getNetworkByNumber(Network::Type, size_t) const; + std::shared_ptr getHardwareInfo(std::chrono::milliseconds timeout = std::chrono::milliseconds(2)); /** @@ -565,6 +569,7 @@ public: */ const std::vector>& getVersions() const { return versions; } const std::vector& getComponentVersions() const { return componentVersions; } + /** * Some alternate communication protocols do not support DFU */ @@ -822,8 +827,6 @@ protected: neodevice_t& getWritableNeoDevice() { return data; } - - private: neodevice_t data; std::shared_ptr latestResetStatus;