summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorLiang Qi <liang.qi@qt.io>2016-09-16 23:24:36 +0200
committerLiang Qi <liang.qi@qt.io>2016-09-16 23:24:43 +0200
commitaabce3a08d1a65f8abc4872bd91a6dfd45cf7fd6 (patch)
tree457dc8b600e0a4db7654708d921ef4ae398ae0d0 /src
parentb956fda0a1fa5813eb147e85ffc98e25d7177481 (diff)
parent9dba73f30505ed7c220055788fba3cd201848fdb (diff)
Merge remote-tracking branch 'origin/5.6' into 5.7
Diffstat (limited to 'src')
-rw-r--r--src/bluetooth/android/devicediscoverybroadcastreceiver.cpp309
-rw-r--r--src/bluetooth/doc/src/bluetooth-index.qdoc4
-rw-r--r--src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp17
-rw-r--r--src/bluetooth/qbluetoothdeviceinfo.cpp8
-rw-r--r--src/bluetooth/qbluetoothlocaldevice.cpp18
-rw-r--r--src/bluetooth/qbluetoothserver.cpp2
-rw-r--r--src/bluetooth/qbluetoothsocket.cpp33
-rw-r--r--src/bluetooth/qbluetoothsocket_osx.mm28
-rw-r--r--src/bluetooth/qlowenergycharacteristic.cpp4
-rw-r--r--src/bluetooth/qlowenergydescriptor.cpp2
10 files changed, 383 insertions, 42 deletions
diff --git a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
index a3d17b90..a246889f 100644
--- a/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
+++ b/src/bluetooth/android/devicediscoverybroadcastreceiver.cpp
@@ -45,6 +45,7 @@
#include "android/jni_android_p.h"
#include <QtCore/private/qjnihelpers_p.h>
#include <QtCore/QHash>
+#include <QtCore/qbitarray.h>
QT_BEGIN_NAMESPACE
@@ -52,14 +53,187 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT_ANDROID)
typedef QHash<jint, QBluetoothDeviceInfo::CoreConfigurations> JCachedBtTypes;
Q_GLOBAL_STATIC(JCachedBtTypes, cachedBtTypes)
+typedef QHash<jint, QBluetoothDeviceInfo::MajorDeviceClass> JCachedMajorTypes;
+Q_GLOBAL_STATIC(JCachedMajorTypes, cachedMajorTypes)
-// class name
+typedef QHash<jint, quint8> JCachedMinorTypes;
+Q_GLOBAL_STATIC(JCachedMinorTypes, cachedMinorTypes)
+
+static QBitArray initializeMinorCaches()
+{
+ const int numberOfMajorDeviceClasses = 11; // count QBluetoothDeviceInfo::MajorDeviceClass values
+
+ // switch below used to ensure that we notice additions to MajorDeviceClass enum
+ const QBluetoothDeviceInfo::MajorDeviceClass classes = QBluetoothDeviceInfo::ComputerDevice;
+ switch (classes) {
+ case QBluetoothDeviceInfo::MiscellaneousDevice:
+ case QBluetoothDeviceInfo::ComputerDevice:
+ case QBluetoothDeviceInfo::PhoneDevice:
+ case QBluetoothDeviceInfo::LANAccessDevice:
+ case QBluetoothDeviceInfo::AudioVideoDevice:
+ case QBluetoothDeviceInfo::PeripheralDevice:
+ case QBluetoothDeviceInfo::ImagingDevice:
+ case QBluetoothDeviceInfo::WearableDevice:
+ case QBluetoothDeviceInfo::ToyDevice:
+ case QBluetoothDeviceInfo::HealthDevice:
+ case QBluetoothDeviceInfo::UncategorizedDevice:
+ break;
+ default:
+ qCWarning(QT_BT_ANDROID) << "Unknown category of major device class:" << classes;
+ }
+
+ return QBitArray(numberOfMajorDeviceClasses, false);
+}
+
+Q_GLOBAL_STATIC_WITH_ARGS(QBitArray, initializedCacheTracker, (initializeMinorCaches()))
+
+
+// class names
static const char * const javaBluetoothDeviceClassName = "android/bluetooth/BluetoothDevice";
+static const char * const javaBluetoothClassDeviceMajorClassName = "android/bluetooth/BluetoothClass$Device$Major";
+static const char * const javaBluetoothClassDeviceClassName = "android/bluetooth/BluetoothClass$Device";
+
+// field names device type (LE vs classic)
static const char * const javaDeviceTypeClassic = "DEVICE_TYPE_CLASSIC";
static const char * const javaDeviceTypeDual = "DEVICE_TYPE_DUAL";
static const char * const javaDeviceTypeLE = "DEVICE_TYPE_LE";
static const char * const javaDeviceTypeUnknown = "DEVICE_TYPE_UNKNOWN";
+struct MajorClassJavaToQtMapping
+{
+ char const * javaFieldName;
+ QBluetoothDeviceInfo::MajorDeviceClass qtMajor;
+};
+
+static const MajorClassJavaToQtMapping majorMappings[] = {
+ { "AUDIO_VIDEO", QBluetoothDeviceInfo::AudioVideoDevice },
+ { "COMPUTER", QBluetoothDeviceInfo::ComputerDevice },
+ { "HEALTH", QBluetoothDeviceInfo::HealthDevice },
+ { "IMAGING", QBluetoothDeviceInfo::ImagingDevice },
+ { "MISC", QBluetoothDeviceInfo::MiscellaneousDevice },
+ { "NETWORKING", QBluetoothDeviceInfo::LANAccessDevice },
+ { "PERIPHERAL", QBluetoothDeviceInfo::PeripheralDevice },
+ { "PHONE", QBluetoothDeviceInfo::PhoneDevice },
+ { "TOY", QBluetoothDeviceInfo::ToyDevice },
+ { "UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedDevice },
+ { "WEARABLE", QBluetoothDeviceInfo::WearableDevice },
+ { Q_NULLPTR, QBluetoothDeviceInfo::UncategorizedDevice } //end of list
+};
+
+// QBluetoothDeviceInfo::MajorDeviceClass value plus 1 matches index
+// UncategorizedDevice shifts to index 0
+static const int minorIndexSizes[] = {
+ 64, // QBluetoothDevice::UncategorizedDevice
+ 61, // QBluetoothDevice::MiscellaneousDevice
+ 18, // QBluetoothDevice::ComputerDevice
+ 35, // QBluetoothDevice::PhoneDevice
+ 62, // QBluetoothDevice::LANAccessDevice
+ 0, // QBluetoothDevice::AudioVideoDevice
+ 56, // QBluetoothDevice::PeripheralDevice
+ 63, // QBluetoothDevice::ImagingDEvice
+ 49, // QBluetoothDevice::WearableDevice
+ 42, // QBluetoothDevice::ToyDevice
+ 26, // QBluetoothDevice::HealthDevice
+};
+
+struct MinorClassJavaToQtMapping
+{
+ char const * javaFieldName;
+ quint8 qtMinor;
+};
+
+static const MinorClassJavaToQtMapping minorMappings[] = {
+ // QBluetoothDevice::AudioVideoDevice -> 17 entries
+ { "AUDIO_VIDEO_CAMCORDER", QBluetoothDeviceInfo::Camcorder }, //index 0
+ { "AUDIO_VIDEO_CAR_AUDIO", QBluetoothDeviceInfo::CarAudio },
+ { "AUDIO_VIDEO_HANDSFREE", QBluetoothDeviceInfo::HandsFreeDevice },
+ { "AUDIO_VIDEO_HEADPHONES", QBluetoothDeviceInfo::Headphones },
+ { "AUDIO_VIDEO_HIFI_AUDIO", QBluetoothDeviceInfo::HiFiAudioDevice },
+ { "AUDIO_VIDEO_LOUDSPEAKER", QBluetoothDeviceInfo::Loudspeaker },
+ { "AUDIO_VIDEO_MICROPHONE", QBluetoothDeviceInfo::Microphone },
+ { "AUDIO_VIDEO_PORTABLE_AUDIO", QBluetoothDeviceInfo::PortableAudioDevice },
+ { "AUDIO_VIDEO_SET_TOP_BOX", QBluetoothDeviceInfo::SetTopBox },
+ { "AUDIO_VIDEO_UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedAudioVideoDevice },
+ { "AUDIO_VIDEO_VCR", QBluetoothDeviceInfo::Vcr },
+ { "AUDIO_VIDEO_VIDEO_CAMERA", QBluetoothDeviceInfo::VideoCamera },
+ { "AUDIO_VIDEO_VIDEO_CONFERENCING", QBluetoothDeviceInfo::VideoConferencing },
+ { "AUDIO_VIDEO_VIDEO_DISPLAY_AND_LOUDSPEAKER", QBluetoothDeviceInfo::VideoDisplayAndLoudspeaker },
+ { "AUDIO_VIDEO_VIDEO_GAMING_TOY", QBluetoothDeviceInfo::GamingDevice },
+ { "AUDIO_VIDEO_VIDEO_MONITOR", QBluetoothDeviceInfo::VideoMonitor },
+ { "AUDIO_VIDEO_WEARABLE_HEADSET", QBluetoothDeviceInfo::WearableHeadsetDevice },
+ { Q_NULLPTR, 0 }, // separator
+
+ // QBluetoothDevice::ComputerDevice -> 7 entries
+ { "COMPUTER_UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedComputer }, // index 18
+ { "COMPUTER_DESKTOP", QBluetoothDeviceInfo::DesktopComputer },
+ { "COMPUTER_HANDHELD_PC_PDA", QBluetoothDeviceInfo::HandheldComputer },
+ { "COMPUTER_LAPTOP", QBluetoothDeviceInfo::LaptopComputer },
+ { "COMPUTER_PALM_SIZE_PC_PDA", QBluetoothDeviceInfo::HandheldClamShellComputer },
+ { "COMPUTER_SERVER", QBluetoothDeviceInfo::ServerComputer },
+ { "COMPUTER_WEARABLE", QBluetoothDeviceInfo::WearableComputer },
+ { Q_NULLPTR, 0 }, // separator
+
+ // QBluetoothDevice::HealthDevice -> 8 entries
+ { "HEALTH_BLOOD_PRESSURE", QBluetoothDeviceInfo::HealthBloodPressureMonitor }, // index 26
+ { "HEALTH_DATA_DISPLAY", QBluetoothDeviceInfo::HealthDataDisplay },
+ { "HEALTH_GLUCOSE", QBluetoothDeviceInfo::HealthGlucoseMeter },
+ { "HEALTH_PULSE_OXIMETER", QBluetoothDeviceInfo::HealthPulseOximeter },
+ { "HEALTH_PULSE_RATE", QBluetoothDeviceInfo::HealthStepCounter },
+ { "HEALTH_THERMOMETER", QBluetoothDeviceInfo::HealthThermometer },
+ { "HEALTH_UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedHealthDevice },
+ { "HEALTH_WEIGHING", QBluetoothDeviceInfo::HealthWeightScale },
+ { Q_NULLPTR, 0 }, // separator
+
+ // QBluetoothDevice::PhoneDevice -> 6 entries
+ { "PHONE_CELLULAR", QBluetoothDeviceInfo::CellularPhone }, // index 35
+ { "PHONE_CORDLESS", QBluetoothDeviceInfo::CordlessPhone },
+ { "PHONE_ISDN", QBluetoothDeviceInfo::CommonIsdnAccessPhone },
+ { "PHONE_MODEM_OR_GATEWAY", QBluetoothDeviceInfo::WiredModemOrVoiceGatewayPhone },
+ { "PHONE_SMART", QBluetoothDeviceInfo::SmartPhone },
+ { "PHONE_UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedPhone },
+ { Q_NULLPTR, 0 }, // separator
+
+ // QBluetoothDevice::ToyDevice -> 6 entries
+ { "TOY_CONTROLLER", QBluetoothDeviceInfo::ToyController }, // index 42
+ { "TOY_DOLL_ACTION_FIGURE", QBluetoothDeviceInfo::ToyDoll },
+ { "TOY_GAME", QBluetoothDeviceInfo::ToyGame },
+ { "TOY_ROBOT", QBluetoothDeviceInfo::ToyRobot },
+ { "TOY_UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedToy },
+ { "TOY_VEHICLE", QBluetoothDeviceInfo::ToyVehicle },
+ { Q_NULLPTR, 0 }, // separator
+
+ // QBluetoothDevice::WearableDevice -> 6 entries
+ { "WEARABLE_GLASSES", QBluetoothDeviceInfo::WearableGlasses }, // index 49
+ { "WEARABLE_HELMET", QBluetoothDeviceInfo::WearableHelmet },
+ { "WEARABLE_JACKET", QBluetoothDeviceInfo::WearableJacket },
+ { "WEARABLE_PAGER", QBluetoothDeviceInfo::WearablePager },
+ { "WEARABLE_UNCATEGORIZED", QBluetoothDeviceInfo::UncategorizedWearableDevice },
+ { "WEARABLE_WRIST_WATCH", QBluetoothDeviceInfo::WearableWristWatch },
+ { Q_NULLPTR, 0 }, // separator
+
+ // QBluetoothDevice::PeripheralDevice -> 3 entries
+ // For some reason these are not mentioned in Android docs but still exist
+ { "PERIPHERAL_NON_KEYBOARD_NON_POINTING", QBluetoothDeviceInfo::UncategorizedPeripheral }, // index 56
+ { "PERIPHERAL_KEYBOARD", QBluetoothDeviceInfo::KeyboardPeripheral },
+ { "PERIPHERAL_POINTING", QBluetoothDeviceInfo::PointingDevicePeripheral },
+ { "PERIPHERAL_KEYBOARD_POINTING", QBluetoothDeviceInfo::KeyboardWithPointingDevicePeripheral },
+ { Q_NULLPTR, 0 }, // separator
+
+ // the following entries do not exist on Android
+ // we map them to the unknown minor version case
+ // QBluetoothDevice::Miscellaneous
+ { Q_NULLPTR, 0 }, // index 61 & separator
+
+ // QBluetoothDevice::LANAccessDevice
+ { Q_NULLPTR, 0 }, // index 62 & separator
+
+ // QBluetoothDevice::ImagingDevice
+ { Q_NULLPTR, 0 }, // index 63 & separator
+
+ // QBluetoothDevice::UncategorizedDevice
+ { Q_NULLPTR, 0 }, // index 64 & separator
+};
+
QBluetoothDeviceInfo::CoreConfigurations qtBtTypeForJavaBtType(jint javaType)
{
const JCachedBtTypes::iterator it = cachedBtTypes()->find(javaType);
@@ -86,6 +260,10 @@ QBluetoothDeviceInfo::CoreConfigurations qtBtTypeForJavaBtType(jint javaType)
cachedBtTypes()->insert(javaType,
QBluetoothDeviceInfo::UnknownCoreConfiguration);
} else {
+ if (env->ExceptionCheck()) {
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
qCWarning(QT_BT_ANDROID) << "Unknown Bluetooth device type value";
}
@@ -95,6 +273,106 @@ QBluetoothDeviceInfo::CoreConfigurations qtBtTypeForJavaBtType(jint javaType)
}
}
+QBluetoothDeviceInfo::MajorDeviceClass resolveAndroidMajorClass(jint javaType)
+{
+ QAndroidJniEnvironment env;
+
+ const JCachedMajorTypes::iterator it = cachedMajorTypes()->find(javaType);
+ if (it == cachedMajorTypes()->end()) {
+ QAndroidJniEnvironment env;
+ // precache all major device class fields
+ int i = 0;
+ jint fieldValue;
+ QBluetoothDeviceInfo::MajorDeviceClass result = QBluetoothDeviceInfo::UncategorizedDevice;
+ while (majorMappings[i].javaFieldName != Q_NULLPTR) {
+ fieldValue = QAndroidJniObject::getStaticField<jint>(
+ javaBluetoothClassDeviceMajorClassName, majorMappings[i].javaFieldName);
+ if (env->ExceptionCheck()) {
+ qCWarning(QT_BT_ANDROID) << "Unknown BluetoothClass.Device.Major field" << javaType;
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+
+ // add fallback value because field not readable
+ cachedMajorTypes()->insert(javaType, QBluetoothDeviceInfo::UncategorizedDevice);
+ } else {
+ cachedMajorTypes()->insert(fieldValue, majorMappings[i].qtMajor);
+ }
+
+ if (fieldValue == javaType)
+ result = majorMappings[i].qtMajor;
+
+ i++;
+ }
+
+ return result;
+ } else {
+ return it.value();
+ }
+}
+
+/*
+ The index for major into the MinorClassJavaToQtMapping and initializedCacheTracker
+ is major+1 except for UncategorizedDevice which is at index 0.
+*/
+int mappingIndexForMajor(QBluetoothDeviceInfo::MajorDeviceClass major)
+{
+ int mappingIndex = (int) major;
+ if (major == QBluetoothDeviceInfo::UncategorizedDevice)
+ mappingIndex = 0;
+ else
+ mappingIndex++;
+
+ Q_ASSERT(mappingIndex >=0
+ && mappingIndex <= (QBluetoothDeviceInfo::HealthDevice + 1));
+
+ return mappingIndex;
+}
+
+void triggerCachingOfMinorsForMajor(QBluetoothDeviceInfo::MajorDeviceClass major)
+{
+ //qCDebug(QT_BT_ANDROID) << "Caching minor values for major" << major;
+ int mappingIndex = mappingIndexForMajor(major);
+ int sizeIndex = minorIndexSizes[mappingIndex];
+ QAndroidJniEnvironment env;
+
+ while (minorMappings[sizeIndex].javaFieldName != Q_NULLPTR) {
+ jint fieldValue = QAndroidJniObject::getStaticField<jint>(
+ javaBluetoothClassDeviceClassName, minorMappings[sizeIndex].javaFieldName);
+ if (env->ExceptionCheck()) { // field lookup failed? skip it
+ env->ExceptionDescribe();
+ env->ExceptionClear();
+ }
+
+ Q_ASSERT(fieldValue >= 0);
+ cachedMinorTypes()->insert(fieldValue, minorMappings[sizeIndex].qtMinor);
+ sizeIndex++;
+ }
+
+ initializedCacheTracker()->setBit(mappingIndex);
+}
+
+quint8 resolveAndroidMinorClass(QBluetoothDeviceInfo::MajorDeviceClass major, jint javaMinor)
+{
+ // there are no minor device classes in java with value 0
+ //qCDebug(QT_BT_ANDROID) << "received minor class device:" << javaMinor;
+ if (javaMinor == 0)
+ return 0;
+
+ int mappingIndex = mappingIndexForMajor(major);
+
+ // whenever we encounter a not yet seen major device class
+ // we populate the cache with all its related minor values
+ if (!initializedCacheTracker()->at(mappingIndex))
+ triggerCachingOfMinorsForMajor(major);
+
+ const JCachedMinorTypes::iterator it = cachedMinorTypes()->find(javaMinor);
+ if (it == cachedMinorTypes()->end())
+ return 0;
+ else
+ return it.value();
+}
+
+
DeviceDiscoveryBroadcastReceiver::DeviceDiscoveryBroadcastReceiver(QObject* parent): AndroidBroadcastReceiver(parent)
{
addAction(valueForStaticField(JavaNames::BluetoothDevice, JavaNames::ActionFound));
@@ -168,10 +446,19 @@ QBluetoothDeviceInfo DeviceDiscoveryBroadcastReceiver::retrieveDeviceInfo(JNIEnv
"()Landroid/bluetooth/BluetoothClass;");
if (!bluetoothClass.isValid())
return QBluetoothDeviceInfo();
- int classType = bluetoothClass.callMethod<jint>("getDeviceClass");
+ QBluetoothDeviceInfo::MajorDeviceClass majorClass = resolveAndroidMajorClass(
+ bluetoothClass.callMethod<jint>("getMajorDeviceClass"));
+ // major device class is 5 bits from index 8 - 12
+ quint32 classType = ((quint32(majorClass) & 0x1f) << 8);
+
+ jint javaMinor = bluetoothClass.callMethod<jint>("getDeviceClass");
+ quint8 minorDeviceType = resolveAndroidMinorClass(majorClass, javaMinor);
+
+ // minor device class is 6 bits from index 2 - 7
+ classType |= ((quint32(minorDeviceType) & 0x3f) << 2);
- static QList<qint32> services;
+ static QList<quint32> services;
if (services.count() == 0)
services << QBluetoothDeviceInfo::PositioningService
<< QBluetoothDeviceInfo::NetworkingService
@@ -182,18 +469,18 @@ QBluetoothDeviceInfo DeviceDiscoveryBroadcastReceiver::retrieveDeviceInfo(JNIEnv
<< QBluetoothDeviceInfo::TelephonyService
<< QBluetoothDeviceInfo::InformationService;
- //Matching BluetoothClass.Service values
- qint32 result = 0;
- qint32 current = 0;
+ // Matching BluetoothClass.Service values
+ quint32 serviceResult = 0;
+ quint32 current = 0;
for (int i = 0; i < services.count(); i++) {
current = services.at(i);
- int id = (current << 16);
- if (bluetoothClass.callMethod<jboolean>("hasService", "(I)Z", id))
- result |= current;
+ int androidId = (current << 16); // Android values shift by 2 bytes compared to Qt enums
+ if (bluetoothClass.callMethod<jboolean>("hasService", "(I)Z", androidId))
+ serviceResult |= current;
}
- result = result << 13;
- classType |= result;
+ // service class info is 11 bits from index 13 - 23
+ classType |= (serviceResult << 13);
QBluetoothDeviceInfo info(deviceAddress, deviceName, classType);
info.setRssi(rssi);
diff --git a/src/bluetooth/doc/src/bluetooth-index.qdoc b/src/bluetooth/doc/src/bluetooth-index.qdoc
index f110179f..b168cd2d 100644
--- a/src/bluetooth/doc/src/bluetooth-index.qdoc
+++ b/src/bluetooth/doc/src/bluetooth-index.qdoc
@@ -35,7 +35,7 @@ The Bluetooth API provides connectivity between Bluetooth enabled devices.
Currently, the API is supported on the following platforms: \l{Qt for Android}{Android},
\l{Qt for iOS}{iOS}, \l{Qt for Linux/X11}{Linux}
-(\l{http://www.bluez.org}{BlueZ 4.x/5.x}) and \l{Qt for OS X}{OS X}.
+(\l{http://www.bluez.org}{BlueZ 4.x/5.x}) and \l{Qt for macOS}{\macos}.
\section1 Overview
@@ -114,7 +114,7 @@ The \l QtBluetooth module exports the following
\li Enables logging of the iOS implementation
\row
\li qt.bluetooth.osx
- \li Enables logging of the OS X implementation
+ \li Enables logging of the \macos implementation
\endtable
\section2 Examples
diff --git a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
index 5f163dfd..be9a4e31 100644
--- a/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
+++ b/src/bluetooth/qbluetoothdevicediscoveryagent_android.cpp
@@ -227,6 +227,11 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processDiscoveredDevices(
Q_Q(QBluetoothDeviceDiscoveryAgent);
+ // Android Classic scan and LE scan can find the same device under different names
+ // The classic name finds the SDP based device name, the LE scan finds the name in
+ // the advertisement package.
+ // If address is same but name different then we keep both entries.
+
for (int i = 0; i < discoveredDevices.size(); i++) {
if (discoveredDevices[i].address() == info.address()) {
if (discoveredDevices[i] == info) {
@@ -235,11 +240,13 @@ void QBluetoothDeviceDiscoveryAgentPrivate::processDiscoveredDevices(
return;
}
- // same device found -> avoid duplicates and update core configuration
- discoveredDevices[i].setCoreConfigurations(discoveredDevices[i].coreConfigurations() | info.coreConfigurations());
-
- emit q->deviceDiscovered(info);
- return;
+ if (discoveredDevices.at(i).name() == info.name()) {
+ qCDebug(QT_BT_ANDROID) << "Almost Duplicate "<< info.address()
+ << info.name() << "- replacing in place";
+ discoveredDevices.replace(i, info);
+ emit q->deviceDiscovered(info);
+ return;
+ }
}
}
diff --git a/src/bluetooth/qbluetoothdeviceinfo.cpp b/src/bluetooth/qbluetoothdeviceinfo.cpp
index 41f77153..f068963e 100644
--- a/src/bluetooth/qbluetoothdeviceinfo.cpp
+++ b/src/bluetooth/qbluetoothdeviceinfo.cpp
@@ -316,7 +316,7 @@ QBluetoothDeviceInfo::QBluetoothDeviceInfo(const QBluetoothAddress &address, con
Constructs a QBluetoothDeviceInfo object with unique \a uuid, device name
\a name and the encoded class of device \a classOfDevice.
- This constructor is required for Low Energy devices on OS X and iOS. CoreBluetooth
+ This constructor is required for Low Energy devices on \macos and iOS. CoreBluetooth
API hides addresses and provides unique UUIDs to identify a device. This UUID is
not the same thing as a service UUID and is required to work later with CoreBluetooth API
and discovered devices.
@@ -460,7 +460,7 @@ bool QBluetoothDeviceInfo::operator!=(const QBluetoothDeviceInfo &other) const
/*!
Returns the address of the device.
- \note On iOS and OS X this address is invalid. Instead \l deviceUuid() should be used.
+ \note On iOS and \macos this address is invalid. Instead \l deviceUuid() should be used.
Those two platforms do not expose Bluetooth addresses for found Bluetooth devices
and utilize unique device identifiers.
@@ -613,7 +613,7 @@ void QBluetoothDeviceInfo::setCached(bool cached)
/*!
Sets the unique identifier \a uuid for Bluetooth devices, that do not have addresses.
- This happens on OS X and iOS, where the CoreBluetooth API hides addresses, but provides
+ This happens on \macos and iOS, where the CoreBluetooth API hides addresses, but provides
UUIDs to identify devices/peripherals.
This uuid is invalid on any other platform.
@@ -631,7 +631,7 @@ void QBluetoothDeviceInfo::setDeviceUuid(const QBluetoothUuid &uuid)
/*!
Returns a unique identifier for a Bluetooth device without an address.
- In general, this uuid is invalid on every platform but OS X and iOS.
+ In general, this uuid is invalid on every platform but \macos and iOS.
It is used as a workaround for those two platforms as they do not
provide Bluetooth addresses for found Bluetooth Low Energy devices.
Every other platform uses \l address() instead.
diff --git a/src/bluetooth/qbluetoothlocaldevice.cpp b/src/bluetooth/qbluetoothlocaldevice.cpp
index b2e2adcf..e2378460 100644
--- a/src/bluetooth/qbluetoothlocaldevice.cpp
+++ b/src/bluetooth/qbluetoothlocaldevice.cpp
@@ -99,7 +99,7 @@ QT_BEGIN_NAMESPACE
only made discoverable for a limited period of time. This can speed up discovery between gaming devices,
as service discovery can be skipped on devices not in LimitedInquiry mode. In this mode, the device will
be connectable and powered on, if required. This mode is is not supported on Android.
- On OS X, it is not possible to set the \l hostMode() to HostConnectable or HostPoweredOff.
+ On \macos, it is not possible to set the \l hostMode() to HostConnectable or HostPoweredOff.
*/
@@ -153,7 +153,7 @@ bool QBluetoothLocalDevice::isValid() const
\note Due to varying security policies on the supported platforms, this method may have
differing behaviors on the various platforms. For example the system may ask the user for
confirmation before turning Bluetooth on or off and not all host modes may be supported.
- On OS X, it is not possbile to programmatically change the \l hostMode().
+ On \macos, it is not possbile to programmatically change the \l hostMode().
A user can only switch Bluetooth on/off in the System Preferences.
Please refer to the platform specific Bluetooth documentation for details.
*/
@@ -161,7 +161,7 @@ bool QBluetoothLocalDevice::isValid() const
/*!
\fn QBluetoothLocalDevice::HostMode QBluetoothLocalDevice::hostMode() const
- Returns the current host mode of this local Bluetooth device. On OS X, it is either
+ Returns the current host mode of this local Bluetooth device. On \macos, it is either
HostPoweredOff or HostConnectable.
*/
@@ -184,7 +184,7 @@ bool QBluetoothLocalDevice::isValid() const
/*!
\fn QList<QBluetoothLocalDevice> QBluetoothLocalDevice::allDevices()
- Returns a list of all available local Bluetooth devices. On OS X, there is
+ Returns a list of all available local Bluetooth devices. On \macos, there is
only the "default" local device.
*/
@@ -196,7 +196,7 @@ bool QBluetoothLocalDevice::isValid() const
\note Due to varying security policies on the supported platforms, this method may have
differing behaviors on the various platforms. For example
the system may ask the user for confirmation before turning Bluetooth on or off.
- On OS X it is not possible to power on/off Bluetooth.
+ On \macos it is not possible to power on/off Bluetooth.
Please refer to the platform specific Bluetooth documentation for details.
*/
@@ -237,7 +237,7 @@ bool QBluetoothLocalDevice::isValid() const
Returns the list of connected devices. This list is different from the list of currently
paired devices.
- On Android and OS X, it is not possible to retrieve a list of connected devices. It is only possible to
+ On Android and \macos, it is not possible to retrieve a list of connected devices. It is only possible to
listen to (dis)connect changes. For convenience, this class monitors all connect
and disconnect events since its instanciation and returns the current list when calling this function.
Therefore it is possible that this function returns an empty list shortly after creating an
@@ -260,7 +260,7 @@ bool QBluetoothLocalDevice::isValid() const
must be called to indicate if the user accepts or rejects the displayed pin.
This signal is only emitted for pairing requests issues by calling \l requestPairing().
- On OS X, this method never gets called - there is a callback with a PIN (IOBluetooth),
+ On \macos, this method never gets called - there is a callback with a PIN (IOBluetooth),
but it expects immediate reply yes/no - and there is no time to show any dialog or compare PINs.
\sa pairingConfirmation()
@@ -288,9 +288,9 @@ bool QBluetoothLocalDevice::isValid() const
\fn QBluetoothLocalDevice::requestPairing(const QBluetoothAddress &address, Pairing pairing)
Set the \a pairing status with \a address. The results are returned by the signal, pairingFinished().
- On Android and OS X, AuthorizedPaired is not possible and will have the same behavior as Paired.
+ On Android and \macos, AuthorizedPaired is not possible and will have the same behavior as Paired.
- On OS X, it is not possible to unpair a device. If Unpaired is requested, \l pairingFinished()
+ On \macos, it is not possible to unpair a device. If Unpaired is requested, \l pairingFinished()
is immediately emitted although the device remains paired. It is possible to request the pairing
for a previously unpaired device. In addition \l AuthorizedPaired has the same behavior as \l Paired.
diff --git a/src/bluetooth/qbluetoothserver.cpp b/src/bluetooth/qbluetoothserver.cpp
index f2a87bd4..a27eb385 100644
--- a/src/bluetooth/qbluetoothserver.cpp
+++ b/src/bluetooth/qbluetoothserver.cpp
@@ -286,7 +286,7 @@ int QBluetoothServer::maxPendingConnections() const
\l QBluetooth::NoSecurity the server object will not employ any authentication or encryption.
Any other security flag combination will trigger a secure Bluetooth connection.
- On OS X, security flags are not supported and will be ignored.
+ On \macos, security flags are not supported and will be ignored.
*/
/*!
diff --git a/src/bluetooth/qbluetoothsocket.cpp b/src/bluetooth/qbluetoothsocket.cpp
index 8504ebd9..d396ca84 100644
--- a/src/bluetooth/qbluetoothsocket.cpp
+++ b/src/bluetooth/qbluetoothsocket.cpp
@@ -207,7 +207,7 @@ Q_DECLARE_LOGGING_CATEGORY(QT_BT)
Although some platforms may differ the socket must generally be connected to guarantee
the return of a valid port number.
- On Android and OS X, this feature is not supported and returns 0.
+ On Android and \macos, this feature is not supported and returns 0.
*/
/*!
@@ -338,6 +338,15 @@ void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, Op
}
d->connectToService(service.device().address(), service.serviceUuid(), openMode);
#else
+ // Report this problem early:
+ if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT) << "QBluetoothSocket::connectToService cannot "
+ "connect with 'UnknownProtocol' type";
+ d->errorString = tr("Socket type not supported");
+ setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
if (service.protocolServiceMultiplexer() > 0) {
if (!d->ensureNativeSocket(QBluetoothServiceInfo::L2capProtocol)) {
d->errorString = tr("Unknown socket error");
@@ -407,6 +416,15 @@ void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const
}
d->connectToService(address, uuid, openMode);
#else
+ // Report this problem early, prevent device discovery:
+ if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT) << "QBluetoothSocket::connectToService cannot "
+ "connect with 'UnknownProtocol' type";
+ d->errorString = tr("Socket type not supported");
+ setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
QBluetoothServiceInfo service;
QBluetoothDeviceInfo device(address, QString(), QBluetoothDeviceInfo::MiscellaneousDevice);
service.setDevice(device);
@@ -444,6 +462,15 @@ void QBluetoothSocket::connectToService(const QBluetoothAddress &address, quint1
setSocketError(QBluetoothSocket::ServiceNotFoundError);
qCWarning(QT_BT) << "Connecting to port is not supported";
#else
+ // Report this problem early:
+ if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT) << "QBluetoothSocket::connectToService cannot "
+ "connect with 'UnknownProtocol' type";
+ d->errorString = tr("Socket type not supported");
+ setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
if (state() != QBluetoothSocket::UnconnectedState) {
qCWarning(QT_BT) << "QBluetoothSocket::connectToService called on busy socket";
d->errorString = QBluetoothSocket::tr("Trying to connect while connection is in progress");
@@ -504,7 +531,7 @@ QString QBluetoothSocket::errorString() const
On Bluez this property is set to QBluetooth::Authorization by default.
- On OS X, this value is ignored as the platform does not permit access
+ On \macos, this value is ignored as the platform does not permit access
to the security parameter of the socket. By default the platform prefers
secure/encrypted connections though and therefore this function always
returns \l QBluetooth::Secure.
@@ -538,7 +565,7 @@ void QBluetoothSocket::setPreferredSecurityFlags(QBluetooth::SecurityFlags flags
during or after the connection has been established. If such a change happens
it is not reflected in the value of this flag.
- On OS X, this flag is always set to \l QBluetooth::Secure.
+ On \macos, this flag is always set to \l QBluetooth::Secure.
\sa setPreferredSecurityFlags()
diff --git a/src/bluetooth/qbluetoothsocket_osx.mm b/src/bluetooth/qbluetoothsocket_osx.mm
index b16a2cf9..69663e58 100644
--- a/src/bluetooth/qbluetoothsocket_osx.mm
+++ b/src/bluetooth/qbluetoothsocket_osx.mm
@@ -79,9 +79,6 @@ QBluetoothSocketPrivate::~QBluetoothSocketPrivate()
void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address, quint16 port,
QIODevice::OpenMode mode)
{
- // We have readwrite channels with IOBluetooth's channels.
- Q_UNUSED(openMode)
-
Q_ASSERT_X(state == QBluetoothSocket::ServiceLookupState
|| state == QBluetoothSocket::UnconnectedState,
Q_FUNC_INFO, "invalid state");
@@ -92,7 +89,7 @@ void QBluetoothSocketPrivate::connectToService(const QBluetoothAddress &address,
txBuffer.clear();
IOReturn status = kIOReturnError;
- // Set socket state on q_ptr will emit a signal,
+ // Setting socket state on q_ptr will emit a signal,
// we'd like to avoid any signal until this function completes.
const QBluetoothSocket::SocketState oldState = state;
// To prevent other connectToService calls (from QBluetoothSocket):
@@ -446,6 +443,14 @@ qint64 QBluetoothSocket::bytesToWrite() const
void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, OpenMode openMode)
{
+ // Report this problem early, potentially avoid device discovery:
+ if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
+ d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
+ setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
if (state() != UnconnectedState && state() != ServiceLookupState) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "called on a busy socket";
d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
@@ -475,6 +480,14 @@ void QBluetoothSocket::connectToService(const QBluetoothServiceInfo &service, Op
void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const QBluetoothUuid &uuid,
OpenMode openMode)
{
+ // Report this problem early, avoid device discovery:
+ if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
+ d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
+ setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
if (state() != QBluetoothSocket::UnconnectedState) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "called on a busy socket";
d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
@@ -492,6 +505,13 @@ void QBluetoothSocket::connectToService(const QBluetoothAddress &address, const
void QBluetoothSocket::connectToService(const QBluetoothAddress &address, quint16 port,
OpenMode openMode)
{
+ if (socketType() == QBluetoothServiceInfo::UnknownProtocol) {
+ qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "cannot connect with 'UnknownProtocol' type";
+ d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_NETWORK_ERROR);
+ setSocketError(QBluetoothSocket::UnsupportedProtocolError);
+ return;
+ }
+
if (state() != QBluetoothSocket::UnconnectedState) {
qCWarning(QT_BT_OSX) << Q_FUNC_INFO << "called on a busy socket";
d_ptr->errorString = QCoreApplication::translate(SOCKET, SOC_CONNECT_IN_PROGRESS);
diff --git a/src/bluetooth/qlowenergycharacteristic.cpp b/src/bluetooth/qlowenergycharacteristic.cpp
index b5b126a5..a8b4c449 100644
--- a/src/bluetooth/qlowenergycharacteristic.cpp
+++ b/src/bluetooth/qlowenergycharacteristic.cpp
@@ -218,7 +218,7 @@ QByteArray QLowEnergyCharacteristic::value() const
or \c 0 if the handle cannot be accessed on the platform or
if the characteristic is invalid.
- \note On OS X and iOS handles can differ from 0, but these
+ \note On \macos and iOS handles can differ from 0, but these
values have no special meaning outside of internal/private API.
*/
QLowEnergyHandle QLowEnergyCharacteristic::handle() const
@@ -320,7 +320,7 @@ bool QLowEnergyCharacteristic::isValid() const
\c 0 if the handle cannot be accessed on the platform or if the
characteristic is invalid.
- \note On OS X and iOS handles can differ from 0, but these
+ \note On \macos and iOS handles can differ from 0, but these
values have no special meaning outside of internal/private API.
\sa isValid()
diff --git a/src/bluetooth/qlowenergydescriptor.cpp b/src/bluetooth/qlowenergydescriptor.cpp
index 5df8d2d2..37a8f619 100644
--- a/src/bluetooth/qlowenergydescriptor.cpp
+++ b/src/bluetooth/qlowenergydescriptor.cpp
@@ -226,7 +226,7 @@ QBluetoothUuid QLowEnergyDescriptor::uuid() const
Returns the handle of the descriptor or \c 0 if the handle
cannot be accessed on the platform or the descriptor is invalid.
- \note On OS X and iOS handles can differ from 0, but these
+ \note On \macos and iOS handles can differ from 0, but these
values have no special meaning outside of internal/private API.
*/
QLowEnergyHandle QLowEnergyDescriptor::handle() const