summaryrefslogtreecommitdiffstats
path: root/src/bluetooth
diff options
context:
space:
mode:
authorFabian Bumberger <fbumberger@rim.com>2013-08-08 11:14:38 +0200
committerThe Qt Project <gerrit-noreply@qt-project.org>2013-08-08 15:31:06 +0200
commitf0e7da6dab3a19a9c978f2cbba2dea60fcea619b (patch)
tree51006c66a4fdc0ae02f93f9cede817c751f4706b /src/bluetooth
parent343107a157cde0e47698200c9ec6fe8f83cd49b5 (diff)
QNX: Make the device discovery agent more robust
Also fixes the autotests. Change-Id: I71983fa3cc49a88bb7b94544b7f24bebbd3cf86e Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/bluetooth')
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_p.h18
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_qnx.cpp163
-rw-r--r--src/bluetooth/qnx/ppshelpers.cpp25
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));