Enroute Flight Navigation
A navigation app for VFR pilots
TrafficDataSource_BluetoothLowEnergy.h
1/***************************************************************************
2 * Copyright (C) 2025-2026 by Stefan Kebekus *
3 * stefan.kebekus@gmail.com *
4 * *
5 * This program is free software; you can redistribute it and/or modify *
6 * it under the terms of the GNU General Public License as published by *
7 * the Free Software Foundation; either version 3 of the License, or *
8 * (at your option) any later version. *
9 * *
10 * This program is distributed in the hope that it will be useful, *
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of *
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
13 * GNU General Public License for more details. *
14 * *
15 * You should have received a copy of the GNU General Public License *
16 * along with this program; if not, write to the *
17 * Free Software Foundation, Inc., *
18 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. *
19 ***************************************************************************/
20
21#pragma once
22
23#include <QBluetoothDeviceDiscoveryAgent>
24#include <QBluetoothDeviceInfo>
25#include <QBluetoothLocalDevice>
26#include <QBluetoothPermission>
27#include <QBluetoothServiceInfo>
28#include <QBluetoothSocket>
29#include <QLowEnergyController>
30
31#include "traffic/TrafficDataSource_AbstractSocket.h"
32
33using namespace Qt::Literals::StringLiterals;
34
35
36namespace Traffic {
37
75
77 Q_OBJECT
78
79public:
88 TrafficDataSource_BluetoothLowEnergy(bool isCanonical, const QBluetoothDeviceInfo& info, QObject* parent);
89
90 // Standard destructor
91 ~TrafficDataSource_BluetoothLowEnergy() override = default;
92
93
94
95 //
96 // Properties
97 //
98
103 Q_PROPERTY(QBluetoothDeviceInfo sourceInfo READ sourceInfo CONSTANT)
104
105
106
107 //
108 // Getter Methods
109 //
110
111
115 [[nodiscard]] QString dataFormat() const override { return u"FLARM/NMEA"_s; }
116
124 [[nodiscard]] QString icon() const override { return u"/icons/material/ic_bluetooth.svg"_s; }
125
133 [[nodiscard]] QString sourceName() const override;
134
139 [[nodiscard]] QBluetoothDeviceInfo sourceInfo() const
140 {
141 return m_info;
142 }
143
144
145public slots:
152
159
160private slots:
161 // Read and process NMEA sentences
162 void onCharacteristicChanged(const QLowEnergyCharacteristic &characteristic, const QByteArray &newValue);
163
164 // Device discovery slots
165 void onDeviceDiscovered(const QBluetoothDeviceInfo &info);
166 void onDiscoveryFinished();
167
168 // Handle errors
169 void onControlerError(QLowEnergyController::Error error);
170
171 void onServiceDiscoveryFinished();
172 void onDiscoveryError(QBluetoothDeviceDiscoveryAgent::Error error);
173
174 void onServiceStateChanged(QLowEnergyService::ServiceState newState);
175
176 void onStateChanged(QLowEnergyController::ControllerState state);
177
178private:
179 Q_DISABLE_COPY_MOVE(TrafficDataSource_BluetoothLowEnergy)
180
181 // Permissions
182 QBluetoothPermission m_bluetoothPermission;
183
184 // Copied from the constructor
185 QBluetoothDeviceInfo m_info;
186
187 // Device discovery
188 QBluetoothDeviceDiscoveryAgent* m_discoveryAgent = nullptr;
189
190 // Helper to setup the controller since we'll recreate it often
191 void setupController(const QBluetoothDeviceInfo &info);
192 // Deletes and nulls the UART service objects (they are parented to this, not
193 // to the controller, so they must be cleaned up explicitly).
194 void cleanupServices();
195 QLowEnergyController* m_control = nullptr;
196
197 QLowEnergyService* m_nordicUARTService = nullptr;
198 QBluetoothUuid const nordicUARTServiceUuid {"6e400001-b5a3-f393-e0a9-e50e24dcca9e"};
199 QBluetoothUuid const nordicUARTTxCharacteristicID {"6e400003-b5a3-f393-e0a9-e50e24dcca9e"};
200
201 QLowEnergyService* m_simpleUARTService = nullptr;
202 QBluetoothUuid const simpleUARTServiceUuid {"0000ffe0-0000-1000-8000-00805f9b34fb"};
203 QBluetoothUuid const simpleUARTCharacteristicID {"0000ffe1-0000-1000-8000-00805f9b34fb"};
204};
205
206} // namespace Traffic
TrafficDataSource_AbstractSocket(bool isCanonical, QObject *parent)
Default constructor.
QString icon() const override
Getter function for the property with the same name.
TrafficDataSource_BluetoothLowEnergy(bool isCanonical, const QBluetoothDeviceInfo &info, QObject *parent)
Default constructor.
QBluetoothDeviceInfo sourceInfo() const
Getter function for the property with the same name.
QString dataFormat() const override
Getter function for the property with the same name.
void connectToTrafficReceiver() override
Start attempt to connect to traffic receiver.
void disconnectFromTrafficReceiver() override
Disconnect from traffic receiver.
QString sourceName() const override
Getter function for the property with the same name.