/*! \file piusb.h * \ingroup USB * \~\brief * \~english USB input/output device declarations * \~russian Объявления USB-устройства ввода/вывода */ /* PIP - Platform Independent Primitives USB, based on libusb Ivan Pelipenko peri4ko@yandex.ru This program is free software: you can redistribute it and/or modify it under the terms of the GNU Lesser General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version. This program is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. You should have received a copy of the GNU Lesser General Public License along with this program. If not, see . */ //! \defgroup USB USB //! \~\brief //! \~english USB support via libusb //! \~russian Поддержка USB с помощью libusb //! //! \~\details //! \~english \section cmake_module_USB Building with CMake //! \~russian \section cmake_module_USB Сборка с использованием CMake //! //! \~\code //! find_package(PIP REQUIRED) //! target_link_libraries([target] PIP::USB) //! \endcode //! //! \~english \par Common //! \~russian \par Общее //! //! \~english //! This module declares raw USB input/output devices built on libusb. //! //! \~russian //! Модуль объявляет USB-устройства ввода/вывода для сырого обмена на базе libusb. //! //! \~\authors //! \~english //! Ivan Pelipenko peri4ko@yandex.ru; //! Andrey Bychkov work.a.b@yandex.ru; //! \~russian //! Иван Пелипенко peri4ko@yandex.ru; //! Андрей Бычков work.a.b@yandex.ru; //! #ifndef PIUSB_H #define PIUSB_H #include "piiodevice.h" #include "pip_usb_export.h" struct usb_dev_handle; //! \ingroup USB //! \~\brief //! \~english USB implementation of \a PIIODevice. //! \~russian USB-реализация \a PIIODevice. class PIP_USB_EXPORT PIUSB: public PIIODevice { PIIODEVICE(PIUSB, "usb"); public: //! \~english Constructs USB device wrapper for vendor ID "vid" and product ID "pid". //! \~russian Создает обертку USB-устройства для vendor ID "vid" и product ID "pid". explicit PIUSB(ushort vid = 0, ushort pid = 0); //! \~english Destroys the USB device wrapper. //! \~russian Уничтожает обертку USB-устройства. virtual ~PIUSB(); //! \ingroup USB //! \~\brief //! \~english Parsed USB endpoint descriptor. //! \~russian Разобранный дескриптор USB endpoint. struct PIP_USB_EXPORT Endpoint { //! \~english Constructs endpoint descriptor and parses cached properties. //! \~russian Создает дескриптор endpoint и разбирает кэшируемые свойства. Endpoint(uchar a = 0, uchar at = 0, ushort mps = 0) { address = a; attributes = at; max_packet_size = mps; parse(); } //! \~english Transfer direction encoded in endpoint address. //! \~russian Направление передачи, закодированное в адресе endpoint. enum Direction { Write = 0, /** \~english Host-to-device endpoint \~russian Endpoint от хоста к устройству */ Read = 1 /** \~english Device-to-host endpoint \~russian Endpoint от устройства к хосту */ }; //! \~english USB transfer type encoded in endpoint attributes. //! \~russian Тип USB-передачи, закодированный в атрибутах endpoint. enum TransferType { Control = 0, /** \~english Control endpoint \~russian Control-endpoint */ Isochronous = 1, /** \~english Isochronous endpoint \~russian Isochronous-endpoint */ Bulk = 2, /** \~english Bulk endpoint \~russian Bulk-endpoint */ Interrupt = 3 /** \~english Interrupt endpoint \~russian Interrupt-endpoint */ }; //! \~english Synchronisation mode for isochronous endpoints. //! \~russian Режим синхронизации для isochronous-endpoint. enum SynchronisationType { NoSynchonisation = 0, /** \~english No synchronisation \~russian Без синхронизации */ Asynchronous = 2, /** \~english Asynchronous synchronisation \~russian Асинхронная синхронизация */ Adaptive = 1, /** \~english Adaptive synchronisation \~russian Адаптивная синхронизация */ Synchronous = 3 /** \~english Synchronous synchronisation \~russian Синхронная синхронизация */ }; //! \~english Usage mode for isochronous endpoints. //! \~russian Режим использования для isochronous-endpoint. enum UsageType { DataEndpoint = 0, /** \~english Data endpoint \~russian Endpoint данных */ FeedbackEndpoint = 2, /** \~english Feedback endpoint \~russian Endpoint обратной связи */ ExplicitFeedbackDataEndpoint = 1 /** \~english Explicit feedback data endpoint \~russian Endpoint данных с явной обратной связью */ }; //! \~english Parses direction and transfer information from \a address and \a attributes. //! \~russian Разбирает направление и тип передачи из \a address и \a attributes. void parse(); //! \~english Returns true if the endpoint is not selected. //! \~russian Возвращает true, если endpoint не выбран. bool isNull() const { return address == 0; } //! \~english Raw USB endpoint address. //! \~russian Сырой адрес USB endpoint. uchar address; //! \~english Raw USB endpoint attributes. //! \~russian Сырые атрибуты USB endpoint. uchar attributes; //! \~english Maximum packet size in bytes. //! \~russian Максимальный размер пакета в байтах. ushort max_packet_size; //! \~english Parsed transfer direction. //! \~russian Разобранное направление передачи. Direction direction; //! \~english Parsed transfer type. //! \~russian Разобранный тип передачи. TransferType transfer_type; //! \~english Parsed synchronisation type for isochronous transfers. //! \~russian Разобранный тип синхронизации для isochronous-передач. SynchronisationType synchronisation_type = NoSynchonisation; //! \~english Parsed usage type for isochronous transfers. //! \~russian Разобранный режим использования для isochronous-передач. UsageType usage_type = DataEndpoint; }; //! \ingroup USB //! \~\brief //! \~english USB interface description with its endpoints. //! \~russian Описание USB-интерфейса и его endpoint. struct PIP_USB_EXPORT Interface { //! \~english Index inside the configuration descriptor. //! \~russian Индекс внутри дескриптора конфигурации. uchar index = 0; //! \~english Value used to select this interface. //! \~russian Значение, используемое для выбора этого интерфейса. uchar value_to_select = 0; //! \~english USB interface class code. //! \~russian Код класса USB-интерфейса. ushort class_code = 0; //! \~english USB interface subclass code. //! \~russian Код подкласса USB-интерфейса. ushort subclass_code = 0; //! \~english USB interface protocol code. //! \~russian Код протокола USB-интерфейса. ushort protocol_code = 0; //! \~english Endpoints exposed by this interface. //! \~russian Endpoint, доступные у этого интерфейса. PIVector endpoints; }; //! \ingroup USB //! \~\brief //! \~english USB configuration description with available interfaces. //! \~russian Описание USB-конфигурации с доступными интерфейсами. struct PIP_USB_EXPORT Configuration { //! \~english Index inside the device descriptor. //! \~russian Индекс внутри дескриптора устройства. uchar index = 0; //! \~english Value used to select this configuration. //! \~russian Значение, используемое для выбора этой конфигурации. uchar value_to_select = 0; //! \~english Raw USB configuration attributes. //! \~russian Сырые атрибуты USB-конфигурации. uchar attributes = 0; //! \~english Maximum bus power in mA. //! \~russian Максимальное потребление по шине в мА. ushort max_power = 0; //! \~english True if the device is self-powered in this configuration. //! \~russian True, если устройство в этой конфигурации имеет собственное питание. bool self_powered = false; //! \~english True if remote wakeup is supported. //! \~russian True, если поддерживается remote wakeup. bool remote_wakeup = false; //! \~english Interfaces available in this configuration. //! \~russian Интерфейсы, доступные в этой конфигурации. PIVector interfaces; }; //! \ingroup USB //! \~\brief //! \~english Top-level USB device descriptor collected during opening. //! \~russian Верхнеуровневый USB-дескриптор, собранный при открытии. struct PIP_USB_EXPORT Descriptor { //! \~english USB specification version in BCD form. //! \~russian Версия спецификации USB в BCD-форме. ushort usb_spec_number = 0; //! \~english Device class code. //! \~russian Код класса устройства. uchar device_class = 0; //! \~english Device subclass code. //! \~russian Код подкласса устройства. uchar device_subclass = 0; //! \~english Device protocol code. //! \~russian Код протокола устройства. uchar device_protocol = 0; //! \~english Maximum packet size for endpoint zero. //! \~russian Максимальный размер пакета для endpoint zero. uchar max_packet_size = 0; //! \~english Vendor identifier. //! \~russian Идентификатор производителя. ushort id_vendor = 0; //! \~english Product identifier. //! \~russian Идентификатор продукта. ushort id_product = 0; //! \~english Device release number in BCD form. //! \~russian Номер релиза устройства в BCD-форме. ushort id_device_release = 0; //! \~english Index of manufacturer string descriptor. //! \~russian Индекс строкового дескриптора производителя. uchar index_manufacturer = 0; //! \~english Index of product string descriptor. //! \~russian Индекс строкового дескриптора продукта. uchar index_product = 0; //! \~english Index of serial number string descriptor. //! \~russian Индекс строкового дескриптора серийного номера. uchar index_serial = 0; //! \~english Available device configurations. //! \~russian Доступные конфигурации устройства. PIVector configurations; }; //! \~english Returns descriptor collected for the currently opened device. //! \~russian Возвращает дескриптор, собранный для текущего открытого устройства. const PIUSB::Descriptor & currentDescriptor() const { return desc_; } //! \~english Returns the currently selected configuration description. //! \~russian Возвращает описание текущей выбранной конфигурации. const PIUSB::Configuration & currentConfiguration() const { return conf_; } //! \~english Returns the currently selected interface description. //! \~russian Возвращает описание текущего выбранного интерфейса. const PIUSB::Interface & currentInterface() const { return iface_; } //! \~english Returns current vendor ID filter. //! \~russian Возвращает текущий фильтр vendor ID. ushort vendorID() const { return vid_; } //! \~english Returns current product ID filter. //! \~russian Возвращает текущий фильтр product ID. ushort productID() const { return pid_; } //! \~english Returns ordinal number among devices with matching vendor and product IDs. //! \~russian Возвращает порядковый номер среди устройств с теми же vendor ID и product ID. int deviceNumber() const { return property("deviceNumber").toInt(); } //! \~english Returns read timeout in milliseconds. //! \~russian Возвращает таймаут чтения в миллисекундах. int timeoutRead() const { return property("timeoutRead").toInt(); } //! \~english Returns write timeout in milliseconds. //! \~russian Возвращает таймаут записи в миллисекундах. int timeoutWrite() const { return property("timeoutWrite").toInt(); } //! \~english Returns endpoint used by \a read(). //! \~russian Возвращает endpoint, используемый методом \a read(). const PIUSB::Endpoint & endpointRead() const { return ep_read; } //! \~english Returns endpoint used by \a write(). //! \~russian Возвращает endpoint, используемый методом \a write(). const PIUSB::Endpoint & endpointWrite() const { return ep_write; } //! \~english Returns endpoints of the currently selected interface. //! \~russian Возвращает endpoint текущего выбранного интерфейса. const PIVector & endpoints() const { return eps; } //! \~english Returns only readable endpoints from \a endpoints(). //! \~russian Возвращает только endpoint для чтения из \a endpoints(). PIVector endpointsRead(); //! \~english Returns only writable endpoints from \a endpoints(). //! \~russian Возвращает только endpoint для записи из \a endpoints(). PIVector endpointsWrite(); //! \~english Returns endpoint with address "address", or null endpoint if it is absent. //! \~russian Возвращает endpoint с адресом "address" или нулевой endpoint, если он отсутствует. PIUSB::Endpoint getEndpointByAddress(uchar address); //! \~english Sets vendor ID filter and updates device path. //! \~russian Устанавливает фильтр vendor ID и обновляет путь устройства. void setVendorID(ushort vid); //! \~english Sets product ID filter and updates device path. //! \~russian Устанавливает фильтр product ID и обновляет путь устройства. void setProductID(ushort pid); //! \~english Selects configuration by its public value and switches to its first interface. //! \~russian Выбирает конфигурацию по её публичному значению и переключается на её первый интерфейс. bool setConfiguration(uchar value); //! \~english Selects interface by its public value and refreshes active endpoints. //! \~russian Выбирает интерфейс по его публичному значению и обновляет активные endpoint. bool setInterface(uchar value); //! \~english Sets endpoint used by \a read(). //! \~russian Устанавливает endpoint, используемый методом \a read(). void setEndpointRead(const PIUSB::Endpoint & ep) { ep_read = ep; } //! \~english Sets endpoint used by \a write(). //! \~russian Устанавливает endpoint, используемый методом \a write(). void setEndpointWrite(const PIUSB::Endpoint & ep) { ep_write = ep; } //! \~english Selects which matching device instance should be opened. //! \~russian Выбирает, какой экземпляр среди совпадающих устройств должен быть открыт. void setDeviceNumber(int dn) { setProperty("deviceNumber", dn); } //! \~english Sets read timeout in milliseconds. //! \~russian Устанавливает таймаут чтения в миллисекундах. void setTimeoutRead(int t) { setProperty("timeoutRead", t); } //! \~english Sets write timeout in milliseconds. //! \~russian Устанавливает таймаут записи в миллисекундах. void setTimeoutWrite(int t) { setProperty("timeoutWrite", t); } //! \~english Reserved control-transfer write helper. //! \~russian Зарезервированный helper для записи через control-transfer. int controlWrite(const void * data, int max_size); //! \~english Resets currently selected read and write endpoints. //! \~russian Сбрасывает текущие выбранные endpoint чтения и записи. virtual void flush() override; protected: bool configureDevice(const void * e_main, const void * e_parent = 0) override; PIString constructFullPathDevice() const override; void configureFromFullPathDevice(const PIString & full_path) override; ssize_t readDevice(void * read_to, ssize_t max_size) override; ssize_t writeDevice(const void * data, ssize_t max_size) override; bool openDevice() override; bool closeDevice() override; DeviceInfoFlags deviceInfoFlags() const override { return PIIODevice::Reliable; } PIVector eps; ushort vid_, pid_; int intefrace_, timeout_r, timeout_w; int interface_claimed; PIUSB::Endpoint ep_read, ep_write; Descriptor desc_; Configuration conf_; Interface iface_; usb_dev_handle * hdev; }; //! \~english Writes endpoint description to \a PICout. //! \~russian Выводит описание endpoint в \a PICout. PIP_USB_EXPORT PICout operator<<(PICout s, const PIUSB::Endpoint & v); #endif