diff --git a/src/bluetooth/bluetooth.pro b/src/bluetooth/bluetooth.pro
index 20f89b8edcf36a8e59d8018c23eb53832099cfdb..b47e234e0e2cf5dc0302c0d31d4468e7404a97eb 100644
--- a/src/bluetooth/bluetooth.pro
+++ b/src/bluetooth/bluetooth.pro
@@ -200,9 +200,9 @@ qtConfig(bluez):qtHaveModule(dbus) {
     SOURCES += \
         qbluetoothdevicediscoveryagent_winrt.cpp \
         qbluetoothlocaldevice_p.cpp \
-        qbluetoothserver_p.cpp \
+        qbluetoothserver_winrt.cpp \
         qbluetoothservicediscoveryagent_winrt.cpp \
-        qbluetoothserviceinfo_p.cpp \
+        qbluetoothserviceinfo_winrt.cpp \
         qbluetoothsocket_winrt.cpp \
         qlowenergycontroller_winrt.cpp
 
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index a27eb3857e09df07805472c71b13bf60218a7e26..41b1d822c9da8db85222afb1ac6759ee76c3e616 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -257,7 +257,7 @@ bool QBluetoothServer::isListening() const
 {
     Q_D(const QBluetoothServer);
 
-#ifdef QT_ANDROID_BLUETOOTH
+#if defined(QT_ANDROID_BLUETOOTH) || defined(QT_WINRT_BLUETOOTH)
     return d->isListening();
 #endif
 
diff --git a/src/bluetooth/qbluetoothserver_p.h b/src/bluetooth/qbluetoothserver_p.h
index 8797cebdebaad3dc2d7f57be28ea3affb061b5fe..833c781ba6965fc367ba0de4b828c4ab8f873f09 100644
--- a/src/bluetooth/qbluetoothserver_p.h
+++ b/src/bluetooth/qbluetoothserver_p.h
@@ -69,6 +69,12 @@ QT_FORWARD_DECLARE_CLASS(QSocketNotifier)
 class ServerAcceptanceThread;
 #endif
 
+#ifdef QT_WINRT_BLUETOOTH
+#include <wrl.h>
+// No forward declares because QBluetoothServerPrivate::listener does not work with them
+#include <windows.networking.sockets.h>
+#endif
+
 QT_BEGIN_NAMESPACE
 
 class QBluetoothAddress;
@@ -114,7 +120,21 @@ public:
     bool isListening() const;
     bool initiateActiveListening(const QBluetoothUuid& uuid, const QString &serviceName);
     bool deactivateActiveListening();
+#elif defined(QT_WINRT_BLUETOOTH)
+    EventRegistrationToken connectionToken {-1};
+
+    mutable QMutex pendingConnectionsMutex;
+    QVector<Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocket>> pendingConnections;
+
+    Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> socketListener;
+    HRESULT handleClientConnection(ABI::Windows::Networking::Sockets::IStreamSocketListener *listener,
+                                   ABI::Windows::Networking::Sockets::IStreamSocketListenerConnectionReceivedEventArgs *args);
 
+public:
+    bool isListening() const;
+    Microsoft::WRL::ComPtr<ABI::Windows::Networking::Sockets::IStreamSocketListener> listener() { return socketListener; }
+    bool initiateActiveListening(const QString &serviceName);
+    bool deactivateActiveListening();
 #endif
 };
 
diff --git a/src/bluetooth/qbluetoothserver_winrt.cpp b/src/bluetooth/qbluetoothserver_winrt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..effe4dc934ccb062fd26fc6f4cc139c2850bd8ba
--- /dev/null
+++ b/src/bluetooth/qbluetoothserver_winrt.cpp
@@ -0,0 +1,243 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "qbluetoothserver.h"
+#include "qbluetoothserver_p.h"
+#include "qbluetoothsocket.h"
+#include "qbluetoothsocket_p.h"
+
+#include <QtCore/QLoggingCategory>
+#include <qfunctions_winrt.h>
+
+#include <windows.networking.h>
+#include <windows.networking.connectivity.h>
+#include <windows.networking.sockets.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Devices;
+using namespace ABI::Windows::Devices::Enumeration;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Networking;
+using namespace ABI::Windows::Networking::Sockets;
+using namespace ABI::Windows::Networking::Connectivity;
+
+typedef ITypedEventHandler<StreamSocketListener *, StreamSocketListenerConnectionReceivedEventArgs *> ClientConnectedHandler;
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT)
+
+QHash<QBluetoothServerPrivate *, int> __fakeServerPorts;
+
+QBluetoothServerPrivate::QBluetoothServerPrivate(QBluetoothServiceInfo::Protocol sType)
+    : maxPendingConnections(1), serverType(sType), m_lastError(QBluetoothServer::NoError), socket(0)
+{
+    socket = new QBluetoothSocket(QBluetoothServiceInfo::RfcommProtocol);
+}
+
+QBluetoothServerPrivate::~QBluetoothServerPrivate()
+{
+    deactivateActiveListening();
+    __fakeServerPorts.remove(this);
+    if (socket)
+        delete socket;
+}
+
+bool QBluetoothServerPrivate::isListening() const
+{
+    return __fakeServerPorts.contains(const_cast<QBluetoothServerPrivate *>(this));
+}
+
+bool QBluetoothServerPrivate::initiateActiveListening(const QString &serviceName)
+{
+    HStringReference serviceNameRef(reinterpret_cast<LPCWSTR>(serviceName.utf16()));
+
+    ComPtr<IAsyncAction> bindAction;
+    HRESULT hr = socketListener->BindServiceNameAsync(serviceNameRef.Get(), &bindAction);
+    Q_ASSERT_SUCCEEDED(hr);
+    hr = QWinRTFunctions::await(bindAction);
+    Q_ASSERT_SUCCEEDED(hr);
+    return true;
+}
+
+bool QBluetoothServerPrivate::deactivateActiveListening()
+{
+    if (!isListening())
+        return true;
+
+    HRESULT hr;
+    hr = socketListener->remove_ConnectionReceived(connectionToken);
+    Q_ASSERT_SUCCEEDED(hr);
+    return true;
+}
+
+HRESULT QBluetoothServerPrivate::handleClientConnection(IStreamSocketListener *listener,
+                                                        IStreamSocketListenerConnectionReceivedEventArgs *args)
+{
+    Q_Q(QBluetoothServer);
+    if (!socketListener || socketListener.Get() != listener) {
+        qCDebug(QT_BT_WINRT) << "Accepting connection from wrong listener. We should not be here.";
+        Q_UNREACHABLE();
+        return S_OK;
+    }
+
+    HRESULT hr;
+    ComPtr<IStreamSocket> socket;
+    hr = args->get_Socket(&socket);
+    Q_ASSERT_SUCCEEDED(hr);
+    QMutexLocker locker(&pendingConnectionsMutex);
+    if (pendingConnections.count() < maxPendingConnections) {
+        qCDebug(QT_BT_WINRT) << "Accepting connection";
+        pendingConnections.append(socket);
+        q->newConnection();
+    } else {
+        qCDebug(QT_BT_WINRT) << "Refusing connection";
+    }
+
+    return S_OK;
+}
+
+void QBluetoothServer::close()
+{
+    Q_D(QBluetoothServer);
+
+    d->deactivateActiveListening();
+    __fakeServerPorts.remove(d);
+}
+
+bool QBluetoothServer::listen(const QBluetoothAddress &address, quint16 port)
+{
+    Q_UNUSED(address);
+    Q_D(QBluetoothServer);
+    if (serverType() != QBluetoothServiceInfo::RfcommProtocol) {
+        d->m_lastError = UnsupportedProtocolError;
+        emit error(d->m_lastError);
+        return false;
+    }
+
+    if (isListening())
+        return false;
+
+    HRESULT hr;
+    hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Networking_Sockets_StreamSocketListener).Get(),
+                            &d->socketListener);
+    Q_ASSERT_SUCCEEDED(hr);
+    hr = d->socketListener->add_ConnectionReceived(Callback<ClientConnectedHandler>(d, &QBluetoothServerPrivate::handleClientConnection).Get(),
+                                                 &d->connectionToken);
+    Q_ASSERT_SUCCEEDED(hr);
+
+    //We can not register an actual Rfcomm port, because the platform does not allow it
+    //but we need a way to associate a server with a service
+    if (port == 0) { //Try to assign a non taken port id
+        for (int i = 1; ; i++){
+            if (__fakeServerPorts.key(i) == 0) {
+                port = i;
+                break;
+            }
+        }
+    }
+
+    if (__fakeServerPorts.key(port) == 0) {
+        __fakeServerPorts[d] = port;
+
+        qCDebug(QT_BT_WINRT) << "Port" << port << "registered";
+    } else {
+        qCWarning(QT_BT_WINRT) << "server with port" << port << "already registered or port invalid";
+        d->m_lastError = ServiceAlreadyRegisteredError;
+        emit error(d->m_lastError);
+        return false;
+    }
+
+    return true;
+}
+
+void QBluetoothServer::setMaxPendingConnections(int numConnections)
+{
+    Q_D(QBluetoothServer);
+    QMutexLocker locker(&d->pendingConnectionsMutex);
+    d->maxPendingConnections = numConnections;
+}
+
+bool QBluetoothServer::hasPendingConnections() const
+{
+    Q_D(const QBluetoothServer);
+    QMutexLocker locker(&d->pendingConnectionsMutex);
+    return !d->pendingConnections.isEmpty();
+}
+
+QBluetoothSocket *QBluetoothServer::nextPendingConnection()
+{
+    Q_D(QBluetoothServer);
+
+    ComPtr<IStreamSocket> socket = d->pendingConnections.takeFirst();
+
+    QBluetoothSocket *newSocket = new QBluetoothSocket();
+    bool success = newSocket->d_ptr->setSocketDescriptor(qintptr(socket.Get()), d->serverType);
+    if (!success) {
+        delete newSocket;
+        newSocket = 0;
+    }
+
+    return newSocket;
+}
+
+QBluetoothAddress QBluetoothServer::serverAddress() const
+{
+    return QBluetoothAddress();
+}
+
+quint16 QBluetoothServer::serverPort() const
+{
+    //We return the fake port
+    Q_D(const QBluetoothServer);
+    return __fakeServerPorts.value((QBluetoothServerPrivate*)d, 0);
+}
+
+void QBluetoothServer::setSecurityFlags(QBluetooth::SecurityFlags security)
+{
+    Q_UNUSED(security);
+}
+
+QBluetooth::SecurityFlags QBluetoothServer::securityFlags() const
+{
+    return QBluetooth::NoSecurity;
+}
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothserviceinfo_p.h b/src/bluetooth/qbluetoothserviceinfo_p.h
index f1f3b669a533cf5f50f7cc8cae12fbaf70a90ec2..2e223a7b9730f3119e490f02f01967c859c698d1 100644
--- a/src/bluetooth/qbluetoothserviceinfo_p.h
+++ b/src/bluetooth/qbluetoothserviceinfo_p.h
@@ -62,6 +62,22 @@
 class OrgBluezServiceInterface;
 class OrgBluezProfileManager1Interface;
 
+#ifdef QT_WINRT_BLUETOOTH
+#include <wrl.h>
+
+namespace ABI {
+    namespace Windows {
+        namespace Devices {
+            namespace Bluetooth {
+                namespace Rfcomm {
+                    struct IRfcommServiceProvider;
+                }
+            }
+        }
+    }
+}
+#endif
+
 QT_BEGIN_NAMESPACE
 
 class QBluetoothServiceInfo;
@@ -98,6 +114,12 @@ private:
     QString profilePath;
 #endif
 
+#ifdef QT_WINRT_BLUETOOTH
+    Microsoft::WRL::ComPtr<ABI::Windows::Devices::Bluetooth::Rfcomm::IRfcommServiceProvider> serviceProvider;
+
+    bool writeSdpAttributes();
+#endif
+
     mutable bool registered;
 };
 
diff --git a/src/bluetooth/qbluetoothserviceinfo_winrt.cpp b/src/bluetooth/qbluetoothserviceinfo_winrt.cpp
new file mode 100644
index 0000000000000000000000000000000000000000..77376dd9ffb7acbf4b82e9c6ab8811f34d1b7146
--- /dev/null
+++ b/src/bluetooth/qbluetoothserviceinfo_winrt.cpp
@@ -0,0 +1,378 @@
+/****************************************************************************
+**
+** Copyright (C) 2017 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 "qbluetoothserviceinfo.h"
+#include "qbluetoothserviceinfo_p.h"
+#include "qbluetoothserver_p.h"
+
+#include <QtCore/QLoggingCategory>
+#include <qfunctions_winrt.h>
+
+#include <wrl.h>
+#include <windows.devices.bluetooth.h>
+#include <windows.devices.bluetooth.rfcomm.h>
+#include <windows.foundation.h>
+#include <windows.networking.sockets.h>
+#include <windows.storage.streams.h>
+
+using namespace Microsoft::WRL;
+using namespace Microsoft::WRL::Wrappers;
+using namespace ABI::Windows::Devices::Bluetooth;
+using namespace ABI::Windows::Devices::Bluetooth::Rfcomm;
+using namespace ABI::Windows::Foundation;
+using namespace ABI::Windows::Foundation::Collections;
+using namespace ABI::Windows::Networking::Sockets;
+using namespace ABI::Windows::Storage::Streams;
+
+QT_BEGIN_NAMESPACE
+
+Q_DECLARE_LOGGING_CATEGORY(QT_BT_WINRT)
+
+#define TYPE_UINT8 8
+#define TYPE_UINT16 9
+#define TYPE_UINT32 10
+#define TYPE_SHORT_UUID 25
+#define TYPE_LONG_UUID 28
+#define TYPE_STRING 37
+#define TYPE_SEQUENCE 53
+
+extern QHash<QBluetoothServerPrivate *, int> __fakeServerPorts;
+
+static ComPtr<IBuffer> bufferFromAttribute(const QVariant &attribute)
+{
+    ComPtr<IDataWriter> writer;
+    HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
+                                  &writer);
+    Q_ASSERT_SUCCEEDED(hr);
+
+    switch (int(attribute.type())) {
+    case QMetaType::Void:
+        qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Void";
+        return nullptr;
+    case QMetaType::UChar:
+        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UChar";
+        hr = writer->WriteByte(TYPE_UINT8);
+        Q_ASSERT_SUCCEEDED(hr);
+        hr = writer->WriteByte(attribute.value<quint8>());
+        Q_ASSERT_SUCCEEDED(hr);
+        break;
+    case QMetaType::UShort:
+        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UShort";
+        hr = writer->WriteByte(TYPE_UINT16);
+        Q_ASSERT_SUCCEEDED(hr);
+        hr = writer->WriteUInt16(attribute.value<quint16>());
+        Q_ASSERT_SUCCEEDED(hr);
+        break;
+    case QMetaType::UInt:
+        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UInt";
+        hr = writer->WriteByte(TYPE_UINT32);
+        Q_ASSERT_SUCCEEDED(hr);
+        hr = writer->WriteByte(attribute.value<quint32>());
+        Q_ASSERT_SUCCEEDED(hr);
+        break;
+    case QMetaType::Char:
+        qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Char";
+        return nullptr;
+        break;
+    case QMetaType::Short:
+        qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Short";
+        return nullptr;
+        break;
+    case QMetaType::Int:
+        qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Int";
+        return nullptr;
+        break;
+    case QMetaType::QString: {
+        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::QString";
+        hr = writer->WriteByte(TYPE_STRING);
+        Q_ASSERT_SUCCEEDED(hr);
+        const QString stringValue = attribute.value<QString>();
+        hr = writer->WriteByte(stringValue.length());
+        Q_ASSERT_SUCCEEDED(hr);
+        HStringReference stringRef(reinterpret_cast<LPCWSTR>(stringValue.utf16()));
+        quint32 bytesWritten;
+        hr = writer->WriteString(stringRef.Get(), &bytesWritten);
+        if (bytesWritten != stringValue.length()) {
+            qCWarning(QT_BT_WINRT) << "Did not write full value to buffer";
+            return nullptr;
+        }
+        Q_ASSERT_SUCCEEDED(hr);
+        break;
+    }
+    case QMetaType::Bool:
+        qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::Bool";
+        return nullptr;
+        break;
+    case QMetaType::QUrl:
+        qCWarning(QT_BT_WINRT) << "Don't know how to register QMetaType::QUrl";
+        return nullptr;
+        break;
+    case QVariant::UserType:
+        if (attribute.userType() == qMetaTypeId<QBluetoothUuid>()) {
+            QBluetoothUuid uuid = attribute.value<QBluetoothUuid>();
+            const int minimumSize = uuid.minimumSize();
+            switch (uuid.minimumSize()) {
+            case 0:
+                qCWarning(QT_BT_WINRT) << "Don't know how to register Uuid of length 0";
+                return nullptr;
+                break;
+            case 2:
+                qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 2" << uuid;
+                hr = writer->WriteByte(TYPE_SHORT_UUID);
+                Q_ASSERT_SUCCEEDED(hr);
+                hr = writer->WriteUInt16(uuid.toUInt16());
+                Q_ASSERT_SUCCEEDED(hr);
+                break;
+            case 4:
+                qCWarning(QT_BT_WINRT) << "Don't know how to register Uuid of length 4";
+                return nullptr;
+                break;
+            case 16:
+                qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 16";
+                hr = writer->WriteByte(TYPE_LONG_UUID);
+                Q_ASSERT_SUCCEEDED(hr);
+                hr = writer->WriteGuid(uuid);
+                Q_ASSERT_SUCCEEDED(hr);
+                break;
+            default:
+                qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute";
+                hr = writer->WriteByte(TYPE_LONG_UUID);
+                Q_ASSERT_SUCCEEDED(hr);
+                hr = writer->WriteGuid(uuid);
+                Q_ASSERT_SUCCEEDED(hr);
+                break;
+            }
+        } else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) {
+            qCDebug(QT_BT_WINRT) << "Registering sequence attribute";
+            hr = writer->WriteByte(TYPE_SEQUENCE);
+            Q_ASSERT_SUCCEEDED(hr);
+            const QBluetoothServiceInfo::Sequence *sequence =
+                    static_cast<const QBluetoothServiceInfo::Sequence *>(attribute.data());
+            ComPtr<IDataWriter> tmpWriter;
+            HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
+                &tmpWriter);
+            Q_ASSERT_SUCCEEDED(hr);
+            foreach (const QVariant &v, *sequence) {
+                ComPtr<IBuffer> tmpBuffer = bufferFromAttribute(v);
+                if (!tmpBuffer) {
+                    qCWarning(QT_BT_WINRT) << "Could not create buffer from attribute in sequence";
+                    return nullptr;
+                }
+                quint32 l;
+                hr = tmpBuffer->get_Length(&l);
+                Q_ASSERT_SUCCEEDED(hr);
+                hr = tmpWriter->WriteBuffer(tmpBuffer.Get());
+                Q_ASSERT_SUCCEEDED(hr);
+            }
+            ComPtr<IBuffer> tmpBuffer;
+            hr = tmpWriter->DetachBuffer(&tmpBuffer);
+            Q_ASSERT_SUCCEEDED(hr);
+            // write sequence length
+            quint32 length;
+            tmpBuffer->get_Length(&length);
+            Q_ASSERT_SUCCEEDED(hr);
+            hr = writer->WriteByte(length + 1);
+            Q_ASSERT_SUCCEEDED(hr);
+            // write sequence data
+            hr = writer->WriteBuffer(tmpBuffer.Get());
+            Q_ASSERT_SUCCEEDED(hr);
+            qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registered sequence attribute with length" << length;
+        } else if (attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
+            qCWarning(QT_BT_WINRT) << "Don't know how to register user type Alternative";
+            return false;
+        }
+        break;
+    default:
+        qCWarning(QT_BT_WINRT) << "Unknown variant type", attribute.userType();
+        return nullptr;
+    }
+    ComPtr<IBuffer> buffer;
+    hr = writer->DetachBuffer(&buffer);
+    Q_ASSERT_SUCCEEDED(hr);
+    return buffer;
+}
+
+QBluetoothServiceInfoPrivate::QBluetoothServiceInfoPrivate()
+    : registered(false)
+{
+}
+
+QBluetoothServiceInfoPrivate::~QBluetoothServiceInfoPrivate()
+{
+}
+
+bool QBluetoothServiceInfoPrivate::isRegistered() const
+{
+    return registered;
+}
+
+bool QBluetoothServiceInfoPrivate::registerService(const QBluetoothAddress &localAdapter)
+{
+    Q_UNUSED(localAdapter);
+    if (registered)
+        return false;
+
+    if (protocolDescriptor(QBluetoothUuid::Rfcomm).isEmpty()) {
+        qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Only RFCOMM services can be registered on WinRT";
+        return false;
+    }
+
+    QBluetoothServerPrivate *sPriv = __fakeServerPorts.key(serverChannel());
+    if (!sPriv)
+        return false;
+
+    HRESULT hr;
+    QBluetoothUuid uuid = attributes.value(QBluetoothServiceInfo::ServiceId).value<QBluetoothUuid>();
+    ComPtr<IRfcommServiceIdStatics> serviceIdStatics;
+    hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_Rfcomm_RfcommServiceId).Get(),
+                                IID_PPV_ARGS(&serviceIdStatics));
+    Q_ASSERT_SUCCEEDED(hr);
+    ComPtr<IRfcommServiceId> serviceId;
+    hr = serviceIdStatics->FromUuid(uuid, &serviceId);
+    Q_ASSERT_SUCCEEDED(hr);
+    ComPtr<IRfcommServiceProviderStatics> providerStatics;
+    hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_Rfcomm_RfcommServiceProvider).Get(),
+                                IID_PPV_ARGS(&providerStatics));
+    Q_ASSERT_SUCCEEDED(hr);
+    ComPtr<IAsyncOperation<RfcommServiceProvider *>> op;
+    hr = providerStatics->CreateAsync(serviceId.Get(), &op);
+    Q_ASSERT_SUCCEEDED(hr);
+    hr = QWinRTFunctions::await(op, serviceProvider.GetAddressOf());
+    Q_ASSERT_SUCCEEDED(hr);
+
+    ComPtr<IStreamSocketListener> listener = sPriv->listener();
+    if (!listener) {
+        qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Could not obtain listener from server.";
+        return false;
+    }
+
+
+    HString serviceIdHString;
+    serviceId->AsString(serviceIdHString.GetAddressOf());
+    Q_ASSERT_SUCCEEDED(hr);
+    const QString serviceIdString = QString::fromWCharArray(WindowsGetStringRawBuffer(serviceIdHString.Get(), nullptr));
+
+    //tell the server what service name our listener should have
+    //and start the real listener
+    bool result = sPriv->initiateActiveListening(serviceIdString);
+    if (!result) {
+        return false;
+    }
+
+    result = writeSdpAttributes();
+    if (!result) {
+        return false;
+    }
+
+    hr = serviceProvider->StartAdvertising(listener.Get());
+    if (FAILED(hr)) {
+        qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Could not start advertising. Check your SDP data.";
+        return false;
+    }
+
+    registered = true;
+    return true;
+}
+
+bool QBluetoothServiceInfoPrivate::unregisterService()
+{
+    if (!registered)
+        return false;
+
+    QBluetoothServerPrivate *sPriv = __fakeServerPorts.key(serverChannel());
+    if (!sPriv) {
+        //QBluetoothServer::close() was called without prior call to unregisterService().
+        //Now it is unregistered anyway.
+        registered = false;
+        return true;
+    }
+
+    bool result = sPriv->deactivateActiveListening();
+    if (!result)
+        return false;
+
+    HRESULT hr;
+    hr = serviceProvider->StopAdvertising();
+    Q_ASSERT_SUCCEEDED(hr);
+
+    registered = false;
+    return true;
+}
+
+bool QBluetoothServiceInfoPrivate::writeSdpAttributes()
+{
+    if (!serviceProvider)
+        return false;
+
+    ComPtr<IDataWriter> writer;
+    HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
+                                  &writer);
+    Q_ASSERT_SUCCEEDED(hr);
+    ComPtr<IMap<UINT32, IBuffer *>> rawAttributes;
+    hr = serviceProvider->get_SdpRawAttributes(&rawAttributes);
+    Q_ASSERT_SUCCEEDED(hr);
+    for (quint16 key : attributes.keys()) {
+        // The SDP Class Id List and RFCOMM and L2CAP protocol descriptors are automatically
+        // generated by the RfcommServiceProvider. Do not specify it in the SDP raw attribute map.
+        if (key == QBluetoothServiceInfo::ServiceClassIds
+                || key == QBluetoothServiceInfo::ProtocolDescriptorList)
+            continue;
+        const QVariant attribute = attributes.value(key);
+        HRESULT hr;
+        ComPtr<IBuffer> buffer = bufferFromAttribute(attribute);
+        if (!buffer) {
+            qCWarning(QT_BT_WINRT) << "Could not create buffer from attribute with id:" << key;
+            return false;
+        }
+
+        hr = writer->WriteBuffer(buffer.Get());
+        Q_ASSERT_SUCCEEDED(hr);
+
+        hr = writer->DetachBuffer(&buffer);
+        Q_ASSERT_SUCCEEDED(hr);
+
+        boolean replaced;
+        hr = rawAttributes->Insert(key, buffer.Get(), &replaced);
+        Q_ASSERT_SUCCEEDED(hr);
+        Q_ASSERT(!replaced);
+    }
+    return true;
+}
+
+QT_END_NAMESPACE
diff --git a/src/bluetooth/qbluetoothsocket_winrt.cpp b/src/bluetooth/qbluetoothsocket_winrt.cpp
index 98847b18cf93321d0e16092c4e4d7e14c0e53a9e..855af16d6250201b4bf5598072fd9569e46f5e8e 100644
--- a/src/bluetooth/qbluetoothsocket_winrt.cpp
+++ b/src/bluetooth/qbluetoothsocket_winrt.cpp
@@ -533,11 +533,22 @@ void QBluetoothSocketPrivate::close()
 bool QBluetoothSocketPrivate::setSocketDescriptor(int socketDescriptor, QBluetoothServiceInfo::Protocol socketType,
                                            QBluetoothSocket::SocketState socketState, QBluetoothSocket::OpenMode openMode)
 {
-    Q_UNUSED(socketDescriptor);
-    Q_UNUSED(socketType)
-    Q_UNUSED(socketState);
-    Q_UNUSED(openMode);
-    return false;
+    Q_Q(QBluetoothSocket);
+    if (socketType != QBluetoothServiceInfo::RfcommProtocol)
+        return false;
+
+    m_socketObject = nullptr;
+    socket = -1;
+
+    m_socketObject = reinterpret_cast<IStreamSocket *>(qintptr(socketDescriptor));
+    if (!m_socketObject)
+        return false;
+    socket = qintptr(m_socketObject.Get());
+    m_worker->setSocket(m_socketObject);
+    if (socketState == QBluetoothSocket::ConnectedState)
+        m_worker->startReading();
+    q->setOpenMode(openMode);
+    return true;
 }
 
 qint64 QBluetoothSocketPrivate::bytesAvailable() const