#pragma once #include "DeviceComplexJsonCommand.h" #include "UsbDeviceManager.h" #include #include namespace Incart::DeviceWebApi { // Адаптированно для прибора: КТ-07-АД-3 (тип 38) HW 1.00, SW 1.23, ревизия ПО 1.03, GuiVer: 4.7 class GetFlashMemoryInfoJsonCommand final : public DeviceComplexJsonCommand { private: const int m_flashBlockSize = 512; Usb::UsbDeviceManager* m_usbDeviceManager; Usb::DeviceInfo m_deviceInfo; uint64_t m_maxAddress; uint64_t m_minAddress; std::string m_fillMemoryPercent; uint32_t m_beginReadBlock; public: GetFlashMemoryInfoJsonCommand(std::shared_ptr description, Usb::UsbDeviceManager* usbDeviceManager) : DeviceComplexJsonCommand(description) , m_usbDeviceManager(usbDeviceManager) , m_deviceInfo(m_usbDeviceManager->getConnectedDeviceInfo()) { } GetFlashMemoryInfoJsonCommand(Usb::UsbDeviceManager* usbDeviceManager) : GetFlashMemoryInfoJsonCommand(createCommandDescription(), usbDeviceManager) { } public: static std::shared_ptr createCommandDescription() { return std::make_shared("GetFlashMemoryInfo", std::make_shared(), std::make_shared(std::vector>{ std::make_shared("MemorySize", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("FillMemoryPercent", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("BeginReadBlock", Net::WebApi::EJsonCommandUnitType::String), std::make_shared("FlashState", Net::WebApi::EJsonCommandUnitType::String) }) ); } std::shared_ptr execute(std::shared_ptr launchedCommandInfo) override { uid = launchedCommandInfo->uid; std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr commandInfo = std::make_shared("ReadMaxAddress", commandQueue->generateUid(), std::vector{}); Usb::DeviceCommand::EStatus commandStatus = m_usbDeviceManager->getCommandSet()->createCommandBytes(commandInfo, commandBytes); if (commandStatus != Usb::DeviceCommand::EStatus::OK) { return DeviceWebApi::JsonCommandStatusCreator::create(commandStatus); } std::shared_ptr getMaxAddressCommand = std::make_shared(commandInfo->name, commandInfo->uid, std::move(commandBytes)); connect(getMaxAddressCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetFlashMemoryInfoJsonCommand::handleReadMaxDeviceAddressIsReady); commandQueue->enqueue(getMaxAddressCommand); return std::make_shared(); } private slots: void handleReadMaxDeviceAddressIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_maxAddress = Common::ByteArrayProvider::ulongFromArray(answer, 4); std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr commandInfo = std::make_shared("ReadMinAddress", commandQueue->generateUid(), std::vector{}); Usb::DeviceCommand::EStatus commandStatus = m_usbDeviceManager->getCommandSet()->createCommandBytes(commandInfo, commandBytes); if (commandStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(commandStatus, answer)); return; } std::shared_ptr getMinAddressCommand = std::make_shared(commandInfo->name, commandInfo->uid, std::move(commandBytes)); connect(getMinAddressCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetFlashMemoryInfoJsonCommand::handleReadMinDeviceAddressIsReady); commandQueue->enqueue(getMinAddressCommand); } void handleReadMinDeviceAddressIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } m_minAddress = Common::ByteArrayProvider::ulongFromArray(answer, 4); std::vector commandBytes = { 0x7e, 0x01, 0x00, 0x0a, 0x00, 0xff, 0xff, 0xbd }; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr getWrittenBytesCountCommand = std::make_shared("ReadWrittenBytesCount", commandQueue->generateUid(), std::move(commandBytes)); connect(getWrittenBytesCountCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetFlashMemoryInfoJsonCommand::handleReadWrittenBytesCountIsReady); commandQueue->enqueue(getWrittenBytesCountCommand); } void handleReadWrittenBytesCountIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } uint64_t writtenMaxAddress = Common::ByteArrayProvider::ulongFromArray(answer, 4); m_beginReadBlock = static_cast(m_minAddress / m_flashBlockSize); uint32_t totalBlockCount = static_cast(m_maxAddress / m_flashBlockSize); uint32_t totalReadBlockCount = totalBlockCount - m_beginReadBlock; uint32_t totalWrittenBlockCount = static_cast(std::min(writtenMaxAddress, m_maxAddress) / m_flashBlockSize); uint32_t writtenBlockCount = totalWrittenBlockCount - std::min(m_beginReadBlock, totalWrittenBlockCount); uint32_t percent = std::min(totalReadBlockCount > 0 ? static_cast(static_cast(writtenBlockCount) * 100 / totalReadBlockCount) : 0, 100); m_fillMemoryPercent = (totalBlockCount > 0) ? std::to_string(percent) : "?"; std::vector commandBytes = { 0x7e, 0x01, 0x00, 0x09, 0x21, 0xff, 0xff, 0xbd }; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr getFlashStateCommand = std::make_shared("GetFlashState", commandQueue->generateUid(), std::move(commandBytes)); connect(getFlashStateCommand.get(), &Usb::ByteCommand::answerIsReady, this, &GetFlashMemoryInfoJsonCommand::handleGetFlashStateIsReady); commandQueue->enqueue(getFlashStateCommand); } void handleGetFlashStateIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { Usb::DeviceCommand::EStatus answerStatus = (Usb::DeviceCommand::EStatus)status; if (answerStatus != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, QJsonDocument(), DeviceWebApi::JsonCommandStatusCreator::create(answerStatus, answer)); return; } std::string flashStateText = getFlashStateText(answer[5] ? 0x02 : 0); QJsonObject jsonRootObject; if ((m_deviceInfo.typeInfo.type != 0) || (m_deviceInfo.hardwareVersion != 0) || (m_deviceInfo.softwareVersion != 0)) { jsonRootObject.insert("MemorySize", QString::number(m_maxAddress)); jsonRootObject.insert("FillMemoryPercent", QString::fromStdString(m_fillMemoryPercent)); jsonRootObject.insert("BeginReadBlock", QString::number(m_beginReadBlock, 16)); jsonRootObject.insert("FlashState", QString::fromStdString(flashStateText)); } QJsonDocument document(jsonRootObject); emit answerIsReady(this, document, std::make_shared()); } private: std::string getFlashStateText(uint8_t flashState) { if ((flashState & 0x04) != 0) { return "Стирание не закончено"; } if ((flashState & 0x01) != 0) { return "Стерта"; } if ((flashState & 0x02) != 0) { return "Прочитана"; } return "Не прочитана"; } }; } // namespace Incart::DeviceWebApi