mirror of
https://bitbucket.org/librepilot/librepilot.git
synced 2024-11-29 07:24:13 +01:00
GCS/IPConnection: fixed a problem that was causing IP telemetry not to work on Windows, moved socket creation to the UAVTalk thread. Segfaults if you don't press "Disconnect" before closing the window!
git-svn-id: svn://svn.openpilot.org/OpenPilot/trunk@1342 ebee16cc-31ac-478f-84a7-5cbb03baadba
This commit is contained in:
parent
9dcae643c1
commit
a24daa7c6d
@ -5,7 +5,8 @@ include(ipconnection_dependencies.pri)
|
||||
HEADERS += ipconnectionplugin.h \
|
||||
ipconnection_global.h \
|
||||
ipconnectionconfiguration.h \
|
||||
ipconnectionoptionspage.h
|
||||
ipconnectionoptionspage.h \
|
||||
ipconnection_internal.h
|
||||
SOURCES += ipconnectionplugin.cpp \
|
||||
ipconnectionconfiguration.cpp \
|
||||
ipconnectionoptionspage.cpp
|
||||
|
23
ground/src/plugins/ipconnection/ipconnection_internal.h
Normal file
23
ground/src/plugins/ipconnection/ipconnection_internal.h
Normal file
@ -0,0 +1,23 @@
|
||||
#ifndef IPCONNECTION_INTERNAL_H
|
||||
#define IPCONNECTION_INTERNAL_H
|
||||
|
||||
#include "ipconnectionplugin.h"
|
||||
|
||||
//Simple class for creating & destroying a socket in the real-time thread
|
||||
//Needed because sockets need to be created in the same thread that they're used
|
||||
class IPConnection : public QObject
|
||||
{
|
||||
Q_OBJECT
|
||||
|
||||
public:
|
||||
|
||||
IPConnection(IPconnectionConnection *connection);
|
||||
//virtual ~IPConnection();
|
||||
|
||||
public slots:
|
||||
|
||||
void onOpenDevice(QString HostName, int Port, bool UseTCP);
|
||||
void onCloseDevice(QAbstractSocket *ipSocket);
|
||||
};
|
||||
|
||||
#endif // IPCONNECTION_INTERNAL_H
|
@ -32,6 +32,7 @@
|
||||
|
||||
#include <extensionsystem/pluginmanager.h>
|
||||
#include <coreplugin/icore.h>
|
||||
#include "ipconnection_internal.h"
|
||||
|
||||
#include <QtCore/QtPlugin>
|
||||
#include <QtGui/QMainWindow>
|
||||
@ -39,9 +40,77 @@
|
||||
#include <QtNetwork/QAbstractSocket>
|
||||
#include <QtNetwork/QTcpSocket>
|
||||
#include <QtNetwork/QUdpSocket>
|
||||
#include <QWaitCondition>
|
||||
#include <coreplugin/threadmanager.h>
|
||||
|
||||
#include <QDebug>
|
||||
|
||||
//Communication between IPconnectionConnection::OpenDevice() and IPConnection::onOpenDevice()
|
||||
QString errorMsg;
|
||||
QWaitCondition openDeviceWait;
|
||||
QReadWriteLock dummyLock;
|
||||
QAbstractSocket *ret;
|
||||
|
||||
IPConnection::IPConnection(IPconnectionConnection *connection) : QObject()
|
||||
{
|
||||
moveToThread(Core::ICore::instance()->threadManager()->getRealTimeThread());
|
||||
|
||||
QObject::connect(connection, SIGNAL(CreateSocket(QString,int,bool)),
|
||||
this, SLOT(onOpenDevice(QString,int,bool)));
|
||||
QObject::connect(connection, SIGNAL(CloseSocket(QAbstractSocket*)),
|
||||
this, SLOT(onCloseDevice(QAbstractSocket*)));
|
||||
}
|
||||
|
||||
/*IPConnection::~IPConnection()
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
void IPConnection::onOpenDevice(QString HostName, int Port, bool UseTCP)
|
||||
{
|
||||
QAbstractSocket *ipSocket;
|
||||
const int Timeout = 5 * 1000;
|
||||
int state;
|
||||
|
||||
if (UseTCP) {
|
||||
ipSocket = new QTcpSocket(this);
|
||||
} else {
|
||||
ipSocket = new QUdpSocket(this);
|
||||
}
|
||||
|
||||
//do sanity check on hostname and port...
|
||||
if((HostName.length()==0)||(Port<1)){
|
||||
errorMsg = "Please configure Host and Port options before opening the connection";
|
||||
|
||||
}
|
||||
else {
|
||||
//try to connect...
|
||||
ipSocket->connectToHost(HostName, Port);
|
||||
|
||||
//in blocking mode so we wait for the connection to succeed
|
||||
if (ipSocket->waitForConnected(Timeout)) {
|
||||
ret = ipSocket;
|
||||
openDeviceWait.wakeAll();
|
||||
return;
|
||||
}
|
||||
//tell user something went wrong
|
||||
errorMsg = ipSocket->errorString ();
|
||||
}
|
||||
/* BUGBUG TODO - returning null here leads to segfault because some caller still calls disconnect without checking our return value properly
|
||||
* someone needs to debug this, I got lost in the calling chain.*/
|
||||
ret = NULL;
|
||||
openDeviceWait.wakeAll();
|
||||
}
|
||||
|
||||
void IPConnection::onCloseDevice(QAbstractSocket *ipSocket)
|
||||
{
|
||||
ipSocket->close ();
|
||||
delete(ipSocket);
|
||||
}
|
||||
|
||||
|
||||
IPConnection * connection = 0;
|
||||
|
||||
IPconnectionConnection::IPconnectionConnection()
|
||||
{
|
||||
ipSocket = NULL;
|
||||
@ -51,6 +120,9 @@ IPconnectionConnection::IPconnectionConnection()
|
||||
|
||||
m_optionspage = new IPconnectionOptionsPage(m_config,this);
|
||||
|
||||
if(!connection)
|
||||
connection = new IPConnection(this);
|
||||
|
||||
//just signal whenever we have a device event...
|
||||
QMainWindow *mw = Core::ICore::instance()->mainWindow();
|
||||
QObject::connect(mw, SIGNAL(deviceChange()),
|
||||
@ -65,6 +137,11 @@ IPconnectionConnection::~IPconnectionConnection()
|
||||
ipSocket->close ();
|
||||
delete(ipSocket);
|
||||
}
|
||||
if(connection)
|
||||
{
|
||||
delete connection;
|
||||
connection = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
void IPconnectionConnection::onEnumerationChanged()
|
||||
@ -86,58 +163,38 @@ QStringList IPconnectionConnection::availableDevices()
|
||||
|
||||
QIODevice *IPconnectionConnection::openDevice(const QString &deviceName)
|
||||
{
|
||||
const int Timeout = 5 * 1000;
|
||||
int state;
|
||||
QString HostName;
|
||||
int Port;
|
||||
bool UseTCP;
|
||||
QMessageBox msgBox;
|
||||
|
||||
if (ipSocket){
|
||||
//Andrew: close any existing socket... this should never occur
|
||||
ipSocket->close ();
|
||||
delete(ipSocket);
|
||||
ipSocket = NULL;
|
||||
}
|
||||
|
||||
if (m_config->UseTCP()) {
|
||||
ipSocket = new QTcpSocket(this);
|
||||
} else {
|
||||
ipSocket = new QUdpSocket(this);
|
||||
}
|
||||
|
||||
//get the configuration info
|
||||
HostName = m_config->HostName();
|
||||
Port = m_config->Port();
|
||||
UseTCP = m_config->UseTCP();
|
||||
|
||||
//do sanity check on hostname and port...
|
||||
if((HostName.length()==0)||(Port<1)){
|
||||
msgBox.setText((const QString )"Please configure Host and Port options before opening the connection");
|
||||
msgBox.exec();
|
||||
|
||||
}
|
||||
else {
|
||||
//try to connect...
|
||||
ipSocket->connectToHost((const QString )HostName, Port);
|
||||
|
||||
//in blocking mode so we wait for the connection to succeed
|
||||
if (ipSocket->waitForConnected(Timeout)) {
|
||||
return ipSocket;
|
||||
}
|
||||
//tell user something went wrong
|
||||
msgBox.setText((const QString )ipSocket->errorString ());
|
||||
msgBox.exec();
|
||||
}
|
||||
/* BUGBUG TODO - returning null here leads to segfault because some caller still calls disconnect without checking our return value properly
|
||||
* someone needs to debug this, I got lost in the calling chain.*/
|
||||
if (ipSocket){
|
||||
//Andrew: close any existing socket... this should never occur
|
||||
emit CloseSocket(ipSocket);
|
||||
ipSocket = NULL;
|
||||
}
|
||||
|
||||
dummyLock.lockForRead();
|
||||
emit CreateSocket(HostName, Port, UseTCP);
|
||||
openDeviceWait.wait(&dummyLock);
|
||||
ipSocket = ret;
|
||||
if(ipSocket == NULL)
|
||||
{
|
||||
msgBox.setText((const QString )errorMsg);
|
||||
msgBox.exec();
|
||||
}
|
||||
return ipSocket;
|
||||
}
|
||||
|
||||
void IPconnectionConnection::closeDevice(const QString &deviceName)
|
||||
{
|
||||
if (ipSocket){
|
||||
ipSocket->close ();
|
||||
delete(ipSocket);
|
||||
emit CloseSocket(ipSocket);
|
||||
ipSocket = NULL;
|
||||
}
|
||||
}
|
||||
|
@ -68,6 +68,11 @@ public:
|
||||
|
||||
protected slots:
|
||||
void onEnumerationChanged();
|
||||
|
||||
signals: //For the benefit of IPConnection
|
||||
void CreateSocket(QString HostName, int Port, bool UseTCP);
|
||||
void CloseSocket(QAbstractSocket *socket);
|
||||
|
||||
private:
|
||||
QAbstractSocket *ipSocket;
|
||||
IPconnectionConfiguration *m_config;
|
||||
|
Loading…
Reference in New Issue
Block a user