| 1 | /**************************************************************************** | 
| 2 | ** | 
| 3 | ** Copyright (C) 2016 The Qt Company Ltd. | 
| 4 | ** Contact: https://www.qt.io/licensing/ | 
| 5 | ** | 
| 6 | ** This file is part of the QtBluetooth module of the Qt Toolkit. | 
| 7 | ** | 
| 8 | ** $QT_BEGIN_LICENSE:GPL-EXCEPT$ | 
| 9 | ** Commercial License Usage | 
| 10 | ** Licensees holding valid commercial Qt licenses may use this file in | 
| 11 | ** accordance with the commercial license agreement provided with the | 
| 12 | ** Software or, alternatively, in accordance with the terms contained in | 
| 13 | ** a written agreement between you and The Qt Company. For licensing terms | 
| 14 | ** and conditions see https://www.qt.io/terms-conditions. For further | 
| 15 | ** information use the contact form at https://www.qt.io/contact-us. | 
| 16 | ** | 
| 17 | ** GNU General Public License Usage | 
| 18 | ** Alternatively, this file may be used under the terms of the GNU | 
| 19 | ** General Public License version 3 as published by the Free Software | 
| 20 | ** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT | 
| 21 | ** included in the packaging of this file. Please review the following | 
| 22 | ** information to ensure the GNU General Public License requirements will | 
| 23 | ** be met: https://www.gnu.org/licenses/gpl-3.0.html. | 
| 24 | ** | 
| 25 | ** $QT_END_LICENSE$ | 
| 26 | ** | 
| 27 | ****************************************************************************/ | 
| 28 |  | 
| 29 | #include "btlocaldevice.h" | 
| 30 | #include <QDebug> | 
| 31 | #include <QTimer> | 
| 32 | #ifdef Q_OS_ANDROID | 
| 33 | #include <QtAndroidExtras/QtAndroid> | 
| 34 | #endif | 
| 35 | #include <QtBluetooth/QBluetoothServiceInfo> | 
| 36 |  | 
| 37 | #define BTCHAT_DEVICE_ADDR "00:15:83:38:17:C3" | 
| 38 |  | 
| 39 | //same uuid as examples/bluetooth/btchat | 
| 40 | //the reverse UUID is only used on Android to counter | 
| 41 | //https://issuetracker.google.com/issues/37076498 (tracked via QTBUG-61392) | 
| 42 | #define TEST_SERVICE_UUID "e8e10f95-1a70-4b27-9ccf-02010264e9c8" | 
| 43 | #define TEST_REVERSE_SERVICE_UUID "c8e96402-0102-cf9c-274b-701a950fe1e8" | 
| 44 |  | 
| 45 | #define SOCKET_PROTOCOL QBluetoothServiceInfo::RfcommProtocol | 
| 46 | //#define SOCKET_PROTOCOL QBluetoothServiceInfo::L2capProtocol | 
| 47 |  | 
| 48 | BtLocalDevice::BtLocalDevice(QObject *parent) : | 
| 49 |     QObject(parent), securityFlags(QBluetooth::NoSecurity) | 
| 50 | { | 
| 51 |     localDevice = new QBluetoothLocalDevice(this); | 
| 52 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::error, | 
| 53 |             receiver: this, slot: &BtLocalDevice::error); | 
| 54 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::hostModeStateChanged, | 
| 55 |             receiver: this, slot: &BtLocalDevice::hostModeStateChanged); | 
| 56 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::pairingFinished, | 
| 57 |             receiver: this, slot: &BtLocalDevice::pairingFinished); | 
| 58 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::deviceConnected, | 
| 59 |             receiver: this, slot: &BtLocalDevice::connected); | 
| 60 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::deviceDisconnected, | 
| 61 |             receiver: this, slot: &BtLocalDevice::disconnected); | 
| 62 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::pairingDisplayConfirmation, | 
| 63 |             receiver: this, slot: &BtLocalDevice::pairingDisplayConfirmation); | 
| 64 |     connect(sender: localDevice, signal: &QBluetoothLocalDevice::pairingDisplayPinCode, | 
| 65 |             receiver: this, slot: &BtLocalDevice::pairingDisplayPinCode); | 
| 66 |  | 
| 67 |     if (localDevice->isValid()) { | 
| 68 |         deviceAgent = new QBluetoothDeviceDiscoveryAgent(this); | 
| 69 |         connect(sender: deviceAgent, signal: &QBluetoothDeviceDiscoveryAgent::deviceDiscovered, | 
| 70 |                 receiver: this, slot: &BtLocalDevice::deviceDiscovered); | 
| 71 |         connect(sender: deviceAgent, signal: &QBluetoothDeviceDiscoveryAgent::finished, | 
| 72 |                 receiver: this, slot: &BtLocalDevice::discoveryFinished); | 
| 73 |         connect(sender: deviceAgent, signal: QOverload<QBluetoothDeviceDiscoveryAgent::Error>::of(ptr: &QBluetoothDeviceDiscoveryAgent::error), | 
| 74 |                 receiver: this, slot: &BtLocalDevice::discoveryError); | 
| 75 |         connect(sender: deviceAgent, signal: &QBluetoothDeviceDiscoveryAgent::canceled, | 
| 76 |                 receiver: this, slot: &BtLocalDevice::discoveryCanceled); | 
| 77 |  | 
| 78 |         serviceAgent = new QBluetoothServiceDiscoveryAgent(this); | 
| 79 |         connect(sender: serviceAgent, signal: &QBluetoothServiceDiscoveryAgent::serviceDiscovered, | 
| 80 |                 receiver: this, slot: &BtLocalDevice::serviceDiscovered); | 
| 81 |         connect(sender: serviceAgent, signal: &QBluetoothServiceDiscoveryAgent::finished, | 
| 82 |                 receiver: this, slot: &BtLocalDevice::serviceDiscoveryFinished); | 
| 83 |         connect(sender: serviceAgent, signal: &QBluetoothServiceDiscoveryAgent::canceled, | 
| 84 |                 receiver: this, slot: &BtLocalDevice::serviceDiscoveryCanceled); | 
| 85 |         connect(sender: serviceAgent, signal: QOverload<QBluetoothServiceDiscoveryAgent::Error>::of(ptr: &QBluetoothServiceDiscoveryAgent::error), | 
| 86 |                 receiver: this, slot: &BtLocalDevice::serviceDiscoveryError); | 
| 87 |  | 
| 88 |         socket = new QBluetoothSocket(SOCKET_PROTOCOL, this); | 
| 89 |         connect(sender: socket, signal: &QBluetoothSocket::stateChanged, | 
| 90 |                 receiver: this, slot: &BtLocalDevice::socketStateChanged); | 
| 91 |         connect(sender: socket, signal: QOverload<QBluetoothSocket::SocketError>::of(ptr: &QBluetoothSocket::error), | 
| 92 |                 receiver: this, slot: &BtLocalDevice::socketError); | 
| 93 |         connect(sender: socket, signal: &QBluetoothSocket::connected, receiver: this, slot: &BtLocalDevice::socketConnected); | 
| 94 |         connect(sender: socket, signal: &QBluetoothSocket::disconnected, receiver: this, slot: &BtLocalDevice::socketDisconnected); | 
| 95 |         connect(sender: socket, signal: &QIODevice::readyRead, receiver: this, slot: &BtLocalDevice::readData); | 
| 96 |         connect(sender: socket, signal: &QBluetoothSocket::bytesWritten, context: this, slot: [](qint64 bytesWritten){ | 
| 97 |             qDebug() << "Bytes Written to Client socket:"  << bytesWritten; | 
| 98 |         }); | 
| 99 |         setSecFlags(static_cast<int>(socket->preferredSecurityFlags())); | 
| 100 |  | 
| 101 |         server = new QBluetoothServer(SOCKET_PROTOCOL, this); | 
| 102 |         connect(sender: server, signal: &QBluetoothServer::newConnection, receiver: this, slot: &BtLocalDevice::serverNewConnection); | 
| 103 |         connect(sender: server, signal: QOverload<QBluetoothServer::Error>::of(ptr: &QBluetoothServer::error), | 
| 104 |                 receiver: this, slot: &BtLocalDevice::serverError); | 
| 105 |     } else { | 
| 106 |         deviceAgent = nullptr; | 
| 107 |         serviceAgent = nullptr; | 
| 108 |         socket = nullptr; | 
| 109 |         server = nullptr; | 
| 110 |     } | 
| 111 | } | 
| 112 |  | 
| 113 | BtLocalDevice::~BtLocalDevice() | 
| 114 | { | 
| 115 |     while (!serverSockets.isEmpty()) | 
| 116 |     { | 
| 117 |         QBluetoothSocket* s = serverSockets.takeFirst(); | 
| 118 |         s->abort(); | 
| 119 |         s->deleteLater(); | 
| 120 |     } | 
| 121 | } | 
| 122 |  | 
| 123 | int BtLocalDevice::secFlags() const | 
| 124 | { | 
| 125 |     return static_cast<int>(securityFlags); | 
| 126 | } | 
| 127 |  | 
| 128 | void BtLocalDevice::setSecFlags(int newFlags) | 
| 129 | { | 
| 130 |     QBluetooth::SecurityFlags fl(newFlags); | 
| 131 |  | 
| 132 |     if (securityFlags != fl) { | 
| 133 |         securityFlags = fl; | 
| 134 |         emit secFlagsChanged(); | 
| 135 |     } | 
| 136 | } | 
| 137 |  | 
| 138 | QString BtLocalDevice::hostMode() const | 
| 139 | { | 
| 140 |     switch (localDevice->hostMode()) { | 
| 141 |     case QBluetoothLocalDevice::HostDiscoverable: | 
| 142 |         return QStringLiteral("HostMode: Discoverable" ); | 
| 143 |     case QBluetoothLocalDevice::HostConnectable: | 
| 144 |         return QStringLiteral("HostMode: Connectable" ); | 
| 145 |     case QBluetoothLocalDevice::HostDiscoverableLimitedInquiry: | 
| 146 |         return QStringLiteral("HostMode: DiscoverableLimit" ); | 
| 147 |     case QBluetoothLocalDevice::HostPoweredOff: | 
| 148 |         return QStringLiteral("HostMode: Powered Off" ); | 
| 149 |     } | 
| 150 |  | 
| 151 |     return QStringLiteral("HostMode: <None>" ); | 
| 152 | } | 
| 153 |  | 
| 154 | void BtLocalDevice::setHostMode(int newMode) | 
| 155 | { | 
| 156 |     localDevice->setHostMode(static_cast<QBluetoothLocalDevice::HostMode>(newMode)); | 
| 157 | } | 
| 158 |  | 
| 159 | void BtLocalDevice::requestPairingUpdate(bool isPairing) | 
| 160 | { | 
| 161 |     QBluetoothAddress baddr(BTCHAT_DEVICE_ADDR); | 
| 162 |     if (baddr.isNull()) | 
| 163 |         return; | 
| 164 |  | 
| 165 |  | 
| 166 |  | 
| 167 |     if (isPairing) { | 
| 168 |         //toggle between authorized and non-authorized pairing to achieve better | 
| 169 |         //level of testing | 
| 170 |         static short pairing = 0; | 
| 171 |         if ((pairing%2) == 1) | 
| 172 |             localDevice->requestPairing(address: baddr, pairing: QBluetoothLocalDevice::Paired); | 
| 173 |         else | 
| 174 |             localDevice->requestPairing(address: baddr, pairing: QBluetoothLocalDevice::AuthorizedPaired); | 
| 175 |         pairing++; | 
| 176 |     } else { | 
| 177 |         localDevice->requestPairing(address: baddr, pairing: QBluetoothLocalDevice::Unpaired); | 
| 178 |     } | 
| 179 |  | 
| 180 |     for (int i = 0; i < foundTestServers.count(); i++) { | 
| 181 |         if (isPairing) | 
| 182 |             localDevice->requestPairing(address: foundTestServers.at(i).device().address(), | 
| 183 |                                     pairing: QBluetoothLocalDevice::Paired); | 
| 184 |         else | 
| 185 |             localDevice->requestPairing(address: foundTestServers.at(i).device().address(), | 
| 186 |                                     pairing: QBluetoothLocalDevice::Unpaired); | 
| 187 |     } | 
| 188 | } | 
| 189 |  | 
| 190 | void BtLocalDevice::pairingFinished(const QBluetoothAddress &address, QBluetoothLocalDevice::Pairing pairing) | 
| 191 | { | 
| 192 |     qDebug() << "(Un)Pairing finished"  << address.toString() << pairing; | 
| 193 | } | 
| 194 |  | 
| 195 | void BtLocalDevice::connected(const QBluetoothAddress &addr) | 
| 196 | { | 
| 197 |     qDebug() << "Newly connected device"  << addr.toString(); | 
| 198 | } | 
| 199 |  | 
| 200 | void BtLocalDevice::disconnected(const QBluetoothAddress &addr) | 
| 201 | { | 
| 202 |     qDebug() << "Newly disconnected device"  << addr.toString(); | 
| 203 | } | 
| 204 |  | 
| 205 | void BtLocalDevice::pairingDisplayConfirmation(const QBluetoothAddress &address, const QString &pin) | 
| 206 | { | 
| 207 |     qDebug() << "PairingDisplayConfirmation"  << address << pin; | 
| 208 |     QTimer::singleShot(msec: 3000, receiver: this, SLOT(confirmPairing())); | 
| 209 | } | 
| 210 |  | 
| 211 | void BtLocalDevice::pairingDisplayPinCode(const QBluetoothAddress &address, const QString &pin) | 
| 212 | { | 
| 213 |     qDebug() << "PairingDisplayPinCode"  << address << pin; | 
| 214 | } | 
| 215 |  | 
| 216 | void BtLocalDevice::confirmPairing() | 
| 217 | { | 
| 218 |     static bool confirm = false; | 
| 219 |     confirm = !confirm; //toggle | 
| 220 |     qDebug() << "######"  << "Sending pairing confirmation: "  << confirm; | 
| 221 |     localDevice->pairingConfirmation(confirmation: confirm); | 
| 222 | } | 
| 223 |  | 
| 224 | void BtLocalDevice::cycleSecurityFlags() | 
| 225 | { | 
| 226 |     if (securityFlags.testFlag(flag: QBluetooth::Secure)) | 
| 227 |         setSecFlags(QBluetooth::NoSecurity); | 
| 228 |     else if (securityFlags.testFlag(flag: QBluetooth::Encryption)) | 
| 229 |         setSecFlags(secFlags() | QBluetooth::Secure); | 
| 230 |     else if (securityFlags.testFlag(flag: QBluetooth::Authentication)) | 
| 231 |         setSecFlags(secFlags() | QBluetooth::Encryption); | 
| 232 |     else if (securityFlags.testFlag(flag: QBluetooth::Authorization)) | 
| 233 |         setSecFlags(secFlags() | QBluetooth::Authentication); | 
| 234 |     else | 
| 235 |         setSecFlags(secFlags() | QBluetooth::Authorization); | 
| 236 | } | 
| 237 |  | 
| 238 | void BtLocalDevice::deviceDiscovered(const QBluetoothDeviceInfo &info) | 
| 239 | { | 
| 240 |     QString services; | 
| 241 |     if (info.serviceClasses() & QBluetoothDeviceInfo::PositioningService) | 
| 242 |         services += "Position|" ; | 
| 243 |     if (info.serviceClasses() & QBluetoothDeviceInfo::NetworkingService) | 
| 244 |         services += "Network|" ; | 
| 245 |     if (info.serviceClasses() & QBluetoothDeviceInfo::RenderingService) | 
| 246 |         services += "Rendering|" ; | 
| 247 |     if (info.serviceClasses() & QBluetoothDeviceInfo::CapturingService) | 
| 248 |         services += "Capturing|" ; | 
| 249 |     if (info.serviceClasses() & QBluetoothDeviceInfo::ObjectTransferService) | 
| 250 |         services += "ObjectTra|" ; | 
| 251 |     if (info.serviceClasses() & QBluetoothDeviceInfo::AudioService) | 
| 252 |         services += "Audio|" ; | 
| 253 |     if (info.serviceClasses() & QBluetoothDeviceInfo::TelephonyService) | 
| 254 |         services += "Telephony|" ; | 
| 255 |     if (info.serviceClasses() & QBluetoothDeviceInfo::InformationService) | 
| 256 |         services += "Information|" ; | 
| 257 |  | 
| 258 |     services.truncate(pos: services.length()-1); //cut last '/' | 
| 259 |  | 
| 260 |     qDebug() << "Found new device: "  << info.name() << info.isValid() << info.address().toString() | 
| 261 |                                      << info.rssi() << info.majorDeviceClass() | 
| 262 |                                      << info.minorDeviceClass() << services; | 
| 263 |  | 
| 264 | } | 
| 265 |  | 
| 266 | void BtLocalDevice::discoveryFinished() | 
| 267 | { | 
| 268 |     qDebug() << "###### Device Discovery Finished" ; | 
| 269 | } | 
| 270 |  | 
| 271 | void BtLocalDevice::discoveryCanceled() | 
| 272 | { | 
| 273 |     qDebug() << "###### Device Discovery Canceled" ; | 
| 274 | } | 
| 275 |  | 
| 276 | void BtLocalDevice::discoveryError(QBluetoothDeviceDiscoveryAgent::Error error) | 
| 277 | { | 
| 278 |     auto *client = qobject_cast<QBluetoothDeviceDiscoveryAgent *>(object: sender()); | 
| 279 |     if (!client) | 
| 280 |         return; | 
| 281 |     qDebug() << "###### Device Discovery Error:"  << error << (client ? client->errorString() : QString()); | 
| 282 | } | 
| 283 |  | 
| 284 | void BtLocalDevice::startDiscovery() | 
| 285 | { | 
| 286 |     if (deviceAgent) { | 
| 287 |         qDebug() << "###### Starting device discovery process" ; | 
| 288 |         deviceAgent->start(method: QBluetoothDeviceDiscoveryAgent::ClassicMethod); | 
| 289 |     } | 
| 290 | } | 
| 291 |  | 
| 292 | void BtLocalDevice::stopDiscovery() | 
| 293 | { | 
| 294 |     if (deviceAgent) { | 
| 295 |         qDebug() << "Stopping device discovery process" ; | 
| 296 |         deviceAgent->stop(); | 
| 297 |     } | 
| 298 | } | 
| 299 |  | 
| 300 | void BtLocalDevice::startServiceDiscovery(bool isMinimalDiscovery) | 
| 301 | { | 
| 302 |     if (serviceAgent) { | 
| 303 |         serviceAgent->setRemoteAddress(QBluetoothAddress()); | 
| 304 |  | 
| 305 |         qDebug() << "###### Starting service discovery process" ; | 
| 306 |         serviceAgent->start(mode: isMinimalDiscovery | 
| 307 |                             ? QBluetoothServiceDiscoveryAgent::MinimalDiscovery | 
| 308 |                             : QBluetoothServiceDiscoveryAgent::FullDiscovery); | 
| 309 |     } | 
| 310 | } | 
| 311 |  | 
| 312 | void BtLocalDevice::startTargettedServiceDiscovery() | 
| 313 | { | 
| 314 |     if (serviceAgent) { | 
| 315 |         const QBluetoothAddress baddr(BTCHAT_DEVICE_ADDR); | 
| 316 |         qDebug() << "###### Starting service discovery on"  | 
| 317 |                  << baddr.toString(); | 
| 318 |         if (baddr.isNull()) | 
| 319 |             return; | 
| 320 |  | 
| 321 |         if (!serviceAgent->setRemoteAddress(baddr)) { | 
| 322 |             qWarning() << "###### Cannot set remote address. Aborting" ; | 
| 323 |             return; | 
| 324 |         } | 
| 325 |  | 
| 326 |         serviceAgent->start(); | 
| 327 |     } | 
| 328 | } | 
| 329 |  | 
| 330 | void BtLocalDevice::stopServiceDiscovery() | 
| 331 | { | 
| 332 |     if (serviceAgent) { | 
| 333 |         qDebug() << "Stopping service discovery process" ; | 
| 334 |         serviceAgent->stop(); | 
| 335 |     } | 
| 336 | } | 
| 337 |  | 
| 338 | void BtLocalDevice::serviceDiscovered(const QBluetoothServiceInfo &info) | 
| 339 | { | 
| 340 |     QStringList classIds; | 
| 341 |     const QList<QBluetoothUuid> uuids = info.serviceClassUuids(); | 
| 342 |     for (const QBluetoothUuid &uuid : uuids) | 
| 343 |         classIds.append(t: uuid.toString()); | 
| 344 |     qDebug() << "$$ Found new service"  << info.device().address().toString() | 
| 345 |              << info.serviceUuid() << info.serviceName() << info.serviceDescription() << classIds; | 
| 346 |  | 
| 347 |     bool matchingService = | 
| 348 |             (info.serviceUuid() == QBluetoothUuid(QString(TEST_SERVICE_UUID))); | 
| 349 | #ifdef Q_OS_ANDROID | 
| 350 |     if (QtAndroid::androidSdkVersion() >= 23) //bug introduced by Android 6.0.1 | 
| 351 |         matchingService = matchingService | 
| 352 |             || (info.serviceUuid() == QBluetoothUuid(QString(TEST_REVERSE_SERVICE_UUID))); | 
| 353 | #endif | 
| 354 |  | 
| 355 |     if (matchingService | 
| 356 |             || info.serviceClassUuids().contains(t: QBluetoothUuid(QString(TEST_SERVICE_UUID)))) | 
| 357 |     { | 
| 358 |         //This is here to detect the test server for SPP testing later on | 
| 359 |         bool alreadyKnown = false; | 
| 360 |         for (const QBluetoothServiceInfo& found : qAsConst(t&: foundTestServers)) { | 
| 361 |             if (found.device().address() == info.device().address()) { | 
| 362 |                 alreadyKnown = true; | 
| 363 |                 break; | 
| 364 |             } | 
| 365 |         } | 
| 366 |  | 
| 367 |         if (!alreadyKnown) { | 
| 368 |             foundTestServers.append(t: info); | 
| 369 |             qDebug() << "@@@@@@@@ Adding:"  << info.device().address().toString(); | 
| 370 |         } | 
| 371 |     } | 
| 372 | } | 
| 373 |  | 
| 374 | void BtLocalDevice::serviceDiscoveryFinished() | 
| 375 | { | 
| 376 |     qDebug() << "###### Service Discovery Finished" ; | 
| 377 | } | 
| 378 |  | 
| 379 | void BtLocalDevice::serviceDiscoveryCanceled() | 
| 380 | { | 
| 381 |     qDebug() << "###### Service Discovery Canceled" ; | 
| 382 | } | 
| 383 |  | 
| 384 | void BtLocalDevice::serviceDiscoveryError(QBluetoothServiceDiscoveryAgent::Error error) | 
| 385 | { | 
| 386 |     auto *client = qobject_cast<QBluetoothServiceDiscoveryAgent *>(object: sender()); | 
| 387 |     if (!client) | 
| 388 |         return; | 
| 389 |     qDebug() << "###### Service Discovery Error:"  << error << (client ? client->errorString() : QString()); | 
| 390 | } | 
| 391 |  | 
| 392 | void BtLocalDevice::dumpServiceDiscovery() | 
| 393 | { | 
| 394 |     if (deviceAgent) { | 
| 395 |         qDebug() << "Device Discovery active:"  << deviceAgent->isActive(); | 
| 396 |         qDebug() << "Error:"  << deviceAgent->error() << deviceAgent->errorString(); | 
| 397 |         const QList<QBluetoothDeviceInfo> list = deviceAgent->discoveredDevices(); | 
| 398 |         qDebug() << "Discovered Devices:"  << list.count(); | 
| 399 |  | 
| 400 |         for (const QBluetoothDeviceInfo &info : list) | 
| 401 |             qDebug() << info.name() << info.address().toString() << info.rssi(); | 
| 402 |     } | 
| 403 |     if (serviceAgent) { | 
| 404 |         qDebug() << "Service Discovery active:"  << serviceAgent->isActive(); | 
| 405 |         qDebug() << "Error:"  << serviceAgent->error() << serviceAgent->errorString(); | 
| 406 |         const QList<QBluetoothServiceInfo> list = serviceAgent->discoveredServices(); | 
| 407 |         qDebug() << "Discovered Services:"  << list.count(); | 
| 408 |  | 
| 409 |         for (const QBluetoothServiceInfo &i : list) { | 
| 410 |             qDebug() << i.device().address().toString() << i.device().name() << i.serviceName(); | 
| 411 |         } | 
| 412 |  | 
| 413 |         qDebug() << "###### TestServer offered by:" ; | 
| 414 |         for (const QBluetoothServiceInfo& found : qAsConst(t&: foundTestServers)) { | 
| 415 |             qDebug() << found.device().name() << found.device().address().toString(); | 
| 416 |         } | 
| 417 |     } | 
| 418 | } | 
| 419 |  | 
| 420 | void BtLocalDevice::connectToService() | 
| 421 | { | 
| 422 |     if (socket) { | 
| 423 |         if (socket->preferredSecurityFlags() != securityFlags) | 
| 424 |             socket->setPreferredSecurityFlags(securityFlags); | 
| 425 |         socket->connectToService(address: QBluetoothAddress(BTCHAT_DEVICE_ADDR),uuid: QBluetoothUuid(QString(TEST_SERVICE_UUID))); | 
| 426 |     } | 
| 427 | } | 
| 428 |  | 
| 429 | void BtLocalDevice::connectToServiceViaSearch() | 
| 430 | { | 
| 431 |     if (socket) { | 
| 432 |         qDebug() << "###### Connecting to service socket" ; | 
| 433 |         if (!foundTestServers.isEmpty()) { | 
| 434 |             if (socket->preferredSecurityFlags() != securityFlags) | 
| 435 |                 socket->setPreferredSecurityFlags(securityFlags); | 
| 436 |  | 
| 437 |             QBluetoothServiceInfo info = foundTestServers.at(i: 0); | 
| 438 |             socket->connectToService(service: info); | 
| 439 |         } else { | 
| 440 |             qWarning() << "Perform search for test service before triggering this function" ; | 
| 441 |         } | 
| 442 |     } | 
| 443 | } | 
| 444 |  | 
| 445 | void BtLocalDevice::disconnectToService() | 
| 446 | { | 
| 447 |     if (socket) { | 
| 448 |         qDebug() << "###### Disconnecting socket" ; | 
| 449 |         socket->disconnectFromService(); | 
| 450 |     } | 
| 451 | } | 
| 452 |  | 
| 453 | void BtLocalDevice::closeSocket() | 
| 454 | { | 
| 455 |     if (socket) { | 
| 456 |         qDebug() << "###### Closing socket" ; | 
| 457 |         socket->close(); | 
| 458 |     } | 
| 459 |  | 
| 460 |     if (!serverSockets.isEmpty()) { | 
| 461 |         qDebug() << "###### Closing server sockets" ; | 
| 462 |         for (QBluetoothSocket *s : serverSockets) | 
| 463 |             s->close(); | 
| 464 |     } | 
| 465 | } | 
| 466 |  | 
| 467 | void BtLocalDevice::abortSocket() | 
| 468 | { | 
| 469 |     if (socket) { | 
| 470 |         qDebug() << "###### Disconnecting socket" ; | 
| 471 |         socket->abort(); | 
| 472 |     } | 
| 473 |  | 
| 474 |     if (!serverSockets.isEmpty()) { | 
| 475 |         qDebug() << "###### Closing server sockets" ; | 
| 476 |         for (QBluetoothSocket *s : serverSockets) | 
| 477 |             s->abort(); | 
| 478 |     } | 
| 479 | } | 
| 480 |  | 
| 481 | void BtLocalDevice::socketConnected() | 
| 482 | { | 
| 483 |     qDebug() << "###### Socket connected" ; | 
| 484 | } | 
| 485 |  | 
| 486 | void BtLocalDevice::socketDisconnected() | 
| 487 | { | 
| 488 |     qDebug() << "###### Socket disconnected" ; | 
| 489 | } | 
| 490 |  | 
| 491 | void BtLocalDevice::socketError(QBluetoothSocket::SocketError error) | 
| 492 | { | 
| 493 |     auto *client = qobject_cast<QBluetoothSocket *>(object: sender()); | 
| 494 |  | 
| 495 |     qDebug() << "###### Socket error"  << error << (client ? client->errorString() : QString()); | 
| 496 | } | 
| 497 |  | 
| 498 | void BtLocalDevice::socketStateChanged(QBluetoothSocket::SocketState state) | 
| 499 | { | 
| 500 |     qDebug() << "###### Socket state"  << state; | 
| 501 |     emit socketStateUpdate(foobar: static_cast<int>(state)); | 
| 502 | } | 
| 503 |  | 
| 504 | void BtLocalDevice::dumpSocketInformation() | 
| 505 | { | 
| 506 |     if (socket) { | 
| 507 |         qDebug() << "*******************************" ; | 
| 508 |         qDebug() << "Local info (addr, name, port):"  << socket->localAddress().toString() | 
| 509 |                  << socket->localName() << socket->localPort(); | 
| 510 |         qDebug() << "Peer Info (adr, name, port):"  << socket->peerAddress().toString() | 
| 511 |                  << socket->peerName() << socket->peerPort(); | 
| 512 |         qDebug() << "socket type:"  << socket->socketType(); | 
| 513 |         qDebug() << "socket state:"  << socket->state(); | 
| 514 |         qDebug() << "socket bytesAvailable()"  << socket->bytesAvailable(); | 
| 515 |         QString tmp; | 
| 516 |         switch (socket->error()) { | 
| 517 |             case QBluetoothSocket::NoSocketError: tmp += "NoSocketError" ; break; | 
| 518 |             case QBluetoothSocket::UnknownSocketError: tmp += "UnknownSocketError" ; break; | 
| 519 |             case QBluetoothSocket::HostNotFoundError: tmp += "HostNotFoundError" ; break; | 
| 520 |             case QBluetoothSocket::ServiceNotFoundError: tmp += "ServiceNotFound" ; break; | 
| 521 |             case QBluetoothSocket::NetworkError: tmp += "NetworkError" ; break; | 
| 522 |             //case QBluetoothSocket::OperationError: tmp+= "OperationError"; break; | 
| 523 |             case QBluetoothSocket::UnsupportedProtocolError: tmp += "UnsupportedProtocolError" ; break; | 
| 524 |             default: tmp+= "Undefined" ; break; | 
| 525 |         } | 
| 526 |  | 
| 527 |         qDebug() << "socket error:"  << tmp << socket->errorString(); | 
| 528 |     } else { | 
| 529 |         qDebug() << "No valid socket existing" ; | 
| 530 |     } | 
| 531 | } | 
| 532 |  | 
| 533 | void BtLocalDevice::writeData() | 
| 534 | { | 
| 535 |     const char * testData = "ABCABC\n" ; | 
| 536 |     if (socket && socket->state() == QBluetoothSocket::ConnectedState) { | 
| 537 |         socket->write(data: testData); | 
| 538 |     } | 
| 539 |     for (QBluetoothSocket* client : serverSockets) { | 
| 540 |         client->write(data: testData); | 
| 541 |     } | 
| 542 | } | 
| 543 |  | 
| 544 | void BtLocalDevice::readData() | 
| 545 | { | 
| 546 |     if (socket) { | 
| 547 |         while (socket->canReadLine()) { | 
| 548 |             QByteArray line = socket->readLine().trimmed(); | 
| 549 |             qDebug() << ">> peer("  << socket->peerName() << socket->peerAddress() | 
| 550 |                      << socket->peerPort() << ") local("  | 
| 551 |                      << socket->localName() << socket->localAddress() << socket->localPort() | 
| 552 |                      << ")>>"  << QString::fromUtf8(str: line.constData(), size: line.length()); | 
| 553 |         } | 
| 554 |     } | 
| 555 | } | 
| 556 |  | 
| 557 | void BtLocalDevice::serverError(QBluetoothServer::Error error) | 
| 558 | { | 
| 559 |     qDebug() << "###### Server socket error"  << error; | 
| 560 | } | 
| 561 |  | 
| 562 | void BtLocalDevice::serverListenPort() | 
| 563 | { | 
| 564 |     if (server && localDevice) { | 
| 565 |         if (server->isListening() || serviceInfo.isRegistered()) { | 
| 566 |             qDebug() << "###### Already listening"  << serviceInfo.isRegistered(); | 
| 567 |             return; | 
| 568 |         } | 
| 569 |  | 
| 570 |         if (server->securityFlags() != securityFlags) { | 
| 571 |             qDebug() << "###### Setting security policy on server socket"  << securityFlags; | 
| 572 |             server->setSecurityFlags(securityFlags); | 
| 573 |         } | 
| 574 |  | 
| 575 |         qDebug() << "###### Start listening via port" ; | 
| 576 |         bool ret = server->listen(address: localDevice->address()); | 
| 577 |         qDebug() << "###### Listening(Expecting TRUE):"  << ret; | 
| 578 |  | 
| 579 |         if (!ret) | 
| 580 |             return; | 
| 581 |  | 
| 582 |         QBluetoothServiceInfo::Sequence profileSequence; | 
| 583 |         QBluetoothServiceInfo::Sequence classId; | 
| 584 |         classId << QVariant::fromValue(value: QBluetoothUuid(QBluetoothUuid::SerialPort)); | 
| 585 |         classId << QVariant::fromValue(value: quint16(0x100)); | 
| 586 |         profileSequence.append(t: QVariant::fromValue(value: classId)); | 
| 587 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::BluetoothProfileDescriptorList, | 
| 588 |                                  value: profileSequence); | 
| 589 |  | 
| 590 |         classId.clear(); | 
| 591 |         classId << QVariant::fromValue(value: QBluetoothUuid(QString(TEST_SERVICE_UUID))); | 
| 592 |         classId << QVariant::fromValue(value: QBluetoothUuid(QBluetoothUuid::SerialPort)); | 
| 593 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::ServiceClassIds, value: classId); | 
| 594 |  | 
| 595 |         // Service name, description and provider | 
| 596 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::ServiceName, value: tr(s: "Bt Chat Server" )); | 
| 597 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::ServiceDescription, | 
| 598 |                                  value: tr(s: "Example bluetooth chat server" )); | 
| 599 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::ServiceProvider, value: tr(s: "qt-project.org" )); | 
| 600 |  | 
| 601 |         // Service UUID set | 
| 602 |         serviceInfo.setServiceUuid(QBluetoothUuid(QString(TEST_SERVICE_UUID))); | 
| 603 |  | 
| 604 |  | 
| 605 |         // Service Discoverability | 
| 606 |         QBluetoothServiceInfo::Sequence browseSequence; | 
| 607 |         browseSequence << QVariant::fromValue(value: QBluetoothUuid(QBluetoothUuid::PublicBrowseGroup)); | 
| 608 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::BrowseGroupList, value: browseSequence); | 
| 609 |  | 
| 610 |         // Protocol descriptor list | 
| 611 |         QBluetoothServiceInfo::Sequence protocolDescriptorList; | 
| 612 |         QBluetoothServiceInfo::Sequence protocol; | 
| 613 |         protocol << QVariant::fromValue(value: QBluetoothUuid(QBluetoothUuid::L2cap)); | 
| 614 |         if (server->serverType() == QBluetoothServiceInfo::L2capProtocol) | 
| 615 |             protocol << QVariant::fromValue(value: server->serverPort()); | 
| 616 |         protocolDescriptorList.append(t: QVariant::fromValue(value: protocol)); | 
| 617 |  | 
| 618 |         if (server->serverType() == QBluetoothServiceInfo::RfcommProtocol) { | 
| 619 |             protocol.clear(); | 
| 620 |             protocol << QVariant::fromValue(value: QBluetoothUuid(QBluetoothUuid::Rfcomm)) | 
| 621 |                      << QVariant::fromValue(value: quint8(server->serverPort())); | 
| 622 |             protocolDescriptorList.append(t: QVariant::fromValue(value: protocol)); | 
| 623 |         } | 
| 624 |         serviceInfo.setAttribute(attributeId: QBluetoothServiceInfo::ProtocolDescriptorList, | 
| 625 |                                  value: protocolDescriptorList); | 
| 626 |  | 
| 627 |         //Register service | 
| 628 |         qDebug() << "###### Registering service on"  << localDevice->address().toString() << server->serverPort(); | 
| 629 |         bool result = serviceInfo.registerService(localAdapter: localDevice->address()); | 
| 630 |         if (!result) { | 
| 631 |             server->close(); | 
| 632 |             qDebug() << "###### Reverting registration due to SDP failure." ; | 
| 633 |         } | 
| 634 |     } | 
| 635 |  | 
| 636 | } | 
| 637 |  | 
| 638 | void BtLocalDevice::serverListenUuid() | 
| 639 | { | 
| 640 |     if (server) { | 
| 641 |         if (server->isListening() || serviceInfo.isRegistered()) { | 
| 642 |             qDebug() << "###### Already listening"  << serviceInfo.isRegistered(); | 
| 643 |             return; | 
| 644 |         } | 
| 645 |  | 
| 646 |         if (server->securityFlags() != securityFlags) { | 
| 647 |             qDebug() << "###### Setting security policy on server socket"  << securityFlags; | 
| 648 |             server->setSecurityFlags(securityFlags); | 
| 649 |         } | 
| 650 |  | 
| 651 |         qDebug() << "###### Start listening via UUID" ; | 
| 652 |         serviceInfo = server->listen(uuid: QBluetoothUuid(QString(TEST_SERVICE_UUID)), serviceName: tr(s: "Bt Chat Server" )); | 
| 653 |         qDebug() << "###### Listening(Expecting TRUE, TRUE):"  << serviceInfo.isRegistered() << serviceInfo.isValid(); | 
| 654 |     } | 
| 655 | } | 
| 656 |  | 
| 657 | void BtLocalDevice::serverClose() | 
| 658 | { | 
| 659 |     if (server) { | 
| 660 |         qDebug() << "###### Closing Server socket" ; | 
| 661 |         if (serviceInfo.isRegistered()) | 
| 662 |             serviceInfo.unregisterService(); | 
| 663 |         server->close(); | 
| 664 |     } | 
| 665 | } | 
| 666 |  | 
| 667 | void BtLocalDevice::serverNewConnection() | 
| 668 | { | 
| 669 |     qDebug() << "###### New incoming server connection, pending:"  << server->hasPendingConnections(); | 
| 670 |     if (!server->hasPendingConnections()) { | 
| 671 |         qDebug() << "FAIL: expected pending server connection" ; | 
| 672 |         return; | 
| 673 |     } | 
| 674 |     QBluetoothSocket *client = server->nextPendingConnection(); | 
| 675 |     if (!client) { | 
| 676 |         qDebug() << "FAIL: Cannot obtain pending server connection" ; | 
| 677 |         return; | 
| 678 |     } | 
| 679 |  | 
| 680 |     client->setParent(this); | 
| 681 |     connect(sender: client, signal: &QBluetoothSocket::disconnected, receiver: this, slot: &BtLocalDevice::clientSocketDisconnected); | 
| 682 |     connect(sender: client, signal: &QIODevice::readyRead, receiver: this, slot: &BtLocalDevice::clientSocketReadyRead); | 
| 683 |     connect(sender: client, signal: &QBluetoothSocket::stateChanged, | 
| 684 |             receiver: this, slot: &BtLocalDevice::socketStateChanged); | 
| 685 |     connect(sender: client, signal: QOverload<QBluetoothSocket::SocketError>::of(ptr: &QBluetoothSocket::error), | 
| 686 |             receiver: this, slot: &BtLocalDevice::socketError); | 
| 687 |     connect(sender: client, signal: &QBluetoothSocket::connected, receiver: this, slot: &BtLocalDevice::socketConnected); | 
| 688 |     connect(sender: client, signal: &QBluetoothSocket::bytesWritten, context: this, slot: [](qint64 bytesWritten){ | 
| 689 |         qDebug() << "Bytes Written to Server socket:"  << bytesWritten; | 
| 690 |     }); | 
| 691 |     serverSockets.append(t: client); | 
| 692 | } | 
| 693 |  | 
| 694 | void BtLocalDevice::clientSocketDisconnected() | 
| 695 | { | 
| 696 |     auto *client = qobject_cast<QBluetoothSocket *>(object: sender()); | 
| 697 |     if (!client) | 
| 698 |         return; | 
| 699 |  | 
| 700 |     qDebug() << "######"  << "Removing server socket connection" ; | 
| 701 |  | 
| 702 |     serverSockets.removeOne(t: client); | 
| 703 |     client->deleteLater(); | 
| 704 | } | 
| 705 |  | 
| 706 |  | 
| 707 | void BtLocalDevice::clientSocketReadyRead() | 
| 708 | { | 
| 709 |     auto *socket = qobject_cast<QBluetoothSocket *>(object: sender()); | 
| 710 |     if (!socket) | 
| 711 |         return; | 
| 712 |  | 
| 713 |     while (socket->canReadLine()) { | 
| 714 |         const QByteArray line = socket->readLine().trimmed(); | 
| 715 |         QString lineString = QString::fromUtf8(str: line.constData(), size: line.length()); | 
| 716 |         qDebug() <<  ">>("  << server->serverAddress() << server->serverPort()  <<")>>"  | 
| 717 |                  << lineString; | 
| 718 |  | 
| 719 |         //when using the tst_QBluetoothSocket we echo received text back | 
| 720 |         //Any line starting with "Echo:" will be echoed | 
| 721 |         if (lineString.startsWith(QStringLiteral("Echo:" ))) { | 
| 722 |             qDebug() << "Assuming tst_qbluetoothsocket as client. Echoing back." ; | 
| 723 |             lineString += QLatin1Char('\n'); | 
| 724 |             socket->write(data: lineString.toUtf8()); | 
| 725 |         } | 
| 726 |     } | 
| 727 | } | 
| 728 |  | 
| 729 |  | 
| 730 | void BtLocalDevice::dumpServerInformation() | 
| 731 | { | 
| 732 |     static QBluetooth::SecurityFlags secFlag = QBluetooth::Authentication; | 
| 733 |     if (server) { | 
| 734 |         qDebug() << "*******************************" ; | 
| 735 |         qDebug() << "server port:"  <<server->serverPort() | 
| 736 |                  << "type:"  << server->serverType() | 
| 737 |                  << "address:"  << server->serverAddress().toString(); | 
| 738 |         qDebug() << "error:"  << server->error(); | 
| 739 |         qDebug() << "listening:"  << server->isListening() | 
| 740 |                  << "hasPending:"  << server->hasPendingConnections() | 
| 741 |                  << "maxPending:"  << server->maxPendingConnections(); | 
| 742 |         qDebug() << "security:"  << server->securityFlags() << "Togling security flag" ; | 
| 743 |         if (secFlag == QBluetooth::Authentication) | 
| 744 |             secFlag = QBluetooth::Encryption; | 
| 745 |         else | 
| 746 |             secFlag = QBluetooth::Authentication; | 
| 747 |  | 
| 748 |         //server->setSecurityFlags(secFlag); | 
| 749 |  | 
| 750 |         for (const QBluetoothSocket *client : qAsConst(t&: serverSockets)) { | 
| 751 |             qDebug() << "##"  << client->localAddress().toString() | 
| 752 |                      << client->localName() << client->localPort(); | 
| 753 |             qDebug() << "##"  << client->peerAddress().toString() | 
| 754 |                      << client->peerName() << client->peerPort(); | 
| 755 |             qDebug() << client->socketType() << client->state(); | 
| 756 |             qDebug() << "Pending bytes: "  << client->bytesAvailable(); | 
| 757 |             QString tmp; | 
| 758 |             switch (client->error()) { | 
| 759 |             case QBluetoothSocket::NoSocketError: tmp += "NoSocketError" ; break; | 
| 760 |             case QBluetoothSocket::UnknownSocketError: tmp += "UnknownSocketError" ; break; | 
| 761 |             case QBluetoothSocket::HostNotFoundError: tmp += "HostNotFoundError" ; break; | 
| 762 |             case QBluetoothSocket::ServiceNotFoundError: tmp += "ServiceNotFound" ; break; | 
| 763 |             case QBluetoothSocket::NetworkError: tmp += "NetworkError" ; break; | 
| 764 |             case QBluetoothSocket::UnsupportedProtocolError: tmp += "UnsupportedProtocolError" ; break; | 
| 765 |             //case QBluetoothSocket::OperationError: tmp+= "OperationError"; break; | 
| 766 |             default: tmp += QString::number(static_cast<int>(client->error())); break; | 
| 767 |             } | 
| 768 |  | 
| 769 |             qDebug() << "socket error:"  << tmp << client->errorString(); | 
| 770 |         } | 
| 771 |     } | 
| 772 | } | 
| 773 |  | 
| 774 | void BtLocalDevice::dumpInformation() | 
| 775 | { | 
| 776 |     qDebug() << "###### default local device" ; | 
| 777 |     dumpLocalDevice(dev: localDevice); | 
| 778 |     const QList<QBluetoothHostInfo> list = QBluetoothLocalDevice::allDevices(); | 
| 779 |     qDebug() << "Found local devices: "   << list.count(); | 
| 780 |     for (const QBluetoothHostInfo &info : list) { | 
| 781 |         qDebug() << "    "  << info.address().toString() << " "  <<info.name(); | 
| 782 |     } | 
| 783 |  | 
| 784 |     QBluetoothAddress address(QStringLiteral("11:22:33:44:55:66" )); | 
| 785 |     QBluetoothLocalDevice temp(address); | 
| 786 |     qDebug() << "###### 11:22:33:44:55:66 address valid:"  << !address.isNull(); | 
| 787 |     dumpLocalDevice(dev: &temp); | 
| 788 |  | 
| 789 |     QBluetoothAddress address2; | 
| 790 |     QBluetoothLocalDevice temp2(address2); | 
| 791 |     qDebug() << "###### 00:00:00:00:00:00 address valid:"  << !address2.isNull(); | 
| 792 |     dumpLocalDevice(dev: &temp2); | 
| 793 |  | 
| 794 |     const QBluetoothAddress BB(BTCHAT_DEVICE_ADDR); | 
| 795 |     qDebug() << "###### Bonding state with"  <<  QString(BTCHAT_DEVICE_ADDR) << ":"  << localDevice->pairingStatus(address: BB); | 
| 796 |     qDebug() << "###### Bonding state with"  << address2.toString() << ": "  << localDevice->pairingStatus(address: address2); | 
| 797 |     qDebug() << "###### Bonding state with"  << address.toString() << ": "  << localDevice->pairingStatus(address); | 
| 798 |  | 
| 799 |     qDebug() << "###### Connected Devices" ; | 
| 800 |     const QList<QBluetoothAddress> connectedDevices = localDevice->connectedDevices(); | 
| 801 |     for (const QBluetoothAddress &addr : connectedDevices) | 
| 802 |         qDebug() << "    "  << addr.toString(); | 
| 803 |  | 
| 804 |     qDebug() << "###### Discovered Devices" ; | 
| 805 |     if (deviceAgent) { | 
| 806 |         const QList<QBluetoothDeviceInfo> devices = deviceAgent->discoveredDevices(); | 
| 807 |         for (const QBluetoothDeviceInfo &info : devices) { | 
| 808 |             deviceDiscovered(info); | 
| 809 |         } | 
| 810 |     } | 
| 811 |  | 
| 812 |     QBluetoothDeviceDiscoveryAgent invalidAgent(QBluetoothAddress("11:22:33:44:55:66" )); | 
| 813 |     invalidAgent.start(); | 
| 814 |     qDebug() << "######"  << "Testing device discovery agent constructor with invalid address" ; | 
| 815 |     qDebug() << "######"  << (invalidAgent.error() == QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError) | 
| 816 |                          << "(Expected: true)" ; | 
| 817 |     QBluetoothDeviceDiscoveryAgent validAgent(localDevice->address()); | 
| 818 |     validAgent.start(); | 
| 819 |     qDebug() << "######"  << (validAgent.error() == QBluetoothDeviceDiscoveryAgent::NoError) << "(Expected: true)" ; | 
| 820 |  | 
| 821 |     QBluetoothServiceDiscoveryAgent invalidSAgent(QBluetoothAddress("11:22:33:44:55:66" )); | 
| 822 |     invalidSAgent.start(); | 
| 823 |     qDebug() << "######"  << "Testing service discovery agent constructor with invalid address" ; | 
| 824 |     qDebug() << "######"  << (invalidSAgent.error() == QBluetoothServiceDiscoveryAgent::InvalidBluetoothAdapterError) | 
| 825 |                          << "(Expected: true)" ; | 
| 826 |     QBluetoothServiceDiscoveryAgent validSAgent(localDevice->address()); | 
| 827 |     validSAgent.start(); | 
| 828 |     qDebug() << "######"  << (validSAgent.error() == QBluetoothServiceDiscoveryAgent::NoError) << "(Expected: true)" ; | 
| 829 | } | 
| 830 |  | 
| 831 | void BtLocalDevice::powerOn() | 
| 832 | { | 
| 833 |     qDebug() << "Powering on" ; | 
| 834 |     localDevice->powerOn(); | 
| 835 | } | 
| 836 |  | 
| 837 | void BtLocalDevice::reset() | 
| 838 | { | 
| 839 |     emit error(error: static_cast<QBluetoothLocalDevice::Error>(1000)); | 
| 840 |     if (serviceAgent) { | 
| 841 |         serviceAgent->clear(); | 
| 842 |     } | 
| 843 |     foundTestServers.clear(); | 
| 844 | } | 
| 845 |  | 
| 846 | void BtLocalDevice::dumpLocalDevice(QBluetoothLocalDevice *dev) | 
| 847 | { | 
| 848 |     qDebug() << "    Valid: "  << dev->isValid(); | 
| 849 |     qDebug() << "    Name"  << dev->name(); | 
| 850 |     qDebug() << "    Address"  << dev->address().toString(); | 
| 851 |     qDebug() << "    HostMode"  << dev->hostMode(); | 
| 852 | } | 
| 853 |  |