From 4aa30934473380793fb7bce38c9c8f6f235c9e4a Mon Sep 17 00:00:00 2001 From: Alex Blasche Date: Fri, 20 Jul 2018 12:15:55 +0200 Subject: Add QBluetoothSocketPrivate interface for WinRT Task-number: QTBUG-68550 Change-Id: I14fe43fcbbbdd6950f05feda900643f6899daa24 Reviewed-by: Oliver Wolff --- src/bluetooth/bluetooth.pro | 5 +- src/bluetooth/qbluetoothserver_winrt.cpp | 2 +- src/bluetooth/qbluetoothsocket.cpp | 6 ++ src/bluetooth/qbluetoothsocket.h | 1 + src/bluetooth/qbluetoothsocket_p.h | 37 --------- src/bluetooth/qbluetoothsocket_winrt.cpp | 63 ++++++++-------- src/bluetooth/qbluetoothsocket_winrt_p.h | 126 +++++++++++++++++++++++++++++++ 7 files changed, 169 insertions(+), 71 deletions(-) create mode 100644 src/bluetooth/qbluetoothsocket_winrt_p.h (limited to 'src') diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro index 69883613..d310dd64 100644 --- a/src/bluetooth/bluetooth.pro +++ b/src/bluetooth/bluetooth.pro @@ -237,7 +237,10 @@ qtConfig(bluez) { qbluetoothsocket_winrt.cpp \ qlowenergycontroller_winrt.cpp - PRIVATE_HEADERS += qlowenergycontroller_winrt_p.h + PRIVATE_HEADERS += qlowenergycontroller_winrt_p.h \ + qbluetoothsocket_winrt_p.h + + PRIVATE_HEADERS -= qbluetoothsocket_p.h lessThan(WINDOWS_SDK_VERSION, 14393) { DEFINES += QT_WINRT_LIMITED_SERVICEDISCOVERY diff --git a/src/bluetooth/qbluetoothserver_winrt.cpp b/src/bluetooth/qbluetoothserver_winrt.cpp index 08aa45b4..a53ef110 100644 --- a/src/bluetooth/qbluetoothserver_winrt.cpp +++ b/src/bluetooth/qbluetoothserver_winrt.cpp @@ -40,7 +40,7 @@ #include "qbluetoothserver.h" #include "qbluetoothserver_p.h" #include "qbluetoothsocket.h" -#include "qbluetoothsocket_p.h" +#include "qbluetoothsocket_winrt_p.h" #include #include diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp index d59b2adb..feb52684 100644 --- a/src/bluetooth/qbluetoothsocket.cpp +++ b/src/bluetooth/qbluetoothsocket.cpp @@ -43,6 +43,8 @@ #include "qbluetoothsocket_bluez_p.h" #elif defined(QT_ANDROID_BLUETOOTH) #include "qbluetoothsocket_android_p.h" +#elif defined(QT_WINRT_BLUETOOTH) +#include "qbluetoothsocket_winrt_p.h" #else #include "qbluetoothsocket_p.h" #endif @@ -262,6 +264,8 @@ QBluetoothSocket::QBluetoothSocket(QBluetoothServiceInfo::Protocol socketType, Q d_ptr = new QBluetoothSocketPrivateBluez(); #elif defined(QT_ANDROID_BLUETOOTH) d_ptr = new QBluetoothSocketPrivateAndroid(); +#elif defined(QT_WINRT_BLUETOOTH) + d_ptr = new QBluetoothSocketPrivateWinRT(); #else d_ptr = new QBluetoothSocketPrivate(); #endif @@ -283,6 +287,8 @@ QBluetoothSocket::QBluetoothSocket(QObject *parent) d_ptr = new QBluetoothSocketPrivateBluez(); #elif defined(QT_ANDROID_BLUETOOTH) d_ptr = new QBluetoothSocketPrivateAndroid(); +#elif defined(QT_WINRT_BLUETOOTH) + d_ptr = new QBluetoothSocketPrivateWinRT(); #else d_ptr = new QBluetoothSocketPrivate(); #endif diff --git a/src/bluetooth/qbluetoothsocket.h b/src/bluetooth/qbluetoothsocket.h index fc36b9ca..7f77d2a8 100644 --- a/src/bluetooth/qbluetoothsocket.h +++ b/src/bluetooth/qbluetoothsocket.h @@ -74,6 +74,7 @@ class Q_BLUETOOTH_EXPORT QBluetoothSocket : public QIODevice friend class QBluetoothSocketPrivateAndroid; friend class QBluetoothSocketPrivateBluez; friend class QBluetoothSocketPrivateBluezDBus; + friend class QBluetoothSocketPrivateWinRT; public: diff --git a/src/bluetooth/qbluetoothsocket_p.h b/src/bluetooth/qbluetoothsocket_p.h index d4839fb0..6eef56fb 100644 --- a/src/bluetooth/qbluetoothsocket_p.h +++ b/src/bluetooth/qbluetoothsocket_p.h @@ -55,12 +55,6 @@ #include "qbluetoothsocketbase_p.h" #include -QT_FORWARD_DECLARE_CLASS(QSocketNotifier) - -#ifdef QT_WINRT_BLUETOOTH -QT_FORWARD_DECLARE_CLASS(SocketWorker) -#endif - QT_BEGIN_NAMESPACE class QBluetoothSocketPrivate : public QBluetoothSocketBasePrivate @@ -91,12 +85,6 @@ public: qint64 writeData(const char *data, qint64 maxSize) override; qint64 readData(char *data, qint64 maxSize) override; -#if defined(QT_WINRT_BLUETOOTH) - bool setSocketDescriptor(Microsoft::WRL::ComPtr socket, - QBluetoothServiceInfo::Protocol socketType, - QBluetoothSocket::SocketState socketState = QBluetoothSocket::ConnectedState, - QBluetoothSocket::OpenMode openMode = QBluetoothSocket::ReadWrite) override; -#endif bool setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, QBluetoothSocket::SocketState socketState = QBluetoothSocket::ConnectedState, QBluetoothSocket::OpenMode openMode = QBluetoothSocket::ReadWrite) override; @@ -104,31 +92,6 @@ public: qint64 bytesAvailable() const override; bool canReadLine() const override; qint64 bytesToWrite() const override; - -#ifdef QT_WINRT_BLUETOOTH - SocketWorker *m_worker; - - Microsoft::WRL::ComPtr m_socketObject; - Microsoft::WRL::ComPtr m_connectOp; - - QMutex m_readMutex; - - // Protected by m_readMutex. Written in addToPendingData (native callback) - QVector m_pendingData; - - Q_INVOKABLE void addToPendingData(const QVector &data); - -private slots: - void handleNewData(const QVector &data); - void handleError(QBluetoothSocket::SocketError error); -#endif // QT_WINRT_BLUETOOTH - -private: - -#ifdef QT_WINRT_BLUETOOTH - HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *action, - ABI::Windows::Foundation::AsyncStatus status); -#endif }; QT_END_NAMESPACE diff --git a/src/bluetooth/qbluetoothsocket_winrt.cpp b/src/bluetooth/qbluetoothsocket_winrt.cpp index 22bdbc7e..46b46c4e 100644 --- a/src/bluetooth/qbluetoothsocket_winrt.cpp +++ b/src/bluetooth/qbluetoothsocket_winrt.cpp @@ -37,8 +37,7 @@ ** ****************************************************************************/ -#include "qbluetoothsocket.h" -#include "qbluetoothsocket_p.h" +#include "qbluetoothsocket_winrt_p.h" #ifdef CLASSIC_APP_BUILD #define Q_OS_WINRT @@ -319,22 +318,22 @@ private: ComPtr> m_readOp; }; -QBluetoothSocketPrivate::QBluetoothSocketPrivate() +QBluetoothSocketPrivateWinRT::QBluetoothSocketPrivateWinRT() : m_worker(new SocketWorker()) { secFlags = QBluetooth::NoSecurity; connect(m_worker, &SocketWorker::newDataReceived, - this, &QBluetoothSocketPrivate::handleNewData, Qt::QueuedConnection); + this, &QBluetoothSocketPrivateWinRT::handleNewData, Qt::QueuedConnection); connect(m_worker, &SocketWorker::socketErrorOccured, - this, &QBluetoothSocketPrivate::handleError, Qt::QueuedConnection); + this, &QBluetoothSocketPrivateWinRT::handleError, Qt::QueuedConnection); } -QBluetoothSocketPrivate::~QBluetoothSocketPrivate() +QBluetoothSocketPrivateWinRT::~QBluetoothSocketPrivateWinRT() { abort(); } -bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothServiceInfo::Protocol type) +bool QBluetoothSocketPrivateWinRT::ensureNativeSocket(QBluetoothServiceInfo::Protocol type) { if (socket != -1) { if (type == socketType) @@ -358,7 +357,7 @@ bool QBluetoothSocketPrivate::ensureNativeSocket(QBluetoothServiceInfo::Protocol return true; } -void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode) +void QBluetoothSocketPrivateWinRT::connectToService(const QBluetoothAddress &address, quint16 port, QIODevice::OpenMode openMode) { Q_Q(QBluetoothSocket); Q_UNUSED(openMode); @@ -377,14 +376,14 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, Q_ASSERT_SUCCEEDED(hr); ComPtr remoteHost; hr = hostNameFactory->CreateHostName(hostNameRef.Get(), &remoteHost); - RETURN_VOID_IF_FAILED("QBluetoothSocketPrivate::connectToService: Could not create hostname."); + RETURN_VOID_IF_FAILED("QBluetoothSocketPrivateWinRT::connectToService: Could not create hostname."); const QString portString = QString::number(port); HStringReference portReference(reinterpret_cast(portString.utf16())); hr = m_socketObject->ConnectAsync(remoteHost.Get(), portReference.Get(), &m_connectOp); if (hr == E_ACCESSDENIED) { - qErrnoWarning(hr, "QBluetoothSocketPrivate::connectToService: Unable to connect to bluetooth socket." + qErrnoWarning(hr, "QBluetoothSocketPrivateWinRT::connectToService: Unable to connect to bluetooth socket." "Please check your manifest capabilities."); q->setSocketState(QBluetoothSocket::UnconnectedState); return; @@ -396,22 +395,22 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, QEventDispatcherWinRT::runOnXamlThread([this]() { HRESULT hr; hr = m_connectOp->put_Completed(Callback( - this, &QBluetoothSocketPrivate::handleConnectOpFinished).Get()); + this, &QBluetoothSocketPrivateWinRT::handleConnectOpFinished).Get()); RETURN_HR_IF_FAILED("connectToHostByName: Could not register \"connectOp\" callback"); return S_OK; }); } -void QBluetoothSocketPrivate::abort() +void QBluetoothSocketPrivateWinRT::abort() { Q_Q(QBluetoothSocket); if (state == QBluetoothSocket::UnconnectedState) return; disconnect(m_worker, &SocketWorker::newDataReceived, - this, &QBluetoothSocketPrivate::handleNewData); + this, &QBluetoothSocketPrivateWinRT::handleNewData); disconnect(m_worker, &SocketWorker::socketErrorOccured, - this, &QBluetoothSocketPrivate::handleError); + this, &QBluetoothSocketPrivateWinRT::handleError); m_worker->close(); m_worker->deleteLater(); @@ -422,7 +421,7 @@ void QBluetoothSocketPrivate::abort() q->setSocketState(QBluetoothSocket::UnconnectedState); } -QString QBluetoothSocketPrivate::localName() const +QString QBluetoothSocketPrivateWinRT::localName() const { const QBluetoothAddress address = localAddress(); if (address.isNull()) @@ -432,7 +431,7 @@ QString QBluetoothSocketPrivate::localName() const return device.name(); } -QBluetoothAddress QBluetoothSocketPrivate::localAddress() const +QBluetoothAddress QBluetoothSocketPrivateWinRT::localAddress() const { if (!m_socketObject) return QBluetoothAddress(); @@ -450,7 +449,7 @@ QBluetoothAddress QBluetoothSocketPrivate::localAddress() const return QBluetoothAddress(qt_QStringFromHString(localAddress)); } -quint16 QBluetoothSocketPrivate::localPort() const +quint16 QBluetoothSocketPrivateWinRT::localPort() const { if (!m_socketObject) return 0; @@ -465,7 +464,7 @@ quint16 QBluetoothSocketPrivate::localPort() const return qt_QStringFromHString(localPortString).toInt(); } -QString QBluetoothSocketPrivate::peerName() const +QString QBluetoothSocketPrivateWinRT::peerName() const { if (!m_socketObject) return QString(); @@ -483,7 +482,7 @@ QString QBluetoothSocketPrivate::peerName() const return qt_QStringFromHString(remoteHostName); } -QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const +QBluetoothAddress QBluetoothSocketPrivateWinRT::peerAddress() const { if (!m_socketObject) return QBluetoothAddress(); @@ -501,7 +500,7 @@ QBluetoothAddress QBluetoothSocketPrivate::peerAddress() const return QBluetoothAddress(qt_QStringFromHString(remoteAddress)); } -quint16 QBluetoothSocketPrivate::peerPort() const +quint16 QBluetoothSocketPrivateWinRT::peerPort() const { if (!m_socketObject) return 0; @@ -516,7 +515,7 @@ quint16 QBluetoothSocketPrivate::peerPort() const return qt_QStringFromHString(remotePortString).toInt(); } -qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize) +qint64 QBluetoothSocketPrivateWinRT::writeData(const char *data, qint64 maxSize) { Q_Q(QBluetoothSocket); @@ -542,7 +541,7 @@ qint64 QBluetoothSocketPrivate::writeData(const char *data, qint64 maxSize) return bytesWritten; } -qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize) +qint64 QBluetoothSocketPrivateWinRT::readData(char *data, qint64 maxSize) { Q_Q(QBluetoothSocket); @@ -558,12 +557,12 @@ qint64 QBluetoothSocketPrivate::readData(char *data, qint64 maxSize) return 0; } -void QBluetoothSocketPrivate::close() +void QBluetoothSocketPrivateWinRT::close() { abort(); } -bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, +bool QBluetoothSocketPrivateWinRT::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode) { Q_UNUSED(socketDescriptor); @@ -574,7 +573,7 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoo return false; } -bool QBluetoothSocketPrivate::setSocketDescriptor(ComPtr socketPtr, QBluetoothServiceInfo::Protocol socketType, +bool QBluetoothSocketPrivateWinRT::setSocketDescriptor(ComPtr socketPtr, QBluetoothServiceInfo::Protocol socketType, QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode) { Q_Q(QBluetoothSocket); @@ -591,22 +590,22 @@ bool QBluetoothSocketPrivate::setSocketDescriptor(ComPtr socketPt return true; } -qint64 QBluetoothSocketPrivate::bytesAvailable() const +qint64 QBluetoothSocketPrivateWinRT::bytesAvailable() const { return buffer.size(); } -qint64 QBluetoothSocketPrivate::bytesToWrite() const +qint64 QBluetoothSocketPrivateWinRT::bytesToWrite() const { return 0; // nothing because always unbuffered } -bool QBluetoothSocketPrivate::canReadLine() const +bool QBluetoothSocketPrivateWinRT::canReadLine() const { return buffer.canReadLine(); } -void QBluetoothSocketPrivate::handleNewData(const QVector &data) +void QBluetoothSocketPrivateWinRT::handleNewData(const QVector &data) { // Defer putting the data into the list until the next event loop iteration // (where the readyRead signal is emitted as well) @@ -614,7 +613,7 @@ void QBluetoothSocketPrivate::handleNewData(const QVector &data) Q_ARG(QVector, data)); } -void QBluetoothSocketPrivate::handleError(QBluetoothSocket::SocketError error) +void QBluetoothSocketPrivateWinRT::handleError(QBluetoothSocket::SocketError error) { Q_Q(QBluetoothSocket); switch (error) { @@ -632,7 +631,7 @@ void QBluetoothSocketPrivate::handleError(QBluetoothSocket::SocketError error) q->setSocketState(QBluetoothSocket::UnconnectedState); } -void QBluetoothSocketPrivate::addToPendingData(const QVector &data) +void QBluetoothSocketPrivateWinRT::addToPendingData(const QVector &data) { Q_Q(QBluetoothSocket); QMutexLocker locker(&m_readMutex); @@ -645,7 +644,7 @@ void QBluetoothSocketPrivate::addToPendingData(const QVector &data) emit q->readyRead(); } -HRESULT QBluetoothSocketPrivate::handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *action, ABI::Windows::Foundation::AsyncStatus status) +HRESULT QBluetoothSocketPrivateWinRT::handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *action, ABI::Windows::Foundation::AsyncStatus status) { Q_Q(QBluetoothSocket); if (status != Completed || !m_connectOp) { // Protect against a late callback diff --git a/src/bluetooth/qbluetoothsocket_winrt_p.h b/src/bluetooth/qbluetoothsocket_winrt_p.h new file mode 100644 index 00000000..a6597009 --- /dev/null +++ b/src/bluetooth/qbluetoothsocket_winrt_p.h @@ -0,0 +1,126 @@ +/**************************************************************************** +** +** Copyright (C) 2018 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 QBLUETOOTHSOCKET_WINRT_P_H +#define QBLUETOOTHSOCKET_WINRT_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 "qbluetoothsocket.h" +#include "qbluetoothsocketbase_p.h" +#include + +QT_FORWARD_DECLARE_CLASS(SocketWorker) + +QT_BEGIN_NAMESPACE + +class QBluetoothSocketPrivateWinRT final: public QBluetoothSocketBasePrivate +{ + Q_OBJECT + friend class QBluetoothServerPrivate; + +public: + QBluetoothSocketPrivateWinRT(); + ~QBluetoothSocketPrivateWinRT(); + + void connectToService(const QBluetoothAddress &address, + quint16 port, + QIODevice::OpenMode openMode); + bool ensureNativeSocket(QBluetoothServiceInfo::Protocol type); + + QString localName() const; + QBluetoothAddress localAddress() const; + quint16 localPort() const; + + QString peerName() const; + QBluetoothAddress peerAddress() const; + quint16 peerPort() const; + + void abort(); + void close(); + + qint64 writeData(const char *data, qint64 maxSize); + qint64 readData(char *data, qint64 maxSize); + + bool setSocketDescriptor(Microsoft::WRL::ComPtr socket, + QBluetoothServiceInfo::Protocol socketType, + QBluetoothSocket::SocketState socketState = QBluetoothSocket::ConnectedState, + QBluetoothSocket::OpenMode openMode = QBluetoothSocket::ReadWrite); + + bool setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType, + QBluetoothSocket::SocketState socketState = QBluetoothSocket::ConnectedState, + QBluetoothSocket::OpenMode openMode = QBluetoothSocket::ReadWrite); + + qint64 bytesAvailable() const; + bool canReadLine() const; + qint64 bytesToWrite() const; + + SocketWorker *m_worker; + + Microsoft::WRL::ComPtr m_socketObject; + Microsoft::WRL::ComPtr m_connectOp; + + QMutex m_readMutex; + + // Protected by m_readMutex. Written in addToPendingData (native callback) + QVector m_pendingData; + + Q_INVOKABLE void addToPendingData(const QVector &data); + +private slots: + void handleNewData(const QVector &data); + void handleError(QBluetoothSocket::SocketError error); + +private: + HRESULT handleConnectOpFinished(ABI::Windows::Foundation::IAsyncAction *action, + ABI::Windows::Foundation::AsyncStatus status); +}; + +QT_END_NAMESPACE + +#endif -- cgit v1.2.3