Commit 8ec600aa authored by Gus Grubba's avatar Gus Grubba

Merge pull request #2375 from dogmaphobic/bluetoothCleanup

Bluetooth Cleanup
parents ec3047af 09b22dd6
......@@ -36,6 +36,7 @@ linux {
CONFIG += AndroidBuild MobileBuild
DEFINES += __android__
DEFINES += __STDC_LIMIT_MACROS
DEFINES += QGC_ENABLE_BLUETOOTH
target.path = $$DESTDIR
} else {
error("Unsuported Linux toolchain, only GCC 32- or 64-bit is supported")
......
......@@ -44,6 +44,18 @@ exists(user_config.pri):infile(user_config.pri, CONFIG) {
message($$sprintf("Using user-supplied additional config: '%1' specified in user_config.pri", $$fromfile(user_config.pri, CONFIG)))
}
# Bluetooth
contains (DEFINES, QGC_DISABLE_BLUETOOTH) {
message("Skipping support for Bluetooth (manual override from command line)")
DEFINES -= QGC_ENABLE_BLUETOOTH
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, QGC_DISABLE_BLUETOOTH) {
message("Skipping support for Bluetooth (manual override from user_config.pri)")
DEFINES -= QGC_ENABLE_BLUETOOTH
} else:exists(user_config.pri):infile(user_config.pri, DEFINES, QGC_ENABLE_BLUETOOTH) {
message("Including support for Bluetooth (manual override from user_config.pri)")
DEFINES += QGC_ENABLE_BLUETOOTH
}
LinuxBuild {
CONFIG += link_pkgconfig
}
......@@ -74,7 +86,7 @@ QT += \
serialport \
}
MobileBuild {
contains(DEFINES, QGC_ENABLE_BLUETOOTH) {
QT += \
bluetooth \
}
......@@ -284,7 +296,7 @@ WindowsBuild {
HEADERS += src/stable_headers.h
}
MobileBuild {
contains(DEFINES, QGC_ENABLE_BLUETOOTH) {
HEADERS += \
src/comm/BluetoothLink.h \
}
......@@ -402,7 +414,7 @@ SOURCES += \
src/ui/SerialConfigurationWindow.cc \
}
MobileBuild {
contains(DEFINES, QGC_ENABLE_BLUETOOTH) {
SOURCES += \
src/comm/BluetoothLink.cc \
}
......
......@@ -37,6 +37,10 @@
#include <QStyleFactory>
#include <QAction>
#ifdef QGC_ENABLE_BLUETOOTH
#include <QBluetoothLocalDevice>
#endif
#include <QDebug>
#include "VideoStreaming.h"
......@@ -170,6 +174,7 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
, _testHighDPI(false)
#endif
, _toolbox(NULL)
, _bluetoothAvailable(false)
{
Q_ASSERT(_app == NULL);
_app = this;
......@@ -319,6 +324,15 @@ QGCApplication::QGCApplication(int &argc, char* argv[], bool unitTesting)
settings.setValue(_settingsVersionKey, QGC_SETTINGS_VERSION);
}
// Initialize Bluetooth
#ifdef QGC_ENABLE_BLUETOOTH
QBluetoothLocalDevice localDevice;
if (localDevice.isValid())
{
_bluetoothAvailable = true;
}
#endif
// Initialize Video Streaming
initializeVideoStreaming(argc, argv);
......
......@@ -133,6 +133,9 @@ public:
// Still working on getting rid of this and using dependency injection instead for everything
QGCToolbox* toolbox(void) { return _toolbox; }
/// Do we have Bluetooth Support?
bool isBluetoothAvailable() { return _bluetoothAvailable; }
public slots:
/// You can connect to this slot to show an information message box from a different thread.
void informationMessageBoxOnMainThread(const QString& title, const QString& msg);
......@@ -225,6 +228,8 @@ private:
QGCToolbox* _toolbox;
bool _bluetoothAvailable;
/// Unit Test have access to creating and destroying singletons
friend class UnitTest;
};
......
......@@ -34,42 +34,26 @@ This file is part of the QGROUNDCONTROL project
#include <QDebug>
#include <iostream>
#include <QtBluetooth/QBluetoothSocket>
#include <QtBluetooth/QBluetoothDeviceDiscoveryAgent>
#include <QtBluetooth/QBluetoothLocalDevice>
#include <QtBluetooth/QBluetoothUuid>
#include <QtBluetooth/QBluetoothSocket>
#include "BluetoothLink.h"
#include "QGC.h"
/*
static void print_device_info(QBluetoothDeviceInfo info)
{
qDebug() << "Bluetooth: " << info.name();
qDebug() << " Services:" << info.serviceClasses();
qDebug() << " Major Classs:" << info.majorDeviceClass();
qDebug() << " Minor Classs:" << info.minorDeviceClass();
qDebug() << " RSSI:" << info.rssi();
qDebug() << " UUID:" << info.deviceUuid();
qDebug() << " Service UUID:" << info.serviceUuids();
qDebug() << " Core Config:" << info.coreConfigurations();
qDebug() << " Valid:" << info.isValid();
qDebug() << " Address:" << info.address().toString();
}
*/
BluetoothLink::BluetoothLink(BluetoothConfiguration* config)
: _connectState(false)
, _targetSocket(NULL)
, _targetDevice(NULL)
, _running(false)
#ifdef __ios__
, _discoveryAgent(NULL)
#endif
, _shutDown(false)
{
Q_ASSERT(config != NULL);
_config = config;
_config->setLink(this);
// We're doing it wrong - because the Qt folks got the API wrong:
// http://blog.qt.digia.com/blog/2010/06/17/youre-doing-it-wrong/
moveToThread(this);
//moveToThread(this);
}
BluetoothLink::~BluetoothLink()
......@@ -77,19 +61,18 @@ BluetoothLink::~BluetoothLink()
// Disconnect link from configuration
_config->setLink(NULL);
_disconnect();
// Tell the thread to exit
_running = false;
quit();
// Wait for it to exit
wait();
this->deleteLater();
#ifdef __ios__
if(_discoveryAgent) {
_shutDown = true;
_discoveryAgent->stop();
_discoveryAgent->deleteLater();
_discoveryAgent = NULL;
}
#endif
}
void BluetoothLink::run()
{
if(_running && _hardwareConnect()) {
exec();
}
}
void BluetoothLink::_restartConnection()
......@@ -142,17 +125,17 @@ void BluetoothLink::readBytes()
void BluetoothLink::_disconnect(void)
{
_running = false;
quit();
wait();
if(_targetDevice)
{
delete _targetDevice;
_targetDevice = NULL;
#ifdef __ios__
if(_discoveryAgent) {
_shutDown = true;
_discoveryAgent->stop();
_discoveryAgent->deleteLater();
_discoveryAgent = NULL;
}
#endif
if(_targetSocket)
{
_targetSocket->deleteLater();
delete _targetSocket;
_targetSocket = NULL;
emit disconnected();
}
......@@ -161,43 +144,86 @@ void BluetoothLink::_disconnect(void)
bool BluetoothLink::_connect(void)
{
if(this->isRunning() || _running)
{
_running = false;
quit();
wait();
}
if(_targetDevice)
{
delete _targetDevice;
_targetDevice = NULL;
}
//-- Start Thread
_running = true;
start(NormalPriority);
_hardwareConnect();
return true;
}
bool BluetoothLink::_hardwareConnect()
{
#ifdef __ios__
if(_discoveryAgent) {
_shutDown = true;
_discoveryAgent->stop();
_discoveryAgent->deleteLater();
_discoveryAgent = NULL;
}
_discoveryAgent = new QBluetoothServiceDiscoveryAgent(this);
QObject::connect(_discoveryAgent, SIGNAL(serviceDiscovered(QBluetoothServiceInfo)), this, SLOT(serviceDiscovered(QBluetoothServiceInfo)));
QObject::connect(_discoveryAgent, SIGNAL(finished()), this, SLOT(discoveryFinished()));
QObject::connect(_discoveryAgent, SIGNAL(canceled()), this, SLOT(discoveryFinished()));
QObject::connect(_discoveryAgent, SIGNAL(error(QBluetoothServiceDiscoveryAgent::Error)),this, SLOT(discoveryError(QBluetoothServiceDiscoveryAgent::Error)));
_shutDown = false;
_discoveryAgent->start();
#else
_createSocket();
_targetSocket->connectToService(QBluetoothAddress(_config->device().address), QBluetoothUuid(QBluetoothUuid::Rfcomm));
#endif
return true;
}
void BluetoothLink::_createSocket()
{
if(_targetSocket)
{
delete _targetSocket;
_targetSocket = NULL;
}
_targetDevice = new QBluetoothDeviceInfo(QBluetoothAddress(_config->device().address), _config->device().name, _config->device().bits);
_targetDevice->setCoreConfigurations(QBluetoothDeviceInfo::BaseRateCoreConfiguration);
_targetSocket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol, this);
_targetSocket->moveToThread(this);
//print_device_info(*_targetDevice);
QObject::connect(_targetSocket, SIGNAL(connected()), this, SLOT(deviceConnected()));
QObject::connect(_targetSocket, SIGNAL(error(QBluetoothSocket::SocketError)), this, SLOT(deviceError(QBluetoothSocket::SocketError)));
QObject::connect(_targetSocket, SIGNAL(readyRead()), this, SLOT(readBytes()));
QObject::connect(_targetSocket, SIGNAL(disconnected()), this, SLOT(deviceDisconnected()));
_targetSocket->connectToService(_targetDevice->address(), QBluetoothUuid(QBluetoothUuid::Rfcomm));
return true;
}
#ifdef __ios__
void BluetoothLink::discoveryError(QBluetoothServiceDiscoveryAgent::Error error)
{
qDebug() << "Discovery error:" << error;
qDebug() << _discoveryAgent->errorString();
}
#endif
#ifdef __ios__
void BluetoothLink::serviceDiscovered(const QBluetoothServiceInfo& info)
{
if(!info.device().name().isEmpty() && !_targetSocket)
{
if(_config->device().uuid == info.device().deviceUuid() && _config->device().name == info.device().name())
{
_createSocket();
_targetSocket->connectToService(info);
}
}
}
#endif
#ifdef __ios__
void BluetoothLink::discoveryFinished()
{
if(_discoveryAgent && !_shutDown)
{
_shutDown = true;
_discoveryAgent->deleteLater();
_discoveryAgent = NULL;
if(!_targetSocket)
{
_connectState = false;
emit communicationError("Could not locate Bluetooth device:", _config->device().name);
}
}
}
#endif
void BluetoothLink::deviceConnected()
{
_connectState = true;
......@@ -274,18 +300,25 @@ void BluetoothConfiguration::copyFrom(LinkConfiguration *source)
void BluetoothConfiguration::saveSettings(QSettings& settings, const QString& root)
{
settings.beginGroup(root);
settings.setValue("name", _device.name);
settings.setValue("address", _device.address);
settings.setValue("bits", _device.bits);
settings.setValue("deviceName", _device.name);
#ifdef __ios__
settings.setValue("uuid", _device.uuid.toString());
#else
settings.setValue("address",_device.address);
#endif
settings.endGroup();
}
void BluetoothConfiguration::loadSettings(QSettings& settings, const QString& root)
{
settings.beginGroup(root);
_device.name = settings.value("name", _device.name).toString();
_device.name = settings.value("deviceName", _device.name).toString();
#ifdef __ios__
QString suuid = settings.value("uuid", _device.uuid.toString()).toString();
_device.uuid = QUuid(suuid);
#else
_device.address = settings.value("address", _device.address).toString();
_device.bits = settings.value("bits", _device.bits).toUInt();
#endif
settings.endGroup();
}
......@@ -337,10 +370,11 @@ void BluetoothConfiguration::deviceDiscovered(QBluetoothDeviceInfo info)
{
BluetoothData data;
data.name = info.name();
#ifdef __ios__
data.uuid = info.deviceUuid();
#else
data.address = info.address().toString();
data.bits |= ((qint32)info.serviceClasses() << 13); // Service Class
data.bits |= ((qint32)info.majorDeviceClass() << 8); // CLASS MAJOR
data.bits |= ((qint32)info.minorDeviceClass() << 2); // CLASS MINOR
#endif
if(!_deviceList.contains(data))
{
_deviceList += data;
......@@ -369,9 +403,19 @@ void BluetoothConfiguration::setDevName(const QString &name)
{
_device = data;
emit devNameChanged();
#ifndef __ios__
emit addressChanged();
#endif
return;
}
}
}
QString BluetoothConfiguration::address()
{
#ifdef __ios__
return QString("");
#else
return _device.address;
#endif
}
......@@ -39,18 +39,20 @@ This file is part of the QGROUNDCONTROL project
#include <QByteArray>
#include <QBluetoothDeviceInfo>
#include <QtBluetooth/QBluetoothSocket>
#include <qbluetoothserviceinfo.h>
#include <qbluetoothservicediscoveryagent.h>
#include "QGCConfig.h"
#include "LinkManager.h"
class QBluetoothDeviceDiscoveryAgent;
class QBluetoothServiceDiscoveryAgent;
class BluetoothData
{
public:
BluetoothData()
{
bits = 0;
}
BluetoothData(const BluetoothData& other)
{
......@@ -58,18 +60,28 @@ public:
}
bool operator==(const BluetoothData& other)
{
return bits == other.bits && name == other.name && address == other.address;
#ifdef __ios__
return uuid == other.uuid && name == other.name;
#else
return name == other.name && address == other.address;
#endif
}
BluetoothData& operator=(const BluetoothData& other)
{
bits = other.bits;
name = other.name;
#ifdef __ios__
uuid = other.uuid;
#else
address = other.address;
#endif
return *this;
}
quint32 bits;
QString name;
#ifdef __ios__
QBluetoothUuid uuid;
#else
QString address;
#endif
};
class BluetoothConfiguration : public LinkConfiguration
......@@ -91,7 +103,7 @@ public:
Q_INVOKABLE void stopScan ();
QString devName () { return _device.name; }
QString address () { return _device.address; }
QString address ();
QStringList nameList () { return _nameList; }
bool scanning () { return _deviceDiscover != NULL; }
......@@ -159,6 +171,11 @@ public slots:
void deviceConnected ();
void deviceDisconnected ();
void deviceError (QBluetoothSocket::SocketError error);
#ifdef __ios__
void serviceDiscovered (const QBluetoothServiceInfo &info);
void discoveryFinished ();
void discoveryError (QBluetoothServiceDiscoveryAgent::Error error);
#endif
protected:
......@@ -177,12 +194,17 @@ private:
bool _hardwareConnect ();
void _restartConnection ();
void _sendBytes (const char* data, qint64 size);
void _createSocket ();
private:
QBluetoothSocket* _targetSocket;
QBluetoothDeviceInfo* _targetDevice;
bool _running;
#ifdef __ios__
QBluetoothServiceDiscoveryAgent* _discoveryAgent;
#endif
bool _shutDown;
};
#endif // BTLINK_H
......@@ -36,7 +36,7 @@ This file is part of the QGROUNDCONTROL project
#ifndef __mobile__
#include "LogReplayLink.h"
#endif
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
#include "BluetoothLink.h"
#endif
#ifdef QT_DEBUG
......@@ -103,7 +103,7 @@ LinkConfiguration* LinkConfiguration::createSettings(int type, const QString& na
case LinkConfiguration::TypeTcp:
config = new TCPConfiguration(name);
break;
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
case LinkConfiguration::TypeBluetooth:
config = new BluetoothConfiguration(name);
break;
......@@ -141,7 +141,7 @@ LinkConfiguration* LinkConfiguration::duplicateSettings(LinkConfiguration* sourc
case TypeTcp:
dupe = new TCPConfiguration(dynamic_cast<TCPConfiguration*>(source));
break;
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
case TypeBluetooth:
dupe = new BluetoothConfiguration(dynamic_cast<BluetoothConfiguration*>(source));
break;
......
......@@ -64,7 +64,7 @@ public:
#endif
TypeUdp, ///< UDP Link
TypeTcp, ///< TCP Link
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
TypeBluetooth, ///< Bluetooth Link
#endif
#if 0
......
......@@ -39,10 +39,9 @@ This file is part of the QGROUNDCONTROL project
#include "LinkManager.h"
#include "QGCApplication.h"
#include "QGCApplication.h"
#include "UDPLink.h"
#include "TCPLink.h"
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
#include "BluetoothLink.h"
#endif
......@@ -125,7 +124,7 @@ LinkInterface* LinkManager::createConnectedLink(LinkConfiguration* config)
case LinkConfiguration::TypeTcp:
pLink = new TCPLink(dynamic_cast<TCPConfiguration*>(config));
break;
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
case LinkConfiguration::TypeBluetooth:
pLink = new BluetoothLink(dynamic_cast<BluetoothConfiguration*>(config));
break;
......@@ -361,7 +360,7 @@ void LinkManager::loadLinkConfigurationList()
case LinkConfiguration::TypeTcp:
pLink = (LinkConfiguration*)new TCPConfiguration(name);
break;
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
case LinkConfiguration::TypeBluetooth:
pLink = (LinkConfiguration*)new BluetoothConfiguration(name);
break;
......@@ -708,7 +707,7 @@ QStringList LinkManager::linkTypeStrings(void) const
#endif
list += "UDP";
list += "TCP";
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
list += "Bluetooth";
#endif
#ifdef QT_DEBUG
......@@ -839,7 +838,7 @@ void LinkManager::_fixUnnamed(LinkConfiguration* config)
}
}
break;
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
case LinkConfiguration::TypeBluetooth: {
BluetoothConfiguration* tconfig = dynamic_cast<BluetoothConfiguration*>(config);
if(tconfig) {
......@@ -888,3 +887,8 @@ bool LinkManager::isAutoconnectLink(LinkInterface* link)
{
return _autoconnectConfigurations.contains(link->getLinkConfiguration());
}
bool LinkManager::isBluetoothAvailable(void)
{
return qgcApp()->isBluetoothAvailable();
}
......@@ -80,6 +80,7 @@ public:
Q_PROPERTY(bool autoconnectPixhawk READ autoconnectPixhawk WRITE setAutoconnectPixhawk NOTIFY autoconnectPixhawkChanged)
Q_PROPERTY(bool autoconnect3DRRadio READ autoconnect3DRRadio WRITE setAutoconnect3DRRadio NOTIFY autoconnect3DRRadioChanged)
Q_PROPERTY(bool autoconnectPX4Flow READ autoconnectPX4Flow WRITE setAutoconnectPX4Flow NOTIFY autoconnectPX4FlowChanged)
Q_PROPERTY(bool isBluetoothAvailable READ isBluetoothAvailable CONSTANT)
/// LinkInterface Accessor
Q_PROPERTY(QmlObjectListModel* links READ links CONSTANT)
......@@ -104,12 +105,13 @@ public:
// Property accessors
bool anyConnectedLinks(void);
bool anyActiveLinks(void);
bool autoconnectUDP(void) { return _autoconnectUDP; }
bool autoconnectPixhawk(void) { return _autoconnectPixhawk; }
bool autoconnect3DRRadio(void) { return _autoconnect3DRRadio; }
bool autoconnectPX4Flow(void) { return _autoconnectPX4Flow; }
bool anyConnectedLinks (void);
bool anyActiveLinks (void);
bool autoconnectUDP (void) { return _autoconnectUDP; }
bool autoconnectPixhawk (void) { return _autoconnectPixhawk; }
bool autoconnect3DRRadio (void) { return _autoconnect3DRRadio; }
bool autoconnectPX4Flow (void) { return _autoconnectPX4Flow; }
bool isBluetoothAvailable (void);
QmlObjectListModel* links (void) { return &_links; }
QmlObjectListModel* linkConfigurations (void) { return &_linkConfigurations; }
......
......@@ -49,7 +49,7 @@ This file is part of the QGROUNDCONTROL project
#endif
#endif
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
#include <QtBluetooth/QBluetoothSocket>
#endif
......@@ -139,7 +139,7 @@ int main(int argc, char *argv[])
#ifndef __ios__
qRegisterMetaType<QSerialPort::SerialPortError>();
#endif
#ifdef __mobile__
#ifdef QGC_ENABLE_BLUETOOTH
qRegisterMetaType<QBluetoothSocket::SocketError>();
qRegisterMetaType<QBluetoothServiceInfo>();
#endif
......
......@@ -39,9 +39,16 @@ Item {
// No need
}
QGCLabel {
text: "Bluetooth Not Available"
visible: !QGroundControl.linkManager.isBluetoothAvailable
anchors.centerIn: parent
}
Column {
id: btColumn
spacing: ScreenTools.defaultFontPixelHeight / 2
visible: QGroundControl.linkManager.isBluetoothAvailable
ExclusiveGroup { id: linkGroup }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment