/****************************************************************************
**
** 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/private/qeventdispatcher_winrt_p.h>
#include <QtCore/QLoggingCategory>
#ifdef CLASSIC_APP_BUILD
#define Q_OS_WINRT
#endif
#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_VOID              0
#define TYPE_UINT8             8
#define TYPE_UINT16            9
#define TYPE_UINT32           10
#define TYPE_UINT64           11
//#define TYPE_UINT128          12
#define TYPE_INT8             16
#define TYPE_INT16            17
#define TYPE_INT32            18
#define TYPE_INT64            19
//#define TYPE_INT128           20
#define TYPE_UUID16           25
#define TYPE_UUID32           26
#define TYPE_UUID128          28
#define TYPE_STRING_BASE      32
#define TYPE_BOOLEAN          40
#define TYPE_SEQUENCE_BASE    48
#define TYPE_ALTERNATIVE_BASE 56
#define TYPE_URL_BASE         64

extern QHash<QBluetoothServerPrivate *, int> __fakeServerPorts;

inline bool typeIsOfBase(unsigned char type, unsigned char baseType)
{
    return ((type & baseType) == baseType);
}

qint64 getLengthForBaseType(unsigned char type, ComPtr<IDataReader> &reader)
{
    const bool isOfBase = (typeIsOfBase(type, TYPE_STRING_BASE)
                           || typeIsOfBase(type, TYPE_SEQUENCE_BASE)
                           || typeIsOfBase(type, TYPE_ALTERNATIVE_BASE)
                           || typeIsOfBase(type, TYPE_URL_BASE));
    if (!isOfBase)
        return -1;

    HRESULT hr;
    // For these types, the first 5 bits are the base type followed by 3 bits
    // describing the size index. This index decides how many additional bits
    // have to be read to get the type's length.
    const unsigned char sizeIndex = (type & 0x7);
    switch (sizeIndex) {
    case 5: {
        quint8 length;
        hr = reader->ReadByte(&length);
        RETURN_IF_FAILED("Could not read length from buffer", return -1);
        return length;
    } case 6: {
        quint16 length;
        hr = reader->ReadUInt16(&length);
        RETURN_IF_FAILED("Could not read length from buffer", return -1);
        return length;
    } case 7: {
        quint32 length;
        hr = reader->ReadUInt32(&length);
        RETURN_IF_FAILED("Could not read length from buffer", return -1);
        return length;
    }
    }
    return -1;
}

bool writeStringHelper(const QString &string, ComPtr<IDataWriter> writer)
{
    HRESULT hr;
    const int stringLength = string.length();
    unsigned char type = TYPE_STRING_BASE;
    if (stringLength < 0) {
        qCWarning(QT_BT_WINRT) << "Can not write invalid string value to buffer";
        return false;
    } if (stringLength <= 0xff) {
        type += 5;
        hr = writer->WriteByte(type);
        RETURN_FALSE_IF_FAILED("Could not write string type data.");
        hr = writer->WriteByte(stringLength);
        RETURN_FALSE_IF_FAILED("Could not write string length.");
    } else if (stringLength <= 0xffff) {
        type += 6;
        hr = writer->WriteByte(type);
        RETURN_FALSE_IF_FAILED("Could not write string type data.");
        hr = writer->WriteUInt16(stringLength);
        RETURN_FALSE_IF_FAILED("Could not write string length.");
    } else {
        type += 7;
        hr = writer->WriteByte(type);
        RETURN_FALSE_IF_FAILED("Could not write string type data.");
        hr = writer->WriteUInt32(stringLength);
        RETURN_FALSE_IF_FAILED("Could not write string length.");
    }
    HStringReference stringRef(reinterpret_cast<LPCWSTR>(string.utf16()));
    quint32 bytesWritten;
    hr = writer->WriteString(stringRef.Get(), &bytesWritten);
    RETURN_FALSE_IF_FAILED("Could not write string to buffer.");
    if (bytesWritten != string.length()) {
        qCWarning(QT_BT_WINRT) << "Did not write full value to buffer";
        return false;
    }
    return true;
}

bool repairProfileDescriptorListIfNeeded(ComPtr<IBuffer> &buffer)
{
    ComPtr<IDataReaderStatics> dataReaderStatics;
    HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(),
                                      &dataReaderStatics);
    Q_ASSERT_SUCCEEDED(hr);

    ComPtr<IDataReader> reader;
    hr = dataReaderStatics->FromBuffer(buffer.Get(), reader.GetAddressOf());
    Q_ASSERT_SUCCEEDED(hr);

    BYTE type;
    hr = reader->ReadByte(&type);
    Q_ASSERT_SUCCEEDED(hr);
    if (!typeIsOfBase(type, TYPE_SEQUENCE_BASE)) {
        qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Malformed profile descriptor list read";
        return false;
    }

    qint64 length = getLengthForBaseType(type, reader);
    hr = reader->ReadByte(&type);
    Q_ASSERT_SUCCEEDED(hr);
    // We have to "repair" the structure if the outer sequence contains a uuid directly
    if (type == TYPE_UUID16 && length == 4) {
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Repairing profile descriptor list";
        quint16 uuid;
        hr = reader->ReadUInt16(&uuid);
        Q_ASSERT_SUCCEEDED(hr);

        ComPtr<IDataWriter> writer;
        hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
            &writer);
        Q_ASSERT_SUCCEEDED(hr);

        hr = writer->WriteByte(TYPE_SEQUENCE_BASE + 5);
        Q_ASSERT_SUCCEEDED(hr);
        // 8 == length of nested sequence (outer sequence -> inner sequence -> uuid and version)
        hr = writer->WriteByte(8);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteByte(TYPE_SEQUENCE_BASE + 5);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteByte(7);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteByte(TYPE_UUID16);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteUInt16(uuid);
        Q_ASSERT_SUCCEEDED(hr);
        // Write default version to make WinRT happy
        hr = writer->WriteByte(TYPE_UINT16);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteUInt16(0x100);
        Q_ASSERT_SUCCEEDED(hr);

        hr = writer->DetachBuffer(&buffer);
        Q_ASSERT_SUCCEEDED(hr);
    }

    return true;
}

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:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Void:";
        hr = writer->WriteByte(TYPE_VOID);
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::UChar:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::UChar:" << attribute.value<quint8>();
        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:" << attribute.value<quint16>();
        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:" << attribute.value<quint32>();
        hr = writer->WriteByte(TYPE_UINT32);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteUInt32(attribute.value<quint32>());
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::ULongLong:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::ULongLong:" << attribute.value<quint64>();
        hr = writer->WriteByte(TYPE_UINT64);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteUInt64(attribute.value<quint64>());
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::Char:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Char:" << attribute.value<qint8>();
        hr = writer->WriteByte(TYPE_INT8);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteByte(attribute.value<qint8>());
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::Short:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Short:" << attribute.value<qint16>();
        hr = writer->WriteByte(TYPE_INT16);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteInt16(attribute.value<qint16>());
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::Int:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Int:" << attribute.value<qint32>();
        hr = writer->WriteByte(TYPE_INT32);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteInt32(attribute.value<qint32>());
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::LongLong:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::LongLong:" << attribute.value<qint64>();
        hr = writer->WriteByte(TYPE_INT64);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteInt64(attribute.value<qint64>());
        Q_ASSERT_SUCCEEDED(hr);
        break;
    case QMetaType::QByteArray: {
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::QByteArray:" << attribute.value<QString>();
        const QString stringValue = QString::fromLatin1(attribute.value<QByteArray>().toHex());
        const bool writeSuccess = writeStringHelper(stringValue, writer);
        if (!writeSuccess)
            return nullptr;
        break;
    }
    case QMetaType::QString: {
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::QString:" << attribute.value<QString>();
        const QString stringValue = attribute.value<QString>();
        const bool writeSucces = writeStringHelper(stringValue, writer);
        if (!writeSucces)
            return nullptr;
        break;
    }
    case QMetaType::Bool:
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering attribute of type QMetaType::Bool:" << attribute.value<bool>();
        hr = writer->WriteByte(TYPE_BOOLEAN);
        Q_ASSERT_SUCCEEDED(hr);
        hr = writer->WriteByte(attribute.value<bool>());
        Q_ASSERT_SUCCEEDED(hr);
        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;
            case 2:
                qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 2:" << uuid;
                hr = writer->WriteByte(TYPE_UUID16);
                Q_ASSERT_SUCCEEDED(hr);
                hr = writer->WriteUInt16(uuid.toUInt16());
                Q_ASSERT_SUCCEEDED(hr);
                break;
            case 4:
                qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute with length 4:" << uuid;
                hr = writer->WriteByte(TYPE_UUID32);
                Q_ASSERT_SUCCEEDED(hr);
                hr = writer->WriteUInt32(uuid.toUInt32());
                Q_ASSERT_SUCCEEDED(hr);
                break;
            case 16:
            default:
                qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registering Uuid attribute:" << uuid;
                hr = writer->WriteByte(TYPE_UUID128);
                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";
            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);
            for (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);
            unsigned char type = TYPE_SEQUENCE_BASE;
            length += 1;
            if (length <= 0xff) {
                type += 5;
                hr = writer->WriteByte(type);
                Q_ASSERT_SUCCEEDED(hr);
                hr = writer->WriteByte(length);
                Q_ASSERT_SUCCEEDED(hr);
            } else if (length <= 0xffff) {
                type += 6;
                hr = writer->WriteByte(type);
                Q_ASSERT_SUCCEEDED(hr);
                hr = writer->WriteUInt16(length);
                Q_ASSERT_SUCCEEDED(hr);
            } else {
                type += 7;
                hr = writer->WriteByte(type);
                Q_ASSERT_SUCCEEDED(hr);
                hr = writer->WriteUInt32(length);
                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 nullptr;
        }
        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 = QEventDispatcherWinRT::runOnXamlThread([providerStatics, serviceId, &op]
    {
        HRESULT hr;
        hr = providerStatics->CreateAsync(serviceId.Get(), &op);
        return hr;
    });
    Q_ASSERT_SUCCEEDED(hr);
    hr = QWinRTFunctions::await(op, serviceProvider.GetAddressOf());
    if (hr == HRESULT_FROM_WIN32(ERROR_DEVICE_NOT_AVAILABLE)) {
        qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "No bluetooth adapter available.";
        return false;
    } else {
        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) {
        qCWarning(QT_BT_WINRT) << "Could not write SDP attributes.";
        return false;
    }
    qCDebug(QT_BT_WINRT) << "SDP attributes written.";

    ComPtr<IRfcommServiceProvider2> serviceProvider2;
    hr = serviceProvider.As(&serviceProvider2);
    Q_ASSERT_SUCCEEDED(hr);
    hr = QEventDispatcherWinRT::runOnXamlThread([listener, serviceProvider2] {
        HRESULT hr;
        hr = serviceProvider2->StartAdvertisingWithRadioDiscoverability(listener.Get(), true);
        return hr;
    });
    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);
    const QList<quint16> keys = attributes.keys();
    for (quint16 key : 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;
        }

        // Other backends support a wrong structure in profile descriptor list. In order to make
        // WinRT accept the list without breaking existing apps we have to repair this structure.
        if (key == QBluetoothServiceInfo::BluetoothProfileDescriptorList) {
            if (!repairProfileDescriptorListIfNeeded(buffer)) {
                qCWarning(QT_BT_WINRT) << Q_FUNC_INFO << "Error while checking/repairing structure of profile descriptor list";
                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);
        qCDebug(QT_BT_WINRT) << Q_FUNC_INFO << "Registered attribute" << QString::number(key, 16).rightJustified(4, '0') << "with value" << attribute;
    }
    return true;
}

QT_END_NAMESPACE
