Details
-
Bug
-
Resolution: Done
-
P2: Important
-
5.11.3, 5.12.0
-
None
-
Linux Raspbian Stretch 2018-11-13
Linux Mint 19
Description
I need to publish a Bluetooth HID service profile, which needs to include a byte-encoded description of the USB-spec HID service reports (example below).
There doesn't seem to be a way to do this using QBluetoothServiceInfo, at least the BlueZ 5 version. If I set the attribute as a QString, it comes out in the registration as a "normal" encoded string, which clearly doesn't work. If I set it as a QByteArray, the parser says the variant type is unrecognized. Am I missing something?
See this code for what is going on (qbluetoothserviceinfo_bluez.cpp::writeAttribute() where is converts a QString type).
I have only tried with Linux/BlueZ 5, so I don't know if this is a problem on other platforms or how one would set a byte array in a descriptor attribute there either.
As as workaround: I made my own BlueZ registration routine using essentially the same code as qbluetoothserviceinfo_bluez, but the XML attribute writer recognizes a QByteArray type and writes it as a hex-encoded string. It works, but a lot of code duplication for just one issue. I also had SDP registration working with a static XML file (skipping QBluetoothServiceInfo entirely), which worked... but I wanted to a) have dynamic attributes/values, and b) standardize the descriptor interface using a QBluetoothServiceInfo instance).
Basic code to attempt to create this attribute in any random QBluetoothServiceInfo object is below. Also how I ended up writing the attribute to XML in the end. I can attach more examples if needed.
Thanks!
-Max
Example desired XML output for an HID report descriptor:
<!-- HIDDescriptorList [0x0206] (USB Report/Physical Descriptors) --> <attribute id="0x0206"> <sequence> <sequence> <uint8 value="0x22" /> <!-- Report type --> <!-- This is the "standard" descriptor for keyboard and mouse from the USB HID v1.11 spec examples. --> <text encoding="hex" value="05010906a101850105079508750119e029e7150025018102950175088103050795067508150026FF00190029FF8100050895057501190129059102950175039103c005010902a10185020901a1000509190129031500250175019503810275059501810105010930093109381581257f750895038106c0c0" /> <!-- Nice parser: https://eleccelerator.com/usbdescreqparser/ --> </sequence> </sequence> </attribute>
Example code to (attempt to) create above attribute:
const QByteArray hidSvcDescript = QByteArray::fromHex("05010906a101850105079508750119e029e7150025018102950175088103050795067508150026FF00190029FF8100050895057501190129059102950175039103c005010902a10185020901a1000509190129031500250175019503810275059501810105010930093109381581257f750895038106c0c0"); const QBluetoothServiceInfo::Sequence hidDescriptorList({ QVariant::fromValue(quint8(0x22)), // Report type QString(hidSvcDescript.toHex()) // Our descriptor array }); // need to wrap it in another sequence const QBluetoothServiceInfo::Sequence hidDescriptorListSeq({ QVariant::fromValue(hidDescriptorList) }); // svcInfo = QBluetoothServiceInfo() svcInfo.setAttribute(0x0206, QVariant::fromValue(hidDescriptorListSeq));
Here's how I convert a QByteArray type to XML attribute (so QBluetoothServiceInfo::setAttribute() gets passed a QByteArray value, instead of QString):
// new case handler for writeAttribute(QXmlStreamWriter *stream, const QVariant &attribute) case QMetaType::QByteArray: stream->writeEmptyElement(QStringLiteral("text")); stream->writeAttribute(QStringLiteral("encoding"), QStringLiteral("hex")); stream->writeAttribute(QStringLiteral("value"), QString(attribute.value<QByteArray>().toHex())); break;
Attachments
For Gerrit Dashboard: QTBUG-73328 | ||||||
---|---|---|---|---|---|---|
# | Subject | Branch | Project | Status | CR | V |
252840,8 | Ensure SDP records can be byte arrays/hex encoded | 5.12 | qt/qtconnectivity | Status: MERGED | +2 | 0 |