summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Pocheptsov <Timur.Pocheptsov@digia.com>2014-09-30 17:29:15 +0200
committerTimur Pocheptsov <Timur.Pocheptsov@digia.com>2014-10-16 09:46:15 +0200
commite417b7036e35744daa1978cd236798e3ee1693c0 (patch)
tree3e86b6ce833e70efa75f8151302973a030338fb2
parent552bdb884b44fffde3075ee2016a8a5c04108b3c (diff)
QtBluetooth - device discovery test on OS X.
- Enable this auto test on OS X, requires a modification: 'stop' is synchronous and so cancelSpy.isEmpty() == false (the last QVERIFY fails. - Fix several problems with SDK versions (workarounds for non-existing methods in SDK < 10.9). - Change error handling: we set an error in a ctor _only_ if QBluetoothAddress parameter was not null (!isNull()) and we failed to find a local device with such an address. This is the only case documented/expected, all others _do_ _not_ set an error, even if a local adapter is off or does not exits. This fixes a failing (to integrate) auto-test. Change-Id: I9902211078330f296775f1c3249da166c19001a4 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
-rw-r--r--src/bluetooth/osx/osxbtdevicepair.mm16
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm18
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_osx.mm79
-rw-r--r--tests/auto/qbluetoothdevicediscoveryagent/qbluetoothdevicediscoveryagent.pro3
-rw-r--r--tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp5
5 files changed, 79 insertions, 42 deletions
diff --git a/src/bluetooth/osx/osxbtdevicepair.mm b/src/bluetooth/osx/osxbtdevicepair.mm
index 8edc30a6..c9d6de32 100644
--- a/src/bluetooth/osx/osxbtdevicepair.mm
+++ b/src/bluetooth/osx/osxbtdevicepair.mm
@@ -97,7 +97,13 @@ using namespace QT_NAMESPACE;
- (void)dealloc
{
- [m_pairing stop]; // Stop also sets a delegate to nil (Apple's docs).
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_NA)
+ // Stop also sets a delegate to nil (Apple's docs).
+ // 10.9 only.
+ [m_pairing stop];
+#else
+ [m_pairing setDelegate:nil];
+#endif
[m_pairing release];
[super dealloc];
@@ -171,22 +177,16 @@ using namespace QT_NAMESPACE;
- (void)devicePairingStarted:(id)sender
{
Q_UNUSED(sender)
- //
- NSLog(@"pairing started ... to be implemented");
}
- (void)devicePairingConnecting:(id)sender
{
Q_UNUSED(sender)
-
- NSLog(@"connecting ... to be implemented");
}
- (void)deviceParingPINCodeRequest:(id)sender
{
Q_UNUSED(sender)
-
- NSLog(@"pin code request ... to be implemented");
}
- (void)devicePairingUserConfirmationRequest:(id)sender
@@ -206,8 +206,6 @@ using namespace QT_NAMESPACE;
{
Q_UNUSED(sender)
Q_UNUSED(passkey)
-
- NSLog(@"pass key notification ... to be implemented");
}
- (void)devicePairingFinished:(id)sender error:(IOReturn)error
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm b/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm
index 2f808038..5f2881af 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_osx.mm
@@ -126,7 +126,6 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(con
if (!controller) {
qCCritical(QT_BT_OSX) << "QBluetoothDeviceDiscoveryAgentPrivate() "
"no default host controller";
- setError(QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError);
return;
}
@@ -134,7 +133,6 @@ QBluetoothDeviceDiscoveryAgentPrivate::QBluetoothDeviceDiscoveryAgentPrivate(con
if (!newInquiry) { // Obj-C's way of "reporting errors":
qCCritical(QT_BT_OSX) << "QBluetoothDeviceDiscoveryAgentPrivate() "
"failed to initialize an inquiry";
- setError(QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError);
return;
}
@@ -167,6 +165,7 @@ bool QBluetoothDeviceDiscoveryAgentPrivate::isActive() const
void QBluetoothDeviceDiscoveryAgentPrivate::start()
{
+ Q_ASSERT_X(isValid(), "start()", "called on invalid device discovery agent");
Q_ASSERT_X(!isActive(), "start()", "called on active device discovery agent");
Q_ASSERT_X(lastError != QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError,
"start()", "called with invalid bluetooth adapter");
@@ -188,6 +187,7 @@ void QBluetoothDeviceDiscoveryAgentPrivate::start()
void QBluetoothDeviceDiscoveryAgentPrivate::stop()
{
+ Q_ASSERT_X(isValid(), "stop()", "called on invalid device discovery agent");
Q_ASSERT_X(isActive(), "stop()", "called whithout active inquiry");
Q_ASSERT_X(lastError != QBluetoothDeviceDiscoveryAgent::InvalidBluetoothAdapterError,
"stop()", "called with invalid bluetooth adapter");
@@ -375,8 +375,18 @@ QList<QBluetoothDeviceInfo> QBluetoothDeviceDiscoveryAgent::discoveredDevices()
void QBluetoothDeviceDiscoveryAgent::start()
{
- if (!isActive() && d_ptr->lastError != InvalidBluetoothAdapterError)
- d_ptr->start();
+ if (d_ptr->lastError != InvalidBluetoothAdapterError) {
+ if (d_ptr->isValid()) {
+ if (!isActive())
+ d_ptr->start();
+ } else {
+ // We previously failed to initialize d_ptr correctly:
+ // either some memory allocation problem or
+ // no BT adapter found.
+ d_ptr->setError(InvalidBluetoothAdapterError);
+ emit error(InvalidBluetoothAdapterError);
+ }
+ }
}
void QBluetoothDeviceDiscoveryAgent::stop()
diff --git a/src/bluetooth/qbluetoothserviceinfo_osx.mm b/src/bluetooth/qbluetoothserviceinfo_osx.mm
index 2ab2c9f1..ae88b4e7 100644
--- a/src/bluetooth/qbluetoothserviceinfo_osx.mm
+++ b/src/bluetooth/qbluetoothserviceinfo_osx.mm
@@ -62,20 +62,23 @@ namespace {
// This is not in osxbtutility_p, since it's not required
// in general and just fixes the problem with SDK < 10.9,
// where we have to care about about IOBluetoothSDPServiceRecordRef.
-class ServiceRecordDeleter
+class ServiceRecordRefGuard
{
public:
- ServiceRecordDeleter(IOBluetoothSDPServiceRecordRef r)
+ ServiceRecordRefGuard(IOBluetoothSDPServiceRecordRef r)
: recordRef(r)
{
}
- ~ServiceRecordDeleter()
+ ~ServiceRecordRefGuard()
{
if (recordRef) // Requires non-NULL pointers.
CFRelease(recordRef);
}
+private:
IOBluetoothSDPServiceRecordRef recordRef;
+
+ Q_DISABLE_COPY(ServiceRecordRefGuard)
};
}
@@ -85,7 +88,6 @@ class QBluetoothServiceInfoPrivate
public:
typedef QBluetoothServiceInfo QSInfo;
QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q);
- ~QBluetoothServiceInfoPrivate();
bool registerService(const QBluetoothAddress &localAdapter = QBluetoothAddress());
@@ -105,20 +107,17 @@ private:
typedef OSXBluetooth::ObjCScopedPointer<IOBluetoothSDPServiceRecord> SDPRecord;
SDPRecord serviceRecord;
+ BluetoothSDPServiceRecordHandle serviceRecordHandle;
};
QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q)
: q_ptr(q),
- registered(false)
+ registered(false),
+ serviceRecordHandle(0)
{
Q_ASSERT_X(q, "QBluetoothServiceInfoPrivate()", "invalid q_ptr (null)");
}
-QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate()
-{
- // TODO: should it unregister?
-}
-
bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &localAdapter)
{
Q_UNUSED(localAdapter)
@@ -129,8 +128,6 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca
Q_ASSERT_X(!serviceRecord, "QBluetoothServiceInfoPrivate::registerService()",
"not registered, but serviceRecord is not nil");
- // TODO: create a service description (as NSDictionary) and add to the
- // local SDP server via IOBluetoothSDPServiceRecord and its methods.
using namespace OSXBluetooth;
ObjCStrongReference<NSMutableDictionary>
@@ -143,56 +140,79 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca
}
SDPRecord newRecord;
-
#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_NA)
newRecord.reset([[IOBluetoothSDPServiceRecord
publishedServiceRecordWithDictionary:serviceDict] retain]);
-
#else
IOBluetoothSDPServiceRecordRef recordRef = Q_NULLPTR;
// With ARC this will require a different cast?
const IOReturn status = IOBluetoothAddServiceDict((CFDictionaryRef)serviceDict.data(), &recordRef);
if (status != kIOReturnSuccess) {
qCWarning(QT_BT_OSX) << "QBluetoothServiceInfoPrivate::registerService(), "
- "failed to create register a service record";
+ "failed to register a service record";
return false;
}
- const ServiceRecordDeleter refGuard(recordRef);
+ const ServiceRecordRefGuard refGuard(recordRef);
newRecord.reset([[IOBluetoothSDPServiceRecord withSDPServiceRecordRef:recordRef] retain]);
- // It's weird, but ... it's not possible to release a record ref yet!
+ // It's weird, but ... it's not possible to release a record ref yet.
#endif
if (!newRecord) {
qCWarning(QT_BT_OSX) << "QBluetoothServiceInfoPrivate::registerService(), "
- "failed to create register a service record";
+ "failed to register a service record";
+ // In case of SDK < 10.9 it's not possible to remove a service record ...
+ // no way to obtain record handle yet.
+ return false;
+ }
+
+ BluetoothSDPServiceRecordHandle newRecordHandle = 0;
+ if ([newRecord getServiceRecordHandle:&newRecordHandle] != kIOReturnSuccess) {
+ qCWarning(QT_BT_OSX) << "QBluetoothServiceInfoPrivate::registerService(), "
+ "failed to register a service record";
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_NA)
+ [newRecord removeServiceRecord];
+#endif
+ // With SDK < 10.9 there is no way to unregister at this point ...
return false;
}
const QSInfo::Protocol type = q_ptr->socketProtocol();
quint16 realPort = 0;
QBluetoothServerPrivate *server = Q_NULLPTR;
+ bool configured = false;
if (type == QBluetoothServiceInfo::L2capProtocol) {
BluetoothL2CAPPSM psm = 0;
server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type);
- if ([newRecord getL2CAPPSM:&psm] != kIOReturnSuccess) {
- [newRecord removeServiceRecord];
- return false;
+ if ([newRecord getL2CAPPSM:&psm] == kIOReturnSuccess) {
+ configured = true;
+ realPort = psm;
}
- realPort = psm;
} else if (type == QBluetoothServiceInfo::RfcommProtocol) {
BluetoothRFCOMMChannelID channelID = 0;
server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type);
- if ([newRecord getRFCOMMChannelID:&channelID] != kIOReturnSuccess) {
- [newRecord removeServiceRecord];
- return false;
+ if ([newRecord getRFCOMMChannelID:&channelID] == kIOReturnSuccess) {
+ configured = true;
+ realPort = channelID;
}
- realPort = channelID;
+ }
+
+ if (!configured) {
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_NA)
+ [newRecord removeServiceRecord];
+#else
+ IOBluetoothRemoveServiceWithRecordHandle(newRecordHandle);
+#endif
+ qCWarning(QT_BT_OSX) << "QBluetoothServiceInfoPrivate::registerService(), "
+ "failed to register a service record";
+ return false;
}
registered = true;
serviceRecord.reset(newRecord.take());
+ serviceRecordHandle = newRecordHandle;
+
if (server)
server->startListener(realPort);
@@ -212,7 +232,13 @@ bool QBluetoothServiceInfoPrivate::unregisterService()
Q_ASSERT_X(serviceRecord, "QBluetoothServiceInfoPrivate::unregisterService()",
"service registered, but serviceRecord is nil");
+#if QT_MAC_PLATFORM_SDK_EQUAL_OR_ABOVE(__MAC_10_9, __IPHONE_NA)
[serviceRecord removeServiceRecord];
+#else
+ // Assert on newRecordHandle? Is 0 a valid/invalid handle?
+ IOBluetoothRemoveServiceWithRecordHandle(serviceRecordHandle);
+#endif
+
serviceRecord.reset(nil);
const QSInfo::Protocol type = q_ptr->socketProtocol();
@@ -228,6 +254,7 @@ bool QBluetoothServiceInfoPrivate::unregisterService()
server->stopListener();
registered = false;
+ serviceRecordHandle = 0;
return true;
}
diff --git a/tests/auto/qbluetoothdevicediscoveryagent/qbluetoothdevicediscoveryagent.pro b/tests/auto/qbluetoothdevicediscoveryagent/qbluetoothdevicediscoveryagent.pro
index 43eda822..a7868123 100644
--- a/tests/auto/qbluetoothdevicediscoveryagent/qbluetoothdevicediscoveryagent.pro
+++ b/tests/auto/qbluetoothdevicediscoveryagent/qbluetoothdevicediscoveryagent.pro
@@ -3,7 +3,6 @@ TARGET=tst_qbluetoothdevicediscoveryagent
CONFIG += testcase
QT = core concurrent bluetooth testlib
+osx:QT += widgets
DEFINES += QT_DISABLE_DEPRECATED_BEFORE=0
-
-osx:CONFIG += insignificant_test
diff --git a/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp b/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp
index ca22c8ea..dec85fba 100644
--- a/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp
+++ b/tests/auto/qbluetoothdevicediscoveryagent/tst_qbluetoothdevicediscoveryagent.cpp
@@ -314,7 +314,10 @@ void tst_QBluetoothDeviceDiscoveryAgent::tst_startStopDeviceDiscoveries()
QVERIFY(errorSpy.isEmpty());
// should only have 1 cancel
QVERIFY(finishedSpy.count() == 1);
- QVERIFY(cancelSpy.isEmpty());
+
+ // On OS X, stop is synchronous (signal will be emitted immediately).
+ if (!immediateSignal)
+ QVERIFY(cancelSpy.isEmpty());
}
void tst_QBluetoothDeviceDiscoveryAgent::finished()