#pragma once #include "ByteCommandQueue.h" #include "DeviceInfo.h" #include "DeviceCommonInfo.h" #include "ComplexCommandFactory.h" #include "LaunchedSimpleCommandInfo.h" #include "DeviceBaseInfoAggregator.h" #include namespace Incart::Usb { class UsbDeviceCommandSet : public QObject { Q_OBJECT private: DeviceInfo m_connectedDeviceInfo; std::unordered_map m_devicesInfo; // читается из json файлов (key: тип прибора) ComplexCommandFactory* m_deviceComplexCommands; // все возможные обработчики сложных команд (фабрика создает генераторы этих команд) bool m_hasConnectedDevice = false; public: UsbDeviceCommandSet(const std::unordered_map& devicesInfo, ComplexCommandFactory* complexCommandFactory) : m_devicesInfo(devicesInfo) , m_deviceComplexCommands(complexCommandFactory) { } public: DevicesInfo::DeviceCommonInfo getDeviceInfo(uint16_t deviceType) { auto it = m_devicesInfo.find(deviceType); if (it != m_devicesInfo.end()) { return it->second; } return DevicesInfo::DeviceCommonInfo{}; } void setConnectedDeviceInfo(const DeviceInfo& deviceInfo) { m_connectedDeviceInfo = deviceInfo; } void setHasConnectedDevice(bool status) { m_hasConnectedDevice = status; } ComplexCommandFactory* getDeviceComplexCommands() { return m_deviceComplexCommands; } // возвращает список простых команд для подключенного прибора std::vector getDeviceSimpleCommandsInfo() { if (!m_hasConnectedDevice) { return std::vector(); } return m_connectedDeviceInfo.typeInfo.commandDesription.simpleCommands; } // возвращает список сложных команд для подключенного прибора std::vector getDeviceComplexCommandsInfo() { if (!m_hasConnectedDevice) { return std::vector(); } return m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands; } std::shared_ptr createComplexCommand(const std::string& name, const std::string& handlerName, std::shared_ptr data = nullptr) { for (auto it = m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands.begin(); it != m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands.end(); it++) { if (Common::StringExtensions::isEqualsInsensitive(name, it->name)) { return m_deviceComplexCommands->create(handlerName, data); } } return nullptr; } std::shared_ptr createComplexCommand(const std::string& name, std::shared_ptr data = nullptr) { for (auto it = m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands.begin(); it != m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands.end(); it++) { if (Common::StringExtensions::isEqualsInsensitive(name, it->name)) { return m_deviceComplexCommands->create(it->handlerName, data); } } return nullptr; } std::shared_ptr getComplexCommandCreator(const std::string& name) { for (auto it = m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands.begin(); it != m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands.end(); it++) { if (Common::StringExtensions::isEqualsInsensitive(name, it->name)) { return m_deviceComplexCommands->getCreator(it->handlerName); } } return nullptr; } DevicesInfo::ComplexCommandInfo* getComplexCommandInfo(const std::string& name) { if (!m_hasConnectedDevice) { return nullptr; } std::vector& complexCommands = m_connectedDeviceInfo.typeInfo.commandDesription.complexCommands; for (size_t i = 0; i < complexCommands.size(); i++) { if (Common::StringExtensions::isEqualsInsensitive(name, complexCommands[i].name)) { return &complexCommands[i]; } } return nullptr; } DeviceCommand::EStatus createCommandBytes(std::shared_ptr commandInfo, std::vector& commandBytes) { if ((m_connectedDeviceInfo.typeInfo.type == 0) && (m_connectedDeviceInfo.hardwareVersion == 0)) { return DeviceCommand::EStatus::DEVICE_DISCONNECTED; } for (auto it = m_connectedDeviceInfo.typeInfo.commandDesription.simpleCommands.begin(); it != m_connectedDeviceInfo.typeInfo.commandDesription.simpleCommands.end(); it++) { if (Common::StringExtensions::isEqualsInsensitive(commandInfo->name, it->name)) { return createCommandBytes(*it, commandInfo, commandBytes); } } return DeviceCommand::EStatus::NOT_EXIST; } private: DeviceCommand::EStatus createCommandBytes(const DevicesInfo::SimpleCommandInfo& commandInfo, std::shared_ptr launchedCommandInfo, std::vector& commandBytes) { if (!launchedCommandInfo->isValid(commandInfo)) { return DeviceCommand::EStatus::BAD_DATA; } std::vector commandData; switch (commandInfo.data.sourceType) { case DevicesInfo::ESourceType::Fixed: if ((commandInfo.data.options.size() > 0) && (commandInfo.data.options[0].size() > 0)) { commandData = commandInfo.data.options[0]; } break; case DevicesInfo::ESourceType::Dynamic: if (launchedCommandInfo->data.size() > 0) { commandData = launchedCommandInfo->data; } break; } if (Common::StringExtensions::isEqualsInsensitive(commandInfo.name, std::string("Custom"))) { commandBytes.insert(commandBytes.end(), commandData.begin(), commandData.end()); } else { uint16_t commandDataLength = static_cast(commandData.size()); commandBytes.push_back((char)0x7e); commandBytes.push_back((char)Common::ByteArrayProvider::lowByte(commandDataLength)); commandBytes.push_back((char)Common::ByteArrayProvider::highByte(commandDataLength)); commandBytes.push_back((char)commandInfo.code); for (auto it = commandData.begin(); it != commandData.end(); it++) { commandBytes.push_back(*it); } commandBytes.push_back((char)0xff); commandBytes.push_back((char)0xff); commandBytes.push_back((char)0xbd); } /* std::cout << "CreateCommandBytes: count=" << commandBytes.size() << " [" << std::hex; for (size_t i = 0; i < commandBytes.size(); i++) { std::cout << " " << std::setfill(' ') << std::setw(2) << static_cast(commandBytes[i] & 0xFF); } std::cout << "]" << std::dec << std::endl; */ return DeviceCommand::EStatus::OK; } }; } // namespace Incart::Usb