2020-10-08 20:01:21 +02:00
|
|
|
#ifndef BLUETOOTHLEUART_H
|
|
|
|
#define BLUETOOTHLEUART_H
|
|
|
|
|
|
|
|
#include <QBluetoothDeviceDiscoveryAgent>
|
|
|
|
#include <QBluetoothDeviceInfo>
|
|
|
|
#include <QLowEnergyController>
|
|
|
|
#include <QLowEnergyService>
|
|
|
|
|
|
|
|
#ifdef QBluetoothLeUart_QML
|
|
|
|
#include <QQmlApplicationEngine>
|
|
|
|
#endif
|
|
|
|
|
2020-10-08 22:03:31 +02:00
|
|
|
#include <qbluetoothleuartdevice.h>
|
2020-10-08 20:01:21 +02:00
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
/*!
|
|
|
|
* \mainpage Qt BluetoothLE UART library
|
|
|
|
*
|
|
|
|
* \section intro_sec Introduction
|
|
|
|
*
|
|
|
|
* This library can be used to talk to BLE devices via UART in Qt.
|
|
|
|
* It was designed to make taklking to device like the ESP32 from Qt easier.
|
|
|
|
*
|
|
|
|
* \section section Installation
|
|
|
|
* \code{.sh}
|
|
|
|
* cd yourRepo
|
|
|
|
* git submodule add https://itsblue.dev/itsblue-development/QBluetoothLeUart.git
|
|
|
|
* git submodule update --init --recursive
|
|
|
|
* \endcode
|
|
|
|
*
|
|
|
|
* And in your MyProject.pro include the .pri file:
|
|
|
|
* \code{.pro}
|
|
|
|
* # Optional: enable QML stuff
|
|
|
|
* CONFIG += QBluetoothLeUart_QML
|
|
|
|
* # Include library
|
|
|
|
* include($$PWD/QBluetoothLeUart/QBluetoothLeUart.pri)
|
|
|
|
* \endcode
|
|
|
|
*/
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief The QBluetoothLeUart class can be used to talk to BluetoothLE devices via UART effordlessly.
|
|
|
|
* It can be used via C++ and QML.
|
|
|
|
*/
|
2020-10-08 20:01:21 +02:00
|
|
|
class QBluetoothLeUart : public QObject
|
|
|
|
{
|
|
|
|
Q_OBJECT
|
2020-10-09 12:06:33 +02:00
|
|
|
Q_PROPERTY(QVariantList avaliableDevices READ getAvailableDevicesDetailList NOTIFY avaliableDevicesChanged)
|
2020-10-08 20:01:21 +02:00
|
|
|
Q_PROPERTY(BluetoothLeUartState state READ getState NOTIFY stateChanged)
|
|
|
|
|
|
|
|
public:
|
2020-10-09 12:06:33 +02:00
|
|
|
/*!
|
|
|
|
* \brief The BluetoothLeUartState enum contains all state of the QBluetoothLeUart class.
|
|
|
|
*/
|
2020-10-08 20:01:21 +02:00
|
|
|
enum BluetoothLeUartState {
|
2020-10-09 12:06:33 +02:00
|
|
|
Idle = 0, /*!< Waiting for instrucions */
|
|
|
|
Scanning, /*!< Scanning for devices */
|
|
|
|
ScanFinished, /*!< Scanning has finished, we are ready to connect */
|
|
|
|
Connecting, /*!< Trying to connect */
|
|
|
|
ScanningForService, /*!< Connection was successfull, now scanning for services */
|
|
|
|
ServiceFound, /*!< Services were found */
|
|
|
|
Connected /*!< Connected. We are now ready to send and receive */
|
2020-10-08 20:01:21 +02:00
|
|
|
};
|
|
|
|
Q_ENUM(BluetoothLeUartState)
|
|
|
|
|
|
|
|
enum BluetoothScanError {
|
|
|
|
UnknownError,
|
|
|
|
AdapterTurnedOffError,
|
|
|
|
InputOutputError
|
|
|
|
};
|
|
|
|
Q_ENUM(BluetoothScanError);
|
|
|
|
|
|
|
|
QBluetoothLeUart(QObject *parent = nullptr);
|
|
|
|
~QBluetoothLeUart();
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to register QMl types
|
|
|
|
*/
|
2020-10-08 20:01:21 +02:00
|
|
|
static void init();
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
/*!
|
|
|
|
* \brief Function to set the UUIDs of the bluetooth service
|
|
|
|
* \param uartServiceUUID Service UUID
|
|
|
|
* \param txUUID UUID of the characteristic used to send data
|
|
|
|
* \param rxUUID UUID of the characteristic used to receive data
|
|
|
|
*/
|
|
|
|
void setUUIDs(const char uartServiceUUID[36], const char txUUID[36], const char rxUUID[36]);
|
2020-10-08 22:03:31 +02:00
|
|
|
|
2020-10-08 20:01:21 +02:00
|
|
|
private:
|
2020-10-09 12:06:33 +02:00
|
|
|
|
|
|
|
// The UUIDs
|
2020-10-08 22:03:31 +02:00
|
|
|
QString uartServiceUUID;
|
|
|
|
QString txUUID;
|
2020-10-09 12:06:33 +02:00
|
|
|
QString rxUUID;
|
2020-10-08 22:03:31 +02:00
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
// current state
|
|
|
|
QBluetoothLeUart::BluetoothLeUartState state;
|
|
|
|
|
|
|
|
// QBluetooth controllers
|
2020-10-08 20:01:21 +02:00
|
|
|
QBluetoothDeviceDiscoveryAgent *bluetoothDeviceDiscoveryAgent;
|
|
|
|
QLowEnergyController *bluetoothController;
|
|
|
|
QLowEnergyService *bluetoothService;
|
2020-10-09 12:06:33 +02:00
|
|
|
|
|
|
|
// Bluetooth device
|
|
|
|
QBluetoothLeUartDevice *currentBluetoothDevice;
|
|
|
|
QList<QBluetoothLeUartDevice*> availableDevices;
|
2020-10-08 20:01:21 +02:00
|
|
|
QLowEnergyDescriptor bluetoothTransmissionDescriptor;
|
|
|
|
bool foundValidUARTService;
|
|
|
|
|
|
|
|
public slots:
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
/*!
|
|
|
|
* \brief Fuction to start scanning for devices
|
|
|
|
*
|
|
|
|
* This function will start the device scanning process and might emit
|
|
|
|
* the following signals during scanning:
|
|
|
|
* - foundNewDevice() when a new device is found
|
|
|
|
* - avaliableDevicesChanged() when a new device is found
|
|
|
|
* - scanFinished() when the scan has finished
|
|
|
|
* - scanningErrorOccured() when an error occured
|
|
|
|
*
|
|
|
|
* \see foundNewDevice()
|
|
|
|
* \see avaliableDevicesChanged()
|
|
|
|
* \see scanFinished()
|
|
|
|
* \see scanningErrorOccured()
|
|
|
|
*
|
|
|
|
* \return true if the scan started, false if the current state was not Idle
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE bool startScanningForDevices();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to stop scanning for devices
|
|
|
|
*
|
|
|
|
* \return true if the scan was stopped, false if the current state was not Scanning
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE bool stopScanningForDevices();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to get all devices that were found during the last scan
|
|
|
|
*
|
|
|
|
* A QBluetoothLeUartDevice object can be used to connect to the specific device
|
|
|
|
*
|
|
|
|
* \see connectToDevice()
|
|
|
|
*
|
|
|
|
* \return List of all devices found during last scan
|
|
|
|
*/
|
2020-10-08 20:01:21 +02:00
|
|
|
Q_INVOKABLE QList<QBluetoothLeUartDevice*> getAvailableDevices();
|
2020-10-09 12:06:33 +02:00
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to get a variant list of all devices that were found during the last scan
|
|
|
|
*
|
|
|
|
* This will return a QVariantList that contains QVariantMaps.
|
|
|
|
* The maps contain the following keys:
|
|
|
|
* - "id" (int): the internal id of the device (used to connect to it)
|
|
|
|
* - "name" (QString): the name of the device
|
|
|
|
* - "address" (QString): the bluetooth address of the device
|
|
|
|
*
|
|
|
|
* \see connectToDevice()
|
|
|
|
*
|
|
|
|
* \return Variant list of all devices found during last scan
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE QVariantList getAvailableDevicesDetailList();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function connect to a device using its internal id
|
|
|
|
*
|
|
|
|
* The id can be found using getAvailableDevicesDetailList()
|
|
|
|
* The connectedToDevice() signal will be emited as soon as the connection was successfull.
|
|
|
|
* As soon as that signal was emited, the sendData() slot can be used to send data and
|
|
|
|
* the dataReceived() signal will be emited whenever data is received.
|
|
|
|
*
|
|
|
|
* \param deviceId the internal id of the device
|
|
|
|
*
|
|
|
|
* \see getAvailableDevicesDetailList()
|
|
|
|
* \see connectedToDevice()
|
|
|
|
* \see dataReceived()
|
|
|
|
*
|
|
|
|
* \return false if the device was not found in the internal list of discovered devices, true otherwise
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE bool connectToDevice(int deviceId);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function connect to a device using a QBluetoothLeUartDevice object
|
|
|
|
*
|
|
|
|
* The QBluetoothLeUartDevice can be found using getAvailableDevices()
|
|
|
|
* The connectedToDevice() signal will be emited as soon as the connection was successfull.
|
|
|
|
* As soon as that signal was emited, the sendData() slot can be used to send data and
|
|
|
|
* the dataReceived() signal will be emited whenever data is received.
|
|
|
|
*
|
|
|
|
* \param device The device to connect to
|
|
|
|
*
|
|
|
|
* \see getAvailableDevices()
|
|
|
|
* \see connectedToDevice()
|
|
|
|
* \see dataReceived()
|
|
|
|
*
|
|
|
|
* \return false if the device was not found in the internal list of discovered devices, true otherwise
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE bool connectToDevice(QBluetoothLeUartDevice *device);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to disconnect from the current device
|
|
|
|
*
|
|
|
|
* \return false if no device was connected, true otherwise
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE bool disconnectFromDevice();
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to send data to the connected device
|
|
|
|
* \param data The data to send
|
|
|
|
* \return false if there was not device connected, true otherwise
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE bool sendData(QString data);
|
|
|
|
|
|
|
|
/*!
|
|
|
|
* \brief Function to get the current state of QBluetoothLeUart
|
|
|
|
* \see BluetoothLeUartState
|
|
|
|
* \return The current state
|
|
|
|
*/
|
|
|
|
Q_INVOKABLE QBluetoothLeUart::BluetoothLeUartState getState() const;
|
2020-10-08 20:01:21 +02:00
|
|
|
|
|
|
|
private slots:
|
|
|
|
void setState(QBluetoothLeUart::BluetoothLeUartState newState);
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
// Slots for QBluetothDeviceDiscoveryAgent
|
2020-10-08 20:01:21 +02:00
|
|
|
void handleDeviceDiscovered(const QBluetoothDeviceInfo&);
|
|
|
|
void handleScanFinished();
|
|
|
|
void handleDeviceScanError(QBluetoothDeviceDiscoveryAgent::Error);
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
// Slots for QLowEnergyController
|
|
|
|
void handleServiceDiscovered(const QBluetoothUuid & uuid);
|
2020-10-08 20:01:21 +02:00
|
|
|
void handleServiceScanDone();
|
|
|
|
void handleControllerError(QLowEnergyController::Error);
|
|
|
|
void handleDeviceConnected();
|
|
|
|
void handleDeviceDisconnected();
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
// Slots for QLowEnergyService
|
2020-10-08 20:01:21 +02:00
|
|
|
void handleServiceStateChange(QLowEnergyService::ServiceState s);
|
|
|
|
void handleServiceCharacteristicChange(const QLowEnergyCharacteristic &c, const QByteArray &value);
|
|
|
|
void handleServiceDescriptorWritten(const QLowEnergyDescriptor &d, const QByteArray &value);
|
|
|
|
|
|
|
|
signals:
|
|
|
|
void stateChanged(QBluetoothLeUart::BluetoothLeUartState newState);
|
2020-10-09 12:06:33 +02:00
|
|
|
|
2020-10-08 20:01:21 +02:00
|
|
|
void foundNewDevice(QBluetoothLeUartDevice* device);
|
2020-10-09 12:06:33 +02:00
|
|
|
void avaliableDevicesChanged(QList<QBluetoothLeUartDevice*> avaliableDevices);
|
|
|
|
void scanFinished(QList<QBluetoothLeUartDevice*> availableDevices);
|
2020-10-08 20:01:21 +02:00
|
|
|
void scanningErrorOccured(QBluetoothLeUart::BluetoothScanError error);
|
2020-10-09 12:06:33 +02:00
|
|
|
|
2020-10-08 20:01:21 +02:00
|
|
|
void connectedToDevice();
|
|
|
|
|
2020-10-09 12:06:33 +02:00
|
|
|
void dataReceived(QString s);
|
|
|
|
|
2020-10-08 20:01:21 +02:00
|
|
|
};
|
|
|
|
|
|
|
|
#endif // BLUETOOTHLEUART_H
|