#pragma once #include "ReadCableInfoCommand.h" #include "ByteCommandQueue.h" namespace Incart::DeviceComplexCommands { class MicroMonReadCableInfoCommand final : public ReadCableInfoCommand { Q_OBJECT private: Usb::ByteCommandQueue* const m_commandQueue; public: MicroMonReadCableInfoCommand(uint32_t uid, Usb::ByteCommandQueue* const commandQueue) : ReadCableInfoCommand(uid), m_commandQueue(commandQueue) { } public: std::shared_ptr execute() override { //JTerminal() << __PRETTY_FUNCTION__; std::shared_ptr command = std::make_shared("ReadCableInfo", m_commandQueue->generateUid(), std::vector{ 0x7e, 0x01, 0x00, 0x1e, 0x0a, 0xff, 0xff, 0xbd }); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, &MicroMonReadCableInfoCommand::handleAnswerIsReady); m_commandQueue->enqueue(command); return std::make_shared(Usb::DeviceCommand::EStatus::OK); } private slots: void handleAnswerIsReady(std::shared_ptr /*command*/, std::vector answer, int32_t status) { //JTerminal() << __PRETTY_FUNCTION__ << std::endl; Usb::CableInfo cableInfo; std::shared_ptr statusInfo; if (status != Usb::DeviceCommand::EStatus::OK) { statusInfo = Usb::DeviceCommandStatusCreator::create(answer, status); } else if (answer.size() < 25) { statusInfo = std::make_shared>>(Usb::DeviceCommand::EStatus::WRONG_FRAME_FORMAT, answer); } else { statusInfo = std::make_shared(Usb::DeviceCommand::EStatus::OK); cableInfo = parseCableInfo(answer); } emit answerIsReady(this, cableInfo, statusInfo); } private: Usb::CableInfo parseCableInfo(const std::vector& answer_) { Usb::CableInfo cableInfo; cableInfo.Version = static_cast(answer_[5]); cableInfo.CableRegime = static_cast(answer_[6]); cableInfo.CableType = static_cast(answer_[7]); cableInfo.CableNumber = makeDoubleWord(answer_, 8); cableInfo.SetupCounter = makeDoubleWord(answer_, 12); cableInfo.DateOfCreate = dateFromHex(answer_, 16); cableInfo.BeginUsageDate = dateFromHex(answer_, 19); cableInfo.LastInstallDate = dateFromHex(answer_, 22); return cableInfo; } QDate dateFromHex(const std::vector& answer_, int offset_) { uint8_t day = fromHexDec(answer_[offset_]); bool isErrorDate = false; if (day == 0xff) { isErrorDate = true; } uint8_t month = (isErrorDate ? 0xff : fromHexDec(answer_[offset_ + 1])); if (month == 0xff) { isErrorDate = true; } uint32_t year = 2000 + (isErrorDate ? 0xff : fromHexDec(answer_[offset_ + 2])); if (year == 0xff) { isErrorDate = true; } if ((day == 0) && (month == 0) && (year == 0)) { isErrorDate = true; } if (isErrorDate) { day = 0xff; month = 0xff; year = 2000 + 0xff; } return QDate(year, month, day); } uint8_t fromHexDec(uint8_t value_) { uint8_t lowByte = static_cast(value_ & 0x0F); uint8_t highByte = static_cast(value_ >> 4); if (highByte > 9 || lowByte > 9) { return 0xff; } return static_cast(lowByte + highByte * 10); } uint32_t makeDoubleWord(const std::vector& answer_, int offset_) { return static_cast(static_cast(answer_[offset_]) + (static_cast(static_cast(answer_[offset_ + 1])) << 8) + (static_cast(static_cast(answer_[offset_ + 2])) << 16) + (static_cast(static_cast(answer_[offset_ + 3])) << 24)); } }; } // namespace Incart::DeviceComplexCommands