summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Blasche <alexander.blasche@qt.io>2018-01-29 19:06:59 +0100
committerOliver Wolff <oliver.wolff@qt.io>2018-08-17 06:28:17 +0000
commit0f930cddefe386c6b6f65b8b11342c9e76876a9b (patch)
tree546340d74090e05865bc4a28d27895ae969e1919
parentc0960600bad55c5df62ba26a78d08179658b0454 (diff)
Add manufacturer data to QBluetoothDeviceInfo
The initial patch was contributed by Thiemo van Engelen. Change-Id: I45fad793ba092ab2820e606d8bf8807afa3e911e Reviewed-by: Oliver Wolff <oliver.wolff@qt.io>
-rw-r--r--src/bluetooth/android/devicediscoverybroadcastreceiver.cpp7
-rw-r--r--src/bluetooth/osx/osxbtledeviceinquiry.mm12
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_bluez.cpp33
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo.cpp55
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo.h6
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo_p.h2
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;