9#include <QtCore/QLoggingCategory>
10#include <QtCore/private/qfunctions_winrt_p.h>
13#include <windows.devices.bluetooth.h>
14#include <windows.devices.bluetooth.rfcomm.h>
15#include <windows.foundation.h>
16#include <windows.networking.sockets.h>
17#include <windows.storage.streams.h>
20using namespace Microsoft::WRL::Wrappers;
22using namespace ABI::Windows::Devices::Bluetooth::Rfcomm;
24using namespace ABI::Windows::Foundation::Collections;
25using namespace ABI::Windows::Networking::Sockets;
45#define TYPE_UUID128 28
46#define TYPE_STRING_BASE 32
47#define TYPE_BOOLEAN 40
48#define TYPE_SEQUENCE_BASE 48
49#define TYPE_ALTERNATIVE_BASE 56
50#define TYPE_URL_BASE 64
56 return ((
type & baseType) == baseType);
72 const unsigned char sizeIndex = (
type & 0x7);
76 hr = reader->ReadByte(&
length);
77 RETURN_IF_FAILED(
"Could not read length from buffer",
return -1);
81 hr = reader->ReadUInt16(&
length);
82 RETURN_IF_FAILED(
"Could not read length from buffer",
return -1);
86 hr = reader->ReadUInt32(&
length);
87 RETURN_IF_FAILED(
"Could not read length from buffer",
return -1);
97 const qsizetype stringLength =
string.size();
99 if (stringLength < 0) {
100 qCWarning(QT_BT_WINDOWS) <<
"Can not write invalid string value to buffer";
102 }
if (stringLength <= 0xff) {
104 hr = writer->WriteByte(
type);
105 RETURN_FALSE_IF_FAILED(
"Could not write string type data.");
106 hr = writer->WriteByte(stringLength);
107 RETURN_FALSE_IF_FAILED(
"Could not write string length.");
108 }
else if (stringLength <= 0xffff) {
110 hr = writer->WriteByte(
type);
111 RETURN_FALSE_IF_FAILED(
"Could not write string type data.");
112 hr = writer->WriteUInt16(stringLength);
113 RETURN_FALSE_IF_FAILED(
"Could not write string length.");
116 hr = writer->WriteByte(
type);
117 RETURN_FALSE_IF_FAILED(
"Could not write string type data.");
118 hr = writer->WriteUInt32(stringLength);
119 RETURN_FALSE_IF_FAILED(
"Could not write string length.");
121 HStringReference stringRef(
reinterpret_cast<LPCWSTR
>(
string.utf16()));
123 hr = writer->WriteString(stringRef.Get(), &
bytesWritten);
124 RETURN_FALSE_IF_FAILED(
"Could not write string to buffer.");
126 qCWarning(QT_BT_WINDOWS) <<
"Did not write full value to buffer";
135 HRESULT hr = GetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataReader).Get(),
137 Q_ASSERT_SUCCEEDED(hr);
140 hr = dataReaderStatics->FromBuffer(
buffer.Get(), reader.GetAddressOf());
141 Q_ASSERT_SUCCEEDED(hr);
144 hr = reader->ReadByte(&
type);
145 Q_ASSERT_SUCCEEDED(hr);
152 hr = reader->ReadByte(&
type);
153 Q_ASSERT_SUCCEEDED(hr);
158 hr = reader->ReadUInt16(&uuid);
159 Q_ASSERT_SUCCEEDED(hr);
162 hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
164 Q_ASSERT_SUCCEEDED(hr);
167 Q_ASSERT_SUCCEEDED(hr);
169 hr = writer->WriteByte(8);
170 Q_ASSERT_SUCCEEDED(hr);
172 Q_ASSERT_SUCCEEDED(hr);
173 hr = writer->WriteByte(7);
174 Q_ASSERT_SUCCEEDED(hr);
176 Q_ASSERT_SUCCEEDED(hr);
177 hr = writer->WriteUInt16(uuid);
178 Q_ASSERT_SUCCEEDED(hr);
181 Q_ASSERT_SUCCEEDED(hr);
182 hr = writer->WriteUInt16(0x100);
183 Q_ASSERT_SUCCEEDED(hr);
185 hr = writer->DetachBuffer(&
buffer);
186 Q_ASSERT_SUCCEEDED(hr);
195 HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
197 Q_ASSERT_SUCCEEDED(hr);
200 case QMetaType::Void:
201 qCDebug(QT_BT_WINDOWS) <<
Q_FUNC_INFO <<
"Registering attribute of type QMetaType::Void:";
203 Q_ASSERT_SUCCEEDED(hr);
205 case QMetaType::UChar:
208 Q_ASSERT_SUCCEEDED(hr);
210 Q_ASSERT_SUCCEEDED(hr);
212 case QMetaType::UShort:
215 Q_ASSERT_SUCCEEDED(hr);
217 Q_ASSERT_SUCCEEDED(hr);
219 case QMetaType::UInt:
222 Q_ASSERT_SUCCEEDED(hr);
224 Q_ASSERT_SUCCEEDED(hr);
226 case QMetaType::ULongLong:
229 Q_ASSERT_SUCCEEDED(hr);
231 Q_ASSERT_SUCCEEDED(hr);
233 case QMetaType::Char:
236 Q_ASSERT_SUCCEEDED(hr);
238 Q_ASSERT_SUCCEEDED(hr);
240 case QMetaType::Short:
243 Q_ASSERT_SUCCEEDED(hr);
245 Q_ASSERT_SUCCEEDED(hr);
250 Q_ASSERT_SUCCEEDED(hr);
252 Q_ASSERT_SUCCEEDED(hr);
254 case QMetaType::LongLong:
257 Q_ASSERT_SUCCEEDED(hr);
259 Q_ASSERT_SUCCEEDED(hr);
261 case QMetaType::QByteArray: {
269 case QMetaType::QString: {
277 case QMetaType::Bool:
280 Q_ASSERT_SUCCEEDED(hr);
281 hr = writer->WriteByte(
attribute.value<
bool>());
282 Q_ASSERT_SUCCEEDED(hr);
284 case QMetaType::QUrl:
285 qCWarning(QT_BT_WINDOWS) <<
"Don't know how to register QMetaType::QUrl";
289 if (
attribute.userType() == qMetaTypeId<QBluetoothUuid>()) {
293 qCWarning(QT_BT_WINDOWS) <<
"Don't know how to register Uuid of length 0";
296 qCDebug(QT_BT_WINDOWS) <<
Q_FUNC_INFO <<
"Registering Uuid attribute with length 2:" << uuid;
298 Q_ASSERT_SUCCEEDED(hr);
299 hr = writer->WriteUInt16(uuid.toUInt16());
300 Q_ASSERT_SUCCEEDED(hr);
303 qCDebug(QT_BT_WINDOWS) <<
Q_FUNC_INFO <<
"Registering Uuid attribute with length 4:" << uuid;
305 Q_ASSERT_SUCCEEDED(hr);
306 hr = writer->WriteUInt32(uuid.toUInt32());
307 Q_ASSERT_SUCCEEDED(hr);
313 Q_ASSERT_SUCCEEDED(hr);
314 hr = writer->WriteGuid(uuid);
315 Q_ASSERT_SUCCEEDED(hr);
318 }
else if (
attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Sequence>()) {
319 qCDebug(QT_BT_WINDOWS) <<
"Registering sequence attribute";
323 HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
325 Q_ASSERT_SUCCEEDED(hr);
329 qCWarning(QT_BT_WINDOWS) <<
"Could not create buffer from attribute in sequence";
333 hr = tmpBuffer->get_Length(&l);
334 Q_ASSERT_SUCCEEDED(hr);
335 hr = tmpWriter->WriteBuffer(tmpBuffer.Get());
336 Q_ASSERT_SUCCEEDED(hr);
339 hr = tmpWriter->DetachBuffer(&tmpBuffer);
340 Q_ASSERT_SUCCEEDED(hr);
343 tmpBuffer->get_Length(&
length);
344 Q_ASSERT_SUCCEEDED(hr);
349 hr = writer->WriteByte(
type);
350 Q_ASSERT_SUCCEEDED(hr);
351 hr = writer->WriteByte(
length);
352 Q_ASSERT_SUCCEEDED(hr);
353 }
else if (
length <= 0xffff) {
355 hr = writer->WriteByte(
type);
356 Q_ASSERT_SUCCEEDED(hr);
357 hr = writer->WriteUInt16(
length);
358 Q_ASSERT_SUCCEEDED(hr);
361 hr = writer->WriteByte(
type);
362 Q_ASSERT_SUCCEEDED(hr);
363 hr = writer->WriteUInt32(
length);
364 Q_ASSERT_SUCCEEDED(hr);
367 hr = writer->WriteBuffer(tmpBuffer.Get());
368 Q_ASSERT_SUCCEEDED(hr);
370 }
else if (
attribute.userType() == qMetaTypeId<QBluetoothServiceInfo::Alternative>()) {
371 qCWarning(QT_BT_WINDOWS) <<
"Don't know how to register user type Alternative";
379 hr = writer->DetachBuffer(&
buffer);
380 Q_ASSERT_SUCCEEDED(hr);
418 hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_Rfcomm_RfcommServiceId).Get(),
419 IID_PPV_ARGS(&serviceIdStatics));
420 Q_ASSERT_SUCCEEDED(hr);
422 hr = serviceIdStatics->FromUuid(uuid, &serviceId);
423 Q_ASSERT_SUCCEEDED(hr);
425 hr = RoGetActivationFactory(HString::MakeReference(RuntimeClass_Windows_Devices_Bluetooth_Rfcomm_RfcommServiceProvider).Get(),
426 IID_PPV_ARGS(&providerStatics));
427 Q_ASSERT_SUCCEEDED(hr);
429 hr = providerStatics->CreateAsync(serviceId.Get(), &op);
430 Q_ASSERT_SUCCEEDED(hr);
431 hr = QWinRTFunctions::await(op, serviceProvider.GetAddressOf());
432 if (hr == HRESULT_FROM_WIN32(ERROR_DEVICE_NOT_AVAILABLE)) {
436 Q_ASSERT_SUCCEEDED(hr);
446 HString serviceIdHString;
447 serviceId->AsString(serviceIdHString.GetAddressOf());
448 Q_ASSERT_SUCCEEDED(hr);
453 bool result = sPriv->initiateActiveListening(serviceIdString);
458 result = writeSdpAttributes();
460 qCWarning(QT_BT_WINDOWS) <<
"Could not write SDP attributes.";
463 qCDebug(QT_BT_WINDOWS) <<
"SDP attributes written.";
466 hr = serviceProvider.As(&serviceProvider2);
467 Q_ASSERT_SUCCEEDED(hr);
468 hr = serviceProvider2->StartAdvertisingWithRadioDiscoverability(listener.Get(),
true);
491 bool result = sPriv->deactivateActiveListening();
496 hr = serviceProvider->StopAdvertising();
497 Q_ASSERT_SUCCEEDED(hr);
503bool QBluetoothServiceInfoPrivate::writeSdpAttributes()
505 if (!serviceProvider)
509 HRESULT hr = RoActivateInstance(HString::MakeReference(RuntimeClass_Windows_Storage_Streams_DataWriter).Get(),
511 Q_ASSERT_SUCCEEDED(hr);
513 hr = serviceProvider->get_SdpRawAttributes(&rawAttributes);
514 Q_ASSERT_SUCCEEDED(hr);
526 qCWarning(QT_BT_WINDOWS) <<
"Could not create buffer from attribute with id:" <<
key;
534 qCWarning(QT_BT_WINDOWS) <<
Q_FUNC_INFO <<
"Error while checking/repairing structure of profile descriptor list";
539 hr = writer->WriteBuffer(
buffer.Get());
540 Q_ASSERT_SUCCEEDED(hr);
542 hr = writer->DetachBuffer(&
buffer);
543 Q_ASSERT_SUCCEEDED(hr);
546 hr = rawAttributes->Insert(
key,
buffer.Get(), &replaced);
547 Q_ASSERT_SUCCEEDED(hr);
QBluetoothServiceInfo::Sequence protocolDescriptor(QBluetoothUuid::ProtocolUuid protocol) const
QMap< quint16, QVariant > attributes
QBluetoothServiceInfoPrivate()
bool registerService(const QBluetoothAddress &localAdapter=QBluetoothAddress())
int serverChannel() const
bool isRegistered() const
~QBluetoothServiceInfoPrivate()
@ BluetoothProfileDescriptorList
int minimumSize() const
Returns the minimum size in bytes that this UUID can be represented in.
QByteArray toHex(char separator='\0') const
Returns a hex encoded copy of the byte array.
T value(const Key &key, const T &defaultValue=T()) const
QList< Key > keys() const
\macro QT_RESTRICTED_CAST_FROM_ASCII
QString rightJustified(qsizetype width, QChar fill=u' ', bool trunc=false) const
Returns a string of size() width that contains the fill character followed by the string.
static QString fromLatin1(QByteArrayView ba)
This is an overloaded member function, provided for convenience. It differs from the above function o...
static QString fromWCharArray(const wchar_t *string, qsizetype size=-1)
static QString number(int, int base=10)
This is an overloaded member function, provided for convenience. It differs from the above function o...
Combined button and popup list for selecting options.
QT_BEGIN_NAMESPACE QHash< QBluetoothServerPrivate *, int > __fakeServerPorts
static ComPtr< IBuffer > bufferFromAttribute(const QVariant &attribute)
#define TYPE_ALTERNATIVE_BASE
qint64 getLengthForBaseType(unsigned char type, ComPtr< IDataReader > &reader)
bool repairProfileDescriptorListIfNeeded(ComPtr< IBuffer > &buffer)
bool typeIsOfBase(unsigned char type, unsigned char baseType)
QHash< QBluetoothServerPrivate *, int > __fakeServerPorts
#define TYPE_SEQUENCE_BASE
bool writeStringHelper(const QString &string, ComPtr< IDataWriter > writer)
void mainThreadCoInit(void *caller)
void mainThreadCoUninit(void *caller)
EGLOutputLayerEXT EGLint attribute
#define qCWarning(category,...)
#define qCDebug(category,...)
#define Q_DECLARE_LOGGING_CATEGORY(name)
GLenum GLsizei GLuint GLint * bytesWritten
GLsizei const GLfloat * v
[13]
GLenum GLuint GLintptr GLsizeiptr size
[1]
GLenum GLuint GLenum GLsizei length
unsigned long long quint64
QT_BEGIN_NAMESPACE typedef signed char qint8
\inmodule QtCore \reentrant