5#include <QtCore/QCoreApplication>
6#include <QtCore/QPermissions>
7#include <QtCore/QThread>
16 , _workerThread(new QThread(this))
18 Q_ASSERT(_bluetoothConfig);
19 if (!_bluetoothConfig) {
20 qCCritical(BluetoothLinkLog) <<
"Invalid BluetoothConfiguration";
26 qCDebug(BluetoothLinkLog) <<
this;
29 ? QStringLiteral(
"BLE_%1") : QStringLiteral(
"Bluetooth_%1");
30 _workerThread->setObjectName(threadName.arg(_bluetoothConfig->name()));
32 _worker->moveToThread(_workerThread.data());
35 (void) connect(_workerThread.data(), &QThread::finished, _worker.data(), &QObject::deleteLater);
52 if (_workerThread->isRunning() && _connectedCache && _worker) {
53 (void) QMetaObject::invokeMethod(_worker,
"disconnectLink", Qt::QueuedConnection);
56 _workerThread->quit();
57 if (!_workerThread->wait(5000)) {
58 qCWarning(BluetoothLinkLog) <<
"Worker thread did not stop within timeout, terminating";
59 _workerThread->terminate();
60 (void) _workerThread->wait(1000);
64 qCDebug(BluetoothLinkLog) <<
this;
69 return _connectedCache;
72bool BluetoothLink::_connect()
77 if (_bluetoothConfig) {
80 return QMetaObject::invokeMethod(_worker.data(),
"connectLink", Qt::QueuedConnection);
86 (void) QMetaObject::invokeMethod(_worker.data(),
"disconnectLink", Qt::QueuedConnection);
90void BluetoothLink::_onConnected()
92 _connectedCache =
true;
93 _disconnectedEmitted =
false;
97void BluetoothLink::_onDisconnected()
99 _connectedCache =
false;
100 if (!_disconnectedEmitted.exchange(
true)) {
105void BluetoothLink::_onErrorOccurred(
const QString &
errorString)
107 qCWarning(BluetoothLinkLog) <<
"Communication error:" <<
errorString;
109 if (!_bluetoothConfig) {
115 ? tr(
"Bluetooth Low Energy") : tr(
"Bluetooth");
118 tr(
"Link %1: (Device: %2) %3").arg(_bluetoothConfig->
name(),
119 _bluetoothConfig->
device().name(),
123void BluetoothLink::_onDataReceived(
const QByteArray &data)
128void BluetoothLink::_onDataSent(
const QByteArray &data)
133void BluetoothLink::_onRssiUpdated(qint16 rssi)
135 if (_bluetoothConfig) {
140void BluetoothLink::_writeBytes(
const QByteArray &bytes)
143 (void) QMetaObject::invokeMethod(_worker.data(),
"writeData", Qt::QueuedConnection, Q_ARG(QByteArray, bytes));
147void BluetoothLink::_checkPermission()
149 QBluetoothPermission permission;
150 permission.setCommunicationModes(QBluetoothPermission::Access);
152 const Qt::PermissionStatus permissionStatus = QCoreApplication::instance()->checkPermission(permission);
153 if (permissionStatus == Qt::PermissionStatus::Undetermined) {
154 QCoreApplication::instance()->requestPermission(permission,
this, [
this](
const QPermission &perm) {
155 _handlePermissionStatus(perm.status());
158 _handlePermissionStatus(permissionStatus);
162void BluetoothLink::_handlePermissionStatus(Qt::PermissionStatus permissionStatus)
164 if (permissionStatus != Qt::PermissionStatus::Granted) {
165 qCWarning(BluetoothLinkLog) <<
"Bluetooth Permission Denied";
166 _onErrorOccurred(tr(
"Bluetooth Permission Denied"));
171 qCDebug(BluetoothLinkLog) <<
"Bluetooth Permission Granted";
173 if (_workerThread && !_workerThread->isRunning()) {
174 _workerThread->start();
175 if (!_workerThread->isRunning()) {
176 qCCritical(BluetoothLinkLog) <<
"Failed to start worker thread";
177 _onErrorOccurred(tr(
"Failed to start Bluetooth worker thread"));
178 _worker->deleteLater();
std::shared_ptr< LinkConfiguration > SharedLinkConfigurationPtr
#define QGC_LOGGING_CATEGORY(name, categoryStr)
void errorOccurred(const QString &errorString)
const QBluetoothDeviceInfo & device() const
void setConnectedRssi(qint16 rssi)
BluetoothMode mode() const
Q_INVOKABLE void stopScan()
bool isConnected() const override
void disconnect() override
~BluetoothLink() override
void dataReceived(const QByteArray &data)
void dataSent(const QByteArray &data)
void errorOccurred(const QString &errorString)
void rssiUpdated(qint16 rssi)
static BluetoothWorker * create(const BluetoothConfiguration *config, QObject *parent=nullptr)
The link interface defines the interface for all links used to communicate with the ground station ap...
void bytesReceived(LinkInterface *link, const QByteArray &data)
void communicationError(const QString &title, const QString &error)
void bytesSent(LinkInterface *link, const QByteArray &data)