#pragma once #include "ComplexCommand.h" #include "ComplexCommandCreateMultidata.h" #include "ByteCommandQueue.h" #include "SetExaminationInfoCommand.h" #include "ByteArrayProvider.h" #include "UsbDeviceManager.h" #include "ExaminationInfo.h" #include "SetDataToEepromCommand.h" #include "PolyCrc16Calculator.h" #include "SetDataToEepromCommand.h" #include "EepromDataRecord.h" #include "InfoMap.h" #include "EEeramVersion9Address.h" namespace Incart::DeviceComplexCommands { class MicroMonSetExaminationInfoCommand : public SetExaminationInfoCommand { private: const size_t m_auxExamInfoMapMaxSize = 0x500; ExaminationInfo m_examinationInfo; Usb::UsbDeviceManager* const m_usbDeviceManager; public: MicroMonSetExaminationInfoCommand(uint32_t uid, const ExaminationInfo& examinationInfo, Usb::UsbDeviceManager* const usbDeviceManager) : SetExaminationInfoCommand(uid) , m_examinationInfo(examinationInfo) , m_usbDeviceManager(usbDeviceManager) { } public: std::shared_ptr execute() override { std::vector commandBytes; Usb::DeviceCommand::EStatus status = createExamInfoCommandBytes(1, toBytes(m_examinationInfo.surname), commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { return Usb::DeviceCommandStatusCreator::create({}, status); } Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr command = std::make_shared("WriteExamInfo", commandQueue->generateUid(), std::move(commandBytes)); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, &MicroMonSetExaminationInfoCommand::handleWriteSurnameIsReady); commandQueue->enqueue(command); return std::make_shared(Usb::DeviceCommand::EStatus::OK); } private slots: void handleWriteSurnameIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { handleWriteExamInfoAnswer(2, toBytes(m_examinationInfo.name), &MicroMonSetExaminationInfoCommand::handleWriteNameIsReady, answer_, status_); } void handleWriteNameIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { handleWriteExamInfoAnswer(3, toBytes(m_examinationInfo.patronymic), &MicroMonSetExaminationInfoCommand::handleWritePatronymicIsReady, answer_, status_); } void handleWritePatronymicIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { handleWriteExamInfoAnswer(4, toBytes(m_examinationInfo.birthdayDate), &MicroMonSetExaminationInfoCommand::handleWriteBirthdayDateIsReady, answer_, status_); } void handleWriteBirthdayDateIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { std::vector flagBytes(4); Common::ByteArrayProvider::setDWordToArray(static_cast(m_examinationInfo.getFlags()), &flagBytes[0], 0); handleWriteExamInfoAnswer(5, flagBytes, &MicroMonSetExaminationInfoCommand::handleWriteFlagsIsReady, answer_, status_); } void handleWriteFlagsIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { handleWriteExamInfoAnswer(6, toBytes(m_examinationInfo.sex.toLowerString()), &MicroMonSetExaminationInfoCommand::handleWriteSexIsReady, answer_, status_); } void handleWriteSexIsReady(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; } std::vector commandDataBytes; packStartTime(m_examinationInfo.startTime, commandDataBytes); packElectrodesInfo(m_examinationInfo.electrodes, commandDataBytes); std::shared_ptr commandData = std::make_shared>(m_usbDeviceManager->getCommandQueue()->generateUid(), EepromDataRecord{ static_cast(EEeramVersion9Address::ExamInfoRest), commandDataBytes }); std::shared_ptr command = std::dynamic_pointer_cast(m_usbDeviceManager->getCommandSet()->createComplexCommand("SetDataToEeprom", commandData)); addExecutedInnerCommand(command); connect(command.get(), &SetDataToEepromCommand::answerIsReady, this, &MicroMonSetExaminationInfoCommand::handleSetRestExamInfoIsReady); std::shared_ptr statusInfo = executeCommand(command); if (statusInfo->status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, statusInfo); } } void handleSetRestExamInfoIsReady(Usb::ComplexCommand* command_, std::shared_ptr status_) { removeExecutedInnerCommand(command_); if (status_->status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, status_); return; } std::vector commandBytes; Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); Usb::DeviceCommand::EStatus status = m_usbDeviceManager->getCommandSet()->createCommandBytes(std::make_shared("WriteLeadType", commandQueue->generateUid(), std::vector{ 0x03, m_examinationInfo.electrodes->getLeadType() }), commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, Usb::DeviceCommandStatusCreator::create({}, status)); return; } std::shared_ptr command = std::make_shared("WriteLeadType", commandQueue->generateUid(), std::move(commandBytes)); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, &MicroMonSetExaminationInfoCommand::handleWriteLeadTypeIsReady); commandQueue->enqueue(command); } void handleWriteLeadTypeIsReady(std::shared_ptr /*command_*/, std::vector answer_, int32_t status_) { if (status_ != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, Usb::DeviceCommandStatusCreator::create(answer_, status_)); return; } InfoMap infoMap; infoMap.addValue("fname", m_examinationInfo.fileName); infoMap.addValue("CableOn", 1); infoMap.addValue("LeadSubSet", static_cast(m_examinationInfo.electrodes->getLeadType())); infoMap.addValue("CableCntr", m_examinationInfo.cableInfo.SetupCounter); infoMap.addValue("CableNumber", m_examinationInfo.cableInfo.CableNumber); infoMap.addValue("CableType", m_examinationInfo.cableInfo.CableType); std::vector infoMapBytes(infoMap.writeToBuffer(EDeviceDataHeadTypes::HeadAuxExamInfo, -1, 0)); if (infoMapBytes.size() > m_auxExamInfoMapMaxSize) { infoMapBytes = {}; } uint16_t infoMapBytesCount = static_cast(infoMapBytes.size()); if (infoMapBytesCount > 0) { std::vector commandDataBytes; Common::ByteArrayProvider::addWord(infoMapBytesCount, commandDataBytes); commandDataBytes.insert(commandDataBytes.end(), infoMapBytes.begin(), infoMapBytes.end()); std::shared_ptr commandData = std::make_shared>(m_usbDeviceManager->getCommandQueue()->generateUid(), EepromDataRecord{ static_cast(EEeramVersion9Address::AuxExamInfo), commandDataBytes }); std::shared_ptr command = std::dynamic_pointer_cast(m_usbDeviceManager->getCommandSet()->createComplexCommand("SetDataToEeprom", commandData)); addExecutedInnerCommand(command); connect(command.get(), &SetDataToEepromCommand::answerIsReady, this, &MicroMonSetExaminationInfoCommand::handleSetAuxExamInfoIsReady); std::shared_ptr statusInfo = executeCommand(command); if (statusInfo->status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, statusInfo); } } else { emit answerIsReady(this, Usb::DeviceCommandStatusCreator::create({}, Usb::DeviceCommand::EStatus::BAD_DATA)); } } void handleSetAuxExamInfoIsReady(Usb::ComplexCommand* command_, std::shared_ptr status_) { removeExecutedInnerCommand(command_); emit answerIsReady(this, status_); } private: template void handleWriteExamInfoAnswer(uint8_t type_, const std::vector& data_, PointerToMemberFunction handler_, const 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; } std::vector commandBytes; status = createExamInfoCommandBytes(type_, data_, commandBytes); if (status != Usb::DeviceCommand::EStatus::OK) { emit answerIsReady(this, Usb::DeviceCommandStatusCreator::create({}, status)); return; } Usb::ByteCommandQueue* commandQueue = m_usbDeviceManager->getCommandQueue(); std::shared_ptr command = std::make_shared("WriteExamInfo", commandQueue->generateUid(), std::move(commandBytes)); connect(command.get(), &Usb::ByteCommand::answerIsReady, this, handler_); commandQueue->enqueue(command); } Usb::DeviceCommand::EStatus createExamInfoCommandBytes(uint8_t type_, const std::vector& data_, std::vector& commandBytes) { std::vector commandDataBytes = { type_ }; commandDataBytes.insert(commandDataBytes.end(), data_.begin(), data_.end()); return m_usbDeviceManager->getCommandSet()->createCommandBytes(std::make_shared("WriteExamInfo" , m_usbDeviceManager->getCommandQueue()->generateUid(), commandDataBytes), commandBytes); } std::vector toBytes(const std::string& text) { std::vector bytes = Common::StringExtensions::toWindows1251FromUtf8(text); bytes.push_back(0); return bytes; } std::vector toBytes(Common::DateObject date_) { std::vector date(4); if (!date_.isDefault()) { date[0] = Common::ByteArrayProvider::toHexFromDec(static_cast(date_.getYear() / 100)); date[1] = Common::ByteArrayProvider::toHexFromDec(static_cast(date_.getYear() % 100)); date[2] = Common::ByteArrayProvider::toHexFromDec(static_cast(date_.getMonth())); date[3] = Common::ByteArrayProvider::toHexFromDec(static_cast(date_.getDay())); } return date; } void packStartTime(Common::DateTimeObject startTime_, std::vector& data_) { std::vector startTimeBytes = Common::DateTimeObject::packToDevice(startTime_); data_.insert(data_.end(), startTimeBytes.begin(), startTimeBytes.end()); } void packElectrodesInfo(std::shared_ptr electrodesInfo_, std::vector& data_) { data_.push_back(electrodesInfo_->getLeadType()); size_t startChannelBlock = data_.size(); std::vector channelNames = electrodesInfo_->getChannelNames(); size_t channelNamesCount = std::min(8, channelNames.size()); size_t channelNameLength; std::vector channelNameBytes; // должно быть заполнено 3*8 байт данными о каналах for (size_t i = 0; i < channelNamesCount; ++i) { channelNameBytes = toBytes(channelNames[i]); channelNameLength = std::min(3, channelNameBytes.size()); data_.insert(data_.end(), channelNameBytes.begin(), channelNameBytes.begin() + channelNameLength); for (size_t j = channelNameLength; j < 3; ++j) { data_.push_back(0); } } // заполняем оставшееся место нулями for (size_t i = data_.size(); i < startChannelBlock + 25; ++i) { data_.push_back(0); } uint16_t crc = PolyCrc16Calculator::calculateCrc(data_, 0, data_.size()); Common::ByteArrayProvider::addWord(crc, data_); } }; } // namespace Incart::DeviceComplexCommands