summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorTimur Pocheptsov <timur.pocheptsov@qt.io>2019-07-04 16:13:44 +0200
committerTimur Pocheptsov <timur.pocheptsov@qt.io>2019-07-15 11:22:23 +0200
commitc1286c3a344593c79feced5c782ff85bca80bfff (patch)
treeee8e20e7971a2ab4453d3cac15f3a01d5c29ce82
parentde3e8e85cc5a442dbae966c6956c84ee434ad108 (diff)
QBluetoothSocket - deduplicate the code (macOS)
Implement the proper interface from QBluetoothSocketBasePrivate, remove a dummy base class. Remove all public API from qbluetoothsocket_osx.mm and re-use the code in qbluetoothsocket.cpp. The code generally is the same, a bit of re-hashin/deletion. Task-number: QTBUG-75348 Change-Id: I0034dfd283daf9d51775d8f9551b85d2d436aa85 Reviewed-by: Oliver Wolff <oliver.wolff@qt.io> Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
-rw-r--r--src/bluetooth/bluetooth.pro2
-rw-r--r--src/bluetooth/osx/osxbt.pri2
-rw-r--r--src/bluetooth/osx/osxbtchanneldelegate.mm52
-rw-r--r--src/bluetooth/osx/osxbtchanneldelegate_p.h79
-rw-r--r--src/bluetooth/osx/osxbtl2capchannel.mm8
-rw-r--r--src/bluetooth/osx/osxbtl2capchannel_p.h6
-rw-r--r--src/bluetooth/osx/osxbtrfcommchannel.mm8
-rw-r--r--src/bluetooth/osx/osxbtrfcommchannel_p.h6
-rw-r--r--src/bluetooth/qbluetoothserver_osx.mm4
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp15
-rw-r--r--src/bluetooth/qbluetoothsocket.h16
-rw-r--r--src/bluetooth/qbluetoothsocket_osx.mm839
-rw-r--r--src/bluetooth/qbluetoothsocket_osx_p.h82
-rw-r--r--src/bluetooth/qbluetoothsocketbase_p.h21
14 files changed, 367 insertions, 773 deletions
diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro
index 0b14357d..4c7a7876 100644
--- a/src/bluetooth/bluetooth.pro
+++ b/src/bluetooth/bluetooth.pro
@@ -176,8 +176,6 @@ qtConfig(bluez) {
SOURCES -= qbluetoothserviceinfo.cpp
SOURCES -= qbluetoothservicediscoveryagent.cpp
- SOURCES -= qbluetoothsocket.cpp
- SOURCES -= qbluetoothsocketbase.cpp
} else:ios|tvos {
DEFINES += QT_IOS_BLUETOOTH
LIBS_PRIVATE += -framework Foundation -framework CoreBluetooth
diff --git a/src/bluetooth/osx/osxbt.pri b/src/bluetooth/osx/osxbt.pri
index 89276310..8f6ea0d1 100644
--- a/src/bluetooth/osx/osxbt.pri
+++ b/src/bluetooth/osx/osxbt.pri
@@ -20,7 +20,6 @@ CONFIG(osx) {
osx/osxbtsdpinquiry_p.h \
osx/osxbtrfcommchannel_p.h \
osx/osxbtl2capchannel_p.h \
- osx/osxbtchanneldelegate_p.h \
osx/osxbtservicerecord_p.h \
osx/osxbtsocketlistener_p.h \
osx/osxbtobexsession_p.h \
@@ -37,7 +36,6 @@ CONFIG(osx) {
osx/osxbtsdpinquiry.mm \
osx/osxbtrfcommchannel.mm \
osx/osxbtl2capchannel.mm \
- osx/osxbtchanneldelegate.mm \
osx/osxbtservicerecord.mm \
osx/osxbtsocketlistener.mm \
osx/osxbtobexsession.mm \
diff --git a/src/bluetooth/osx/osxbtchanneldelegate.mm b/src/bluetooth/osx/osxbtchanneldelegate.mm
deleted file mode 100644
index 822e9d4e..00000000
--- a/src/bluetooth/osx/osxbtchanneldelegate.mm
+++ /dev/null
@@ -1,52 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtBluetooth module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#include "osxbtchanneldelegate_p.h"
-
-QT_BEGIN_NAMESPACE
-
-namespace OSXBluetooth {
-
-ChannelDelegate::~ChannelDelegate()
-{
-}
-
-}
-
-QT_END_NAMESPACE
diff --git a/src/bluetooth/osx/osxbtchanneldelegate_p.h b/src/bluetooth/osx/osxbtchanneldelegate_p.h
deleted file mode 100644
index 1102e935..00000000
--- a/src/bluetooth/osx/osxbtchanneldelegate_p.h
+++ /dev/null
@@ -1,79 +0,0 @@
-/****************************************************************************
-**
-** Copyright (C) 2016 The Qt Company Ltd.
-** Contact: https://www.qt.io/licensing/
-**
-** This file is part of the QtBluetooth module of the Qt Toolkit.
-**
-** $QT_BEGIN_LICENSE:LGPL$
-** Commercial License Usage
-** Licensees holding valid commercial Qt licenses may use this file in
-** accordance with the commercial license agreement provided with the
-** Software or, alternatively, in accordance with the terms contained in
-** a written agreement between you and The Qt Company. For licensing terms
-** and conditions see https://www.qt.io/terms-conditions. For further
-** information use the contact form at https://www.qt.io/contact-us.
-**
-** GNU Lesser General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU Lesser
-** General Public License version 3 as published by the Free Software
-** Foundation and appearing in the file LICENSE.LGPL3 included in the
-** packaging of this file. Please review the following information to
-** ensure the GNU Lesser General Public License version 3 requirements
-** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
-**
-** GNU General Public License Usage
-** Alternatively, this file may be used under the terms of the GNU
-** General Public License version 2.0 or (at your option) the GNU General
-** Public license version 3 or any later version approved by the KDE Free
-** Qt Foundation. The licenses are as published by the Free Software
-** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
-** included in the packaging of this file. Please review the following
-** information to ensure the GNU General Public License requirements will
-** be met: https://www.gnu.org/licenses/gpl-2.0.html and
-** https://www.gnu.org/licenses/gpl-3.0.html.
-**
-** $QT_END_LICENSE$
-**
-****************************************************************************/
-
-#ifndef OSXBTCHANNELDELEGATE_P_H
-#define OSXBTCHANNELDELEGATE_P_H
-
-//
-// W A R N I N G
-// -------------
-//
-// This file is not part of the Qt API. It exists purely as an
-// implementation detail. This header file may change from version to
-// version without notice, or even be removed.
-//
-// We mean it.
-//
-
-#include <QtCore/qglobal.h>
-
-#include <IOKit/IOReturn.h>
-
-QT_BEGIN_NAMESPACE
-
-namespace OSXBluetooth {
-
-class ChannelDelegate
-{
-public:
- virtual ~ChannelDelegate();
-
- virtual void setChannelError(IOReturn errorCode) = 0;
- virtual void channelOpenComplete() = 0;
- virtual void channelClosed() = 0;
-
- virtual void readChannelData(void *data, std::size_t size) = 0;
- virtual void writeComplete() = 0;
-};
-
-}
-
-QT_END_NAMESPACE
-
-#endif
diff --git a/src/bluetooth/osx/osxbtl2capchannel.mm b/src/bluetooth/osx/osxbtl2capchannel.mm
index dc8468a0..03e3a982 100644
--- a/src/bluetooth/osx/osxbtl2capchannel.mm
+++ b/src/bluetooth/osx/osxbtl2capchannel.mm
@@ -37,10 +37,10 @@
**
****************************************************************************/
-#include "osxbtchanneldelegate_p.h"
#include "osxbtl2capchannel_p.h"
#include "qbluetoothaddress.h"
#include "osxbtutility_p.h"
+#include "btdelegates_p.h"
#include <QtCore/qloggingcategory.h>
#include <QtCore/qdebug.h>
@@ -49,13 +49,13 @@ QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel)
{
- QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *delegate;
+ QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *delegate;
IOBluetoothDevice *device;
IOBluetoothL2CAPChannel *channel;
bool connected;
}
-- (id)initWithDelegate:(OSXBluetooth::ChannelDelegate *)aDelegate
+- (id)initWithDelegate:(DarwinBluetooth::ChannelDelegate *)aDelegate
{
Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
@@ -69,7 +69,7 @@ QT_USE_NAMESPACE
return self;
}
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth::ChannelDelegate) *)aDelegate
+- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth::ChannelDelegate) *)aDelegate
channel:(IOBluetoothL2CAPChannel *)aChannel
{
// This type of channel does not require connect, it's created with
diff --git a/src/bluetooth/osx/osxbtl2capchannel_p.h b/src/bluetooth/osx/osxbtl2capchannel_p.h
index 512087b4..42eec8e7 100644
--- a/src/bluetooth/osx/osxbtl2capchannel_p.h
+++ b/src/bluetooth/osx/osxbtl2capchannel_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
class QBluetoothAddress;
-namespace OSXBluetooth {
+namespace DarwinBluetooth {
class ChannelDelegate;
@@ -73,8 +73,8 @@ QT_END_NAMESPACE
@interface QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel) : NSObject<IOBluetoothL2CAPChannelDelegate>
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate;
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate
+- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *)aDelegate;
+- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *)aDelegate
channel:(IOBluetoothL2CAPChannel *)aChannel;
- (void)dealloc;
diff --git a/src/bluetooth/osx/osxbtrfcommchannel.mm b/src/bluetooth/osx/osxbtrfcommchannel.mm
index 00b67ee0..d2d3e2f8 100644
--- a/src/bluetooth/osx/osxbtrfcommchannel.mm
+++ b/src/bluetooth/osx/osxbtrfcommchannel.mm
@@ -37,22 +37,22 @@
**
****************************************************************************/
-#include "osxbtchanneldelegate_p.h"
#include "osxbtrfcommchannel_p.h"
#include "qbluetoothaddress.h"
#include "osxbtutility_p.h"
+#include "btdelegates_p.h"
QT_USE_NAMESPACE
@implementation QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel)
{
- QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *delegate;
+ QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *delegate;
IOBluetoothDevice *device;
IOBluetoothRFCOMMChannel *channel;
bool connected;
}
-- (id)initWithDelegate:(OSXBluetooth::ChannelDelegate *)aDelegate
+- (id)initWithDelegate:(DarwinBluetooth::ChannelDelegate *)aDelegate
{
Q_ASSERT_X(aDelegate, Q_FUNC_INFO, "invalid delegate (null)");
@@ -66,7 +66,7 @@ QT_USE_NAMESPACE
return self;
}
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth::ChannelDelegate) *)aDelegate
+- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth::ChannelDelegate) *)aDelegate
channel:(IOBluetoothRFCOMMChannel *)aChannel
{
// This type of channel does not require connect, it's created with
diff --git a/src/bluetooth/osx/osxbtrfcommchannel_p.h b/src/bluetooth/osx/osxbtrfcommchannel_p.h
index 775999ed..44416cce 100644
--- a/src/bluetooth/osx/osxbtrfcommchannel_p.h
+++ b/src/bluetooth/osx/osxbtrfcommchannel_p.h
@@ -63,7 +63,7 @@ QT_BEGIN_NAMESPACE
class QBluetoothAddress;
-namespace OSXBluetooth {
+namespace DarwinBluetooth {
class ChannelDelegate;
@@ -73,8 +73,8 @@ QT_END_NAMESPACE
@interface QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel) : NSObject<IOBluetoothRFCOMMChannelDelegate>
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate;
-- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(OSXBluetooth)::ChannelDelegate *)aDelegate
+- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *)aDelegate;
+- (id)initWithDelegate:(QT_PREPEND_NAMESPACE(DarwinBluetooth)::ChannelDelegate *)aDelegate
channel:(IOBluetoothRFCOMMChannel *)aChannel;
- (void)dealloc;
diff --git a/src/bluetooth/qbluetoothserver_osx.mm b/src/bluetooth/qbluetoothserver_osx.mm
index 325381c8..9674331d 100644
--- a/src/bluetooth/qbluetoothserver_osx.mm
+++ b/src/bluetooth/qbluetoothserver_osx.mm
@@ -389,10 +389,10 @@ QBluetoothSocket *QBluetoothServer::nextPendingConnection()
d_ptr->pendingConnections.pop_front();
if (d_ptr->serverType == ServiceInfo::RfcommProtocol) {
- if (!newSocket->d_ptr->setChannel(channel.getAs<IOBluetoothRFCOMMChannel>()))
+ if (!static_cast<QBluetoothSocketPrivate *>(newSocket->d_ptr)->setRFCOMChannel(channel.getAs<IOBluetoothRFCOMMChannel>()))
return nullptr;
} else {
- if (!newSocket->d_ptr->setChannel(channel.getAs<IOBluetoothL2CAPChannel>()))
+ if (!static_cast<QBluetoothSocketPrivate *>(newSocket->d_ptr)->setL2CAPChannel(channel.getAs<IOBluetoothL2CAPChannel>()))
return nullptr;
}
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index db7c8be4..b1f75741 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -47,6 +47,8 @@
#include "qbluetoothsocket_android_p.h"
#elif defined(QT_WINRT_BLUETOOTH)
#include "qbluetoothsocket_winrt_p.h"
+#elif defined(QT_OSX_BLUETOOTH)
+#include "qbluetoothsocket_osx_p.h"
#else
#include "qbluetoothsocket_dummy_p.h"
#endif
@@ -267,6 +269,8 @@ static QBluetoothSocketBasePrivate *createSocketPrivate()
return new QBluetoothSocketPrivateAndroid();
#elif defined(QT_WINRT_BLUETOOTH)
return new QBluetoothSocketPrivateWinRT();
+#elif defined(QT_OSX_BLUETOOTH)
+ return new QBluetoothSocketPrivate();
#else
return new QBluetoothSocketPrivateDummy();
#endif
@@ -513,6 +517,9 @@ QString QBluetoothSocket::errorString() const
*/
void QBluetoothSocket::setPreferredSecurityFlags(QBluetooth::SecurityFlags flags)
{
+#ifdef QT_OSX_BLUETOOTH
+ return; // not supported on macOS.
+#endif
Q_D(QBluetoothSocketBase);
if (d->secFlags != flags)
d->secFlags = flags;
@@ -534,8 +541,13 @@ void QBluetoothSocket::setPreferredSecurityFlags(QBluetooth::SecurityFlags flags
*/
QBluetooth::SecurityFlags QBluetoothSocket::preferredSecurityFlags() const
{
+#if QT_OSX_BLUETOOTH
+ // not supported on macOS - platform always uses encryption
+ return QBluetooth::Secure;
+#else
Q_D(const QBluetoothSocketBase);
return d->secFlags;
+#endif // QT_OSX_BLUETOOTH
}
/*!
@@ -559,6 +571,9 @@ void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
emit disconnected();
}
if(state == ListeningState){
+#ifdef QT_OSX_BLUETOOTH
+ qCWarning(QT_BT) << "listening socket is not supported by IOBluetooth";
+#endif
// TODO: look at this, is this really correct?
// if we're a listening socket we can't handle connects?
if (d->readNotifier) {
diff --git a/src/bluetooth/qbluetoothsocket.h b/src/bluetooth/qbluetoothsocket.h
index d2535544..256a95dc 100644
--- a/src/bluetooth/qbluetoothsocket.h
+++ b/src/bluetooth/qbluetoothsocket.h
@@ -52,21 +52,14 @@
QT_BEGIN_NAMESPACE
-#ifndef QT_OSX_BLUETOOTH
+
class QBluetoothSocketBasePrivate;
-#else
-class QBluetoothSocketPrivate;
-#endif
class Q_BLUETOOTH_EXPORT QBluetoothSocket : public QIODevice
{
Q_OBJECT
-#ifndef QT_OSX_BLUETOOTH
- Q_DECLARE_PRIVATE(QBluetoothSocketBase)
-#else
- Q_DECLARE_PRIVATE(QBluetoothSocket)
-#endif
+ Q_DECLARE_PRIVATE(QBluetoothSocketBase)
friend class QBluetoothServer;
friend class QBluetoothServerPrivate;
@@ -187,11 +180,8 @@ protected:
QBluetoothServiceInfo::Protocol socketType,
QObject *parent = nullptr);
#endif
-#ifndef QT_OSX_BLUETOOTH
+
QBluetoothSocketBasePrivate *d_ptr;
-#else
- QBluetoothSocketPrivate *d_ptr;
-#endif
private:
friend class QLowEnergyControllerPrivateBluez;
diff --git a/src/bluetooth/qbluetoothsocket_osx.mm b/src/bluetooth/qbluetoothsocket_osx.mm
index 7f630146..f74c14f8 100644
--- a/src/bluetooth/qbluetoothsocket_osx.mm
+++ b/src/bluetooth/qbluetoothsocket_osx.mm
@@ -43,6 +43,9 @@
// dependencies problem.
#include "qbluetoothsocketbase_p.h"
#include "qbluetoothsocket_osx_p.h"
+
+#include "osx/osxbtrfcommchannel_p.h"
+#include "osx/osxbtl2capchannel_p.h"
#include "qbluetoothlocaldevice.h"
#include "qbluetoothdeviceinfo.h"
#include "osx/osxbtutility_p.h"
@@ -57,30 +60,294 @@
QT_BEGIN_NAMESPACE
+namespace {
+
+using DarwinBluetooth::RetainPolicy;
+using ObjCL2CAPChannel = QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel);
+using ObjCRFCOMMChannel = QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel);
+
+} // unnamed namespace
+
QBluetoothSocketPrivate::QBluetoothSocketPrivate()
- : writeChunk(std::numeric_limits<UInt16>::max()),
- openMode(QIODevice::NotOpen), // That's what is set in public class' ctors.
- state(QBluetoothSocket::UnconnectedState),
- socketType(QBluetoothServiceInfo::UnknownProtocol),
- socketError(QBluetoothSocket::NoSocketError),
- isConnecting(false)
+ : writeChunk(std::numeric_limits<UInt16>::max())
{
q_ptr = nullptr;
}
QBluetoothSocketPrivate::~QBluetoothSocketPrivate()
{
- // "Empty" dtor to make a shared pointer happy (parametrized with
- // incomplete type in the header file).
+}
+
+bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothServiceInfo::Protocol type)
+{
+ // For now - very simplistic, we don't call it in this file, public class
+ // only calls it in a ctor, setting the protocol RFCOMM (in case of Android)
+ // or, indeed, doing, socket-related initialization in BlueZ backend.
+ Q_ASSERT(socketType == QBluetoothServiceInfo::UnknownProtocol);
+ socketType = type;
+ return type != QBluetoothServiceInfo::UnknownProtocol;
+}
+
+QString QBluetoothSocketPrivate::localName() const
+{
+ const QBluetoothLocalDevice device;
+ return device.name();
+}
+
+QBluetoothAddress QBluetoothSocketPrivate::localAddress() const
+{
+ const QBluetoothLocalDevice device;
+ return device.address();
+}
+
+quint16 QBluetoothSocketPrivate::localPort() const
+{
+ return 0;
+}
+
+QString QBluetoothSocketPrivate::peerName() const
+{
+ QT_BT_MAC_AUTORELEASEPOOL;
+
+ NSString *nsName = nil;
+ if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
+ if (rfcommChannel)
+ nsName = [rfcommChannel.getAs<ObjCRFCOMMChannel>() peerName];
+ } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
+ if (l2capChannel)
+ nsName = [l2capChannel.getAs<ObjCL2CAPChannel>() peerName];
+ }
+
+ if (nsName)
+ return QString::fromNSString(nsName);
+
+ return QString();
+}
+
+QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const
+{
+ BluetoothDeviceAddress addr = {};
+ if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
+ if (rfcommChannel)
+ addr = [rfcommChannel.getAs<ObjCRFCOMMChannel>() peerAddress];
+ } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
+ if (l2capChannel)
+ addr = [l2capChannel.getAs<ObjCL2CAPChannel>() peerAddress];
+ }
+
+ return OSXBluetooth::qt_address(&addr);
+}
+
+quint16 QBluetoothSocketPrivate::peerPort() const
+{
+ if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
+ if (rfcommChannel)
+ return [rfcommChannel.getAs<ObjCRFCOMMChannel>() getChannelID];
+ } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
+ if (l2capChannel)
+ return [l2capChannel.getAs<ObjCL2CAPChannel>() getPSM];
+ }
+
+ return 0;
+}
+
+void QBluetoothSocketPrivate::abort()
+{
+ // Can never be called while we're in connectToService:
+ Q_ASSERT_X(!isConnecting, Q_FUNC_INFO, "internal inconsistency - "
+ "still in connectToService()");
+
+ if (socketType == QBluetoothServiceInfo::RfcommProtocol)
+ rfcommChannel.reset();
+ else if (socketType == QBluetoothServiceInfo::L2capProtocol)
+ l2capChannel.reset();
+
+ Q_ASSERT(q_ptr);
+
+ q_ptr->setSocketState(QBluetoothSocket::UnconnectedState);
+ emit q_ptr->readChannelFinished();
+ emit q_ptr->disconnected();
+
+}
+
+void QBluetoothSocketPrivate::close()
+{
+ // Can never be called while we're in connectToService:
+ Q_ASSERT_X(!isConnecting, Q_FUNC_INFO, "internal inconsistency - "
+ "still in connectToService()");
+
+ if (!txBuffer.size())
+ abort();
+}
+
+
+qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
+{
+ Q_ASSERT_X(data, Q_FUNC_INFO, "invalid data (null)");
+ Q_ASSERT_X(maxSize > 0, Q_FUNC_INFO, "invalid data size");
+
+ if (state != QBluetoothSocket::ConnectedState) {
+ errorString = QCoreApplication::translate(SOCKET, SOC_NOWRITE);
+ q_ptr->setSocketError(QBluetoothSocket::OperationError);
+ return -1;
+ }
+
+ // We do not have a real socket API under the hood,
+ // IOBluetoothL2CAPChannel is buffered (writeAsync).
+
+ if (!txBuffer.size())
+ QMetaObject::invokeMethod(this, "_q_writeNotify", Qt::QueuedConnection);
+
+ char *dst = txBuffer.reserve(int(maxSize));
+ std::copy(data, data + maxSize, dst);
+
+ return maxSize;
+}
+
+qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
+{
+ if (!data)
+ return 0;
+
+ if (state != QBluetoothSocket::ConnectedState) {
+ errorString = QCoreApplication::translate(SOCKET, SOC_NOREAD);
+ q_ptr->setSocketError(QBluetoothSocket::OperationError);
+ return -1;
+ }
+
+ if (!buffer.isEmpty())
+ return buffer.read(data, int(maxSize));
+
+ return 0;
+}
+
+qint64 QBluetoothSocketPrivate::bytesAvailable() const
+{
+ return buffer.size();
+}
+
+bool QBluetoothSocketPrivate::canReadLine() const
+{
+ return buffer.canReadLine();
+}
+
+qint64 QBluetoothSocketPrivate::bytesToWrite() const
+{
+ return txBuffer.size();
+}
+
+bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
+ QBluetoothSocket::SocketState socketState, QIODevice::OpenMode openMode)
+{
+ Q_UNUSED(socketDescriptor)
+ Q_UNUSED(socketType)
+ Q_UNUSED(socketState)
+ Q_UNUSED(openMode)
+
+ qCWarning(QT_BT_OSX) << "setting a socket descriptor is not supported by IOBluetooth";
+ // Noop on macOS.
+ return true;
+}
+
+void QBluetoothSocketPrivate::connectToServiceHelper(const QBluetoothAddress &address, quint16 port,
+ QIODevice::OpenMode openMode)
+{
+ Q_UNUSED(address)
+ Q_UNUSED(port)
+ Q_UNUSED(openMode)
+}
+
+void QBluetoothSocketPrivate::connectToService(const QBluetoothServiceInfo &service, QIODevice::OpenMode openMode)
+{
+ Q_ASSERT(q_ptr);
+
+ OSXBluetooth::qt_test_iobluetooth_runloop();
+
+ if (state!= QBluetoothSocket::UnconnectedState && state != QBluetoothSocket::ServiceLookupState) {
+ qCWarning(QT_BT_OSX) << "called on a busy socket";
+ errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
+ q_ptr->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ // Report this problem early, potentially avoid device discovery:
+ if (service.socketProtocol() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
+ errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
+ q_ptr->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
+ socketType = service.socketProtocol();
+
+ if (service.protocolServiceMultiplexer() > 0) {
+ connectToService(service.device().address(),
+ quint16(service.protocolServiceMultiplexer()),
+ openMode);
+ } else if (service.serverChannel() > 0) {
+ connectToService(service.device().address(),
+ quint16(service.serverChannel()),
+ openMode);
+ } else {
+ // Try service discovery.
+ if (service.serviceUuid().isNull()) {
+ qCWarning(QT_BT_OSX) << "No port, no PSM, and no "
+ "UUID provided, unable to connect";
+ return;
+ }
+
+ q_ptr->doDeviceDiscovery(service, openMode);
+ }
+}
+
+void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid,
+ QIODevice::OpenMode openMode)
+{
+ Q_ASSERT(q_ptr);
+
+ OSXBluetooth::qt_test_iobluetooth_runloop();
+
+ // Report this problem early, avoid device discovery:
+ if (socketType == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
+ errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
+ q_ptr->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
+ if (state != QBluetoothSocket::UnconnectedState) {
+ qCWarning(QT_BT_OSX) << "called on a busy socket";
+ errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
+ q_ptr->setSocketError(QBluetoothSocket::OperationError);
+ return;
+ }
+
+ QBluetoothDeviceInfo device(address, QString(), QBluetoothDeviceInfo::MiscellaneousDevice);
+ QBluetoothServiceInfo service;
+ service.setDevice(device);
+ service.setServiceUuid(uuid);
+ q_ptr->doDeviceDiscovery(service, openMode);
}
void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port,
QIODevice::OpenMode mode)
{
- Q_ASSERT_X(state == QBluetoothSocket::ServiceLookupState
- || state == QBluetoothSocket::UnconnectedState,
+ Q_ASSERT(q_ptr);
+
+ OSXBluetooth::qt_test_iobluetooth_runloop();
+
+ if (socketType == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
+ errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
+ q_ptr->setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
+ Q_ASSERT_X(state == QBluetoothSocket::ServiceLookupState || state == QBluetoothSocket::UnconnectedState,
Q_FUNC_INFO, "invalid state");
+ q_ptr->setOpenMode(mode);
+
socketError = QBluetoothSocket::NoSocketError;
errorString.clear();
buffer.clear();
@@ -100,15 +367,15 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address,
openMode = mode;
if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
- rfcommChannel.reset([[ObjCRFCOMMChannel alloc] initWithDelegate:this]);
+ rfcommChannel.reset([[ObjCRFCOMMChannel alloc] initWithDelegate:this], RetainPolicy::noInitialRetain);
if (rfcommChannel)
- status = [rfcommChannel connectAsyncToDevice:address withChannelID:port];
+ status = [rfcommChannel.getAs<ObjCRFCOMMChannel>() connectAsyncToDevice:address withChannelID:port];
else
status = kIOReturnNoMemory;
} else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
- l2capChannel.reset([[ObjCL2CAPChannel alloc] initWithDelegate:this]);
+ l2capChannel.reset([[ObjCL2CAPChannel alloc] initWithDelegate:this], RetainPolicy::noInitialRetain);
if (l2capChannel)
- status = [l2capChannel connectAsyncToDevice:address withPSM:port];
+ status = [l2capChannel.getAs<ObjCL2CAPChannel>() connectAsyncToDevice:address withPSM:port];
else
status = kIOReturnNoMemory;
}
@@ -148,84 +415,6 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address,
}
}
-void QBluetoothSocketPrivate::close()
-{
- // Can never be called while we're in connectToService:
- Q_ASSERT_X(!isConnecting, Q_FUNC_INFO, "internal inconsistency - "
- "still in connectToService()");
-
- if (!txBuffer.size())
- abort();
-}
-
-void QBluetoothSocketPrivate::abort()
-{
- // Can never be called while we're in connectToService:
- Q_ASSERT_X(!isConnecting, Q_FUNC_INFO, "internal inconsistency - "
- "still in connectToService()");
-
- if (socketType == QBluetoothServiceInfo::RfcommProtocol)
- rfcommChannel.reset(nil);
- else if (socketType == QBluetoothServiceInfo::L2capProtocol)
- l2capChannel.reset(nil);
-}
-
-quint64 QBluetoothSocketPrivate::bytesAvailable() const
-{
- return buffer.size();
-}
-
-QString QBluetoothSocketPrivate::peerName() const
-{
- QT_BT_MAC_AUTORELEASEPOOL;
-
- NSString *nsName = nil;
- if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
- if (rfcommChannel)
- nsName = [rfcommChannel peerName];
- } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
- if (l2capChannel)
- nsName = [l2capChannel peerName];
- }
-
- if (nsName)
- return QString::fromNSString(nsName);
-
- return QString();
-}
-
-QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const
-{
- BluetoothDeviceAddress addr = {};
- if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
- if (rfcommChannel)
- addr = [rfcommChannel peerAddress];
- } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
- if (l2capChannel)
- addr = [l2capChannel peerAddress];
- }
-
- return OSXBluetooth::qt_address(&addr);
-}
-
-quint16 QBluetoothSocketPrivate::peerPort() const
-{
- if (socketType == QBluetoothServiceInfo::RfcommProtocol) {
- if (rfcommChannel)
- return [rfcommChannel getChannelID];
- } else if (socketType == QBluetoothServiceInfo::L2capProtocol) {
- if (l2capChannel)
- return [l2capChannel getPSM];
- }
-
- return 0;
-}
-
-void QBluetoothSocketPrivate::_q_readNotify()
-{
- // Noop.
-}
-
void QBluetoothSocketPrivate::_q_writeNotify()
{
Q_ASSERT_X(socketType == QBluetoothServiceInfo::L2capProtocol
@@ -238,14 +427,14 @@ void QBluetoothSocketPrivate::_q_writeNotify()
if (txBuffer.size()) {
const bool isL2CAP = socketType == QBluetoothServiceInfo::L2capProtocol;
writeChunk.resize(isL2CAP ? std::numeric_limits<UInt16>::max() :
- [rfcommChannel getMTU]);
+ [rfcommChannel.getAs<ObjCRFCOMMChannel>() getMTU]);
const int size = txBuffer.read(writeChunk.data(), writeChunk.size());
IOReturn status = kIOReturnError;
if (!isL2CAP)
- status = [rfcommChannel writeAsync:writeChunk.data() length:UInt16(size)];
+ status = [rfcommChannel.getAs<ObjCRFCOMMChannel>() writeAsync:writeChunk.data() length:UInt16(size)];
else
- status = [l2capChannel writeAsync:writeChunk.data() length:UInt16(size)];
+ status = [l2capChannel.getAs<ObjCL2CAPChannel>() writeAsync:writeChunk.data() length:UInt16(size)];
if (status != kIOReturnSuccess) {
errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
@@ -260,21 +449,22 @@ void QBluetoothSocketPrivate::_q_writeNotify()
close();
}
-bool QBluetoothSocketPrivate::setChannel(IOBluetoothRFCOMMChannel *channel)
+bool QBluetoothSocketPrivate::setRFCOMChannel(void *generic)
{
// A special case "constructor": on OS X we do not have a real listening socket,
// instead a bluetooth server "listens" for channel open notifications and
// creates (if asked by a user later) a "socket" object
// for this connection. This function initializes
// a "socket" from such an external channel (reported by a notification).
-
+ auto channel = static_cast<IOBluetoothRFCOMMChannel *>(generic);
// It must be a newborn socket!
Q_ASSERT_X(socketError == QBluetoothSocket::NoSocketError
&& state == QBluetoothSocket::UnconnectedState && !rfcommChannel && !l2capChannel,
Q_FUNC_INFO, "unexpected socket state");
openMode = QIODevice::ReadWrite;
- rfcommChannel.reset([[ObjCRFCOMMChannel alloc] initWithDelegate:this channel:channel]);
+ rfcommChannel.reset([[ObjCRFCOMMChannel alloc] initWithDelegate:this channel:channel],
+ RetainPolicy::noInitialRetain);
if (rfcommChannel) {// We do not handle errors, up to an external user.
q_ptr->setOpenMode(QIODevice::ReadWrite);
state = QBluetoothSocket::ConnectedState;
@@ -284,13 +474,14 @@ bool QBluetoothSocketPrivate::setChannel(IOBluetoothRFCOMMChannel *channel)
return rfcommChannel;
}
-bool QBluetoothSocketPrivate::setChannel(IOBluetoothL2CAPChannel *channel)
+bool QBluetoothSocketPrivate::setL2CAPChannel(void *generic)
{
// A special case "constructor": on OS X we do not have a real listening socket,
// instead a bluetooth server "listens" for channel open notifications and
// creates (if asked by a user later) a "socket" object
// for this connection. This function initializes
// a "socket" from such an external channel (reported by a notification).
+ auto channel = static_cast<IOBluetoothL2CAPChannel *>(generic);
// It must be a newborn socket!
Q_ASSERT_X(socketError == QBluetoothSocket::NoSocketError
@@ -298,7 +489,7 @@ bool QBluetoothSocketPrivate::setChannel(IOBluetoothL2CAPChannel *channel)
Q_FUNC_INFO, "unexpected socket state");
openMode = QIODevice::ReadWrite;
- l2capChannel.reset([[ObjCL2CAPChannel alloc] initWithDelegate:this channel:channel]);
+ l2capChannel.reset([[ObjCL2CAPChannel alloc] initWithDelegate:this channel:channel], RetainPolicy::noInitialRetain);
if (l2capChannel) {// We do not handle errors, up to an external user.
q_ptr->setOpenMode(QIODevice::ReadWrite);
state = QBluetoothSocket::ConnectedState;
@@ -308,7 +499,6 @@ bool QBluetoothSocketPrivate::setChannel(IOBluetoothL2CAPChannel *channel)
return l2capChannel;
}
-
void QBluetoothSocketPrivate::setChannelError(IOReturn errorCode)
{
Q_UNUSED(errorCode)
@@ -365,7 +555,7 @@ void QBluetoothSocketPrivate::readChannelData(void *data, std::size_t size)
Q_ASSERT_X(q_ptr, Q_FUNC_INFO, "invalid q_ptr (null)");
const char *src = static_cast<char *>(data);
- char *dst = buffer.reserve(size);
+ char *dst = buffer.reserve(int(size));
std::copy(src, src + size, dst);
if (!isConnecting) {
@@ -379,449 +569,4 @@ void QBluetoothSocketPrivate::writeComplete()
_q_writeNotify();
}
-qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize)
-{
- Q_ASSERT_X(data, Q_FUNC_INFO, "invalid data (null)");
- Q_ASSERT_X(maxSize > 0, Q_FUNC_INFO, "invalid data size");
-
- if (state != QBluetoothSocket::ConnectedState) {
- errorString = QCoreApplication::translate(SOCKET, SOC_NOWRITE);
- q_ptr->setSocketError(QBluetoothSocket::OperationError);
- return -1;
- }
-
- // We do not have a real socket API under the hood,
- // IOBluetoothL2CAPChannel buffered (writeAsync).
-
- if (!txBuffer.size())
- QMetaObject::invokeMethod(this, "_q_writeNotify", Qt::QueuedConnection);
-
- char *dst = txBuffer.reserve(maxSize);
- std::copy(data, data + maxSize, dst);
-
- return maxSize;
-}
-
-QBluetoothSocket::QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, QObject *parent)
- : QIODevice(parent),
- d_ptr(new QBluetoothSocketPrivate)
-{
- d_ptr->q_ptr = this;
- d_ptr->socketType = socketType;
-
- setOpenMode(NotOpen);
-}
-
-QBluetoothSocket::QBluetoothSocket(QObject *parent)
- : QIODevice(parent),
- d_ptr(new QBluetoothSocketPrivate)
-{
- d_ptr->q_ptr = this;
- setOpenMode(NotOpen);
-}
-
-QBluetoothSocket::~QBluetoothSocket()
-{
- delete d_ptr;
-}
-
-bool QBluetoothSocket::isSequential() const
-{
- return true;
-}
-
-qint64 QBluetoothSocket::bytesAvailable() const
-{
- return QIODevice::bytesAvailable() + d_ptr->bytesAvailable();
-}
-
-qint64 QBluetoothSocket::bytesToWrite() const
-{
- return d_ptr->txBuffer.size();
-}
-
-void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode)
-{
- OSXBluetooth::qt_test_iobluetooth_runloop();
-
- if (state() != UnconnectedState && state() != ServiceLookupState) {
- qCWarning(QT_BT_OSX) << "called on a busy socket";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
- setSocketError(OperationError);
- return;
- }
-
- // Report this problem early, potentially avoid device discovery:
- if (service.socketProtocol() == QBluetoothServiceInfo::UnknownProtocol) {
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
- setSocketError(QBluetoothSocket::UnsupportedProtocolError);
- return;
- }
-
- d_ptr->socketType = service.socketProtocol();
-
- if (service.protocolServiceMultiplexer() > 0) {
- d_ptr->connectToService(service.device().address(),
- service.protocolServiceMultiplexer(),
- openMode);
- } else if (service.serverChannel() > 0) {
- d_ptr->connectToService(service.device().address(),
- service.serverChannel(), openMode);
- } else {
- // Try service discovery.
- if (service.serviceUuid().isNull()) {
- qCWarning(QT_BT_OSX) << "No port, no PSM, and no "
- "UUID provided, unable to connect";
- return;
- }
-
- doDeviceDiscovery(service, openMode);
- }
-}
-
-void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid,
- OpenMode openMode)
-{
- OSXBluetooth::qt_test_iobluetooth_runloop();
-
- // Report this problem early, avoid device discovery:
- if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
- setSocketError(QBluetoothSocket::UnsupportedProtocolError);
- return;
- }
-
- if (state() != QBluetoothSocket::UnconnectedState) {
- qCWarning(QT_BT_OSX) << "called on a busy socket";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
- setSocketError(QBluetoothSocket::OperationError);
- return;
- }
-
- QBluetoothDeviceInfo device(address, QString(), QBluetoothDeviceInfo::MiscellaneousDevice);
- QBluetoothServiceInfo service;
- service.setDevice(device);
- service.setServiceUuid(uuid);
- doDeviceDiscovery(service, openMode);
-}
-
-void QBluetoothSocket::connectToService(const QBluetoothAddress &address, quint16 port,
- OpenMode openMode)
-{
- OSXBluetooth::qt_test_iobluetooth_runloop();
-
- if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
- qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
- setSocketError(QBluetoothSocket::UnsupportedProtocolError);
- return;
- }
-
- if (state() != QBluetoothSocket::UnconnectedState) {
- qCWarning(QT_BT_OSX) << "called on a busy socket";
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
- setSocketError(OperationError);
- return;
- }
-
- setOpenMode(openMode);
- d_ptr->connectToService(address, port, openMode);
-}
-
-QBluetoothServiceInfo::Protocol QBluetoothSocket::socketType() const
-{
- return d_ptr->socketType;
-}
-
-QBluetoothSocket::SocketState QBluetoothSocket::state() const
-{
- return d_ptr->state;
-}
-
-QBluetoothSocket::SocketError QBluetoothSocket::error() const
-{
- return d_ptr->socketError;
-}
-
-QString QBluetoothSocket::errorString() const
-{
- return d_ptr->errorString;
-}
-
-void QBluetoothSocket::setSocketState(QBluetoothSocket::SocketState state)
-{
- const SocketState oldState = d_ptr->state;
- d_ptr->state = state;
- if (oldState != d_ptr->state)
- emit stateChanged(state);
-
- if (state == ListeningState) {
- // We can register for L2CAP/RFCOMM open notifications,
- // that's different from 'listen' and is implemented
- // in QBluetoothServer.
- qCWarning(QT_BT_OSX) << "listening sockets are not supported";
- }
-}
-
-bool QBluetoothSocket::canReadLine() const
-{
- return d_ptr->buffer.canReadLine() || QIODevice::canReadLine();
-}
-
-void QBluetoothSocket::setSocketError(QBluetoothSocket::SocketError socketError)
-{
- d_ptr->socketError = socketError;
- emit error(socketError);
-}
-
-void QBluetoothSocket::doDeviceDiscovery(const QBluetoothServiceInfo &service, OpenMode openMode)
-{
- OSXBluetooth::qt_test_iobluetooth_runloop();
-
- setSocketState(ServiceLookupState);
-
- if (d_ptr->discoveryAgent)
- d_ptr->discoveryAgent->stop();
-
- d_ptr->discoveryAgent.reset(new QBluetoothServiceDiscoveryAgent(this));
- d_ptr->discoveryAgent->setRemoteAddress(service.device().address());
-
- connect(d_ptr->discoveryAgent.data(), SIGNAL(serviceDiscovered(QBluetoothServiceInfo)),
- this, SLOT(serviceDiscovered(QBluetoothServiceInfo)));
- connect(d_ptr->discoveryAgent.data(), SIGNAL(finished()),
- this, SLOT(discoveryFinished()));
-
- d_ptr->openMode = openMode;
-
- if (!service.serviceUuid().isNull())
- d_ptr->discoveryAgent->setUuidFilter(service.serviceUuid());
-
- if (!service.serviceClassUuids().isEmpty())
- d_ptr->discoveryAgent->setUuidFilter(service.serviceClassUuids());
-
- Q_ASSERT_X(!d_ptr->discoveryAgent->uuidFilter().isEmpty(), Q_FUNC_INFO,
- "invalid service info");
-
- d_ptr->discoveryAgent->start(QBluetoothServiceDiscoveryAgent::FullDiscovery);
-}
-
-void QBluetoothSocket::serviceDiscovered(const QBluetoothServiceInfo &service)
-{
- if (service.protocolServiceMultiplexer() != 0 || service.serverChannel() != 0) {
- d_ptr->discoveryAgent->stop();
- connectToService(service, d_ptr->openMode);
- }
-}
-
-void QBluetoothSocket::discoveryFinished()
-{
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_SERVICE_NOT_FOUND);
- setSocketState(UnconnectedState);
- setSocketError(ServiceNotFoundError);
-}
-
-void QBluetoothSocket::abort()
-{
- if (state() == UnconnectedState)
- return;
-
- setOpenMode(NotOpen);
-
- if (state() == ServiceLookupState && d_ptr->discoveryAgent) {
- d_ptr->discoveryAgent->disconnect();
- d_ptr->discoveryAgent->stop();
- d_ptr->discoveryAgent.reset();
- }
-
- setSocketState(QBluetoothSocket::ClosingState);
- d_ptr->abort();
-
- setSocketState(QBluetoothSocket::UnconnectedState);
- emit readChannelFinished();
- emit disconnected();
-}
-
-void QBluetoothSocket::disconnectFromService()
-{
- close();
-}
-
-QString QBluetoothSocket::localName() const
-{
- const QBluetoothLocalDevice device;
- return device.name();
-}
-
-QBluetoothAddress QBluetoothSocket::localAddress() const
-{
- const QBluetoothLocalDevice device;
- return device.address();
-}
-
-quint16 QBluetoothSocket::localPort() const
-{
- return 0;
-}
-
-QString QBluetoothSocket::peerName() const
-{
- return d_ptr->peerName();
-}
-
-QBluetoothAddress QBluetoothSocket::peerAddress() const
-{
- return d_ptr->peerAddress();
-}
-
-quint16 QBluetoothSocket::peerPort() const
-{
- return d_ptr->peerPort();
-}
-
-qint64 QBluetoothSocket::writeData(const char *data, qint64 maxSize)
-{
- if (!data || maxSize <= 0) {
- d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_INVAL_DATASIZE);
- setSocketError(QBluetoothSocket::OperationError);
- return -1;
- }
-
- return d_ptr->writeData(data, maxSize);
-}
-
-qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize)
-{
- if (state != QBluetoothSocket::ConnectedState) {
- errorString = QCoreApplication::translate(SOCKET, SOC_NOREAD);
- q_ptr->setSocketError(QBluetoothSocket::OperationError);
- return -1;
- }
-
- if (!buffer.isEmpty())
- return buffer.read(data, maxSize);
-
- return 0;
-}
-
-qint64 QBluetoothSocket::readData(char *data, qint64 maxSize)
-{
- return d_ptr->readData(data, maxSize);
-}
-
-void QBluetoothSocket::close()
-{
- if (state() == UnconnectedState)
- return;
-
- setOpenMode(NotOpen);
-
- if (state() == ServiceLookupState && d_ptr->discoveryAgent) {
- d_ptr->discoveryAgent->disconnect();
- d_ptr->discoveryAgent->stop();
- d_ptr->discoveryAgent.reset();
- }
-
- setSocketState(ClosingState);
-
- d_ptr->close();
-
- setSocketState(UnconnectedState);
- emit readChannelFinished();
- emit disconnected();
-}
-
-bool QBluetoothSocket::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
- SocketState socketState, OpenMode openMode)
-{
- Q_UNUSED(socketDescriptor)
- Q_UNUSED(socketType)
- Q_UNUSED(socketState)
- Q_UNUSED(openMode)
-
- // Noop on OS X.
- return true;
-}
-
-int QBluetoothSocket::socketDescriptor() const
-{
- return -1;
-}
-
-/* not supported on OS X */
-void QBluetoothSocket::setPreferredSecurityFlags(QBluetooth::SecurityFlags flags)
-{
- Q_UNUSED(flags)
-}
-
-/* not supported on OS X - platform always uses encryption */
-QBluetooth::SecurityFlags QBluetoothSocket::preferredSecurityFlags() const
-{
- return QBluetooth::Secure;
-}
-
-#ifndef QT_NO_DEBUG_STREAM
-
-QDebug operator<<(QDebug debug, QBluetoothSocket::SocketError error)
-{
- switch (error) {
- case QBluetoothSocket::UnknownSocketError:
- debug << "QBluetoothSocket::UnknownSocketError";
- break;
- case QBluetoothSocket::HostNotFoundError:
- debug << "QBluetoothSocket::HostNotFoundError";
- break;
- case QBluetoothSocket::RemoteHostClosedError:
- debug << "QBluetoothSocket::RemoteHostClosedError";
- break;
- case QBluetoothSocket::ServiceNotFoundError:
- debug << "QBluetoothSocket::ServiceNotFoundError";
- break;
- case QBluetoothSocket::NetworkError:
- debug << "QBluetoothSocket::NetworkError";
- break;
- case QBluetoothSocket::UnsupportedProtocolError:
- debug << "QBluetoothSocket::UnsupportedProtocolError";
- break;
- default:
- debug << "QBluetoothSocket::SocketError(" << (int)error << ")";
- }
- return debug;
-}
-
-QDebug operator<<(QDebug debug, QBluetoothSocket::SocketState state)
-{
- switch (state) {
- case QBluetoothSocket::UnconnectedState:
- debug << "QBluetoothSocket::UnconnectedState";
- break;
- case QBluetoothSocket::ConnectingState:
- debug << "QBluetoothSocket::ConnectingState";
- break;
- case QBluetoothSocket::ConnectedState:
- debug << "QBluetoothSocket::ConnectedState";
- break;
- case QBluetoothSocket::BoundState:
- debug << "QBluetoothSocket::BoundState";
- break;
- case QBluetoothSocket::ClosingState:
- debug << "QBluetoothSocket::ClosingState";
- break;
- case QBluetoothSocket::ListeningState:
- debug << "QBluetoothSocket::ListeningState";
- break;
- case QBluetoothSocket::ServiceLookupState:
- debug << "QBluetoothSocket::ServiceLookupState";
- break;
- default:
- debug << "QBluetoothSocket::SocketState(" << (int)state << ")";
- }
- return debug;
-}
-
-#endif // QT_NO_DEBUG_STREAM
-
-#include "moc_qbluetoothsocket.cpp"
-
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothsocket_osx_p.h b/src/bluetooth/qbluetoothsocket_osx_p.h
index dcc684b8..1291878c 100644
--- a/src/bluetooth/qbluetoothsocket_osx_p.h
+++ b/src/bluetooth/qbluetoothsocket_osx_p.h
@@ -53,12 +53,11 @@
#ifdef QT_OSX_BLUETOOTH
-#include "osx/osxbtchanneldelegate_p.h"
-#include "osx/osxbtrfcommchannel_p.h"
-#include "osx/osxbtl2capchannel_p.h"
+#include "qbluetoothsocketbase_p.h"
#include "qbluetoothserviceinfo.h"
-#include "osx/osxbtutility_p.h"
+#include "osx/btdelegates_p.h"
#include "qbluetoothsocket.h"
+#include "osx/btraii_p.h"
#ifndef QPRIVATELINEARBUFFER_BUFFERSIZE
#define QPRIVATELINEARBUFFER_BUFFERSIZE Q_INT64_C(16384)
@@ -74,14 +73,11 @@
#include <QtCore/qstring.h>
#include <QtCore/qvector.h>
-@class IOBluetoothRFCOMMChannel;
-@class IOBluetoothL2CAPChannel;
-
QT_BEGIN_NAMESPACE
class QBluetoothAddress;
-class QBluetoothSocketPrivate : public QBluetoothSocketBasePrivate, public OSXBluetooth::ChannelDelegate
+class QBluetoothSocketPrivate : public QBluetoothSocketBasePrivate, public DarwinBluetooth::ChannelDelegate
{
friend class QBluetoothSocket;
friend class QBluetoothServer;
@@ -90,25 +86,47 @@ public:
QBluetoothSocketPrivate();
~QBluetoothSocketPrivate();
- void connectToService(const QBluetoothAddress &address, quint16 port,
- QIODevice::OpenMode openMode);
+ //
+ bool ensureNativeSocket(QBluetoothServiceInfo::Protocol type) override;
+
+ QString localName() const override;
+ QBluetoothAddress localAddress() const override;
+ quint16 localPort() const override;
+
+ QString peerName() const override;
+ QBluetoothAddress peerAddress() const override;
+ quint16 peerPort() const override;
- void close();
- void abort();
+ void abort() override;
+ void close() override;
- quint64 bytesAvailable() const;
+ qint64 writeData(const char *data, qint64 maxSize) override;
+ qint64 readData(char *data, qint64 maxSize) override;
- QString peerName() const;
- QBluetoothAddress peerAddress() const;
- quint16 peerPort() const;
+ qint64 bytesAvailable() const override;
+ bool canReadLine() const override;
+ qint64 bytesToWrite() const override;
- void _q_readNotify();
- void _q_writeNotify() override;
+ bool setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
+ QBluetoothSocket::SocketState socketState,
+ QBluetoothSocket::OpenMode openMode) override;
+
+ void connectToServiceHelper(const QBluetoothAddress &address, quint16 port,
+ QIODevice::OpenMode openMode) override;
+ void connectToService(const QBluetoothServiceInfo &service,
+ QIODevice::OpenMode openMode) override;
+ void connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid,
+ QIODevice::OpenMode openMode) override;
+
+ void connectToService(const QBluetoothAddress &address, quint16 port,
+ QIODevice::OpenMode openMode) override;
+
+ void _q_writeNotify();
private:
// Create a socket from an external source (without connectToService).
- bool setChannel(IOBluetoothRFCOMMChannel *channel);
- bool setChannel(IOBluetoothL2CAPChannel *channel);
+ bool setRFCOMChannel(void *channel);
+ bool setL2CAPChannel(void *channel);
// L2CAP and RFCOMM delegate
void setChannelError(IOReturn errorCode) override;
@@ -117,33 +135,15 @@ private:
void readChannelData(void *data, std::size_t size) override;
void writeComplete() override;
- qint64 writeData(const char *data, qint64 maxSize);
- qint64 readData(char *data, qint64 maxSize);
-
- QScopedPointer<QBluetoothServiceDiscoveryAgent> discoveryAgent;
-
- QPrivateLinearBuffer buffer;
- QPrivateLinearBuffer txBuffer;
QVector<char> writeChunk;
- // Probably, not needed.
- QIODevice::OpenMode openMode;
-
- QBluetoothSocket::SocketState state;
- QBluetoothServiceInfo::Protocol socketType;
-
- QBluetoothSocket::SocketError socketError;
- QString errorString;
-
- typedef QT_MANGLE_NAMESPACE(OSXBTL2CAPChannel) ObjCL2CAPChannel;
- typedef OSXBluetooth::ObjCScopedPointer<ObjCL2CAPChannel> L2CAPChannel;
+ using L2CAPChannel = DarwinBluetooth::ScopedPointer;
L2CAPChannel l2capChannel;
- typedef QT_MANGLE_NAMESPACE(OSXBTRFCOMMChannel) ObjCRFCOMMChannel;
- typedef OSXBluetooth::ObjCScopedPointer<ObjCRFCOMMChannel> RFCOMMChannel;
+ using RFCOMMChannel = L2CAPChannel;
RFCOMMChannel rfcommChannel;
// A trick to deal with channel open too fast (synchronously).
- bool isConnecting;
+ bool isConnecting = false;
};
QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothsocketbase_p.h b/src/bluetooth/qbluetoothsocketbase_p.h
index 410dcbbd..d1894e96 100644
--- a/src/bluetooth/qbluetoothsocketbase_p.h
+++ b/src/bluetooth/qbluetoothsocketbase_p.h
@@ -89,7 +89,6 @@ QT_FORWARD_DECLARE_CLASS(QBluetoothServiceDiscoveryAgent)
QT_BEGIN_NAMESPACE
-#ifndef QT_OSX_BLUETOOTH
class QBluetoothSocketBasePrivate : public QObject
{
Q_OBJECT
@@ -198,26 +197,6 @@ static inline quint64 convertAddress(const quint8 (&from)[6], quint64 *to = null
return result;
}
-#else // QT_OSX_BLUETOOTH
-
-// QBluetoothSocketPrivate on macOS can not contain
-// Q_OBJECT (moc does not parse Objective-C syntax).
-// But QBluetoothSocket still requires QMetaObject::invokeMethod
-// to work. Here's the trick:
-class QBluetoothSocketBasePrivate : public QObject
-{
-// The most important part of it:
- Q_OBJECT
-public slots:
- virtual void _q_writeNotify() = 0;
-
-protected:
- Q_DECLARE_PUBLIC(QBluetoothSocket)
- QBluetoothSocket *q_ptr;
-};
-
-#endif // QT_OSX_BLUETOOTH
-
QT_END_NAMESPACE
#endif // QBLUETOOTHSOCKETBASE_P_H