1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-18 03:52:11 +01:00

Now able (hopefully) to unplug USB device from PC whilst the GCS is still connected to it via USB .. in WINDOWS ONLY.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@2913 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
pip 2011-02-28 00:34:31 +00:00 committed by pip
parent 011abe3117
commit a2cf1c4673
4 changed files with 195 additions and 107 deletions

View File

@ -45,6 +45,7 @@ static const int WRITE_SIZE = 64;
// *********************************************************************************
/** /**
* Thread to desynchronize reading from the device * Thread to desynchronize reading from the device
@ -85,6 +86,8 @@ protected:
}; };
// *********************************************************************************
/** /**
* This class is nearly the same than RawHIDReadThread but for writing * This class is nearly the same than RawHIDReadThread but for writing
*/ */
@ -126,7 +129,7 @@ protected:
bool m_running; bool m_running;
}; };
// *********************************************************************************
RawHIDReadThread::RawHIDReadThread(RawHID *hid) RawHIDReadThread::RawHIDReadThread(RawHID *hid)
: m_hid(hid), : m_hid(hid),
@ -206,6 +209,8 @@ RawHIDWriteThread::RawHIDWriteThread(RawHID *hid)
{ {
} }
// *********************************************************************************
RawHIDWriteThread::~RawHIDWriteThread() RawHIDWriteThread::~RawHIDWriteThread()
{ {
m_running = false; m_running = false;
@ -283,20 +288,28 @@ qint64 RawHIDWriteThread::getBytesToWrite()
return m_writeBuffer.size(); return m_writeBuffer.size();
} }
// *********************************************************************************
RawHID::RawHID(const QString &deviceName) RawHID::RawHID(const QString &deviceName)
:QIODevice(), :QIODevice(),
serialNumber(deviceName), serialNumber(deviceName),
m_deviceNo(-1), m_deviceNo(-1),
m_readThread(NULL), m_readThread(NULL),
m_writeThread(NULL) m_writeThread(NULL),
m_mutex(NULL)
{ {
m_mutex = new QMutex(QMutex::Recursive);
// detect if the USB device is unplugged
QObject::connect(&dev, SIGNAL(deviceUnplugged(int)), this, SLOT(onDeviceUnplugged(int)));
//find the device the user want to open and close the other //find the device the user want to open and close the other
int opened = dev.open(USB_MAX_DEVICES, USB_VID, USB_PID, USB_USAGE_PAGE, USB_USAGE); 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 //for each devices found, get serial number and close
for (int i=0; i<opened; i++) for (int i = 0; i < opened; i++)
{ {
if(deviceName == dev.getserial(i)) if (deviceName == dev.getserial(i))
m_deviceNo = i; m_deviceNo = i;
else else
dev.close(i); dev.close(i);
@ -318,46 +331,72 @@ RawHID::RawHID(const QString &deviceName)
RawHID::~RawHID() RawHID::~RawHID()
{ {
if(m_readThread) dev.close(m_deviceNo);
if (m_readThread)
delete m_readThread; delete m_readThread;
if(m_writeThread) if (m_writeThread)
delete m_writeThread; delete m_writeThread;
} }
void RawHID::onDeviceUnplugged(int num)
{
if (num != m_deviceNo)
return;
// the USB device has been unplugged
close();
}
bool RawHID::open(OpenMode mode) bool RawHID::open(OpenMode mode)
{ {
if(m_deviceNo < 0) QMutexLocker locker(m_mutex);
if (m_deviceNo < 0)
return false; return false;
QIODevice::open(mode); QIODevice::open(mode);
if(!m_readThread) if (!m_readThread)
m_readThread = new RawHIDReadThread(this); m_readThread = new RawHIDReadThread(this);
if(!m_writeThread) if (!m_writeThread)
m_writeThread = new RawHIDWriteThread(this); m_writeThread = new RawHIDWriteThread(this);
if (m_readThread) m_readThread->start(); // Pip
if (m_writeThread) m_writeThread->start(); // Pip
return true; return true;
} }
void RawHID::close() void RawHID::close()
{ {
emit aboutToClose(); emit aboutToClose();
if(m_readThread) {
m_mutex->lock();
if (m_readThread)
{
m_readThread->terminate(); m_readThread->terminate();
delete m_readThread; // calls wait delete m_readThread; // calls wait
m_readThread = NULL; m_readThread = NULL;
} }
if(m_writeThread) { if (m_writeThread)
{
m_writeThread->terminate(); m_writeThread->terminate();
delete m_writeThread; delete m_writeThread;
m_writeThread = NULL; m_writeThread = NULL;
} }
dev.close(m_deviceNo); dev.close(m_deviceNo);
m_mutex->unlock();
emit closed();
QIODevice::close(); QIODevice::close();
} }
@ -368,21 +407,42 @@ bool RawHID::isSequential() const
qint64 RawHID::bytesAvailable() const qint64 RawHID::bytesAvailable() const
{ {
QMutexLocker locker(m_mutex);
if (!m_readThread)
return -1;
return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable(); return m_readThread->getBytesAvailable() + QIODevice::bytesAvailable();
} }
qint64 RawHID::bytesToWrite() const qint64 RawHID::bytesToWrite() const
{ {
QMutexLocker locker(m_mutex);
if (!m_writeThread)
return -1;
return m_writeThread->getBytesToWrite() + QIODevice::bytesToWrite(); return m_writeThread->getBytesToWrite() + QIODevice::bytesToWrite();
} }
qint64 RawHID::readData(char *data, qint64 maxSize) qint64 RawHID::readData(char *data, qint64 maxSize)
{ {
QMutexLocker locker(m_mutex);
if (!m_readThread || !data)
return -1;
return m_readThread->getReadData(data, maxSize); return m_readThread->getReadData(data, maxSize);
} }
qint64 RawHID::writeData(const char *data, qint64 maxSize) qint64 RawHID::writeData(const char *data, qint64 maxSize)
{ {
QMutexLocker locker(m_mutex);
if (!m_writeThread || !data)
return -1;
return m_writeThread->pushDataToWrite(data, maxSize); return m_writeThread->pushDataToWrite(data, maxSize);
} }
// *********************************************************************************

View File

@ -47,6 +47,8 @@ class RawHIDWriteThread;
*/ */
class RAWHID_EXPORT RawHID : public QIODevice class RAWHID_EXPORT RawHID : public QIODevice
{ {
Q_OBJECT
friend class RawHIDReadThread; friend class RawHIDReadThread;
friend class RawHIDWriteThread; friend class RawHIDWriteThread;
@ -59,6 +61,12 @@ public:
virtual void close(); virtual void close();
virtual bool isSequential() const; virtual bool isSequential() const;
signals:
void closed();
public slots:
void onDeviceUnplugged(int num);
protected: protected:
virtual qint64 readData(char *data, qint64 maxSize); virtual qint64 readData(char *data, qint64 maxSize);
virtual qint64 writeData(const char *data, qint64 maxSize); virtual qint64 writeData(const char *data, qint64 maxSize);
@ -72,6 +80,8 @@ protected:
RawHIDReadThread *m_readThread; RawHIDReadThread *m_readThread;
RawHIDWriteThread *m_writeThread; RawHIDWriteThread *m_writeThread;
QMutex *m_mutex;
}; };
#endif // RAWHID_H #endif // RAWHID_H

View File

@ -171,6 +171,17 @@ void RawHIDConnection::onRawHidDestroyed(QObject *obj) // Pip
RawHidHandle = NULL; RawHidHandle = NULL;
} }
void RawHIDConnection::onRawHidClosed()
{
if (RawHidHandle)
{
// delete RawHidHandle;
// RawHidHandle = NULL;
emit deviceClosed(this);
}
}
QIODevice *RawHIDConnection::openDevice(const QString &deviceName) QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
{ {
//added by andrew //added by andrew
@ -181,7 +192,11 @@ QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
//return new RawHID(deviceName); //return new RawHID(deviceName);
RawHidHandle = new RawHID(deviceName); RawHidHandle = new RawHID(deviceName);
connect(RawHidHandle, SLOT(destroyed(QObject *)), this, SLOT(onRawHidDestroyed(QObject *))); // Pip if (RawHidHandle)
{
connect(RawHidHandle, SIGNAL(closed()), this, SLOT(onRawHidClosed()), Qt::QueuedConnection);
connect(RawHidHandle, SIGNAL(destroyed(QObject *)), this, SLOT(onRawHidDestroyed(QObject *)), Qt::QueuedConnection);
}
return RawHidHandle; return RawHidHandle;
} }
@ -197,7 +212,7 @@ void RawHIDConnection::closeDevice(const QString &deviceName)
delete RawHidHandle; delete RawHidHandle;
RawHidHandle = NULL; RawHidHandle = NULL;
emit deviceClosed(this); // Pip emit deviceClosed(this);
} }
//end added by andrew //end added by andrew
} }

View File

@ -94,6 +94,9 @@ public:
signals: signals:
void deviceClosed(QObject *obj); // Pip void deviceClosed(QObject *obj); // Pip
public slots:
void onRawHidClosed();
protected slots: protected slots:
void onEnumerationChanged(); void onEnumerationChanged();