#pragma once #include "UsbDeviceManager.h" #include "GetDataFromEepromCommand.h" namespace Incart::DeviceComplexCommands { class MicroMonGetDataFromEepromCommand final : public GetDataFromEepromCommand { private: const uint16_t m_quant = 0x10; uint16_t m_startAddress; uint16_t m_currAddress; uint16_t m_endAddress; std::vector m_data; Usb::UsbDeviceManager* const m_usbDeviceManager; public: MicroMonGetDataFromEepromCommand(uint32_t uid, uint16_t address_, uint16_t dataLength_, Usb::UsbDeviceManager* const usbDeviceManager) : GetDataFromEepromCommand(uid) , m_startAddress(address_) , m_currAddress(address_) , m_endAddress(static_cast(address_ + dataLength_)) , m_usbDeviceManager(usbDeviceManager) { } public: std::shared_ptr execute() override { return readFirstDataPortion(); } private slots: void handleReadFromEepromAnswerIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { Usb::DeviceCommand::EStatus status = static_cast(status_); if (status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, {}, Usb::DeviceCommandStatusCreator::create(answer_, status_)); return; } if (answer_.size() < 8) { emit answerIsReady(this, {}, Usb::DeviceCommandStatusCreator::create(answer_, Usb::DeviceCommand::EStatus::WRONG_FRAME_FORMAT)); return; } m_data.insert(m_data.end(), answer_.begin() + 4, answer_.end() - 3); readNextDataPortion(); } private: std::shared_ptr readFirstDataPortion() { if (m_currAddress < m_endAddress) { uint16_t currCount = calculateQuant(m_currAddress, m_endAddress); std::vector commandBytes; Usb::DeviceCommand::EStatus status = createReadCommandBytes(currCount, commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { return Usb::DeviceCommandStatusCreator::create({}, status); } sendReadCommand(currCount, commandBytes); } return std::make_shared(Usb::DeviceCommand::EStatus::OK); } void readNextDataPortion() { if (m_currAddress < m_endAddress) { uint16_t currCount = calculateQuant(m_currAddress, m_endAddress); std::vector commandBytes; Usb::DeviceCommand::EStatus status = createReadCommandBytes(currCount, commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, {}, Usb::DeviceCommandStatusCreator::create({}, status)); } sendReadCommand(currCount, commandBytes); } else { emit answerIsReady(this, m_data, std::make_shared(Usb::DeviceCommand::EStatus::OK)); } } Usb::DeviceCommand::EStatus createReadCommandBytes(uint16_t currCount_, std::vector& commandBytes_) { std::vector commandData; Common::ByteArrayProvider::addWord(m_currAddress, commandData); Common::ByteArrayProvider::addWord(0x0500, commandData); Common::ByteArrayProvider::addWord(currCount_, commandData); return m_usbDeviceManager->getCommandSet()->createCommandBytes(std::make_shared("ReadFromEeprom", m_usbDeviceManager->getCommandQueue()->generateUid(), commandData), commandBytes_); } void sendReadCommand(uint16_t currCount_, const std::vector& commandBytes_) { Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr command = std::make_shared("ReadFromEeprom", commandQueue->generateUid(), std::move(commandBytes_)); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, &MicroMonGetDataFromEepromCommand::handleReadFromEepromAnswerIsReady); m_currAddress += currCount_; commandQueue->enqueue(command); } uint16_t calculateQuant(uint16_t currAddress_, uint16_t maxAddress_) { uint16_t quant = static_cast(maxAddress_ - currAddress_); return std::min(quant, ((currAddress_) / m_quant + 1) * m_quant - currAddress_); } }; } // namespace Incart::DeviceComplexCommands