diff options
-rw-r--r-- | src/bluetooth/android/devicediscoverybroadcastreceiver.cpp | 7 | ||||
-rw-r--r-- | src/bluetooth/osx/osxbtledeviceinquiry.mm | 12 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp | 33 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdeviceinfo.cpp | 55 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdeviceinfo.h | 6 | ||||
-rw-r--r-- | src/bluetooth/qbluetoothdeviceinfo_p.h | 2 |
6 files changed, 108 insertions, 7 deletions
diff --git a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp index 131fb48d..99245af3 100644 --- a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp +++ b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp @@ -245,6 +245,7 @@ enum ADType { ADType32BitUuidComplete = 0x05, ADType128BitUuidIncomplete = 0x06, ADType128BitUuidComplete = 0x07, + ADTypeManufacturerSpecificData = 0xff, // .. more will be added when required }; @@ -548,6 +549,12 @@ QBluetoothDeviceInfo DeviceDiscoveryBroadcastReceiver::retrieveDeviceInfo(JNIEnv foundService = QBluetoothUuid(qToBigEndian<quint128>(qFromLittleEndian<quint128>(dataPtr))); break; + case ADTypeManufacturerSpecificData: + if (nBytes >= 3) { + info.setManufacturerData(qFromLittleEndian<quint16>(dataPtr), + QByteArray(dataPtr + 2, nBytes - 3)); + } + break; default: // no other types supported yet and therefore skipped // https://www.bluetooth.org/en-us/specification/assigned-numbers/generic-access-profile diff --git a/src/bluetooth/osx/osxbtledeviceinquiry.mm b/src/bluetooth/osx/osxbtledeviceinquiry.mm index 2cece15b..e61968ed 100644 --- a/src/bluetooth/osx/osxbtledeviceinquiry.mm +++ b/src/bluetooth/osx/osxbtledeviceinquiry.mm @@ -45,6 +45,7 @@ #include <QtCore/qloggingcategory.h> #include <QtCore/qdebug.h> +#include <QtCore/qendian.h> #include <algorithm> @@ -81,6 +82,7 @@ struct AdvertisementData { // For now, we "parse": QString localName; QList<QBluetoothUuid> serviceUuids; + QHash<quint16, QByteArray> manufacturerData; // TODO: other keys probably? AdvertisementData(NSDictionary *AdvertisementData); }; @@ -105,6 +107,12 @@ AdvertisementData::AdvertisementData(NSDictionary *advertisementData) for (CBUUID *cbUuid in uuids) serviceUuids << qt_uuid(cbUuid); } + + value = [advertisementData objectForKey:CBAdvertisementDataManufacturerDataKey]; + if (value && [value isKindOfClass:[NSData class]]) { + QByteArray data = QByteArray::fromNSData(static_cast<NSData *>(value)); + manufacturerData.insert(qFromLittleEndian<quint16>(data.constData()), data.mid(2)); + } } } @@ -321,6 +329,10 @@ QT_USE_NAMESPACE QBluetoothDeviceInfo::DataIncomplete); } + const QList<quint16> keys = qtAdvData.manufacturerData.keys(); + for (quint16 key : keys) + newDeviceInfo.setManufacturerData(key, qtAdvData.manufacturerData.value(key)); + // CoreBluetooth scans only for LE devices. newDeviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::LowEnergyCoreConfiguration); emit notifier->deviceDiscovered(newDeviceInfo); diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp index 3d09a4df..a5fdb323 100644 --- a/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp +++ b/src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp @@ -420,7 +420,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& dev qCDebug(QT_BT_BLUEZ) << "Discovered: " << btAddress.toString() << btName << "Num UUIDs" << device.uUIDs().count() << "total device" << discoveredDevices.count() << "cached" - << "RSSI" << device.rSSI() << "Class" << btClass; + << "RSSI" << device.rSSI() << "Class" << btClass + << "Num ManufacturerData" << device.manufacturerData().size(); OrgFreedesktopDBusPropertiesInterface *prop = new OrgFreedesktopDBusPropertiesInterface( QStringLiteral("org.bluez"), devicePath, QDBusConnection::systemBus(), q); @@ -459,6 +460,12 @@ void QBluetoothDeviceDiscoveryAgentPrivate::deviceFoundBluez5(const QString& dev deviceInfo.setCoreConfigurations(QBluetoothDeviceInfo::BaseRateAndLowEnergyCoreConfiguration); } + const ManufacturerDataList deviceManufacturerData = device.manufacturerData(); + const QList<quint16> keys = deviceManufacturerData.keys(); + for (quint16 key : keys) + deviceInfo.setManufacturerData( + key, deviceManufacturerData.value(key).variant().toByteArray()); + for (int i = 0; i < discoveredDevices.size(); i++) { if (discoveredDevices[i].address() == deviceInfo.address()) { if (discoveredDevices[i] == deviceInfo && lowEnergySearchTimeout > 0) { @@ -615,7 +622,8 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_PropertiesChanged(const QString & { Q_Q(QBluetoothDeviceDiscoveryAgent); if (interface == QStringLiteral("org.bluez.Device1") - && changed_properties.contains(QStringLiteral("RSSI"))) { + && (changed_properties.contains(QStringLiteral("RSSI")) + || changed_properties.contains(QStringLiteral("ManufacturerData")))) { OrgFreedesktopDBusPropertiesInterface *props = qobject_cast<OrgFreedesktopDBusPropertiesInterface *>(q->sender()); if (!props) @@ -625,10 +633,23 @@ void QBluetoothDeviceDiscoveryAgentPrivate::_q_PropertiesChanged(const QString & QDBusConnection::systemBus()); for (int i = 0; i < discoveredDevices.size(); i++) { if (discoveredDevices[i].address().toString() == device.address()) { - qCDebug(QT_BT_BLUEZ) << "Updating RSSI for" << device.address() - << changed_properties.value(QStringLiteral("RSSI")); - discoveredDevices[i].setRssi( - changed_properties.value(QStringLiteral("RSSI")).toInt()); + if (changed_properties.contains(QStringLiteral("RSSI"))) { + qCDebug(QT_BT_BLUEZ) << "Updating RSSI for" << device.address() + << changed_properties.value(QStringLiteral("RSSI")); + discoveredDevices[i].setRssi( + changed_properties.value(QStringLiteral("RSSI")).toInt()); + } + if (changed_properties.contains(QStringLiteral("ManufacturerData"))) { + qCDebug(QT_BT_BLUEZ) << "Updating ManufacturerData for" << device.address(); + + QVector<QPair<quint16,QByteArray>> manufacturerData; + ManufacturerDataList changedManufacturerData = + qvariant_cast< ManufacturerDataList >(changed_properties.value(QStringLiteral("ManufacturerData"))); + + const QList<quint16> keys = changedManufacturerData.keys(); + for (quint16 key : keys) + discoveredDevices[i].setManufacturerData(key, changedManufacturerData.value(key).variant().toByteArray()); + } return; } } diff --git a/src/bluetooth/qbluetoothdeviceinfo.cpp b/src/bluetooth/qbluetoothdeviceinfo.cpp index f068963e..ce557912 100644 --- a/src/bluetooth/qbluetoothdeviceinfo.cpp +++ b/src/bluetooth/qbluetoothdeviceinfo.cpp @@ -405,6 +405,7 @@ QBluetoothDeviceInfo &QBluetoothDeviceInfo::operator=(const QBluetoothDeviceInfo d->cached = other.d_func()->cached; d->serviceUuidsCompleteness = other.d_func()->serviceUuidsCompleteness; d->serviceUuids = other.d_func()->serviceUuids; + d->manufacturerData = other.d_func()->manufacturerData; d->rssi = other.d_func()->rssi; d->deviceCoreConfiguration = other.d_func()->deviceCoreConfiguration; d->deviceUuid = other.d_func()->deviceUuid; @@ -439,6 +440,8 @@ bool QBluetoothDeviceInfo::operator==(const QBluetoothDeviceInfo &other) const return false; if (d->serviceUuids != other.d_func()->serviceUuids) return false; + if (d->manufacturerData != other.d_func()->manufacturerData) + return false; if (d->deviceCoreConfiguration != other.d_func()->deviceCoreConfiguration) return false; if (d->deviceUuid != other.d_func()->deviceUuid) @@ -557,10 +560,60 @@ QList<QBluetoothUuid> QBluetoothDeviceInfo::serviceUuids(DataCompleteness *compl QBluetoothDeviceInfo::DataCompleteness QBluetoothDeviceInfo::serviceUuidsCompleteness() const { Q_D(const QBluetoothDeviceInfo); - return d->serviceUuidsCompleteness; } + +/*! + Returns all manufacturer ids attached to this device information. + + \sa manufacturerData(), setManufacturerData() + + \since 5.12 + */ +QVector<quint16> QBluetoothDeviceInfo::manufactuerIds() const +{ + Q_D(const QBluetoothDeviceInfo); + return d->manufacturerData.keys().toVector(); +} + +/*! + Returns the data associated with the given \a manufacturerId. + + Manufacturer data is defined by + the Supplement to the Bluetooth Core Specification and consists of two segments: + + \list + \li Manufacturer specific identifier code from the + \l {https://www.bluetooth.com/specifications/assigned-numbers} {Assigned Numbers} + Company Identifiers document + \li Sequence of arbitrary data octets + \endlist + + The interpretation of the data octets is defined by the manufacturer + specified by the company identifier. + + \sa manufacturerIds(), setManufacturerData() + \since 5.12 + */ +QByteArray QBluetoothDeviceInfo::manufacturerData(quint16 manufacturerId) const +{ + Q_D(const QBluetoothDeviceInfo); + return d->manufacturerData.value(manufacturerId); +} + +/*! + Sets the advertised manufacturer \a data for the given \a manufacturerId. + + \sa manufacturerData, + \since 5.12 +*/ +void QBluetoothDeviceInfo::setManufacturerData(quint16 manufacturerId, const QByteArray &data) +{ + Q_D(QBluetoothDeviceInfo); + d->manufacturerData.insert(manufacturerId, data); +} + /*! Sets the CoreConfigurations of the device to \a coreConfigs. This will help to make a difference between regular and Low Energy devices. diff --git a/src/bluetooth/qbluetoothdeviceinfo.h b/src/bluetooth/qbluetoothdeviceinfo.h index f2558bbf..c69a7242 100644 --- a/src/bluetooth/qbluetoothdeviceinfo.h +++ b/src/bluetooth/qbluetoothdeviceinfo.h @@ -44,6 +44,8 @@ #include <QtCore/qstring.h> #include <QtCore/qmetatype.h> +#include <QtCore/qbytearray.h> +#include <QtCore/qvector.h> QT_BEGIN_NAMESPACE @@ -235,6 +237,10 @@ public: QList<QBluetoothUuid> serviceUuids(DataCompleteness *completeness = nullptr) const; DataCompleteness serviceUuidsCompleteness() const; + QVector<quint16> manufactuerIds() const; + QByteArray manufacturerData(quint16 manufacturerId) const; + void setManufacturerData(quint16 manufacturerId, const QByteArray &data); + void setCoreConfigurations(QBluetoothDeviceInfo::CoreConfigurations coreConfigs); QBluetoothDeviceInfo::CoreConfigurations coreConfigurations() const; diff --git a/src/bluetooth/qbluetoothdeviceinfo_p.h b/src/bluetooth/qbluetoothdeviceinfo_p.h index 8d827f0b..15c9e21c 100644 --- a/src/bluetooth/qbluetoothdeviceinfo_p.h +++ b/src/bluetooth/qbluetoothdeviceinfo_p.h @@ -56,6 +56,7 @@ #include "qbluetoothuuid.h" #include <QString> +#include <QtCore/qhash.h> QT_BEGIN_NAMESPACE @@ -78,6 +79,7 @@ public: QBluetoothDeviceInfo::DataCompleteness serviceUuidsCompleteness; QList<QBluetoothUuid> serviceUuids; + QHash<quint16, QByteArray> manufacturerData; QBluetoothDeviceInfo::CoreConfigurations deviceCoreConfiguration; QBluetoothUuid deviceUuid; |