/*! \file piusb.h
* \ingroup USB
* \~\brief
* \~english USB device
* \~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
//! These files provides works with raw USB device
//!
//! \~russian
//! Эти файлы обеспечивают работу с сырым USB устройством
//!
//! \~\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"
struct usb_dev_handle;
class PIP_EXPORT PIUSB: public PIIODevice {
PIIODEVICE(PIUSB, "usb");
public:
explicit PIUSB(ushort vid = 0, ushort pid = 0);
virtual ~PIUSB();
struct PIP_EXPORT Endpoint {
Endpoint(uchar a = 0, uchar at = 0, ushort mps = 0) {
address = a;
attributes = at;
max_packet_size = mps;
parse();
}
enum Direction {
Write = 0,
Read = 1
};
enum TransferType {
Control = 0,
Isochronous = 1,
Bulk = 2,
Interrupt = 3
};
enum SynchronisationType {
NoSynchonisation = 0,
Asynchronous = 2,
Adaptive = 1,
Synchronous = 3
};
enum UsageType {
DataEndpoint = 0,
FeedbackEndpoint = 2,
ExplicitFeedbackDataEndpoint = 1
};
void parse();
bool isNull() const { return address == 0; }
uchar address;
uchar attributes;
ushort max_packet_size;
Direction direction;
TransferType transfer_type;
SynchronisationType synchronisation_type;
UsageType usage_type;
};
struct PIP_EXPORT Interface {
Interface() { index = value_to_select = class_code = subclass_code = protocol_code = 0; }
uchar index;
uchar value_to_select;
ushort class_code;
ushort subclass_code;
ushort protocol_code;
PIVector endpoints;
};
struct PIP_EXPORT Configuration {
Configuration() {
index = value_to_select = attributes = max_power = 0;
self_powered = remote_wakeup = false;
}
uchar index;
uchar value_to_select;
uchar attributes;
ushort max_power; // mA
bool self_powered;
bool remote_wakeup;
PIVector interfaces;
};
struct PIP_EXPORT Descriptor {
Descriptor() {
usb_spec_number = 0;
device_class = device_subclass = device_protocol = max_packet_size = 0;
id_vendor = id_product = id_device_release = 0;
index_manufacturer = index_product = index_serial = 0;
}
ushort usb_spec_number;
uchar device_class;
uchar device_subclass;
uchar device_protocol;
uchar max_packet_size;
ushort id_vendor;
ushort id_product;
ushort id_device_release;
uchar index_manufacturer;
uchar index_product;
uchar index_serial;
PIVector configurations;
};
const PIUSB::Descriptor & currentDescriptor() const { return desc_; }
const PIUSB::Configuration & currentConfiguration() const { return conf_; }
const PIUSB::Interface & currentInterface() const { return iface_; }
ushort vendorID() const { return vid_; }
ushort productID() const { return pid_; }
int deviceNumber() const { return property("deviceNumber").toInt(); }
int timeoutRead() const { return property("timeoutRead").toInt(); }
int timeoutWrite() const { return property("timeoutWrite").toInt(); }
const PIUSB::Endpoint & endpointRead() const { return ep_read; }
const PIUSB::Endpoint & endpointWrite() const { return ep_write; }
const PIVector & endpoints() const { return eps; }
PIVector endpointsRead();
PIVector endpointsWrite();
PIUSB::Endpoint getEndpointByAddress(uchar address);
void setVendorID(ushort vid) {
vid_ = vid;
setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));
}
void setProductID(ushort pid) {
pid_ = pid;
setPath(PIString::fromNumber(vid_, 16).expandLeftTo(4, "0") + ":" + PIString::fromNumber(pid_, 16).expandLeftTo(4, "0"));
}
bool setConfiguration(uchar value);
bool setInterface(uchar value);
void setEndpointRead(const PIUSB::Endpoint & ep) { ep_read = ep; }
void setEndpointWrite(const PIUSB::Endpoint & ep) { ep_write = ep; }
void setDeviceNumber(int dn) { setProperty("deviceNumber", dn); }
void setTimeoutRead(int t) { setProperty("timeoutRead", t); }
void setTimeoutWrite(int t) { setProperty("timeoutWrite", t); }
int controlWrite(const void * data, int max_size);
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;
};
PIP_EXPORT PICout operator<<(PICout s, const PIUSB::Endpoint & v);
#endif // PIUSB_H