1
0
mirror of https://bitbucket.org/librepilot/librepilot.git synced 2025-01-29 14:52:12 +01:00

Attempt to fix GCS crashes on USB disconnect: please confirm on other operating systems it is still working fine in all situations.

git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@3066 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
edouard 2011-03-25 10:59:24 +00:00 committed by edouard
parent 2e5863281c
commit 9d0ce95b37
8 changed files with 214 additions and 271 deletions

View File

@ -106,50 +106,44 @@ void ConnectionManager::init()
*/ */
bool ConnectionManager::connectDevice() bool ConnectionManager::connectDevice()
{ {
devListItem connection_device = findDevice(m_availableDevList->currentText()); devListItem connection_device = findDevice(m_availableDevList->currentText());
if (!connection_device.connection) if (!connection_device.connection)
return false; return false;
QIODevice *io_dev = connection_device.connection->openDevice(connection_device.devName); QIODevice *io_dev = connection_device.connection->openDevice(connection_device.devName);
if (!io_dev) if (!io_dev)
return false; return false;
io_dev->open(QIODevice::ReadWrite); io_dev->open(QIODevice::ReadWrite);
// check if opening the device worked // check if opening the device worked
if (!io_dev->isOpen()) if (!io_dev->isOpen()) {
{ qDebug() << "Error: io_dev->isOpen() returned FALSE .. could not open connection to " << connection_device.devName
qDebug() << "Error: io_dev->isOpen() returned FALSE .. could not open connection to " << connection_device.devName << ": " << io_dev->errorString();
<< ": " << io_dev->errorString();
// close the device // close the device
try // EDOUARD: why do we close if we could not open ???
{ try {
connection_device.connection->closeDevice(connection_device.devName); connection_device.connection->closeDevice(connection_device.devName);
} }
catch (...) catch (...) { // handle exception
{ // handle exception qDebug() << "Exception: connection_device.connection->closeDevice(" << connection_device.devName << ")";
qDebug() << "Exception: connection_device.connection->closeDevice(" << connection_device.devName << ")"; }
} return false;
}
return false; // we appear to have connected to the device OK
} // remember the connection/device details
m_connectionDevice = connection_device;
m_ioDev = io_dev;
// we appear to have connected to the device OK connect(m_connectionDevice.connection, SIGNAL(destroyed(QObject *)), this, SLOT(onConnectionDestroyed(QObject *)), Qt::QueuedConnection);
// remember the connection/device details // signal interested plugins that we connected to the device
m_connectionDevice = connection_device; emit deviceConnected(m_ioDev);
m_ioDev = io_dev; m_connectBtn->setText("Disconnect");
m_availableDevList->setEnabled(false);
connect(m_connectionDevice.connection, SIGNAL(destroyed(QObject *)), this, SLOT(onConnectionDestroyed(QObject *)), Qt::QueuedConnection); return true;
m_connectBtn->setText("Disconnect");
m_availableDevList->setEnabled(false);
// signal interested plugins that we connected to the device
emit deviceConnected(m_ioDev);
return true;
} }
/** /**
@ -158,30 +152,32 @@ bool ConnectionManager::connectDevice()
*/ */
bool ConnectionManager::disconnectDevice() bool ConnectionManager::disconnectDevice()
{ {
if (!m_ioDev) if (!m_ioDev) {
{ // apparently we are already disconnected // apparently we are already disconnected: this can
// happen if a plugin tries to force a disconnect whereas
// we are not connected. Just return.
return false;
}
m_connectionDevice.connection = NULL; // We are connected - disconnect from the device
m_ioDev = NULL;
return false; // signal interested plugins that user is disconnecting his device
} emit deviceAboutToDisconnect();
// we appear to be connected - disconnect from the device try {
if (m_connectionDevice.connection)
m_connectionDevice.connection->closeDevice(m_connectionDevice.devName);
} catch (...) { // handle exception
qDebug() << "Exception: m_connectionDevice.connection->closeDevice(" << m_connectionDevice.devName << ")";
}
try m_connectionDevice.connection = NULL;
{ m_ioDev = NULL;
if (m_connectionDevice.connection)
m_connectionDevice.connection->closeDevice(m_connectionDevice.devName);
}
catch (...)
{ // handle exception
qDebug() << "Exception: m_connectionDevice.connection->closeDevice(" << m_connectionDevice.devName << ")";
}
onConnectionClosed(m_connectionDevice.connection); m_connectBtn->setText("Connect");
m_availableDevList->setEnabled(true);
return true; return true;
} }
/** /**
@ -222,24 +218,11 @@ void ConnectionManager::aboutToRemoveObject(QObject *obj)
m_connectionsList.removeAt(m_connectionsList.indexOf(connection)); m_connectionsList.removeAt(m_connectionsList.indexOf(connection));
} }
void ConnectionManager::onConnectionClosed(QObject *obj) // Pip
{
if (!m_connectionDevice.connection || m_connectionDevice.connection != obj)
return;
m_connectionDevice.connection = NULL;
m_ioDev = NULL;
m_connectBtn->setText("Connect");
m_availableDevList->setEnabled(true);
// signal interested plugins that user is disconnecting his device
emit deviceDisconnected();
}
void ConnectionManager::onConnectionDestroyed(QObject *obj) // Pip void ConnectionManager::onConnectionDestroyed(QObject *obj) // Pip
{ {
onConnectionClosed(obj); //onConnectionClosed(obj);
disconnectDevice();
} }
/** /**
@ -247,13 +230,14 @@ void ConnectionManager::onConnectionDestroyed(QObject *obj) // Pip
*/ */
void ConnectionManager::onConnectPressed() void ConnectionManager::onConnectPressed()
{ {
if (!m_ioDev || !m_connectionDevice.connection) // Check if we have a ioDev already created:
{ // connecting if (!m_ioDev)
connectDevice(); { // connecting
connectDevice();
} }
else else
{ // disconnecting { // disconnecting
disconnectDevice(); disconnectDevice();
} }
} }
@ -318,7 +302,8 @@ void ConnectionManager::unregisterAll(IConnection *connection)
{ {
if (m_connectionDevice.connection && m_connectionDevice.connection == connection) if (m_connectionDevice.connection && m_connectionDevice.connection == connection)
{ // we are currently using the one we are about to erase { // we are currently using the one we are about to erase
onConnectionClosed(m_connectionDevice.connection); //onConnectionClosed(m_connectionDevice.connection);
disconnectDevice();
} }
iter = m_devList.erase(iter); iter = m_devList.erase(iter);

View File

@ -81,7 +81,7 @@ protected:
signals: signals:
void deviceConnected(QIODevice *dev); void deviceConnected(QIODevice *dev);
void deviceDisconnected(); void deviceAboutToDisconnect();
private slots: private slots:
void objectAdded(QObject *obj); void objectAdded(QObject *obj);
@ -90,7 +90,7 @@ private slots:
void onConnectPressed(); void onConnectPressed();
void devChanged(IConnection *connection); void devChanged(IConnection *connection);
void onConnectionClosed(QObject *obj); // void onConnectionClosed(QObject *obj);
void onConnectionDestroyed(QObject *obj); void onConnectionDestroyed(QObject *obj);
protected: protected:

View File

@ -94,7 +94,7 @@ QStringList RawHIDConnection::availableDevices()
QIODevice *RawHIDConnection::openDevice(const QString &deviceName) QIODevice *RawHIDConnection::openDevice(const QString &deviceName)
{ {
//added by andrew //added by andrew
if (RawHidHandle) if (RawHidHandle)
closeDevice(deviceName); closeDevice(deviceName);
//end added by andrew //end added by andrew

View File

@ -74,7 +74,7 @@ ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent)
// running the scopes if we are not connected and not replaying logs // running the scopes if we are not connected and not replaying logs
// Also listen to disconnect actions from the user // Also listen to disconnect actions from the user
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(stopPlotting())); connect(cm, SIGNAL(deviceAboutToDisconnect()), this, SLOT(stopPlotting()));
connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(startPlotting())); connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(startPlotting()));
m_csvLoggingStarted=0; m_csvLoggingStarted=0;
@ -89,7 +89,7 @@ ScopeGadgetWidget::ScopeGadgetWidget(QWidget *parent) : QwtPlot(parent)
m_csvLoggingStartTime = QDateTime::currentDateTime(); m_csvLoggingStartTime = QDateTime::currentDateTime();
//Listen to autopilot connection events //Listen to autopilot connection events
connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(csvLoggingDisconnect())); connect(cm, SIGNAL(deviceAboutToDisconnect()), this, SLOT(csvLoggingDisconnect()));
connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(csvLoggingConnect())); connect(cm, SIGNAL(deviceConnected(QIODevice*)), this, SLOT(csvLoggingConnect()));
} }

View File

@ -56,6 +56,7 @@ const quint8 UAVTalk::crc_table[256] = {
UAVTalk::UAVTalk(QIODevice* iodev, UAVObjectManager* objMngr) UAVTalk::UAVTalk(QIODevice* iodev, UAVObjectManager* objMngr)
{ {
io = iodev; io = iodev;
this->objMngr = objMngr; this->objMngr = objMngr;
rxState = STATE_SYNC; rxState = STATE_SYNC;
@ -67,23 +68,17 @@ UAVTalk::UAVTalk(QIODevice* iodev, UAVObjectManager* objMngr)
memset(&stats, 0, sizeof(ComStats)); memset(&stats, 0, sizeof(ComStats));
if (io) // Pip connect(io, SIGNAL(readyRead()), this, SLOT(processInputStream()));
connect(io, SIGNAL(readyRead()), this, SLOT(processInputStream()));
} }
UAVTalk::~UAVTalk() UAVTalk::~UAVTalk()
{ {
// Pip
mutex->lock();
io = NULL;
objMngr = NULL;
mutex->unlock();
// According to Qt, it is not necessary to disconnect upon // According to Qt, it is not necessary to disconnect upon
// object deletion. // object deletion.
//disconnect(io, SIGNAL(readyRead()), this, SLOT(processInputStream())); //disconnect(io, SIGNAL(readyRead()), this, SLOT(processInputStream()));
} }
/** /**
* Reset the statistics counters * Reset the statistics counters
*/ */
@ -109,24 +104,9 @@ void UAVTalk::processInputStream()
{ {
quint8 tmp; quint8 tmp;
while (true) while (io->bytesAvailable() > 0)
{ {
mutex->lock(); // Pip io->read((char*)&tmp, 1);
if (!io)
{
mutex->unlock();
break;
}
if (!io->isOpen() || io->bytesAvailable() <= 0)
{
mutex->unlock();
break;
}
qint64 bytes_read = io->read((char*)&tmp, sizeof(tmp));
mutex->unlock();
if (bytes_read <= 0) break; // Pip
processInputByte(tmp); processInputByte(tmp);
} }
} }
@ -216,9 +196,6 @@ bool UAVTalk::objectTransaction(UAVObject* obj, quint8 type, bool allInstances)
*/ */
bool UAVTalk::processInputByte(quint8 rxbyte) bool UAVTalk::processInputByte(quint8 rxbyte)
{ {
if (!objMngr || !io) // Pip
return false;
// Update stats // Update stats
stats.rxBytes++; stats.rxBytes++;
@ -429,10 +406,7 @@ bool UAVTalk::receiveObject(quint8 type, quint32 objId, quint16 instId, quint8*
{ {
Q_UNUSED(length); Q_UNUSED(length);
if (!objMngr || !io) // Pip UAVObject* obj = NULL;
return false;
UAVObject* obj = NULL;
bool error = false; bool error = false;
bool allInstances = (instId == ALL_INSTANCES? true : false); bool allInstances = (instId == ALL_INSTANCES? true : false);
@ -531,10 +505,7 @@ bool UAVTalk::receiveObject(quint8 type, quint32 objId, quint16 instId, quint8*
*/ */
UAVObject* UAVTalk::updateObject(quint32 objId, quint16 instId, quint8* data) UAVObject* UAVTalk::updateObject(quint32 objId, quint16 instId, quint8* data)
{ {
if (!objMngr || !io) // Pip // Get object
return NULL;
// Get object
UAVObject* obj = objMngr->getObject(objId, instId); UAVObject* obj = objMngr->getObject(objId, instId);
// If the instance does not exist create it // If the instance does not exist create it
if (obj == NULL) if (obj == NULL)
@ -589,10 +560,7 @@ void UAVTalk::updateAck(UAVObject* obj)
*/ */
bool UAVTalk::transmitObject(UAVObject* obj, quint8 type, bool allInstances) bool UAVTalk::transmitObject(UAVObject* obj, quint8 type, bool allInstances)
{ {
if (!objMngr || !io) // Pip // If all instances are requested on a single instance object it is an error
return false;
// If all instances are requested on a single instance object it is an error
if (allInstances && obj->isSingleInstance()) if (allInstances && obj->isSingleInstance())
{ {
allInstances = false; allInstances = false;
@ -654,10 +622,7 @@ bool UAVTalk::transmitSingleObject(UAVObject* obj, quint8 type, bool allInstance
quint16 instId; quint16 instId;
quint16 allInstId = ALL_INSTANCES; quint16 allInstId = ALL_INSTANCES;
if (!objMngr || !io) // Pip // Setup type and object id fields
return false;
// Setup type and object id fields
objId = obj->getObjID(); objId = obj->getObjID();
txBuffer[0] = SYNC_VAL; txBuffer[0] = SYNC_VAL;
txBuffer[1] = type; txBuffer[1] = type;

View File

@ -1,127 +1,127 @@
/** /**
****************************************************************************** ******************************************************************************
* *
* @file uavtalk.h * @file uavtalk.h
* @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010. * @author The OpenPilot Team, http://www.openpilot.org Copyright (C) 2010.
* @addtogroup GCSPlugins GCS Plugins * @addtogroup GCSPlugins GCS Plugins
* @{ * @{
* @addtogroup UAVTalkPlugin UAVTalk Plugin * @addtogroup UAVTalkPlugin UAVTalk Plugin
* @{ * @{
* @brief The UAVTalk protocol plugin * @brief The UAVTalk protocol plugin
*****************************************************************************/ *****************************************************************************/
/* /*
* This program is free software; you can redistribute it and/or modify * This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by * it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 3 of the License, or * the Free Software Foundation; either version 3 of the License, or
* (at your option) any later version. * (at your option) any later version.
* *
* This program is distributed in the hope that it will be useful, but * This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY * WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
* for more details. * for more details.
* *
* You should have received a copy of the GNU General Public License along * You should have received a copy of the GNU General Public License along
* with this program; if not, write to the Free Software Foundation, Inc., * with this program; if not, write to the Free Software Foundation, Inc.,
* 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*/ */
#ifndef UAVTALK_H #ifndef UAVTALK_H
#define UAVTALK_H #define UAVTALK_H
#include <QIODevice> #include <QIODevice>
#include <QMutex> #include <QMutex>
#include <QMutexLocker> #include <QMutexLocker>
#include <QSemaphore> #include <QSemaphore>
#include "uavobjectmanager.h" #include "uavobjectmanager.h"
#include "uavtalk_global.h" #include "uavtalk_global.h"
class UAVTALK_EXPORT UAVTalk: public QObject class UAVTALK_EXPORT UAVTalk: public QObject
{ {
Q_OBJECT Q_OBJECT
public: public:
typedef struct { typedef struct {
quint32 txBytes; quint32 txBytes;
quint32 rxBytes; quint32 rxBytes;
quint32 txObjectBytes; quint32 txObjectBytes;
quint32 rxObjectBytes; quint32 rxObjectBytes;
quint32 rxObjects; quint32 rxObjects;
quint32 txObjects; quint32 txObjects;
quint32 txErrors; quint32 txErrors;
quint32 rxErrors; quint32 rxErrors;
} ComStats; } ComStats;
UAVTalk(QIODevice* iodev, UAVObjectManager* objMngr); UAVTalk(QIODevice* iodev, UAVObjectManager* objMngr);
~UAVTalk(); ~UAVTalk();
bool sendObject(UAVObject* obj, bool acked, bool allInstances); bool sendObject(UAVObject* obj, bool acked, bool allInstances);
bool sendObjectRequest(UAVObject* obj, bool allInstances); bool sendObjectRequest(UAVObject* obj, bool allInstances);
void cancelTransaction(); void cancelTransaction();
ComStats getStats(); ComStats getStats();
void resetStats(); void resetStats();
signals: signals:
void transactionCompleted(UAVObject* obj); void transactionCompleted(UAVObject* obj);
private slots: private slots:
void processInputStream(void); void processInputStream(void);
private: private:
// Constants // Constants
static const int TYPE_MASK = 0xFC; static const int TYPE_MASK = 0xFC;
static const int TYPE_VER = 0x20; static const int TYPE_VER = 0x20;
static const int TYPE_OBJ = (TYPE_VER | 0x00); static const int TYPE_OBJ = (TYPE_VER | 0x00);
static const int TYPE_OBJ_REQ = (TYPE_VER | 0x01); static const int TYPE_OBJ_REQ = (TYPE_VER | 0x01);
static const int TYPE_OBJ_ACK = (TYPE_VER | 0x02); static const int TYPE_OBJ_ACK = (TYPE_VER | 0x02);
static const int TYPE_ACK = (TYPE_VER | 0x03); static const int TYPE_ACK = (TYPE_VER | 0x03);
static const int MIN_HEADER_LENGTH = 8; // sync(1), type (1), size(2), object ID(4) static const int MIN_HEADER_LENGTH = 8; // sync(1), type (1), size(2), object ID(4)
static const int MAX_HEADER_LENGTH = 10; // sync(1), type (1), size(2), object ID (4), instance ID(2, not used in single objects) static const int MAX_HEADER_LENGTH = 10; // sync(1), type (1), size(2), object ID (4), instance ID(2, not used in single objects)
static const int CHECKSUM_LENGTH = 1; static const int CHECKSUM_LENGTH = 1;
static const int MAX_PAYLOAD_LENGTH = 256; static const int MAX_PAYLOAD_LENGTH = 256;
static const int MAX_PACKET_LENGTH = (MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH + CHECKSUM_LENGTH); static const int MAX_PACKET_LENGTH = (MAX_HEADER_LENGTH + MAX_PAYLOAD_LENGTH + CHECKSUM_LENGTH);
static const quint16 ALL_INSTANCES = 0xFFFF; static const quint16 ALL_INSTANCES = 0xFFFF;
static const int TX_BUFFER_SIZE = 2*1024; static const int TX_BUFFER_SIZE = 2*1024;
static const quint8 crc_table[256]; static const quint8 crc_table[256];
// Types // Types
typedef enum {STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS} RxStateType; typedef enum {STATE_SYNC, STATE_TYPE, STATE_SIZE, STATE_OBJID, STATE_INSTID, STATE_DATA, STATE_CS} RxStateType;
// Variables // Variables
QIODevice* io; QIODevice* io;
UAVObjectManager* objMngr; UAVObjectManager* objMngr;
QMutex* mutex; QMutex* mutex;
UAVObject* respObj; UAVObject* respObj;
bool respAllInstances; bool respAllInstances;
quint8 rxBuffer[MAX_PACKET_LENGTH]; quint8 rxBuffer[MAX_PACKET_LENGTH];
quint8 txBuffer[MAX_PACKET_LENGTH]; quint8 txBuffer[MAX_PACKET_LENGTH];
// Variables used by the receive state machine // Variables used by the receive state machine
quint8 rxTmpBuffer[4]; quint8 rxTmpBuffer[4];
quint8 rxType; quint8 rxType;
quint32 rxObjId; quint32 rxObjId;
quint16 rxInstId; quint16 rxInstId;
quint16 rxLength; quint16 rxLength;
quint16 rxPacketLength; quint16 rxPacketLength;
quint8 rxCSPacket, rxCS; quint8 rxCSPacket, rxCS;
qint32 rxCount; qint32 rxCount;
qint32 packetSize; qint32 packetSize;
RxStateType rxState; RxStateType rxState;
ComStats stats; ComStats stats;
// Methods // Methods
bool objectTransaction(UAVObject* obj, quint8 type, bool allInstances); bool objectTransaction(UAVObject* obj, quint8 type, bool allInstances);
bool processInputByte(quint8 rxbyte); bool processInputByte(quint8 rxbyte);
bool receiveObject(quint8 type, quint32 objId, quint16 instId, quint8* data, qint32 length); bool receiveObject(quint8 type, quint32 objId, quint16 instId, quint8* data, qint32 length);
UAVObject* updateObject(quint32 objId, quint16 instId, quint8* data); UAVObject* updateObject(quint32 objId, quint16 instId, quint8* data);
void updateAck(UAVObject* obj); void updateAck(UAVObject* obj);
bool transmitObject(UAVObject* obj, quint8 type, bool allInstances); bool transmitObject(UAVObject* obj, quint8 type, bool allInstances);
bool transmitSingleObject(UAVObject* obj, quint8 type, bool allInstances); bool transmitSingleObject(UAVObject* obj, quint8 type, bool allInstances);
quint8 updateCRC(quint8 crc, const quint8 data); quint8 updateCRC(quint8 crc, const quint8 data);
quint8 updateCRC(quint8 crc, const quint8* data, qint32 length); quint8 updateCRC(quint8 crc, const quint8* data, qint32 length);
}; };
#endif // UAVTALK_H #endif // UAVTALK_H

View File

@ -31,27 +31,29 @@
UAVTalkPlugin::UAVTalkPlugin() UAVTalkPlugin::UAVTalkPlugin()
{ {
telMngr = NULL; // Pip
} }
UAVTalkPlugin::~UAVTalkPlugin() UAVTalkPlugin::~UAVTalkPlugin()
{ {
if (telMngr) // Pip
telMngr->stop();
} }
void UAVTalkPlugin::extensionsInitialized() void UAVTalkPlugin::extensionsInitialized()
{ {
// Get UAVObjectManager instance
ExtensionSystem::PluginManager* pm = ExtensionSystem::PluginManager::instance();
objMngr = pm->getObject<UAVObjectManager>();
// Create TelemetryManager // Create TelemetryManager
telMngr = new TelemetryManager(); telMngr = new TelemetryManager();
if (!telMngr) return; // Pip
addAutoReleasedObject(telMngr); addAutoReleasedObject(telMngr);
// Connect to connection manager so we get notified when the user connect to his device // Connect to connection manager so we get notified when the user connect to his device
Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager(); Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
QObject::connect(cm, SIGNAL(deviceConnected(QIODevice *)), QObject::connect(cm, SIGNAL(deviceConnected(QIODevice *)),
this, SLOT(onDeviceConnect(QIODevice *))); this, SLOT(onDeviceConnect(QIODevice *)));
QObject::connect(cm, SIGNAL(deviceDisconnected()), QObject::connect(cm, SIGNAL(deviceAboutToDisconnect()),
this, SLOT(onDeviceDisconnect())); this, SLOT(onDeviceDisconnect()));
} }
@ -65,18 +67,17 @@ bool UAVTalkPlugin::initialize(const QStringList & arguments, QString * errorStr
void UAVTalkPlugin::shutdown() void UAVTalkPlugin::shutdown()
{ {
} }
void UAVTalkPlugin::onDeviceConnect(QIODevice *dev) void UAVTalkPlugin::onDeviceConnect(QIODevice *dev)
{ {
if (telMngr) // Pip telMngr->start(dev);
telMngr->start(dev);
} }
void UAVTalkPlugin::onDeviceDisconnect() void UAVTalkPlugin::onDeviceDisconnect()
{ {
if (telMngr) // Pip telMngr->stop();
telMngr->stop();
} }
Q_EXPORT_PLUGIN(UAVTalkPlugin) Q_EXPORT_PLUGIN(UAVTalkPlugin)

View File

@ -43,14 +43,6 @@ UploaderGadgetWidget::UploaderGadgetWidget(QWidget *parent) : QWidget(parent)
connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect())); connect(telMngr, SIGNAL(connected()), this, SLOT(onAutopilotConnect()));
connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect())); connect(telMngr, SIGNAL(disconnected()), this, SLOT(onAutopilotDisconnect()));
// Note: remove listening to the connection manager, it overlaps with
// listening to the telemetry manager, we should only listen to one, not both.
// Also listen to disconnect actions from the user:
// Core::ConnectionManager *cm = Core::ICore::instance()->connectionManager();
// connect(cm, SIGNAL(deviceDisconnected()), this, SLOT(onAutopilotDisconnect()));
connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(goToBootloader())); connect(m_config->haltButton, SIGNAL(clicked()), this, SLOT(goToBootloader()));
connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset())); connect(m_config->resetButton, SIGNAL(clicked()), this, SLOT(systemReset()));
connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot())); connect(m_config->bootButton, SIGNAL(clicked()), this, SLOT(systemBoot()));