From ec4aa0bcb592e9668b0767906157a1a51915d76c Mon Sep 17 00:00:00 2001 From: Nedim Hadzic Date: Thu, 20 Mar 2014 12:08:08 +0100 Subject: Added and improved error handling in controller class Error enums added and implemented together with examples. Change-Id: I912c396080ee9a6b87f41104eb7e41f8c62abf8b Reviewed-by: Alex Blasche --- .../bluetooth/btfiletransfer/btfiletransfer.pro | 2 +- examples/bluetooth/heartlistener/heartrate.cpp | 14 +++-- examples/bluetooth/heartlistener/heartrate.h | 5 +- examples/bluetooth/lowenergyscanner/device.cpp | 7 ++- examples/bluetooth/lowenergyscanner/device.h | 4 +- src/bluetooth/qlowenergycontroller.cpp | 29 ++++++++- src/bluetooth/qlowenergycontroller.h | 13 +++- src/bluetooth/qlowenergycontroller_bluez.cpp | 19 +++--- src/bluetooth/qlowenergycontroller_p.cpp | 3 +- src/bluetooth/qlowenergycontroller_p.h | 1 + src/bluetooth/qlowenergycontroller_qnx.cpp | 72 ++++++++++++++-------- .../tst_qbluetoothservicediscoveryagent.cpp | 1 + 12 files changed, 117 insertions(+), 53 deletions(-) diff --git a/examples/bluetooth/btfiletransfer/btfiletransfer.pro b/examples/bluetooth/btfiletransfer/btfiletransfer.pro index 00b16415..e5d47302 100644 --- a/examples/bluetooth/btfiletransfer/btfiletransfer.pro +++ b/examples/bluetooth/btfiletransfer/btfiletransfer.pro @@ -26,5 +26,5 @@ OTHER_FILES += \ RESOURCES += \ btfiletransfer.qrc -target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/scanner +target.path = $$[QT_INSTALL_EXAMPLES]/bluetooth/btfiletransfer INSTALLS += target diff --git a/examples/bluetooth/heartlistener/heartrate.cpp b/examples/bluetooth/heartlistener/heartrate.cpp index a1f80121..7d135e5b 100644 --- a/examples/bluetooth/heartlistener/heartrate.cpp +++ b/examples/bluetooth/heartlistener/heartrate.cpp @@ -145,8 +145,10 @@ void HeartRate::connectToService(const QString &address) m_leInfo = new QLowEnergyController(); connect(m_leInfo, SIGNAL(connected(QLowEnergyServiceInfo)), this, SLOT(serviceConnected(QLowEnergyServiceInfo))); connect(m_leInfo, SIGNAL(disconnected(QLowEnergyServiceInfo)), this, SLOT(serviceDisconnected(QLowEnergyServiceInfo))); - connect(m_leInfo, SIGNAL(error(QLowEnergyServiceInfo)), this, SLOT(errorReceived(QLowEnergyServiceInfo))); - connect(m_leInfo, SIGNAL(error(QLowEnergyCharacteristicInfo)), this, SLOT(errorReceivedCharacteristic(QLowEnergyCharacteristicInfo))); + connect(m_leInfo, SIGNAL(error(QLowEnergyServiceInfo,QLowEnergyController::Error)), + this, SLOT(errorReceived(QLowEnergyServiceInfo,QLowEnergyController::Error))); + connect(m_leInfo, SIGNAL(error(QLowEnergyCharacteristicInfo,QLowEnergyController::Error)), + this, SLOT(errorReceivedCharacteristic(QLowEnergyCharacteristicInfo,QLowEnergyController::Error))); connect(m_leInfo, SIGNAL(valueChanged(QLowEnergyCharacteristicInfo)), this, SLOT(receiveMeasurement(QLowEnergyCharacteristicInfo))); } //! [Connect signals] @@ -253,15 +255,15 @@ int HeartRate::hR() const } //! [Error handling] -void HeartRate::errorReceived(const QLowEnergyServiceInfo &leService) +void HeartRate::errorReceived(const QLowEnergyServiceInfo &leService, QLowEnergyController::Error error) { - qWarning() << "Error: " << leService.serviceUuid() << m_leInfo->errorString(); + qWarning() << "Error: " << leService.serviceUuid() << m_leInfo->errorString() << error; setMessage(QStringLiteral("Error: ") + m_leInfo->errorString()); } -void HeartRate::errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &leCharacteristic) +void HeartRate::errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &leCharacteristic, QLowEnergyController::Error error) { - qWarning() << "Error: " << leCharacteristic.uuid() << m_leInfo->errorString(); + qWarning() << "Error: " << leCharacteristic.uuid() << m_leInfo->errorString() << error; setMessage(QStringLiteral("Error: ") + m_leInfo->errorString()); } //! [Error handling] diff --git a/examples/bluetooth/heartlistener/heartrate.h b/examples/bluetooth/heartlistener/heartrate.h index 33e3181c..581000ad 100644 --- a/examples/bluetooth/heartlistener/heartrate.h +++ b/examples/bluetooth/heartlistener/heartrate.h @@ -59,7 +59,6 @@ QT_FORWARD_DECLARE_CLASS (QLowEnergyServiceInfo) QT_FORWARD_DECLARE_CLASS (QLowEnergyCharacteristicInfo) -QT_FORWARD_DECLARE_CLASS (QLowEnergyController) QT_USE_NAMESPACE class HeartRate: public QObject @@ -98,8 +97,8 @@ public slots: void serviceScanError(QBluetoothServiceDiscoveryAgent::Error); void serviceConnected(const QLowEnergyServiceInfo &); void receiveMeasurement(const QLowEnergyCharacteristicInfo &); - void errorReceived(const QLowEnergyServiceInfo &); - void errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &); + void errorReceived(const QLowEnergyServiceInfo &, QLowEnergyController::Error); + void errorReceivedCharacteristic(const QLowEnergyCharacteristicInfo &, QLowEnergyController::Error); void serviceDisconnected(const QLowEnergyServiceInfo &); void disconnectService(); void obtainResults(); diff --git a/examples/bluetooth/lowenergyscanner/device.cpp b/examples/bluetooth/lowenergyscanner/device.cpp index 44cd3512..d137fd40 100644 --- a/examples/bluetooth/lowenergyscanner/device.cpp +++ b/examples/bluetooth/lowenergyscanner/device.cpp @@ -152,7 +152,8 @@ void Device::scanServices(QString address) // Connecting signals and slots for connecting to LE services. info = new QLowEnergyController(); connect(info, SIGNAL(connected(QLowEnergyServiceInfo)), this, SLOT(serviceConnected(QLowEnergyServiceInfo))); - connect(info, SIGNAL(error(QLowEnergyServiceInfo)), this, SLOT(errorReceived(QLowEnergyServiceInfo))); + connect(info, SIGNAL(error(QLowEnergyServiceInfo, QLowEnergyCOntroller::Error)), + this, SLOT(errorReceived(QLowEnergyServiceInfo,QLowEnergyCOntroller::Error))); connect(info, SIGNAL(disconnected(QLowEnergyServiceInfo)), this, SLOT(serviceDisconnected(QLowEnergyServiceInfo))); } } @@ -195,9 +196,9 @@ void Device::serviceConnected(const QLowEnergyServiceInfo &service) emit characteristicsDone(); } -void Device::errorReceived(const QLowEnergyServiceInfo &service) +void Device::errorReceived(const QLowEnergyServiceInfo &service, QLowEnergyController::Error error) { - qWarning() << "Error: " << info->errorString() << service.serviceUuid(); + qWarning() << "Error: " << info->errorString() << service.serviceUuid() << error; setUpdate(info->errorString()); } diff --git a/examples/bluetooth/lowenergyscanner/device.h b/examples/bluetooth/lowenergyscanner/device.h index 307b0fb9..3ac28c8f 100644 --- a/examples/bluetooth/lowenergyscanner/device.h +++ b/examples/bluetooth/lowenergyscanner/device.h @@ -49,6 +49,7 @@ #include #include #include "deviceinfo.h" +#include "qlowenergycontroller.h" #include "qlowenergyserviceinfo.h" #include "serviceinfo.h" #include "characteristicinfo.h" @@ -56,7 +57,6 @@ QT_FORWARD_DECLARE_CLASS (QBluetoothDeviceInfo) QT_FORWARD_DECLARE_CLASS (QLowEnergyServiceInfo) QT_FORWARD_DECLARE_CLASS (QLowEnergyCharacteristicInfo) -QT_FORWARD_DECLARE_CLASS (QLowEnergyController) QT_FORWARD_DECLARE_CLASS (QBluetoothServiceInfo) class Device: public QObject @@ -86,7 +86,7 @@ public slots: void serviceScanDone(); void serviceConnected(const QLowEnergyServiceInfo &service); void connectToService(const QString &uuid); - void errorReceived(const QLowEnergyServiceInfo &service); + void errorReceived(const QLowEnergyServiceInfo &service, QLowEnergyController::Error); void disconnectFromService(); void serviceDisconnected(const QLowEnergyServiceInfo &service); void serviceScanError(QBluetoothServiceDiscoveryAgent::Error); diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp index 3ff8e131..d993e205 100644 --- a/src/bluetooth/qlowenergycontroller.cpp +++ b/src/bluetooth/qlowenergycontroller.cpp @@ -65,7 +65,20 @@ QT_BEGIN_NAMESPACE service on the same LE device. - \sa QLowEnergyServiceInfo, QLowEnergyCharacteristicInfo + \sa QLowEnergyServiceInfo, QLowEnergyCharacteristicInfo, QLowEnergyDescriptorInfo +*/ + +/*! + \enum QLowEnergyController::Error + + Indicates all possible error conditions found during Bluetooth Low Energy communication. + + \value NoError No error has occurred. + \value UnknownError An unknown error has occurred. + \value InputOutputError BLE device is not responding. + \value OperationError The error occurred while communicating with the BLE device + (connecting, disconnecting, receiving updates,etc). + \value PermissionError Characteristic does not have required permissions. */ /*! @@ -78,7 +91,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn void QLowEnergyController::error(const QLowEnergyServiceInfo &) + \fn void QLowEnergyController::error(const QLowEnergyServiceInfo &, QLowEnergyController::Error) This signal is emitted when the service error occurs. @@ -86,7 +99,7 @@ QT_BEGIN_NAMESPACE */ /*! - \fn void QLowEnergyController::error(const QLowEnergyCharacteristicInfo &) + \fn void QLowEnergyController::error(const QLowEnergyCharacteristicInfo &, QLowEnergyController::Error) This signal is emitted when the characteristic error occurs. @@ -235,4 +248,14 @@ bool QLowEnergyController::writeDescriptor(const QLowEnergyDescriptorInfo &descr return d_ptr->write(descriptor); } +/*! + This method returns the last error that was emitted. + + \sa errorString(), error() + */ +QLowEnergyController::Error QLowEnergyController::error() const +{ + return d_ptr->error; +} + QT_END_NAMESPACE diff --git a/src/bluetooth/qlowenergycontroller.h b/src/bluetooth/qlowenergycontroller.h index e993d8d7..53e29343 100644 --- a/src/bluetooth/qlowenergycontroller.h +++ b/src/bluetooth/qlowenergycontroller.h @@ -57,6 +57,13 @@ class Q_BLUETOOTH_EXPORT QLowEnergyController: public QObject { Q_OBJECT public: + enum Error { + NoError, + UnknownError, + OperationError, + InputOutputError, + PermissionError + }; QLowEnergyController(QObject *parent = 0); QLowEnergyController(const QBluetoothAddress &localAdapter, QObject *parent = 0); ~QLowEnergyController(); @@ -75,15 +82,15 @@ public: QString errorString() const; void setRandomAddress(); + Error error() const; Q_SIGNALS: void connected(const QLowEnergyServiceInfo &); + void error(const QLowEnergyServiceInfo &, QLowEnergyController::Error); + void error(const QLowEnergyCharacteristicInfo &, QLowEnergyController::Error); void disconnected(const QLowEnergyServiceInfo &); - void valueChanged(const QLowEnergyCharacteristicInfo &); - void error(const QLowEnergyServiceInfo &); - void error(const QLowEnergyCharacteristicInfo &); private: Q_DECLARE_PRIVATE(QLowEnergyController) QLowEnergyControllerPrivate *d_ptr; diff --git a/src/bluetooth/qlowenergycontroller_bluez.cpp b/src/bluetooth/qlowenergycontroller_bluez.cpp index fcf94bda..8fc7bf23 100644 --- a/src/bluetooth/qlowenergycontroller_bluez.cpp +++ b/src/bluetooth/qlowenergycontroller_bluez.cpp @@ -54,7 +54,7 @@ QT_BEGIN_NAMESPACE Q_DECLARE_LOGGING_CATEGORY(QT_BT_BLUEZ) QLowEnergyControllerPrivate::QLowEnergyControllerPrivate(): - m_randomAddress(false), m_step(0), m_commandStarted(false) + error(QLowEnergyController::NoError), m_randomAddress(false), m_step(0), m_commandStarted(false) { } @@ -132,14 +132,17 @@ void QLowEnergyControllerPrivate::_q_replyReceived(const QString &reply) connectToTerminal(); if (reply.contains(QStringLiteral("Connection refused (111)"))) { errorString = QStringLiteral("Connection refused (111)"); + error = QLowEnergyController::InputOutputError; disconnectAllServices(); } else if (reply.contains(QStringLiteral("Device busy"))) { - errorString = QStringLiteral("Connection refused (111)"); + errorString = QStringLiteral("Device busy"); + error = QLowEnergyController::InputOutputError; disconnectAllServices(); } else if (reply.contains(QStringLiteral("disconnected"))) { errorString = QStringLiteral("Trying to execute command on disconnected service"); + error = QLowEnergyController::OperationError; disconnectAllServices(); } else { @@ -328,8 +331,8 @@ void QLowEnergyControllerPrivate::disconnectAllServices() m_leServices.at(i).d_ptr->connected = false; emit q_ptr->disconnected(m_leServices.at(i)); } - if (errorString != QString()) - emit q_ptr->error(m_leServices.at(i)); + if (error != QLowEnergyController::NoError) + emit q_ptr->error(m_leServices.at(i), error); m_step = 0; } m_leServices.clear(); @@ -404,9 +407,9 @@ bool QLowEnergyControllerPrivate::enableNotification(const QLowEnergyCharacteris } } } - + error = QLowEnergyController::UnknownError; errorString = QStringLiteral("Characteristic or notification descriptor not found."); - emit q_ptr->error(characteristic); + emit q_ptr->error(characteristic, error); return false; } @@ -438,13 +441,15 @@ bool QLowEnergyControllerPrivate::write(const QLowEnergyCharacteristicInfo &char writeValue(characteristic.handle(), characteristic.value()); return true; } else { + error = QLowEnergyController::PermissionError; errorString = QStringLiteral("This characteristic does not support write operations."); } } else { + error = QLowEnergyController::OperationError; errorString = QStringLiteral("The device is not connected or characteristic is not valid"); } - emit q_ptr->error(characteristic); + emit q_ptr->error(characteristic, error); return false; } diff --git a/src/bluetooth/qlowenergycontroller_p.cpp b/src/bluetooth/qlowenergycontroller_p.cpp index de634133..07d58fdd 100644 --- a/src/bluetooth/qlowenergycontroller_p.cpp +++ b/src/bluetooth/qlowenergycontroller_p.cpp @@ -44,7 +44,8 @@ QT_BEGIN_NAMESPACE -QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() +QLowEnergyControllerPrivate::QLowEnergyControllerPrivate(): + error(QLowEnergyController::NoError) { } diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 971cd7dd..45cefdc8 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -62,6 +62,7 @@ public: QList m_leServices; QString errorString; + QLowEnergyController::Error error; #ifdef QT_QNX_BLUETOOTH static void serviceConnected(const char*, const char*, int, int, short unsigned int, short unsigned int, short unsigned int, void*); diff --git a/src/bluetooth/qlowenergycontroller_qnx.cpp b/src/bluetooth/qlowenergycontroller_qnx.cpp index bf1a57d7..ac8bb551 100644 --- a/src/bluetooth/qlowenergycontroller_qnx.cpp +++ b/src/bluetooth/qlowenergycontroller_qnx.cpp @@ -129,8 +129,9 @@ void QLowEnergyControllerPrivate::serviceConnected(const char *bdaddr, const cha if (err != 0) { qCDebug(QT_BT_QNX) << "An error occurred in service connected callback: " << qt_error_string(err); + p->error = QLowEnergyController::OperationError; p->errorString = qt_error_string(err); - p->q_ptr->error(p->m_leServices.at(index)); + Q_EMIT p->q_ptr->error(p->m_leServices.at(index), p->error); } if (index != -1) { p->m_leServices.at(index).d_ptr->characteristicList.clear(); @@ -139,8 +140,9 @@ void QLowEnergyControllerPrivate::serviceConnected(const char *bdaddr, const cha if (!data) { qCDebug(QT_BT_QNX) << "[SERVICE: Connected] GATT characteristics: Not enough memory"; bt_gatt_disconnect_instance(instance); + p->error = QLowEnergyController::OperationError; p->errorString = QStringLiteral("GATT characteristics: Not enough memory"); - p->q_ptr->error(p->m_leServices.at(index)); + Q_EMIT p->q_ptr->error(p->m_leServices.at(index), p->error); return; } @@ -154,8 +156,9 @@ void QLowEnergyControllerPrivate::serviceConnected(const char *bdaddr, const cha if (!allCharacteristicList) { qCDebug(QT_BT_QNX) <<" GATT characteristics: Not enough memory"; bt_gatt_disconnect_instance(instance); + p->error = QLowEnergyController::OperationError; p->errorString = QStringLiteral("GATT characteristics: Not enough memory"); - p->q_ptr->error(p->m_leServices.at(index)); + Q_EMIT p->q_ptr->error(p->m_leServices.at(index), p->error); return; } @@ -200,8 +203,9 @@ void QLowEnergyControllerPrivate::serviceConnected(const char *bdaddr, const cha int rc = bt_gatt_reg_notifications(instance, &(p->serviceNotification)); if (!rc) { qCDebug(QT_BT_QNX) << "[SERVICE: Connected] bt_gatt_reg_notifications failed." << errno << qt_error_string(errno); + p->error = QLowEnergyController::OperationError; p->errorString = qt_error_string(errno); - p->q_ptr->error(p->m_leServices.at(index)); + Q_EMIT p->q_ptr->error(p->m_leServices.at(index), p->error); } else { qCDebug(QT_BT_QNX) << "[SERVICE: Connected] bt_gatt_reg_notifications was presumably OK"; } @@ -222,7 +226,7 @@ void QLowEnergyControllerPrivate::serviceConnected(const char *bdaddr, const cha p->m_leServices.at(index).d_ptr->connected = true; qCDebug(QT_BT_QNX) << p; - emit p->q_ptr->connected(p->m_leServices.at(index)); + Q_EMIT p->q_ptr->connected(p->m_leServices.at(index)); qCDebug(QT_BT_QNX) << "---------------------------------------------------------------------------------"; } else { qCDebug(QT_BT_QNX) << "Unregistered service connected"; @@ -263,7 +267,7 @@ void QLowEnergyControllerPrivate::serviceNotification(int instance, short unsign p->m_leServices.at(i).d_ptr->characteristicList.at(j).d_ptr->notification = true; p->m_leServices.at(i).d_ptr->characteristicList.at(j).d_ptr->value = receivedValue; - p->q_ptr->valueChanged(p->m_leServices.at(i).d_ptr->characteristicList.at(j)); + Q_EMIT p->q_ptr->valueChanged(p->m_leServices.at(i).d_ptr->characteristicList.at(j)); current = true; } } @@ -305,7 +309,7 @@ void QLowEnergyControllerPrivate::serviceDisconnected(const char *bdaddr, const leUuid = QBluetoothUuid(lowEnergyUuid.toUShort(0,0)); } QLowEnergyServiceInfo leService(leUuid); - emit p->q_ptr->connected(leService); + Q_EMIT p->q_ptr->connected(leService); qCDebug(QT_BT_QNX) << "---------------------------------------------------"; qCDebug(QT_BT_QNX) << "[SERVICE: Disconnect] (service, instance, reason):" << service << instance << reason; @@ -315,7 +319,8 @@ void QLowEnergyControllerPrivate::serviceDisconnected(const char *bdaddr, const delete classPointer; } -QLowEnergyControllerPrivate::QLowEnergyControllerPrivate() +QLowEnergyControllerPrivate::QLowEnergyControllerPrivate(): + error(QLowEnergyController::NoError) { qRegisterMetaType("QLowEnergyServiceInfo"); qRegisterMetaType("QLowEnergyCharacteristicInfo"); @@ -328,9 +333,11 @@ QLowEnergyControllerPrivate::~QLowEnergyControllerPrivate() void QLowEnergyControllerPrivate::connectService(const QLowEnergyServiceInfo &service) { + Q_Q(QLowEnergyController); if (!service.isValid()) { + error = QLowEnergyController::UnknownError; errorString = QStringLiteral("Service not valid."); - emit q_ptr->error(service); + Q_EMIT q->error(service, error); return; } @@ -338,8 +345,9 @@ void QLowEnergyControllerPrivate::connectService(const QLowEnergyServiceInfo &se for (int i = 0; i < m_leServices.size(); i++) { if (m_leServices.at(i).serviceUuid() == service.serviceUuid()) { if (m_leServices.at(i).isConnected()) { + error = QLowEnergyController::OperationError; errorString = QStringLiteral("Service already connected"); - emit q_ptr->error(m_leServices.at(i)); + Q_EMIT q->error(m_leServices.at(i), error); } else { m_leServices.replace(i, service); @@ -357,16 +365,18 @@ void QLowEnergyControllerPrivate::connectService(const QLowEnergyServiceInfo &se process = process->instance(); if (!process->isConnected()) { qCDebug(QT_BT_QNX) << "[INIT] Init problem." << errno << qt_error_string(errno); + error = QLowEnergyController::InputOutputError; errorString = QStringLiteral("Initialization of device falied. ") + qt_error_string(errno); - emit q_ptr->error(service); + Q_EMIT q->error(service, error); return; } errno = 0; if (bt_gatt_init(&gatt_callbacks) < 0) { qCDebug(QT_BT_QNX) << "[INIT] GAT Init problem." << errno << qt_error_string(errno); + error = QLowEnergyController::UnknownError; errorString = QStringLiteral("Callbacks initialization failed. ") + qt_error_string(errno); - emit q_ptr->error(service); + Q_EMIT q->error(service, error); return; } if (bt_le_init(0) != EOK) { @@ -390,14 +400,16 @@ void QLowEnergyControllerPrivate::connectService(const QLowEnergyServiceInfo &se if (bt_gatt_connect_service(service.device().address().toString().toLocal8Bit().constData(), serviceUuid.toLocal8Bit().constData(), 0, &conParm, classPointer) < 0) { qCDebug(QT_BT_QNX) << "[SERVICE] Connection to service failed." << errno << qt_error_string(errno); + error = QLowEnergyController::OperationError; errorString = QStringLiteral("[SERVICE] Connection to service failed.") + qt_error_string(errno); - emit q_ptr->error(service); + Q_EMIT q->error(service, error); } qCDebug(QT_BT_QNX) << "errno after connect: " << errno; } void QLowEnergyControllerPrivate::disconnectService(const QLowEnergyServiceInfo &leService) { + Q_Q(QLowEnergyController); if (leService.isValid()){ QString serviceUuid = leService.serviceUuid().toString().remove(QLatin1Char('{')).remove(QLatin1Char('}')); if (leService.serviceName() == QStringLiteral("Unknown Service")) @@ -407,8 +419,9 @@ void QLowEnergyControllerPrivate::disconnectService(const QLowEnergyServiceInfo if (leService.isConnected()) { if (bt_gatt_disconnect_service(leService.device().address().toString().toLocal8Bit().constData(), serviceUuid.toLocal8Bit().constData()) < 0) { qCDebug(QT_BT_QNX) << "[SERVICE] Disconnect service request failed. " << errno << qt_error_string(errno); + error = QLowEnergyController::OperationError; errorString = QStringLiteral("[SERVICE] Disconnect service request failed. ") + qt_error_string(errno); - emit q_ptr->error(leService); + Q_EMIT q->error(leService, error); } else { for (int i = 0; i < m_leServices.size(); i++) { if (leService.serviceUuid() == m_leServices.at(i).serviceUuid()) { @@ -417,12 +430,13 @@ void QLowEnergyControllerPrivate::disconnectService(const QLowEnergyServiceInfo } } leService.d_ptr->connected = false; - emit q_ptr->disconnected(leService); + Q_EMIT q->disconnected(leService); qCDebug(QT_BT_QNX) << "[SERVICE] Disconnected from service OK."; } } else { + error = QLowEnergyController::UnknownError; errorString = QStringLiteral("Service is not connected"); - q_ptr->error(leService); + Q_EMIT q->error(leService, error); } } else { disconnectAllServices(); @@ -431,6 +445,7 @@ void QLowEnergyControllerPrivate::disconnectService(const QLowEnergyServiceInfo void QLowEnergyControllerPrivate::disconnectAllServices() { + Q_Q(QLowEnergyController); for (int i = 0; i < m_leServices.size(); i++) { QString serviceUuid = m_leServices.at(i).serviceUuid().toString().remove(QLatin1Char('{')).remove(QLatin1Char('}')); if (m_leServices.at(i).serviceName() == QStringLiteral("Unknown Service")) @@ -442,11 +457,12 @@ void QLowEnergyControllerPrivate::disconnectAllServices() qCDebug(QT_BT_QNX) << m_leServices.at(i).device().address().toString().toLocal8Bit().constData() << serviceUuid.toLocal8Bit().constData(); if (bt_gatt_disconnect_service( m_leServices.at(i).device().address().toString().toLocal8Bit().constData(), serviceUuid.toLocal8Bit().constData()) < 0) { qCDebug(QT_BT_QNX) << "[SERVICE] Disconnect service request failed. " << errno << qt_error_string(errno); + error = QLowEnergyController::OperationError; errorString = QStringLiteral("[SERVICE] Disconnect service request failed. ") + qt_error_string(errno); - emit q_ptr->error( m_leServices.at(i)); + Q_EMIT q->error( m_leServices.at(i), error); } else { m_leServices.at(i).d_ptr->connected = false; - emit q_ptr->disconnected(m_leServices.at(i)); + Q_EMIT q->disconnected(m_leServices.at(i)); qCDebug(QT_BT_QNX) << "[SERVICE] Disconnected from service OK."; } } @@ -456,24 +472,28 @@ void QLowEnergyControllerPrivate::disconnectAllServices() bool QLowEnergyControllerPrivate::enableNotification(const QLowEnergyCharacteristicInfo &characteristic) { + Q_Q(QLowEnergyController); if (characteristic.d_ptr->instance == -1) { qCDebug(QT_BT_QNX) << " GATT service not connected "; + error = QLowEnergyController::UnknownError; errorString = QStringLiteral("Service is not connected"); - emit q_ptr->error(characteristic); + Q_EMIT q->error(characteristic, error); return false; } if (!(characteristic.d_ptr->permission & QLowEnergyCharacteristicInfo::Notify)) { qCDebug(QT_BT_QNX) << "Notification changes not allowed"; + error = QLowEnergyController::PermissionError; errorString = QStringLiteral("This characteristic does not support notifications."); - emit q_ptr->error(characteristic); + Q_EMIT q->error(characteristic, error); return false; } int rc = bt_gatt_enable_notify(characteristic.d_ptr->instance, &characteristic.d_ptr->characteristic, 1); if (!rc) { qCDebug(QT_BT_QNX) << "bt_gatt_enable_notify errno=" << errno << qt_error_string(errno); + error = QLowEnergyController::OperationError; errorString = qt_error_string(errno); - emit q_ptr->error(characteristic); + Q_EMIT q->error(characteristic, error); return false; } else { qCDebug(QT_BT_QNX) << "bt_gatt_enable_notify was presumably OK"; @@ -492,9 +512,11 @@ void QLowEnergyControllerPrivate::disableNotification(const QLowEnergyCharacteri bool QLowEnergyControllerPrivate::write(const QLowEnergyCharacteristicInfo &characteristic) { + Q_Q(QLowEnergyController); if (!characteristic.isValid()) { + error = QLowEnergyController::UnknownError; errorString = QStringLiteral("Characteristic not valid."); - emit q_ptr->error(characteristic); + Q_EMIT q->error(characteristic, error); return false; } @@ -503,12 +525,14 @@ bool QLowEnergyControllerPrivate::write(const QLowEnergyCharacteristicInfo &char if (errorString == QString()) { return true; } else { - emit q_ptr->error(characteristic); + error = QLowEnergyController::OperationError; + Q_EMIT q->error(characteristic, error); return false; } } else { + error = QLowEnergyController::PermissionError; errorString = QStringLiteral("Characteristic does not allow write operations. The wanted value was not written to the device."); - emit q_ptr->error(characteristic); + Q_EMIT q->error(characteristic, error); return false; } diff --git a/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp b/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp index d7a6a6ef..20a38772 100644 --- a/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp +++ b/tests/auto/qbluetoothservicediscoveryagent/tst_qbluetoothservicediscoveryagent.cpp @@ -505,6 +505,7 @@ void tst_QBluetoothServiceDiscoveryAgent::tst_serviceDiscovery() QVERIFY(info.isValid()); QCOMPARE(leController.errorString(), QString()); + QCOMPARE(leController.error(), QLowEnergyController::NoError); QVERIFY((info.characteristics().size() > 0)); qDebug() << "LE Service Connected: " << info.serviceName() << info.serviceUuid(); leTestCounter++; -- cgit v1.2.3