diff options
author | Fabian Bumberger <fbumberger@rim.com> | 2013-08-08 11:14:38 +0200 |
---|---|---|
committer | The Qt Project <gerrit-noreply@qt-project.org> | 2013-08-08 15:31:06 +0200 |
commit | f0e7da6dab3a19a9c978f2cbba2dea60fcea619b (patch) | |
tree | 51006c66a4fdc0ae02f93f9cede817c751f4706b | |
parent | 343107a157cde0e47698200c9ec6fe8f83cd49b5 (diff) |
QNX: Make the device discovery agent more robust
Also fixes the autotests.
Change-Id: I71983fa3cc49a88bb7b94544b7f24bebbd3cf86e
Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_p.h | 18 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp | 163 | ||||
-rw-r--r-- | src/bluetooth/qnx/ppshelpers.cpp | 25 |
3 files changed, 134 insertions, 72 deletions
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h index 15970ed0..73673c59 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_p.h +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_p.h @@ -88,10 +88,9 @@ private: QBluetoothDeviceDiscoveryAgent::Error lastError; QString errorString; +#ifdef QT_BLUEZ_BLUETOOTH bool pendingCancel; bool pendingStart; - -#ifdef QT_BLUEZ_BLUETOOTH OrgBluezManagerInterface *manager; OrgBluezAdapterInterface *adapter; #elif defined(QTM_QNX_BLUETOOTH) @@ -100,16 +99,23 @@ private: void remoteDevicesChanged(int); void controlReply(ppsResult result); void controlEvent(ppsResult result); + void startDeviceSearch(); private: - void abort(); - QSocketNotifier *m_rdNotifier; QTimer m_finishedTimer; - bool m_controlRegistered; - int m_rdfd; + bool m_active; + enum Ops{ + None, + Cancel, + Start + }; + Ops m_nextOp; + Ops m_currentOp; + void processNextOp(); + bool isFinished; #endif QBluetoothDeviceDiscoveryAgent *q_ptr; diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp index de50b997..6370e521 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp @@ -50,45 +50,58 @@ QT_BEGIN_NAMESPACE_BLUETOOTH QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(): - QObject(0), lastError(QBluetoothDeviceDiscoveryAgent::NoError), pendingCancel(false), pendingStart(false), m_rdfd(-1) + QObject(0), lastError(QBluetoothDeviceDiscoveryAgent::NoError), + m_rdfd(-1), m_active(false), m_nextOp(None), m_currentOp(None) { inquiryType = QBluetoothDeviceDiscoveryAgent::GeneralUnlimitedInquiry; + ppsRegisterControl(); + ppsRegisterForEvent(QStringLiteral("device_added"), this); + ppsRegisterForEvent(QStringLiteral("device_search"), this); + connect(&m_finishedTimer, SIGNAL(timeout()), this, SLOT(finished())); } QBluetoothDeviceDiscoveryAgentPrivate::~QBluetoothDeviceDiscoveryAgentPrivate() { - if (pendingStart) + if (m_active) stop(); - ppsUnregisterForEvent(QStringLiteral("device_added"), this); ppsUnregisterForEvent(QStringLiteral("device_search"), this); + ppsUnregisterControl(this); } bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const { - return pendingStart; + return m_active; } void QBluetoothDeviceDiscoveryAgentPrivate::start() { - qBBBluetoothDebug() << "Starting device discovery"; Q_Q(QBluetoothDeviceDiscoveryAgent); - if (pendingStart) - return; - pendingStart = true; + m_active = true; + isFinished = false; discoveredDevices.clear(); - if (m_rdfd != -1 || (m_rdfd = qt_safe_open("/pps/services/bluetooth/remote_devices/.all", O_RDONLY)) == -1) { - qWarning() << Q_FUNC_INFO << "rdfd - failed to open /pps/services/bluetooth/remote_devices/.all"; + if (m_currentOp == Cancel) { + m_nextOp = Start; + return; + } + if (m_nextOp == Cancel) { + m_nextOp = None; + } + m_currentOp = Start; + + if (m_rdfd != -1) { + qBBBluetoothDebug() << "RDev FD still open"; + } else if ((m_rdfd = qt_safe_open("/pps/services/bluetooth/remote_devices/.all", O_RDONLY)) == -1) { + qWarning() << Q_FUNC_INFO << "rdfd - failed to open /pps/services/bluetooth/remote_devices/.all" + << m_rdfd; lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; emit q->error(lastError); stop(); return; } else { m_rdNotifier = new QSocketNotifier(m_rdfd, QSocketNotifier::Read, this); - if (m_rdNotifier) { - connect(m_rdNotifier, SIGNAL(activated(int)), this, SLOT(remoteDevicesChanged(int))); - } else { + if (!m_rdNotifier) { qWarning() << Q_FUNC_INFO << "failed to connect to m_rdNotifier"; lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; emit q->error(lastError); @@ -97,32 +110,46 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start() } } - //If there is no new results after 7 seconds, the device inquire will be stopped - m_finishedTimer.start(7000); - connect(&m_finishedTimer, SIGNAL(timeout()), this, SLOT(finished())); - - if (!m_controlRegistered) { - ppsRegisterControl(); - m_controlRegistered = true; + if (ppsSendControlMessage("device_search", this)) { + //If there is no new results after 7 seconds, the device inquire will be stopped + m_finishedTimer.start(10000); + connect(m_rdNotifier, SIGNAL(activated(int)), this, SLOT(remoteDevicesChanged(int))); + } else { + qWarning() << "Could not write to control FD"; + m_active = false; + q->error(QBluetoothDeviceDiscoveryAgent::IOFailure); + return; } - - ppsSendControlMessage("device_search", this); - ppsRegisterForEvent(QStringLiteral("device_added"), this); - - ppsRegisterForEvent(QStringLiteral("device_search"), this); } void QBluetoothDeviceDiscoveryAgentPrivate::stop() { Q_Q(QBluetoothDeviceDiscoveryAgent); + m_active = false; + m_finishedTimer.stop(); + if (m_currentOp == Start) { + m_nextOp = Cancel; + return; + } + m_currentOp = Cancel; + qBBBluetoothDebug() << "Stopping device search"; ppsSendControlMessage("cancel_device_search",this); - emit q->canceled(); - abort(); + + if (m_rdNotifier) { + delete m_rdNotifier; + m_rdNotifier = 0; + } + if (m_rdfd != -1) { + qt_safe_close(m_rdfd); + m_rdfd = -1; + } } void QBluetoothDeviceDiscoveryAgentPrivate::remoteDevicesChanged(int fd) { + if (!m_active) + return; pps_decoder_t ppsDecoder; pps_decoder_initialize(&ppsDecoder, NULL); @@ -147,9 +174,11 @@ void QBluetoothDeviceDiscoveryAgentPrivate::remoteDevicesChanged(int fd) QBluetoothDeviceInfo deviceInfo(deviceAddr, deviceName, cod); deviceInfo.setRssi(rssi); + bool updated = false; //Prevent a device from beeing listed twice for (int i=0; i < discoveredDevices.size(); i++) { if (discoveredDevices.at(i).address() == deviceInfo.address()) { + updated = true; if (discoveredDevices.at(i) == deviceInfo) { return; } else { @@ -160,35 +189,45 @@ void QBluetoothDeviceDiscoveryAgentPrivate::remoteDevicesChanged(int fd) } //Starts the timer again m_finishedTimer.start(7000); - if (!deviceAddr.isNull()) { - discoveredDevices.append(deviceInfo); qBBBluetoothDebug() << "Device discovered: " << deviceName << deviceAddr.toString(); - emit q_ptr->deviceDiscovered(discoveredDevices.last()); + discoveredDevices.append(deviceInfo); + if (!updated)//We are not allowed to emit a signal with the updated version + emit q_ptr->deviceDiscovered(discoveredDevices.last()); } } void QBluetoothDeviceDiscoveryAgentPrivate::controlReply(ppsResult result) { - if (result.msg == QStringLiteral("device_search")) { + Q_Q(QBluetoothDeviceDiscoveryAgent); + if (result.msg == QStringLiteral("device_search") && m_currentOp == Start) { if (result.dat.size() > 0 && result.dat.first() == QStringLiteral("EOK")) { //Do nothing. We can not be certain, that the device search is over yet - } - else { - qWarning() << "A PPS Bluetooth error occured:" << result.errorMsg; - q_ptr->error(QBluetoothDeviceDiscoveryAgent::UnknownError); - lastError = QBluetoothDeviceDiscoveryAgent::UnknownError; + } else if (result.error == 16) { + qBBBluetoothDebug() << "Could not start device inquire bc resource is busy"; + if (m_nextOp == None) { //We try again + ppsSendControlMessage("cancel_device_search",this); + QTimer::singleShot(5000, this, SLOT(startDeviceSearch())); + m_finishedTimer.start(20000); + } + return; + } else { + qWarning("A PPS Bluetooth error occurred:"); + q_ptr->error(QBluetoothDeviceDiscoveryAgent::IOFailure); + lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; errorString = result.errorMsg; stop(); } - } else if (result.msg == QStringLiteral("cancel_device_search")) { + processNextOp(); + } else if (result.msg == QStringLiteral("cancel_device_search") && m_currentOp == Cancel && !isFinished) { qBBBluetoothDebug() << "Cancel device search"; - if (result.error == 16) { - qWarning() << Q_FUNC_INFO << "Resource is busy. Is Bluetooth enabled?"; - lastError = QBluetoothDeviceDiscoveryAgent::PoweredOff; - errorString = result.errorMsg; - } - //stop(); +// if (!result.errorMsg.isEmpty()) { +// lastError = QBluetoothDeviceDiscoveryAgent::IOFailure; +// errorString = result.errorMsg; +// q_ptr->error(QBluetoothDeviceDiscoveryAgent::IOFailure); +// } + emit q->canceled(); + processNextOp(); } } @@ -199,30 +238,36 @@ void QBluetoothDeviceDiscoveryAgentPrivate::controlEvent(ppsResult result) } } - void QBluetoothDeviceDiscoveryAgentPrivate::finished() { - qBBBluetoothDebug() << "Device discovery finished"; - m_finishedTimer.stop(); - stop(); - q_ptr->finished(); + if (m_active) { + qBBBluetoothDebug() << "Device discovery finished"; + isFinished = true; + stop(); + q_ptr->finished(); + } } -void QBluetoothDeviceDiscoveryAgentPrivate::abort() +void QBluetoothDeviceDiscoveryAgentPrivate::startDeviceSearch() { - if (m_controlRegistered) { - ppsUnregisterControl(this); - m_controlRegistered = false; + if (m_currentOp == Start) { + ppsSendControlMessage("device_search", this); //Try again } +} - pendingStart = false; - if (m_rdNotifier) { - delete m_rdNotifier; - m_rdNotifier = 0; +void QBluetoothDeviceDiscoveryAgentPrivate::processNextOp() +{ + if (m_currentOp == m_nextOp) { + m_currentOp = None; + m_nextOp = None; } - if (m_rdfd != -1) { - qt_safe_close(m_rdfd); - m_rdfd = -1; + m_currentOp = m_nextOp; + m_nextOp = None; + + if (m_currentOp == Start) { + start(); + } else if (m_currentOp == Cancel) { + stop(); } } diff --git a/src/bluetooth/qnx/ppshelpers.cpp b/src/bluetooth/qnx/ppshelpers.cpp index 1b1eb82b..5d05c88c 100644 --- a/src/bluetooth/qnx/ppshelpers.cpp +++ b/src/bluetooth/qnx/ppshelpers.cpp @@ -72,16 +72,15 @@ QList<QPair<QString, QObject*> > evtRegistration; void BBSocketNotifier::distribute() { - qBBBluetoothDebug() << "Distributing"; ppsDecodeControlResponse(); } void BBSocketNotifier::closeControlFD() { if (count <= 0) { + delete ppsCtrlNotifier; qt_safe_close(ppsCtrlFD); ppsCtrlFD = -1; - delete ppsCtrlNotifier; ppsCtrlNotifier = 0; } } @@ -98,7 +97,12 @@ QPair<int, QObject*> takeObjectInWList(int id) void ppsRegisterControl() { qBBBluetoothDebug() << "Register for Control"; - if (count == 0) { + count++; + if (count == 1) { + if (ppsCtrlFD != -1) { + qBBBluetoothDebug() << "PPS control FD not properly deinitialized"; + return; + } ppsCtrlFD = qt_safe_open(btControlFDPath, O_RDWR | O_SYNC); if (ppsCtrlFD == -1) { qWarning() << Q_FUNC_INFO << "ppsCtrlFD - failed to qt_safe_open" << btControlFDPath; @@ -107,7 +111,6 @@ void ppsRegisterControl() QObject::connect(ppsCtrlNotifier, SIGNAL(activated(int)), &bbSocketNotifier, SLOT(distribute())); } } - count++; } void ppsUnregisterControl(QObject *obj) @@ -143,7 +146,8 @@ bool endCtrlMessage(pps_encoder_t *encoder) if (pps_encoder_buffer(encoder) != 0) { int res = qt_safe_write(ppsCtrlFD, pps_encoder_buffer(encoder), pps_encoder_length(encoder)); if (res == -1) { - qWarning() << Q_FUNC_INFO << "Error when writing to control FD. Is Bluetooth powerd on?" << errno; + qWarning() << Q_FUNC_INFO << "Error when writing to control FD. Is Bluetooth powerd on?" + << errno << ppsCtrlFD; return false; } } @@ -201,7 +205,9 @@ void ppsDecodeControlResponse() if (ppsCtrlFD != -1) { char buf[ppsBufferSize]; - qt_safe_read( ppsCtrlFD, &buf, sizeof(buf) ); + qt_safe_read(ppsCtrlFD, &buf, sizeof(buf) ); + if (buf[0] != '@') + return; qBBBluetoothDebug() << "CTRL Response" << buf; pps_decoder_t ppsDecoder; @@ -229,6 +235,11 @@ void ppsDecodeControlResponse() if (pps_decoder_get_string(&ppsDecoder, "errstr", &buf) == PPS_DECODER_OK) result.errorMsg = QString::fromUtf8(buf); + int dat; + if (pps_decoder_get_int(&ppsDecoder, "err", &dat) == PPS_DECODER_OK) { + result.error = dat; + } + //The dat object can be either a string or a array pps_node_type_t nodeType = pps_decoder_type(&ppsDecoder,"dat"); if (nodeType == PPS_TYPE_STRING) { @@ -276,7 +287,7 @@ void ppsDecodeControlResponse() if (wMessage.second != 0) wMessage.second->metaObject()->invokeMethod(wMessage.second, "controlReply", Q_ARG(ppsResult, result)); } else if (resType == EVENT) { - qBBBluetoothDebug() << "Distributing event" << result.msg; + //qBBBluetoothDebug() << "Distributing event" << result.msg; for (int i=0; i < evtRegistration.size(); i++) { if (result.msg == evtRegistration.at(i).first) evtRegistration.at(i).second->metaObject()->invokeMethod(evtRegistration.at(i).second, "controlEvent", Q_ARG(ppsResult, result)); |