Skip to content
BluetoothLink.h 5.65 KiB
Newer Older
dogmaphobic's avatar
dogmaphobic committed
/*=====================================================================

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>

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

class QBluetoothDeviceDiscoveryAgent;

class BluetoothConfiguration : public LinkConfiguration
{
    Q_OBJECT

public:

    BluetoothConfiguration(const QString& name);
    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(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; }
    bool        scanning                () { return _deviceDiscover != NULL; }

    void        setDevice               (QString device);
    void        setAddress              (QString address) { _address = address; emit addressChanged(); }

    /// 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          ();
    QString     settingsURL             () { return "BluetoothSettings.qml"; }

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

signals:
    void        newDevice               (QBluetoothDeviceInfo info);
    void        deviceChanged           ();
    void        addressChanged          ();
    void        deviceListChanged       ();
    void        scanningChanged         ();

private:

private:
    QBluetoothDeviceDiscoveryAgent*     _deviceDiscover;
    QString                             _device;
    QString                             _address;
    QStringList                         _deviceList;
    QStringList                         _addressList;
};

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);
    void    stateChanged            (QBluetoothSocket::SocketState state);
    void    deviceDiscovered        (QBluetoothDeviceInfo info);
    void    doneScanning            ();

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);

private:

    QBluetoothSocket*                   _targetSocket;
    QBluetoothDeviceInfo*               _targetDevice;
    QBluetoothDeviceDiscoveryAgent*     _deviceDiscover;
    bool                                _running;
};

#endif // BTLINK_H