2727#include " logging.h"
2828#include " notifications.h"
2929
30- BluetoothControl::BluetoothControl (QObject *parent) : QObject(parent) {
30+ BluetoothControl::BluetoothControl (QObject *parent)
31+ : QObject(parent), m_discoveryAgent(nullptr ), m_dockSocket(nullptr ) {
3132 qCInfo (lcBluetooth) << " Bluetooth starting" ;
3233
33- // if there is a bluetooth device, let's set up some things
34+ // if there is a Bluetooth device, let's set up some things
35+ // FIXME move out of constructor
3436 if (m_localDevice.isValid ()) {
3537 qCDebug (lcBluetooth) << " Bluetooth init OK" ;
3638
39+ QObject::connect (&m_localDevice, &QBluetoothLocalDevice::pairingDisplayConfirmation, this ,
40+ &BluetoothControl::onPairingDisplayConfirmation);
41+ QObject::connect (&m_localDevice, &QBluetoothLocalDevice::pairingFinished, this ,
42+ &BluetoothControl::onPairingDone);
43+ QObject::connect (&m_localDevice, &QBluetoothLocalDevice::error, this , &BluetoothControl::onPairingError);
3744 } else {
3845 qCCritical (lcBluetooth) << " Bluetooth device was not found." ;
3946 Notifications::getInstance ()->add (true , tr (" Bluetooth device was not found." ));
4047 }
4148}
4249
43- void BluetoothControl::turnOn () {
44- if (m_localDevice.hostMode () == QBluetoothLocalDevice::HostPoweredOff) {
45- m_localDevice.powerOn ();
46- qCDebug (lcBluetooth) << " Bluetooth on" ;
47- }
50+ BluetoothControl::~BluetoothControl () {
51+ close ();
4852}
4953
50- void BluetoothControl::turnOff () {
51- m_localDevice.setHostMode (QBluetoothLocalDevice::HostPoweredOff);
52- qCDebug (lcBluetooth) << " Bluetooth off" ;
54+ bool BluetoothControl::isEnabled () {
55+ return (m_localDevice.hostMode () != QBluetoothLocalDevice::HostPoweredOff);
56+ }
57+
58+ void BluetoothControl::setEnabled (bool enabled) {
59+ if (enabled) {
60+ if (m_localDevice.hostMode () == QBluetoothLocalDevice::HostPoweredOff) {
61+ m_localDevice.powerOn ();
62+ qCInfo (lcBluetooth) << " Bluetooth on" ;
63+ }
64+ } else {
65+ m_localDevice.setHostMode (QBluetoothLocalDevice::HostPoweredOff);
66+ qCInfo (lcBluetooth) << " Bluetooth off" ;
67+ }
68+
69+ emit bluetoothStatusChanged ();
5370}
5471
5572void BluetoothControl::lookForDocks () {
56- turnOn ( );
73+ setEnabled ( true );
5774
58- qCDebug (lcBluetooth) << " Creating bluetooth discovery agent" ;
75+ qCDebug (lcBluetooth) << " Creating Bluetooth discovery agent" ;
5976 m_discoveryAgent = new QBluetoothDeviceDiscoveryAgent (this );
6077
6178 QObject::connect (m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, this ,
6279 &BluetoothControl::onDeviceDiscovered);
6380 QObject::connect (m_discoveryAgent, &QBluetoothDeviceDiscoveryAgent::finished, this ,
6481 &BluetoothControl::onDiscoveryFinished);
65- qCDebug (lcBluetooth) << " Starting Bluetooth discovery..." ;
82+
83+ qCInfo (lcBluetooth) << " Starting Bluetooth discovery..." ;
6684 m_discoveryAgent->start ();
6785}
6886
6987void BluetoothControl::onDeviceDiscovered (const QBluetoothDeviceInfo &device) {
88+ qCDebug (lcBluetooth ()) << " Discovered:" << device.address () << device.name ();
7089 // if dock is found
90+ // FIXME support multiple discovered docks
7191 if (device.name ().contains (" YIO-Dock" )) {
7292 // stop the discovery
7393 m_discoveryAgent->stop ();
@@ -78,61 +98,117 @@ void BluetoothControl::onDeviceDiscovered(const QBluetoothDeviceInfo &device) {
7898 } else {
7999 m_dockServiceUuid = QBluetoothUuid (QStringLiteral (" 00001101-0000-1000-8000-00805f9b34fb" ));
80100 }
101+
81102 QString name = device.name ();
103+ emit dockFound (name);
82104
83- emit dockFound (name);
84- qCDebug (lcBluetooth) << " YIO Dock found" << name;
105+ // TODO(zehnm) split pairing & socket connection from discovery: UI should initiate pairing & command sending
106+ qCInfo (lcBluetooth) << " YIO Dock found. Request pairing with " << name;
85107
86- QObject::connect (&m_localDevice, &QBluetoothLocalDevice::pairingFinished, this ,
87- &BluetoothControl::onPairingDone);
88- qCDebug (lcBluetooth) << " Pairing requested." ;
89108 m_localDevice.requestPairing (m_dockAddress, QBluetoothLocalDevice::Paired);
90109 }
91110}
92111
93112void BluetoothControl::onDiscoveryFinished () {
94- qCDebug (lcBluetooth) << " Bluetooth discovery finished." ;
95- if (m_discoveryAgent) {
96- m_discoveryAgent->deleteLater ();
113+ if (m_discoveryAgent->error () != QBluetoothDeviceDiscoveryAgent::NoError) {
114+ qCWarning (lcBluetooth) << " Bluetooth discovery finished with error:" << m_discoveryAgent->error ()
115+ << m_discoveryAgent->errorString ();
116+ dockSetupError ();
117+ } else {
118+ QMap<QString, QString> devices;
119+ for (const QBluetoothDeviceInfo &device : m_discoveryAgent->discoveredDevices ()) {
120+ devices.insert (device.address ().toString (), device.name ());
121+ }
122+ qCInfo (lcBluetooth) << " Bluetooth discovery finished." << devices;
97123 }
124+
125+ m_discoveryAgent->deleteLater ();
126+ m_discoveryAgent = nullptr ;
98127}
99128
100129void BluetoothControl::sendCredentialsToDock (const QString &msg) {
101130 qCDebug (lcBluetooth) << " Got the wifi credentials." ;
102131 m_dockMessage = msg;
103132}
104133
134+ void BluetoothControl::onPairingDisplayConfirmation (const QBluetoothAddress &address, QString pin) {
135+ qCInfo (lcBluetooth ()) << " Confirming pairing request" << address << pin;
136+ m_localDevice.pairingConfirmation (true );
137+ }
138+
139+ void BluetoothControl::onPairingDone (const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) {
140+ if (address == m_dockAddress && pairing == QBluetoothLocalDevice::Paired) {
141+ qCInfo (lcBluetooth) << " Pairing done with" << address;
142+ emit dockPaired (address.toString ());
143+ m_dockSocket = new QBluetoothSocket (QBluetoothServiceInfo::RfcommProtocol, this );
144+
145+ QObject::connect (m_dockSocket, &QBluetoothSocket::connected, this , &BluetoothControl::onDockConnected);
146+ QObject::connect (m_dockSocket, QOverload<QBluetoothSocket::SocketError>::of (&QBluetoothSocket::error), this ,
147+ &BluetoothControl::onDockSocketError);
148+
149+ m_dockSocket->connectToService (m_dockAddress, m_dockServiceUuid);
150+ qCDebug (lcBluetooth) << " Connecting to Bluetooth service" << m_dockAddress << " with uuid" << m_dockServiceUuid;
151+ }
152+ }
153+
154+ void BluetoothControl::onPairingError (QBluetoothLocalDevice::Error error) {
155+ Q_UNUSED (error)
156+ qCWarning (lcBluetooth) << " Pairing failed with" << m_dockAddress;
157+ dockSetupError ();
158+ }
159+
105160void BluetoothControl::onDockConnected () {
106- qCDebug (lcBluetooth) << " Open bluetooth socket" ;
107- // open bluetooth socket
108- m_dockSocket->open (QIODevice::WriteOnly);
161+ qCDebug (lcBluetooth) << " Opening Bluetooth socket to dock" ;
162+ emit dockConnected (m_dockAddress.toString (), m_dockServiceUuid.toString ());
109163
110- // format the message
164+ if (!m_dockSocket->open (QIODevice::WriteOnly)) {
165+ qCCritical (lcBluetooth ()) << " Could not open Bluetooth socket to dock" ;
166+ dockSetupError ();
167+ return ;
168+ }
169+
170+ // send credential message
111171 QByteArray text = m_dockMessage.toUtf8 () + ' \n ' ;
112172 qCDebug (lcBluetooth) << " Sending message to dock:" << text;
113- m_dockSocket->write (text);
114- qCDebug (lcBluetooth) << " Message sent to dock." ;
173+ if (m_dockSocket->write (text) == -1 ) {
174+ qCCritical (lcBluetooth ()) << " Could not send message to dock" ;
175+ dockSetupError ();
176+ return ;
177+ }
115178
179+ qCInfo (lcBluetooth) << " Wifi setup message sent to dock." ;
180+
181+ // TODO(zehnm) why this delay? For the dock to connect to wifi?
116182 QTimer::singleShot (6000 , [=]() {
117- // close and delete the socket
118- m_dockSocket->close ();
119- m_dockSocket->deleteLater ();
183+ close ();
184+ setEnabled (false );
120185
121- // power off the bluetooth
122- turnOff ();
123- m_discoveryAgent->deleteLater ();
124186 emit dockMessageSent ();
125187 });
126188}
127189
128- void BluetoothControl::onPairingDone (const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) {
129- if (address == m_dockAddress && pairing == QBluetoothLocalDevice::Paired) {
130- qCDebug (lcBluetooth) << " Pairing done." ;
131- m_dockSocket = new QBluetoothSocket (QBluetoothServiceInfo::RfcommProtocol, this );
132-
133- QObject::connect (m_dockSocket, &QBluetoothSocket::connected, this , &BluetoothControl::onDockConnected);
190+ void BluetoothControl::onDockSocketError (QBluetoothSocket::SocketError error) {
191+ qCCritical (lcBluetooth ()) << " Dock socket error:" << error << m_dockSocket->errorString ();
192+ dockSetupError ();
193+ }
134194
135- m_dockSocket->connectToService (m_dockAddress, m_dockServiceUuid);
136- qCDebug (lcBluetooth) << " Connecting to bluetooth service" << m_dockAddress << m_dockServiceUuid;
195+ void BluetoothControl::close () {
196+ if (m_dockSocket) {
197+ m_dockSocket->close ();
198+ m_dockSocket->deleteLater ();
199+ m_dockSocket = nullptr ;
137200 }
201+ if (m_discoveryAgent) {
202+ m_discoveryAgent->deleteLater ();
203+ m_discoveryAgent = nullptr ;
204+ }
205+ }
206+
207+ void BluetoothControl::dockSetupError () {
208+ close ();
209+ setEnabled (false );
210+
211+ // TODO(zehnm) restart Bluetooth service?
212+
213+ emit dockSetupFailed ();
138214}
0 commit comments