From 054fab6c28e8d55e7710e186217370c9a334deea Mon Sep 17 00:00:00 2001 From: dogmaphobic Date: Sat, 5 Dec 2015 01:36:45 -0500 Subject: [PATCH] Bluetooth for Android complete. --- qgroundcontrol.pro | 8 +- src/comm/BluetoothLink.cc | 145 ++++++++--------------- src/comm/BluetoothLink.h | 61 ++++++---- src/comm/LinkConfiguration.cc | 6 +- src/comm/LinkConfiguration.h | 2 +- src/comm/LinkManager.cc | 14 +-- src/comm/SerialLink.cc | 2 +- src/main.cc | 4 +- src/ui/QGCLinkConfiguration.cc | 2 +- src/ui/preferences/BluetoothSettings.qml | 20 +--- src/ui/preferences/LinkSettings.qml | 1 + src/ui/preferences/SerialSettings.qml | 2 +- 12 files changed, 119 insertions(+), 148 deletions(-) diff --git a/qgroundcontrol.pro b/qgroundcontrol.pro index 83ee73aa5..228643ab3 100644 --- a/qgroundcontrol.pro +++ b/qgroundcontrol.pro @@ -74,7 +74,7 @@ QT += \ serialport \ } -!WindowsBuild { +MobileBuild { QT += \ bluetooth \ } @@ -309,7 +309,9 @@ HEADERS += \ WindowsBuild { PRECOMPILED_HEADER += src/stable_headers.h HEADERS += src/stable_headers.h -} else { +} + +MobileBuild { HEADERS += \ src/comm/BluetoothLink.h \ } @@ -433,7 +435,7 @@ SOURCES += \ src/ui/SerialConfigurationWindow.cc \ } -!WindowsBuild { +MobileBuild { SOURCES += \ src/comm/BluetoothLink.cc \ } diff --git a/src/comm/BluetoothLink.cc b/src/comm/BluetoothLink.cc index 6fb2a0eb8..69895e54f 100644 --- a/src/comm/BluetoothLink.cc +++ b/src/comm/BluetoothLink.cc @@ -42,6 +42,7 @@ This file is part of the QGROUNDCONTROL project #include "BluetoothLink.h" #include "QGC.h" +/* static void print_device_info(QBluetoothDeviceInfo info) { qDebug() << "Bluetooth: " << info.name(); @@ -53,13 +54,14 @@ static void print_device_info(QBluetoothDeviceInfo info) 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) - , _deviceDiscover(NULL) , _running(false) { Q_ASSERT(config != NULL); @@ -67,7 +69,7 @@ BluetoothLink::BluetoothLink(BluetoothConfiguration* 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() @@ -85,39 +87,11 @@ BluetoothLink::~BluetoothLink() void BluetoothLink::run() { - while (!_targetDevice && _running) - this->msleep(50); if(_running && _hardwareConnect()) { exec(); } } -void BluetoothLink::deviceDiscovered(QBluetoothDeviceInfo info) -{ - if(info.name() == _config->device()) - { - if(!_targetDevice) - { - print_device_info(info); - _targetDevice = new QBluetoothDeviceInfo(info); - //-- Start Thread - _running = true; - start(NormalPriority); - } - } -} - -void BluetoothLink::doneScanning() -{ - if(!_targetDevice) - { - _connectState = false; - qWarning() << "Bluetooth scanning did not find device" << _config->device(); - emit communicationError("Bluetooth Link Error", "Device Not Found"); - _running = false; - } -} - void BluetoothLink::_restartConnection() { if(this->isConnected()) @@ -182,12 +156,6 @@ void BluetoothLink::_disconnect(void) _targetSocket = NULL; emit disconnected(); } - if(_deviceDiscover) - { - _deviceDiscover->stop(); - delete _deviceDiscover; - _deviceDiscover = NULL; - } _connectState = false; } @@ -199,23 +167,14 @@ bool BluetoothLink::_connect(void) quit(); wait(); } - if(_deviceDiscover) - { - _deviceDiscover->stop(); - delete _deviceDiscover; - _deviceDiscover = NULL; - } if(_targetDevice) { delete _targetDevice; _targetDevice = NULL; } - //-- Scan devices - _deviceDiscover = new QBluetoothDeviceDiscoveryAgent(); - QObject::connect(_deviceDiscover, SIGNAL(deviceDiscovered(QBluetoothDeviceInfo)), this, SLOT(deviceDiscovered(QBluetoothDeviceInfo))); - QObject::connect(_deviceDiscover, SIGNAL(finished()), this, SLOT(doneScanning())); - _deviceDiscover->setInquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry); - _deviceDiscover->start(); + //-- Start Thread + _running = true; + start(NormalPriority); return true; } @@ -226,37 +185,19 @@ bool BluetoothLink::_hardwareConnect() delete _targetSocket; _targetSocket = NULL; } - // Build Device Class Descriptor - /* - quint32 device_class = 0; - device_class |= ((0x20 | 0x100) << 13); // Service Class - device_class |= (0x04 << 8); // Audio Device (CLASS MAJOR) The Crossfire presents itself as an "Audio Service" - device_class |= (0x01 << 2); // WearableHeadsetDevice (CLASS MINOR) - qDebug() << _config->address() << _config->device() << device_class; - _targetDevice = new QBluetoothDeviceInfo(QBluetoothAddress(_config->address()), _config->device(), device_class); + _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); - - qDebug() << "Connecting..."; - print_device_info(*_targetDevice); - + //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())); - QObject::connect(_targetSocket, SIGNAL(stateChanged(QBluetoothSocket::SocketState)), this, SLOT(stateChanged(QBluetoothSocket::SocketState))); _targetSocket->connectToService(_targetDevice->address(), QBluetoothUuid(QBluetoothUuid::Rfcomm)); return true; } -void BluetoothLink::stateChanged(QBluetoothSocket::SocketState state) -{ - qDebug() << "Bluetooth state:" << state; -} - void BluetoothLink::deviceConnected() { _connectState = true; @@ -310,8 +251,7 @@ BluetoothConfiguration::BluetoothConfiguration(BluetoothConfiguration* source) : LinkConfiguration(source) , _deviceDiscover(NULL) { - _address = source->address(); - _device = source->device(); + _device = source->device(); } BluetoothConfiguration::~BluetoothConfiguration() @@ -328,25 +268,24 @@ void BluetoothConfiguration::copyFrom(LinkConfiguration *source) LinkConfiguration::copyFrom(source); BluetoothConfiguration* usource = dynamic_cast(source); Q_ASSERT(usource != NULL); - _address = usource->address(); - _device = usource->device(); + _device = usource->device(); } void BluetoothConfiguration::saveSettings(QSettings& settings, const QString& root) { settings.beginGroup(root); - settings.setValue("device", _device); - settings.setValue("address", _address); + settings.setValue("name", _device.name); + settings.setValue("address", _device.address); + settings.setValue("bits", _device.bits); settings.endGroup(); } void BluetoothConfiguration::loadSettings(QSettings& settings, const QString& root) { settings.beginGroup(root); - QString device = settings.value("device", _device).toString(); - QString address = settings.value("address", _address).toString(); - _device = device; - _address = address; + _device.name = settings.value("name", _device.name).toString(); + _device.address = settings.value("address", _device.address).toString(); + _device.bits = settings.value("bits", _device.bits).toUInt(); settings.endGroup(); } @@ -364,7 +303,10 @@ void BluetoothConfiguration::stopScan() { if(_deviceDiscover) { - + _deviceDiscover->stop(); + _deviceDiscover->deleteLater(); + _deviceDiscover = NULL; + emit scanningChanged(); } } @@ -373,27 +315,40 @@ void BluetoothConfiguration::startScan() if(!_deviceDiscover) { _deviceDiscover = new QBluetoothDeviceDiscoveryAgent(this); - connect(_deviceDiscover, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothConfiguration::deviceDiscovered); - connect(_deviceDiscover, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothConfiguration::doneScanning); + connect(_deviceDiscover, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this, &BluetoothConfiguration::deviceDiscovered); + connect(_deviceDiscover, &QBluetoothDeviceDiscoveryAgent::finished, this, &BluetoothConfiguration::doneScanning); emit scanningChanged(); } else { _deviceDiscover->stop(); } + _nameList.clear(); _deviceList.clear(); - _addressList.clear(); - emit deviceListChanged(); + emit nameListChanged(); _deviceDiscover->setInquiryType(QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry); _deviceDiscover->start(); } void BluetoothConfiguration::deviceDiscovered(QBluetoothDeviceInfo info) { - _deviceList += info.name(); - _addressList += info.address().toString(); - print_device_info(info); - emit deviceListChanged(); + //print_device_info(info); + if(!info.name().isEmpty() && info.isValid()) + { + BluetoothData data; + data.name = info.name(); + 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 + if(!_deviceList.contains(data)) + { + _deviceList += data; + _nameList += data.name; + emit nameListChanged(); + return; + } + } } void BluetoothConfiguration::doneScanning() @@ -406,15 +361,17 @@ void BluetoothConfiguration::doneScanning() } } -void BluetoothConfiguration::setDevice(QString device) +void BluetoothConfiguration::setDevName(const QString &name) { - int idx = _deviceList.indexOf(device); - if(idx >= 0) + foreach(const BluetoothData& data, _deviceList) { - _address = _addressList.at(idx); - _device = device; - emit deviceChanged(); - emit addressChanged(); + if(data.name == name) + { + _device = data; + emit devNameChanged(); + emit addressChanged(); + return; + } } } diff --git a/src/comm/BluetoothLink.h b/src/comm/BluetoothLink.h index ee4993c41..24da5353b 100644 --- a/src/comm/BluetoothLink.h +++ b/src/comm/BluetoothLink.h @@ -45,6 +45,33 @@ This file is part of the QGROUNDCONTROL project class QBluetoothDeviceDiscoveryAgent; +class BluetoothData +{ +public: + BluetoothData() + { + bits = 0; + } + BluetoothData(const BluetoothData& other) + { + *this = other; + } + bool operator==(const BluetoothData& other) + { + return bits == other.bits && name == other.name && address == other.address; + } + BluetoothData& operator=(const BluetoothData& other) + { + bits = other.bits; + name = other.name; + address = other.address; + return *this; + } + quint32 bits; + QString name; + QString address; +}; + class BluetoothConfiguration : public LinkConfiguration { Q_OBJECT @@ -55,21 +82,22 @@ public: BluetoothConfiguration(BluetoothConfiguration* source); ~BluetoothConfiguration(); - Q_PROPERTY(QString device READ device WRITE setDevice NOTIFY deviceChanged) - Q_PROPERTY(QString address READ address WRITE setAddress NOTIFY addressChanged) - Q_PROPERTY(QStringList deviceList READ deviceList NOTIFY deviceListChanged) + Q_PROPERTY(QString devName READ devName WRITE setDevName NOTIFY devNameChanged) + Q_PROPERTY(QString address READ address NOTIFY addressChanged) + Q_PROPERTY(QStringList nameList READ nameList NOTIFY nameListChanged) Q_PROPERTY(bool scanning READ scanning NOTIFY scanningChanged) Q_INVOKABLE void startScan (); Q_INVOKABLE void stopScan (); - QString device () { return _device; } - QString address () { return _address; } - QStringList deviceList () { return _deviceList; } + QString devName () { return _device.name; } + QString address () { return _device.address; } + QStringList nameList () { return _nameList; } bool scanning () { return _deviceDiscover != NULL; } - void setDevice (QString device); - void setAddress (QString address) { _address = address; emit addressChanged(); } + BluetoothData device () { return _device; } + + void setDevName (const QString& name); /// From LinkConfiguration LinkType type () { return LinkConfiguration::TypeBluetooth; } @@ -85,19 +113,16 @@ public slots: signals: void newDevice (QBluetoothDeviceInfo info); - void deviceChanged (); + void devNameChanged (); void addressChanged (); - void deviceListChanged (); + void nameListChanged (); void scanningChanged (); -private: - private: QBluetoothDeviceDiscoveryAgent* _deviceDiscover; - QString _device; - QString _address; - QStringList _deviceList; - QStringList _addressList; + BluetoothData _device; + QStringList _nameList; + QList _deviceList; }; class BluetoothLink : public LinkInterface @@ -133,9 +158,6 @@ public slots: void deviceConnected (); void deviceDisconnected (); void deviceError (QBluetoothSocket::SocketError error); - void stateChanged (QBluetoothSocket::SocketState state); - void deviceDiscovered (QBluetoothDeviceInfo info); - void doneScanning (); protected: @@ -159,7 +181,6 @@ private: QBluetoothSocket* _targetSocket; QBluetoothDeviceInfo* _targetDevice; - QBluetoothDeviceDiscoveryAgent* _deviceDiscover; bool _running; }; diff --git a/src/comm/LinkConfiguration.cc b/src/comm/LinkConfiguration.cc index 9af87788f..0779af060 100644 --- a/src/comm/LinkConfiguration.cc +++ b/src/comm/LinkConfiguration.cc @@ -36,7 +36,7 @@ This file is part of the QGROUNDCONTROL project #ifndef __mobile__ #include "LogReplayLink.h" #endif -#ifndef Q_OS_WIN +#ifdef __mobile__ #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; -#ifndef Q_OS_WIN +#ifdef __mobile__ case LinkConfiguration::TypeBluetooth: config = new BluetoothConfiguration(name); break; @@ -141,7 +141,7 @@ LinkConfiguration* LinkConfiguration::duplicateSettings(LinkConfiguration* sourc case TypeTcp: dupe = new TCPConfiguration(dynamic_cast(source)); break; -#ifndef Q_OS_WIN +#ifdef __mobile__ case TypeBluetooth: dupe = new BluetoothConfiguration(dynamic_cast(source)); break; diff --git a/src/comm/LinkConfiguration.h b/src/comm/LinkConfiguration.h index 082f09618..a874329a8 100644 --- a/src/comm/LinkConfiguration.h +++ b/src/comm/LinkConfiguration.h @@ -64,7 +64,7 @@ public: #endif TypeUdp, ///< UDP Link TypeTcp, ///< TCP Link -#ifndef Q_OS_WIN +#ifdef __mobile__ TypeBluetooth, ///< Bluetooth Link #endif #if 0 diff --git a/src/comm/LinkManager.cc b/src/comm/LinkManager.cc index 93b5e5c2a..3a01b6bab 100644 --- a/src/comm/LinkManager.cc +++ b/src/comm/LinkManager.cc @@ -44,7 +44,7 @@ This file is part of the QGROUNDCONTROL project #include "QGCApplication.h" #include "UDPLink.h" #include "TCPLink.h" -#ifndef Q_OS_WIN +#ifdef __mobile__ #include "BluetoothLink.h" #endif @@ -127,7 +127,7 @@ LinkInterface* LinkManager::createConnectedLink(LinkConfiguration* config) case LinkConfiguration::TypeTcp: pLink = new TCPLink(dynamic_cast(config)); break; -#ifndef Q_OS_WIN +#ifdef __mobile__ case LinkConfiguration::TypeBluetooth: pLink = new BluetoothLink(dynamic_cast(config)); break; @@ -367,7 +367,7 @@ void LinkManager::loadLinkConfigurationList() case LinkConfiguration::TypeTcp: pLink = (LinkConfiguration*)new TCPConfiguration(name); break; -#ifndef Q_OS_WIN +#ifdef __mobile__ case LinkConfiguration::TypeBluetooth: pLink = (LinkConfiguration*)new BluetoothConfiguration(name); break; @@ -714,7 +714,7 @@ QStringList LinkManager::linkTypeStrings(void) const #endif list += "UDP"; list += "TCP"; -#ifndef Q_OS_WIN +#ifdef __mobile__ list += "Bluetooth"; #endif #ifdef QT_DEBUG @@ -823,7 +823,7 @@ void LinkManager::_fixUnnamed(LinkConfiguration* config) #ifndef __ios__ case LinkConfiguration::TypeSerial: { QString tname = dynamic_cast(config)->portName(); -#ifdef Q_OS_WIN32 +#ifdef Q_OS_WIN tname.replace("\\\\.\\", ""); #else tname.replace("/dev/cu.", ""); @@ -845,11 +845,11 @@ void LinkManager::_fixUnnamed(LinkConfiguration* config) } } break; -#ifndef Q_OS_WIN +#ifdef __mobile__ case LinkConfiguration::TypeBluetooth: { BluetoothConfiguration* tconfig = dynamic_cast(config); if(tconfig) { - config->setName(QString("Bluetooth Device on %1").arg(tconfig->device())); + config->setName(QString("%1 (Bluetooth Device)").arg(tconfig->device().name)); } } break; diff --git a/src/comm/SerialLink.cc b/src/comm/SerialLink.cc index 308537e70..4f1b25087 100644 --- a/src/comm/SerialLink.cc +++ b/src/comm/SerialLink.cc @@ -471,7 +471,7 @@ void SerialConfiguration::setPortName(const QString& portName) QString SerialConfiguration::cleanPortDisplayname(const QString name) { QString pname = name.trimmed(); -#ifdef Q_OS_WIN32 +#ifdef Q_OS_WIN pname.replace("\\\\.\\", ""); #else pname.replace("/dev/cu.", ""); diff --git a/src/main.cc b/src/main.cc index 03a524fce..12ab5816a 100644 --- a/src/main.cc +++ b/src/main.cc @@ -50,7 +50,7 @@ This file is part of the QGROUNDCONTROL project #endif #endif -#ifndef Q_OS_WIN +#ifdef __mobile__ #include #endif @@ -140,7 +140,7 @@ int main(int argc, char *argv[]) #ifndef __ios__ qRegisterMetaType(); #endif -#ifndef Q_OS_WIN +#ifdef __mobile__ qRegisterMetaType(); qRegisterMetaType(); #endif diff --git a/src/ui/QGCLinkConfiguration.cc b/src/ui/QGCLinkConfiguration.cc index 8db70b76a..279a66a48 100644 --- a/src/ui/QGCLinkConfiguration.cc +++ b/src/ui/QGCLinkConfiguration.cc @@ -143,7 +143,7 @@ void QGCLinkConfiguration::_fixUnnamed(LinkConfiguration* config) #ifndef __ios__ case LinkConfiguration::TypeSerial: { QString tname = dynamic_cast(config)->portName(); -#ifdef Q_OS_WIN32 +#ifdef Q_OS_WIN tname.replace("\\\\.\\", ""); #else tname.replace("/dev/cu.", ""); diff --git a/src/ui/preferences/BluetoothSettings.qml b/src/ui/preferences/BluetoothSettings.qml index b6a10e4ec..c821ad4a4 100644 --- a/src/ui/preferences/BluetoothSettings.qml +++ b/src/ui/preferences/BluetoothSettings.qml @@ -39,8 +39,6 @@ Item { // No need } - property var _currentDevice: "" - Column { id: btColumn spacing: ScreenTools.defaultFontPixelHeight / 2 @@ -73,7 +71,7 @@ Item { } QGCLabel { id: deviceField - text: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth ? subEditConfig.device : "" + text: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth ? subEditConfig.devName : "" } } Row { @@ -111,10 +109,10 @@ Item { height: 1 width: _secondColumn color: qgcPal.button - visible: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth && subEditConfig.deviceList.length > 0 + visible: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth && subEditConfig.nameList.length > 0 } Repeater { - model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth ? subEditConfig.deviceList : "" + model: subEditConfig && subEditConfig.linkType === LinkConfiguration.TypeBluetooth ? subEditConfig.nameList : "" delegate: QGCButton { text: modelData @@ -123,7 +121,8 @@ Item { exclusiveGroup: linkGroup onClicked: { checked = true - _btSettings._currentDevice = modelData + if(subEditConfig && modelData !== "") + subEditConfig.devName = modelData } } } @@ -161,15 +160,6 @@ Item { subEditConfig.stopScan() } } - QGCButton { - width: ScreenTools.defaultFontPixelWidth * 10 - enabled: _btSettings._currentDevice && _btSettings._currentDevice !== "" - text: "Select" - onClicked: { - if(subEditConfig) - subEditConfig.device = _btSettings._currentDevice - } - } } } } diff --git a/src/ui/preferences/LinkSettings.qml b/src/ui/preferences/LinkSettings.qml index 4088ca33a..9afbbecbc 100644 --- a/src/ui/preferences/LinkSettings.qml +++ b/src/ui/preferences/LinkSettings.qml @@ -202,6 +202,7 @@ Rectangle { } } Flickable { + id: settingsFlick clip: true anchors.top: parent.top width: parent.width diff --git a/src/ui/preferences/SerialSettings.qml b/src/ui/preferences/SerialSettings.qml index b15101c78..06f4465ef 100644 --- a/src/ui/preferences/SerialSettings.qml +++ b/src/ui/preferences/SerialSettings.qml @@ -75,7 +75,7 @@ Item { } Component.onCompleted: { if(subEditConfig != null) { - if(subEditConfig.portDisplayName === "") + if(subEditConfig.portDisplayName === "" && QGroundControl.linkManager.serialPorts.length > 0) subEditConfig.portName = QGroundControl.linkManager.serialPorts[0] var index = commPortCombo.find(subEditConfig.portDisplayName) if (index === -1) { -- 2.22.0