summaryrefslogtreecommitdiffstats
path: root/src/bluetooth/qbluetoothserviceinfo_osx.mm
diff options
context:
space:
mode:
authorTimur Pocheptsov <Timur.Pocheptsov@digia.com>2014-09-23 17:18:05 +0200
committerTimur Pocheptsov <Timur.Pocheptsov@digia.com>2014-09-26 18:19:54 +0200
commitd66c466a135e4bebc293256f6ca361b287fd9bdb (patch)
tree503ba3d58787adfcc6dca6b3cab16b47bd0c32ae /src/bluetooth/qbluetoothserviceinfo_osx.mm
parentd1d77c8210ecf7a89a81dad69d21b91e06bf129e (diff)
Port QBluetoothServer to OS X.
Implement QBluetoothServer using IOBluetooth framework. - Add empty (for now) implementation + modify .pro file. - Add a 'socket listener'. Actually, there are no sockets, no 'listen' but I still have to emulate this to make a server work. - Implement (to some degree) QBluetoothServer::listen member functions: on OS X QBluetoothServer::listen(address, port) does not really create a listening socket, it just checks that this port is not busy yet (IOBluetooth can either listen on a port you provide, or can listen on any port, but it can not select some port and listen on it. Only after service registered (with 'invalid' port first) - we have a real channelID or PSM. - Server port - either a "fake" port assigned by QBluetoothServer::listen, or a real port as registered by IOBluetooth. - Update a dependency. - Implement nextPendingConnection. - Implement fake server ports (something similar to Android version), but on OS X these fake ports can later be replaced with real ports. - Service info updates PSM/ChannelID with a real port and also starts a listener. - Unregister a server (dtor, close, etc.) - Do not update a 'fake' port with a real one: it can happen, that a real port is already taken by some 'fake' port and this will break the whole idea of fake ports. Let them be always fake, the real is required only when starting a 'listener'. - With 'fake' server ports '0' is not valid anymore (use serverPort() instead). Change-Id: I44537a35891c6806e58ec874a18bd938d4b41c53 Reviewed-by: Alex Blasche <alexander.blasche@digia.com>
Diffstat (limited to 'src/bluetooth/qbluetoothserviceinfo_osx.mm')
-rw-r--r--src/bluetooth/qbluetoothserviceinfo_osx.mm72
1 files changed, 39 insertions, 33 deletions
diff --git a/src/bluetooth/qbluetoothserviceinfo_osx.mm b/src/bluetooth/qbluetoothserviceinfo_osx.mm
index 621aab35..61f68f7f 100644
--- a/src/bluetooth/qbluetoothserviceinfo_osx.mm
+++ b/src/bluetooth/qbluetoothserviceinfo_osx.mm
@@ -40,6 +40,7 @@
****************************************************************************/
#include "osx/osxbtservicerecord_p.h"
+#include "qbluetoothserver_osx_p.h"
#include "qbluetoothserviceinfo.h"
#include "qbluetoothdeviceinfo.h"
#include "osx/osxbtutility_p.h"
@@ -47,6 +48,7 @@
#include <QtCore/qloggingcategory.h>
#include <QtCore/qvariant.h>
#include <QtCore/qglobal.h>
+#include <QtCore/qmutex.h>
#include <QtCore/qmap.h>
#include <QtCore/qurl.h>
@@ -58,6 +60,7 @@ QT_BEGIN_NAMESPACE
class QBluetoothServiceInfoPrivate
{
public:
+ typedef QBluetoothServiceInfo QSInfo;
QBluetoothServiceInfoPrivate(QBluetoothServiceInfo *q);
~QBluetoothServiceInfoPrivate();
@@ -116,54 +119,45 @@ bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &loca
return false;
}
- serviceRecord.reset([[IOBluetoothSDPServiceRecord
+ SDPRecord newRecord([[IOBluetoothSDPServiceRecord
publishedServiceRecordWithDictionary:serviceDict] retain]);
- if (!serviceRecord) {
+ if (!newRecord) {
qCWarning(QT_BT_OSX) << "QBluetoothServiceInfoPrivate::registerService(), "
"failed to create register a service record";
return false;
}
- QBluetoothServiceInfo::Sequence protocolDescriptorList;
- bool updatePDL = false;
+ const QSInfo::Protocol type = q_ptr->socketProtocol();
+ quint16 realPort = 0;
+ QBluetoothServerPrivate *server = Q_NULLPTR;
- if (q_ptr->socketProtocol() == QBluetoothServiceInfo::L2capProtocol) {
- //
+ if (type == QBluetoothServiceInfo::L2capProtocol) {
BluetoothL2CAPPSM psm = 0;
- if ([serviceRecord getL2CAPPSM:&psm] == kIOReturnSuccess) {
- if (psm != q_ptr->protocolServiceMultiplexer()) {
- // Update with a real PSM assigned by IOBluetooth!
- updatePDL = true;
- QBluetoothServiceInfo::Sequence protocol;
- protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
- protocol << QVariant::fromValue(qint16(psm));
- protocolDescriptorList.append(QVariant::fromValue(protocol));
- }
+ server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type);
+ if ([newRecord getL2CAPPSM:&psm] != kIOReturnSuccess) {
+ [newRecord removeServiceRecord];
+ return false;
}
- } else if (q_ptr->socketProtocol() == QBluetoothServiceInfo::RfcommProtocol) {
- //
+ realPort = psm;
+ } else if (type == QBluetoothServiceInfo::RfcommProtocol) {
BluetoothRFCOMMChannelID channelID = 0;
- if ([serviceRecord getRFCOMMChannelID:&channelID] == kIOReturnSuccess) {
- if (channelID != q_ptr->serverChannel()) {
- updatePDL = true;
- QBluetoothServiceInfo::Sequence protocol;
- protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::L2cap));
- protocolDescriptorList.append(QVariant::fromValue(protocol));
- protocol.clear();
- protocol << QVariant::fromValue(QBluetoothUuid(QBluetoothUuid::Rfcomm))
- << QVariant::fromValue(quint8(channelID));
- protocolDescriptorList.append(QVariant::fromValue(protocol));
- }
+ server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type);
+ if ([newRecord getRFCOMMChannelID:&channelID] != kIOReturnSuccess) {
+ [newRecord removeServiceRecord];
+ return false;
}
+ realPort = channelID;
}
- if (updatePDL)
- q_ptr->setAttribute(QBluetoothServiceInfo::ProtocolDescriptorList, protocolDescriptorList);
-
- // TODO - check ServiceRecordHandle + error handling - if we failed to obtain a port.
+ if (!server) {
+ [newRecord removeServiceRecord];
+ return false;
+ }
registered = true;
+ serviceRecord.reset(newRecord.take());
+ server->startListener(realPort);
return true;
}
@@ -184,7 +178,19 @@ bool QBluetoothServiceInfoPrivate::unregisterService()
[serviceRecord removeServiceRecord];
serviceRecord.reset(nil);
- return false;
+ const QSInfo::Protocol type = q_ptr->socketProtocol();
+ QBluetoothServerPrivate *server = Q_NULLPTR;
+
+ const QMutexLocker lock(&QBluetoothServerPrivate::channelMapMutex());
+ if (type == QSInfo::RfcommProtocol)
+ server = QBluetoothServerPrivate::registeredServer(q_ptr->serverChannel(), type);
+ else if (type == QSInfo::L2capProtocol)
+ server = QBluetoothServerPrivate::registeredServer(q_ptr->protocolServiceMultiplexer(), type);
+
+ if (server)
+ server->stopListener();
+
+ return true;
}
bool QBluetoothServiceInfo::isRegistered() const