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 \
|
HEADERS += ipconnectionplugin.h \
|
||||||
ipconnection_global.h \
|
ipconnection_global.h \
|
||||||
ipconnectionconfiguration.h \
|
ipconnectionconfiguration.h \
|
||||||
ipconnectionoptionspage.h
|
ipconnectionoptionspage.h \
|
||||||
|
ipconnection_internal.h
|
||||||
SOURCES += ipconnectionplugin.cpp \
|
SOURCES += ipconnectionplugin.cpp \
|
||||||
ipconnectionconfiguration.cpp \
|
ipconnectionconfiguration.cpp \
|
||||||
ipconnectionoptionspage.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 <extensionsystem/pluginmanager.h>
|
||||||
#include <coreplugin/icore.h>
|
#include <coreplugin/icore.h>
|
||||||
|
#include "ipconnection_internal.h"
|
||||||
|
|
||||||
#include <QtCore/QtPlugin>
|
#include <QtCore/QtPlugin>
|
||||||
#include <QtGui/QMainWindow>
|
#include <QtGui/QMainWindow>
|
||||||
@ -39,9 +40,77 @@
|
|||||||
#include <QtNetwork/QAbstractSocket>
|
#include <QtNetwork/QAbstractSocket>
|
||||||
#include <QtNetwork/QTcpSocket>
|
#include <QtNetwork/QTcpSocket>
|
||||||
#include <QtNetwork/QUdpSocket>
|
#include <QtNetwork/QUdpSocket>
|
||||||
|
#include <QWaitCondition>
|
||||||
|
#include <coreplugin/threadmanager.h>
|
||||||
|
|
||||||
#include <QDebug>
|
#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()
|
IPconnectionConnection::IPconnectionConnection()
|
||||||
{
|
{
|
||||||
ipSocket = NULL;
|
ipSocket = NULL;
|
||||||
@ -51,6 +120,9 @@ IPconnectionConnection::IPconnectionConnection()
|
|||||||
|
|
||||||
m_optionspage = new IPconnectionOptionsPage(m_config,this);
|
m_optionspage = new IPconnectionOptionsPage(m_config,this);
|
||||||
|
|
||||||
|
if(!connection)
|
||||||
|
connection = new IPConnection(this);
|
||||||
|
|
||||||
//just signal whenever we have a device event...
|
//just signal whenever we have a device event...
|
||||||
QMainWindow *mw = Core::ICore::instance()->mainWindow();
|
QMainWindow *mw = Core::ICore::instance()->mainWindow();
|
||||||
QObject::connect(mw, SIGNAL(deviceChange()),
|
QObject::connect(mw, SIGNAL(deviceChange()),
|
||||||
@ -65,6 +137,11 @@ IPconnectionConnection::~IPconnectionConnection()
|
|||||||
ipSocket->close ();
|
ipSocket->close ();
|
||||||
delete(ipSocket);
|
delete(ipSocket);
|
||||||
}
|
}
|
||||||
|
if(connection)
|
||||||
|
{
|
||||||
|
delete connection;
|
||||||
|
connection = NULL;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPconnectionConnection::onEnumerationChanged()
|
void IPconnectionConnection::onEnumerationChanged()
|
||||||
@ -86,58 +163,38 @@ QStringList IPconnectionConnection::availableDevices()
|
|||||||
|
|
||||||
QIODevice *IPconnectionConnection::openDevice(const QString &deviceName)
|
QIODevice *IPconnectionConnection::openDevice(const QString &deviceName)
|
||||||
{
|
{
|
||||||
const int Timeout = 5 * 1000;
|
|
||||||
int state;
|
|
||||||
QString HostName;
|
QString HostName;
|
||||||
int Port;
|
int Port;
|
||||||
|
bool UseTCP;
|
||||||
QMessageBox msgBox;
|
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
|
//get the configuration info
|
||||||
HostName = m_config->HostName();
|
HostName = m_config->HostName();
|
||||||
Port = m_config->Port();
|
Port = m_config->Port();
|
||||||
|
UseTCP = m_config->UseTCP();
|
||||||
|
|
||||||
//do sanity check on hostname and port...
|
if (ipSocket){
|
||||||
if((HostName.length()==0)||(Port<1)){
|
//Andrew: close any existing socket... this should never occur
|
||||||
msgBox.setText((const QString )"Please configure Host and Port options before opening the connection");
|
emit CloseSocket(ipSocket);
|
||||||
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.*/
|
|
||||||
ipSocket = NULL;
|
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;
|
return ipSocket;
|
||||||
}
|
}
|
||||||
|
|
||||||
void IPconnectionConnection::closeDevice(const QString &deviceName)
|
void IPconnectionConnection::closeDevice(const QString &deviceName)
|
||||||
{
|
{
|
||||||
if (ipSocket){
|
if (ipSocket){
|
||||||
ipSocket->close ();
|
emit CloseSocket(ipSocket);
|
||||||
delete(ipSocket);
|
|
||||||
ipSocket = NULL;
|
ipSocket = NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -68,6 +68,11 @@ public:
|
|||||||
|
|
||||||
protected slots:
|
protected slots:
|
||||||
void onEnumerationChanged();
|
void onEnumerationChanged();
|
||||||
|
|
||||||
|
signals: //For the benefit of IPConnection
|
||||||
|
void CreateSocket(QString HostName, int Port, bool UseTCP);
|
||||||
|
void CloseSocket(QAbstractSocket *socket);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
QAbstractSocket *ipSocket;
|
QAbstractSocket *ipSocket;
|
||||||
IPconnectionConfiguration *m_config;
|
IPconnectionConfiguration *m_config;
|
||||||
|
Loading…
Reference in New Issue
Block a user