BluetoothLink.h 6.38 KB
Newer Older
dogmaphobic's avatar
dogmaphobic committed
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41
/*=====================================================================

QGroundControl Open Source Ground Control Station

(c) 2009 - 2015 QGROUNDCONTROL PROJECT <http://www.qgroundcontrol.org>

This file is part of the QGROUNDCONTROL project

    QGROUNDCONTROL is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    QGROUNDCONTROL is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with QGROUNDCONTROL. If not, see <http://www.gnu.org/licenses/>.

======================================================================*/

/*!
 * @file
 *   @brief Bluetooth connection for unmanned vehicles
 *   @author Gus Grubba <mavlink@grubba.com>
 *
 */

#ifndef BTLINK_H
#define BTLINK_H

#include <QString>
#include <QList>
#include <QMutex>
#include <QMutexLocker>
#include <QQueue>
#include <QByteArray>
#include <QBluetoothDeviceInfo>
#include <QtBluetooth/QBluetoothSocket>
dogmaphobic's avatar
dogmaphobic committed
42 43
#include <qbluetoothserviceinfo.h>
#include <qbluetoothservicediscoveryagent.h>
dogmaphobic's avatar
dogmaphobic committed
44 45 46 47 48

#include "QGCConfig.h"
#include "LinkManager.h"

class QBluetoothDeviceDiscoveryAgent;
dogmaphobic's avatar
dogmaphobic committed
49
class QBluetoothServiceDiscoveryAgent;
dogmaphobic's avatar
dogmaphobic committed
50

51 52 53 54 55 56 57 58 59 60 61 62
class BluetoothData
{
public:
    BluetoothData()
    {
    }
    BluetoothData(const BluetoothData& other)
    {
        *this = other;
    }
    bool operator==(const BluetoothData& other)
    {
dogmaphobic's avatar
dogmaphobic committed
63 64 65 66 67
#ifdef __ios__
        return uuid == other.uuid && name == other.name;
#else
        return name == other.name && address == other.address;
#endif
68 69 70 71
    }
    BluetoothData& operator=(const BluetoothData& other)
    {
        name = other.name;
dogmaphobic's avatar
dogmaphobic committed
72 73 74
#ifdef __ios__
        uuid = other.uuid;
#else
75
        address = other.address;
dogmaphobic's avatar
dogmaphobic committed
76
#endif
77 78 79
        return *this;
    }
    QString name;
dogmaphobic's avatar
dogmaphobic committed
80 81 82
#ifdef __ios__
    QBluetoothUuid uuid;
#else
83
    QString address;
dogmaphobic's avatar
dogmaphobic committed
84
#endif
85 86
};

dogmaphobic's avatar
dogmaphobic committed
87 88 89 90 91 92 93 94 95 96
class BluetoothConfiguration : public LinkConfiguration
{
    Q_OBJECT

public:

    BluetoothConfiguration(const QString& name);
    BluetoothConfiguration(BluetoothConfiguration* source);
    ~BluetoothConfiguration();

97 98 99
    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)
dogmaphobic's avatar
dogmaphobic committed
100 101 102 103 104
    Q_PROPERTY(bool         scanning    READ scanning                     NOTIFY scanningChanged)

    Q_INVOKABLE void        startScan   ();
    Q_INVOKABLE void        stopScan    ();

105
    QString     devName                 () { return _device.name; }
dogmaphobic's avatar
dogmaphobic committed
106
    QString     address                 ();
107
    QStringList nameList                () { return _nameList; }
dogmaphobic's avatar
dogmaphobic committed
108 109
    bool        scanning                () { return _deviceDiscover != NULL; }

110 111 112
    BluetoothData    device             () { return _device; }

    void        setDevName              (const QString& name);
dogmaphobic's avatar
dogmaphobic committed
113 114 115 116 117 118 119

    /// From LinkConfiguration
    LinkType    type                    () { return LinkConfiguration::TypeBluetooth; }
    void        copyFrom                (LinkConfiguration* source);
    void        loadSettings            (QSettings& settings, const QString& root);
    void        saveSettings            (QSettings& settings, const QString& root);
    void        updateSettings          ();
120
    bool        isAutoConnectAllowed    () { return false; }
dogmaphobic's avatar
dogmaphobic committed
121 122 123 124 125 126 127 128
    QString     settingsURL             () { return "BluetoothSettings.qml"; }

public slots:
    void        deviceDiscovered        (QBluetoothDeviceInfo info);
    void        doneScanning            ();

signals:
    void        newDevice               (QBluetoothDeviceInfo info);
129
    void        devNameChanged          ();
dogmaphobic's avatar
dogmaphobic committed
130
    void        addressChanged          ();
131
    void        nameListChanged         ();
dogmaphobic's avatar
dogmaphobic committed
132 133 134 135
    void        scanningChanged         ();

private:
    QBluetoothDeviceDiscoveryAgent*     _deviceDiscover;
136 137 138
    BluetoothData                       _device;
    QStringList                         _nameList;
    QList<BluetoothData>                _deviceList;
dogmaphobic's avatar
dogmaphobic committed
139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173
};

class BluetoothLink : public LinkInterface
{
    Q_OBJECT

    friend class BluetoothConfiguration;
    friend class LinkManager;

public:
    void    requestReset            () { }
    bool    isConnected             () const;
    QString getName                 () const;

    // Extensive statistics for scientific purposes
    qint64  getConnectionSpeed      () const;
    qint64  getCurrentInDataRate    () const;
    qint64  getCurrentOutDataRate   () const;

    void run();

    // These are left unimplemented in order to cause linker errors which indicate incorrect usage of
    // connect/disconnect on link directly. All connect/disconnect calls should be made through LinkManager.
    bool    connect                 (void);
    bool    disconnect              (void);

    LinkConfiguration* getLinkConfiguration() { return _config; }

public slots:

    void    readBytes               ();
    void    writeBytes              (const char* data, qint64 length);
    void    deviceConnected         ();
    void    deviceDisconnected      ();
    void    deviceError             (QBluetoothSocket::SocketError error);
dogmaphobic's avatar
dogmaphobic committed
174 175 176 177 178
#ifdef __ios__
    void    serviceDiscovered       (const QBluetoothServiceInfo &info);
    void    discoveryFinished       ();
    void    discoveryError          (QBluetoothServiceDiscoveryAgent::Error error);
#endif
dogmaphobic's avatar
dogmaphobic committed
179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196

protected:

    BluetoothConfiguration*     _config;
    bool                        _connectState;

private:
    // Links are only created/destroyed by LinkManager so constructor/destructor is not public
    BluetoothLink(BluetoothConfiguration* config);
    ~BluetoothLink();

    // From LinkInterface
    bool _connect               (void);
    void _disconnect            (void);

    bool _hardwareConnect       ();
    void _restartConnection     ();
    void _sendBytes             (const char* data, qint64 size);
dogmaphobic's avatar
dogmaphobic committed
197
    void _createSocket          ();
dogmaphobic's avatar
dogmaphobic committed
198 199 200

private:

dogmaphobic's avatar
dogmaphobic committed
201 202 203 204 205 206 207
    QBluetoothSocket*           _targetSocket;
#ifdef __ios__
    QBluetoothServiceDiscoveryAgent* _discoveryAgent;
#endif

    bool                        _shutDown;

dogmaphobic's avatar
dogmaphobic committed
208 209 210
};

#endif // BTLINK_H