mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2025-02-19 09:54:15 +01:00
OP-334 OP-332 Linux usb monitor working fine now, and rawhidplugin.cpp updated to use this new mechanism, no more polling thread opening the device every second!
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2957 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
623bdb6298
commit
e4535ed575
@ -358,7 +358,7 @@ void pjrc_rawhid::hid_close(hid_t *hid)
|
||||
if (!hid) return;
|
||||
if (!hid->open) return;
|
||||
|
||||
usb_release_interface(hid->usb, hid->iface);
|
||||
usb_release_interface(hid->usb, hid->iface);
|
||||
|
||||
int others = 0;
|
||||
for (hid_t *p = first_hid; p; p = p->next)
|
||||
@ -370,4 +370,5 @@ void pjrc_rawhid::hid_close(hid_t *hid)
|
||||
usb_close(hid->usb);
|
||||
|
||||
hid->usb = NULL;
|
||||
hid->open = 0;
|
||||
}
|
||||
|
@ -36,83 +36,19 @@
|
||||
|
||||
#include "rawhid_const.h"
|
||||
|
||||
// **********************************************************************
|
||||
|
||||
RawHIDEnumerationThread::RawHIDEnumerationThread(RawHIDConnection *rawhid) :
|
||||
QThread(rawhid), // Pip
|
||||
m_rawhid(rawhid),
|
||||
m_running(true)
|
||||
{
|
||||
if (m_rawhid)
|
||||
connect(m_rawhid, SLOT(destroyed(QObject *)), this, SLOT(onRawHidConnectionDestroyed(QObject *))); // Pip
|
||||
}
|
||||
|
||||
RawHIDEnumerationThread::~RawHIDEnumerationThread()
|
||||
{
|
||||
m_rawhid = NULL; // safe guard
|
||||
|
||||
m_running = false;
|
||||
|
||||
// wait for the thread to terminate
|
||||
if (!wait(100))
|
||||
qDebug() << "Cannot terminate RawHIDEnumerationThread";
|
||||
}
|
||||
|
||||
void RawHIDEnumerationThread::onRawHidConnectionDestroyed(QObject *obj) // Pip
|
||||
{
|
||||
if (!m_rawhid || m_rawhid != obj)
|
||||
return;
|
||||
|
||||
m_rawhid = NULL;
|
||||
}
|
||||
|
||||
void RawHIDEnumerationThread::run()
|
||||
{
|
||||
QStringList devices = m_rawhid->availableDevices();
|
||||
|
||||
int counter = 0;
|
||||
|
||||
while (m_running)
|
||||
{
|
||||
// update available devices every second (doesn't need more)
|
||||
if (m_rawhid)
|
||||
{
|
||||
if (!m_rawhid->deviceOpened()) // this was stopping us getting enumerations changes fed back
|
||||
{
|
||||
if (++counter >= 100)
|
||||
{
|
||||
counter = 0;
|
||||
|
||||
QStringList newDev = m_rawhid->availableDevices();
|
||||
if (devices != newDev)
|
||||
{
|
||||
devices = newDev;
|
||||
emit enumerationChanged();
|
||||
}
|
||||
}
|
||||
}
|
||||
// else
|
||||
// counter = 0;
|
||||
}
|
||||
else
|
||||
counter = 0;
|
||||
|
||||
msleep(10);
|
||||
}
|
||||
}
|
||||
|
||||
// **********************************************************************
|
||||
|
||||
RawHIDConnection::RawHIDConnection()
|
||||
: m_enumerateThread(this)
|
||||
: m_usbMonitor(this)
|
||||
{
|
||||
//added by andrew
|
||||
RawHidHandle = NULL;
|
||||
enablePolling = true;
|
||||
|
||||
QObject::connect(&m_enumerateThread, SIGNAL(enumerationChanged()), this, SLOT(onEnumerationChanged()));
|
||||
connect(&m_usbMonitor, SIGNAL(deviceDiscovered(USBPortInfo)), this, SLOT(onDeviceConnected()));
|
||||
connect(&m_usbMonitor, SIGNAL(deviceRemoved(USBPortInfo)), this, SLOT(onDeviceDisconnected()));
|
||||
|
||||
m_enumerateThread.start();
|
||||
}
|
||||
|
||||
RawHIDConnection::~RawHIDConnection()
|
||||
@ -122,47 +58,42 @@ RawHIDConnection::~RawHIDConnection()
|
||||
}
|
||||
}
|
||||
|
||||
void RawHIDConnection::onEnumerationChanged()
|
||||
/**
|
||||
The USB monitor tells us a new device appeared
|
||||
*/
|
||||
void RawHIDConnection::onDeviceConnected()
|
||||
{
|
||||
if (RawHidHandle) // Pip
|
||||
{ // check to see if the connection has closed
|
||||
if (!RawHidHandle->isOpen())
|
||||
{ // connection has closed .. hmmmm, this connection is still showing as open after the USB device is unplugged from PC
|
||||
delete RawHidHandle;
|
||||
RawHidHandle = NULL;
|
||||
|
||||
emit deviceClosed(this);
|
||||
}
|
||||
}
|
||||
emit availableDevChanged(this);
|
||||
}
|
||||
|
||||
/**
|
||||
The USB monitor tells us a device disappeard
|
||||
*/
|
||||
void RawHIDConnection::onDeviceDisconnected()
|
||||
{
|
||||
emit deviceClosed(this);
|
||||
if (enablePolling)
|
||||
emit availableDevChanged(this);
|
||||
}
|
||||
|
||||
/**
|
||||
Returns the list of all currently available devices
|
||||
*/
|
||||
QStringList RawHIDConnection::availableDevices()
|
||||
{
|
||||
QMutexLocker locker(&m_enumMutex);
|
||||
|
||||
QStringList devices;
|
||||
|
||||
if (enablePolling)
|
||||
{
|
||||
pjrc_rawhid dev;
|
||||
|
||||
// open all device we can
|
||||
int opened = dev.open(USB_MAX_DEVICES, USB_VID, USB_PID, USB_USAGE_PAGE, USB_USAGE);
|
||||
|
||||
// for each devices found, get serial number and close it back
|
||||
for (int i = 0; i < opened; i++)
|
||||
{
|
||||
devices.append(dev.getserial(i));
|
||||
dev.close(i);
|
||||
}
|
||||
QList<USBPortInfo> portsList = m_usbMonitor.availableDevices();
|
||||
// We currently list devices by their serial number
|
||||
foreach(USBPortInfo prt, portsList) {
|
||||
devices.append(prt.serialNumber);
|
||||
}
|
||||
|
||||
return devices;
|
||||
}
|
||||
|
||||
|
||||
/// TODO: still needed ???
|
||||
void RawHIDConnection::onRawHidDestroyed(QObject *obj) // Pip
|
||||
{
|
||||
if (!RawHidHandle || RawHidHandle != obj)
|
||||
@ -171,13 +102,11 @@ void RawHIDConnection::onRawHidDestroyed(QObject *obj) // Pip
|
||||
RawHidHandle = NULL;
|
||||
}
|
||||
|
||||
/// TODO: still needed ???
|
||||
void RawHIDConnection::onRawHidClosed()
|
||||
{
|
||||
if (RawHidHandle)
|
||||
{
|
||||
// delete RawHidHandle;
|
||||
// RawHidHandle = NULL;
|
||||
|
||||
emit deviceClosed(this);
|
||||
}
|
||||
}
|
||||
@ -201,6 +130,7 @@ QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
|
||||
return RawHidHandle;
|
||||
}
|
||||
|
||||
|
||||
void RawHIDConnection::closeDevice(const QString &deviceName)
|
||||
{
|
||||
Q_UNUSED(deviceName);
|
||||
|
@ -30,6 +30,7 @@
|
||||
|
||||
#include "rawhid_global.h"
|
||||
#include "rawhid.h"
|
||||
#include "usbmonitor.h"
|
||||
|
||||
#include "coreplugin/iconnection.h"
|
||||
#include <extensionsystem/iplugin.h>
|
||||
@ -41,32 +42,6 @@ class IConnection;
|
||||
class RawHIDConnection;
|
||||
|
||||
|
||||
/**
|
||||
* Helper thread to check on device connection/disconnection
|
||||
* Underlying HID library is not really easy to use,
|
||||
* so we have to poll for device modification in a separate thread
|
||||
*/
|
||||
class RAWHID_EXPORT RawHIDEnumerationThread : public QThread
|
||||
{
|
||||
Q_OBJECT
|
||||
public:
|
||||
RawHIDEnumerationThread(RawHIDConnection *rawhid);
|
||||
virtual ~RawHIDEnumerationThread();
|
||||
|
||||
virtual void run();
|
||||
|
||||
signals:
|
||||
void enumerationChanged();
|
||||
|
||||
protected slots:
|
||||
void onRawHidConnectionDestroyed(QObject *obj); // Pip
|
||||
|
||||
protected:
|
||||
RawHIDConnection *m_rawhid;
|
||||
bool m_running;
|
||||
};
|
||||
|
||||
|
||||
/**
|
||||
* Define a connection via the IConnection interface
|
||||
* Plugin will add a instance of this class to the pool,
|
||||
@ -89,7 +64,7 @@ public:
|
||||
virtual void suspendPolling();
|
||||
virtual void resumePolling();
|
||||
|
||||
bool deviceOpened() { return (RawHidHandle != NULL); } // Pip
|
||||
bool deviceOpened() { return (RawHidHandle != NULL); } // Pip
|
||||
|
||||
signals:
|
||||
void deviceClosed(QObject *obj); // Pip
|
||||
@ -98,10 +73,11 @@ public slots:
|
||||
void onRawHidClosed();
|
||||
|
||||
protected slots:
|
||||
void onEnumerationChanged();
|
||||
void onDeviceConnected();
|
||||
void onDeviceDisconnected();
|
||||
|
||||
private slots:
|
||||
void onRawHidDestroyed(QObject *obj);
|
||||
void onRawHidDestroyed(QObject *obj);
|
||||
|
||||
private:
|
||||
RawHID *RawHidHandle;
|
||||
@ -109,7 +85,7 @@ private:
|
||||
|
||||
protected:
|
||||
QMutex m_enumMutex;
|
||||
RawHIDEnumerationThread m_enumerateThread;
|
||||
USBMonitor m_usbMonitor;
|
||||
bool m_deviceOpened;
|
||||
};
|
||||
|
||||
|
@ -42,12 +42,12 @@ void USBMonitor::deviceEventReceived() {
|
||||
|
||||
dev = udev_monitor_receive_device(this->monitor);
|
||||
if (dev) {
|
||||
printf("Got Device");
|
||||
printf("------- Got Device Event");
|
||||
QString action = QString(udev_device_get_action(dev));
|
||||
if (action == "add") {
|
||||
QString devtype = QString(udev_device_get_devtype(dev));
|
||||
if (action == "add" && devtype == "usb_device") {
|
||||
emit deviceDiscovered(makePortInfo(dev));
|
||||
|
||||
} else if (action == "remove"){
|
||||
} else if (action == "remove" && devtype == "usb_device"){
|
||||
emit deviceRemoved(makePortInfo(dev));
|
||||
}
|
||||
|
||||
@ -67,8 +67,8 @@ USBMonitor::USBMonitor(QObject *parent): QThread(parent) {
|
||||
this->context = udev_new();
|
||||
|
||||
this->monitor = udev_monitor_new_from_netlink(this->context, "udev");
|
||||
// udev_monitor_filter_add_match_subsystem_devtype(
|
||||
// this->monitor, "hidraw", NULL);
|
||||
udev_monitor_filter_add_match_subsystem_devtype(
|
||||
this->monitor, "usb", NULL);
|
||||
udev_monitor_enable_receiving(this->monitor);
|
||||
this->monitorNotifier = new QSocketNotifier(
|
||||
udev_monitor_get_fd(this->monitor), QSocketNotifier::Read, this);
|
||||
@ -95,7 +95,8 @@ QList<USBPortInfo> USBMonitor::availableDevices()
|
||||
struct udev_device *dev;
|
||||
|
||||
enumerate = udev_enumerate_new(this->context);
|
||||
udev_enumerate_add_match_subsystem(enumerate,"hidwraw");
|
||||
// udev_enumerate_add_match_subsystem(enumerate,"usb");
|
||||
udev_enumerate_add_match_sysattr(enumerate, "idVendor", "20a0");
|
||||
udev_enumerate_scan_devices(enumerate);
|
||||
devices = udev_enumerate_get_list_entry(enumerate);
|
||||
// Will use the 'native' udev functions to loop:
|
||||
@ -113,6 +114,7 @@ QList<USBPortInfo> USBMonitor::availableDevices()
|
||||
subsystem/devtype pair of "usb"/"usb_device". This will
|
||||
be several levels up the tree, but the function will find
|
||||
it.*/
|
||||
/*
|
||||
dev = udev_device_get_parent_with_subsystem_devtype(
|
||||
dev,
|
||||
"usb",
|
||||
@ -121,24 +123,10 @@ QList<USBPortInfo> USBMonitor::availableDevices()
|
||||
printf("Unable to find parent usb device.");
|
||||
return devicesList;
|
||||
}
|
||||
*/
|
||||
|
||||
/* From here, we can call get_sysattr_value() for each file
|
||||
in the device's /sys entry. The strings passed into these
|
||||
functions (idProduct, idVendor, serial, etc.) correspond
|
||||
directly to the files in the directory which represents
|
||||
the USB device. Note that USB strings are Unicode, UCS2
|
||||
encoded, but the strings returned from
|
||||
udev_device_get_sysattr_value() are UTF-8 encoded. */
|
||||
printf(" VID/PID: %s %s\n",
|
||||
udev_device_get_sysattr_value(dev,"idVendor"),
|
||||
udev_device_get_sysattr_value(dev, "idProduct"));
|
||||
printf(" %s\n %s\n",
|
||||
udev_device_get_sysattr_value(dev,"manufacturer"),
|
||||
udev_device_get_sysattr_value(dev,"product"));
|
||||
printf(" serial: %s\n",
|
||||
udev_device_get_sysattr_value(dev, "serial"));
|
||||
devicesList.append(makePortInfo(dev));
|
||||
udev_device_unref(dev);
|
||||
udev_device_unref(dev);
|
||||
}
|
||||
/* free the enumerator object */
|
||||
udev_enumerate_unref(enumerate);
|
||||
@ -171,6 +159,21 @@ USBPortInfo USBMonitor::makePortInfo(struct udev_device *dev)
|
||||
printf(" Subsystem: %s", udev_device_get_subsystem(dev));
|
||||
printf(" Devtype: %s", udev_device_get_devtype(dev));
|
||||
printf(" Action: %s", udev_device_get_action(dev));
|
||||
/* From here, we can call get_sysattr_value() for each file
|
||||
in the device's /sys entry. The strings passed into these
|
||||
functions (idProduct, idVendor, serial, etc.) correspond
|
||||
directly to the files in the directory which represents
|
||||
the USB device. Note that USB strings are Unicode, UCS2
|
||||
encoded, but the strings returned from
|
||||
udev_device_get_sysattr_value() are UTF-8 encoded. */
|
||||
printf(" VID/PID: %s %s",
|
||||
udev_device_get_sysattr_value(dev,"idVendor"),
|
||||
udev_device_get_sysattr_value(dev, "idProduct"));
|
||||
printf(" %s - %s",
|
||||
udev_device_get_sysattr_value(dev,"manufacturer"),
|
||||
udev_device_get_sysattr_value(dev,"product"));
|
||||
printf(" serial: %s",
|
||||
udev_device_get_sysattr_value(dev, "serial"));
|
||||
|
||||
prtInfo.vendorID = QString(udev_device_get_sysattr_value(dev, "idVendor")).toInt();
|
||||
prtInfo.productID = QString(udev_device_get_sysattr_value(dev, "idProduct")).toInt();
|
||||
|
Loading…
x
Reference in New Issue
Block a user