summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java28
-rw-r--r--src/bluetooth/qlowenergyconnectionparameters.cpp29
-rw-r--r--src/bluetooth/qlowenergycontroller.cpp30
-rw-r--r--src/bluetooth/qlowenergycontroller_android.cpp22
4 files changed, 100 insertions, 9 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java
index 3348e4de..53c7305f 100644
--- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java
+++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLE.java
@@ -52,6 +52,7 @@ import android.os.Handler;
import android.os.Looper;
import android.util.Log;
import java.util.concurrent.atomic.AtomicInteger;
+import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Hashtable;
@@ -60,6 +61,7 @@ import java.util.List;
import java.util.NoSuchElementException;
import java.util.UUID;
+
public class QtBluetoothLE {
private static final String TAG = "QtBluetoothGatt";
private final BluetoothAdapter mBluetoothAdapter;
@@ -1282,6 +1284,32 @@ public class QtBluetoothLE {
return modifiedHandle;
}
+ // Directly called from public Qt API
+ public boolean requestConnectionUpdatePriority(double minimalInterval)
+ {
+ if (mBluetoothGatt == null)
+ return false;
+
+ try {
+ //Android API v21
+ Method connectionUpdateMethod = mBluetoothGatt.getClass().getDeclaredMethod(
+ "requestConnectionPriority", int.class);
+ if (connectionUpdateMethod == null)
+ return false;
+
+ int requestPriority = 0; // BluetoothGatt.CONNECTION_PRIORITY_BALANCED
+ if (minimalInterval < 30)
+ requestPriority = 1; // BluetoothGatt.CONNECTION_PRIORITY_HIGH
+ else if (minimalInterval > 100)
+ requestPriority = 2; //BluetoothGatt/CONNECTION_PRIORITY_LOW_POWER
+
+ Object result = connectionUpdateMethod.invoke(mBluetoothGatt, requestPriority);
+ return (Boolean) result;
+ } catch (Exception ex) {
+ return false;
+ }
+ }
+
public native void leConnectionStateChange(long qtObject, int wasErrorTransition, int newState);
public native void leServicesDiscovered(long qtObject, int errorCode, String uuidList);
public native void leServiceDetailDiscoveryFinished(long qtObject, final String serviceUuid,
diff --git a/src/bluetooth/qlowenergyconnectionparameters.cpp b/src/bluetooth/qlowenergyconnectionparameters.cpp
index af4502dd..95256402 100644
--- a/src/bluetooth/qlowenergyconnectionparameters.cpp
+++ b/src/bluetooth/qlowenergyconnectionparameters.cpp
@@ -68,6 +68,32 @@ public:
with each other. In general, a lower connection interval and latency means faster communication,
but also higher power consumption. How these criteria should be weighed against each other
is highly dependent on the concrete use case.
+
+ Android only indirectly permits the adjustment of this parameter set.
+ The platform separates the connection parameters into three categories (hight, low & balanced
+ priority). Each category implies a predefined set of values for \l minimumInterval(),
+ \l maximumInterval() and \l latency(). Additionally, the value ranges of each category can vary
+ from one Android device to the next. Qt uses the \l minimumInterval() to determine the target
+ category as follows:
+
+ \table
+ \header
+ \li minimumInterval()
+ \li Android priority
+ \row
+ \li interval < 30
+ \li CONNECTION_PRIORITY_HIGH
+ \row
+ \li 30 <= interval <= 100
+ \li CONNECTION_PRIORITY_BALANCED
+ \row
+ \li interval > 100
+ \li CONNECTION_PRIORITY_LOW_POWER
+ \endtable
+
+ The \l supervisionTimeout() cannot be changed on Android and is therefore ignored.
+
+
\inmodule QtBluetooth
\ingroup shared
@@ -163,6 +189,9 @@ int QLowEnergyConnectionParameters::latency() const
Sets the link supervision timeout to \a timeout milliseconds.
There are several constraints on this value: It must be in the range [100,32000] and it must be
larger than (1 + \l latency()) * 2 * \l maximumInterval().
+
+ On Android, this timeout is not adjustable and therefore ignored.
+
\sa supervisionTimeout()
*/
void QLowEnergyConnectionParameters::setSupervisionTimeout(int timeout)
diff --git a/src/bluetooth/qlowenergycontroller.cpp b/src/bluetooth/qlowenergycontroller.cpp
index 13077d7d..6a9b50a0 100644
--- a/src/bluetooth/qlowenergycontroller.cpp
+++ b/src/bluetooth/qlowenergycontroller.cpp
@@ -968,19 +968,35 @@ QLowEnergyService *QLowEnergyController::addService(const QLowEnergyServiceData
/*!
Requests the controller to update the connection according to \a parameters.
If the request is successful, the \l connectionUpdated() signal will be emitted
- with the actual new parameters.
- See the \l QLowEnergyConnectionParameters class for more information on connection parameters.
- \note Currently, this functionality is only implemented on Linux.
-
+ with the actual new parameters. See the \l QLowEnergyConnectionParameters class for more
+ information on connection parameters.
+
+ Android only indirectly permits the adjustment of this parameter set.
+ The connection parameters are separated into three categories (high, low & balanced priority).
+ Each category implies a pre-configured set of values for
+ \l QLowEnergyConnectionParameters::minimumInterval(),
+ \l QLowEnergyConnectionParameters::maximumInterval() and
+ \l QLowEnergyConnectionParameters::latency(). Although the connection request is an asynchronous
+ operation, Android does not provide a callback stating the result of the request. This is
+ an acknowledged Android bug. Due to this bug Android does not emit the \l connectionUpdated()
+ signal.
+
+ \note Currently, this functionality is only implemented on Linux and Android.
+
+ \sa connectionUpdated()
\since 5.7
*/
void QLowEnergyController::requestConnectionUpdate(const QLowEnergyConnectionParameters &parameters)
{
- if (state() != ConnectedState) {
+ switch (state()) {
+ case ConnectedState:
+ case DiscoveredState:
+ case DiscoveringState:
+ d_ptr->requestConnectionUpdate(parameters);
+ break;
+ default:
qCWarning(QT_BT) << "Connection update request only possible in connected state";
- return;
}
- d_ptr->requestConnectionUpdate(parameters);
}
/*!
diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp
index 20b6519c..6cd1ced1 100644
--- a/src/bluetooth/qlowenergycontroller_android.cpp
+++ b/src/bluetooth/qlowenergycontroller_android.cpp
@@ -45,6 +45,7 @@
#include <QtBluetooth/QLowEnergyDescriptorData>
#include <QtBluetooth/QLowEnergyAdvertisingData>
#include <QtBluetooth/QLowEnergyAdvertisingParameters>
+#include <QtBluetooth/QLowEnergyConnectionParameters>
QT_BEGIN_NAMESPACE
@@ -771,8 +772,25 @@ void QLowEnergyControllerPrivate::stopAdvertising()
void QLowEnergyControllerPrivate::requestConnectionUpdate(const QLowEnergyConnectionParameters &params)
{
- Q_UNUSED(params);
- qCWarning(QT_BT_ANDROID) << "Connection update not implemented for Android";
+ // Possible since Android v21
+ // Android does not permit specification of specific latency or min/max
+ // connection intervals (see BluetoothGatt.requestConnectionPriority()
+ // In fact, each device manufacturer is permitted to change those values via a config
+ // file too. Therefore we can only make an approximated guess (see implementation below)
+ // In addition there is no feedback signal (known bug) from the hardware layer as per v24.
+
+ // TODO recheck in later Android releases whether callback for
+ // BluetoothGatt.requestConnectionPriority() was added
+
+ if (role != QLowEnergyController::CentralRole) {
+ qCWarning(QT_BT_ANDROID) << "On Android, connection requests only work for central role";
+ return;
+ }
+
+ bool result = hub->javaObject().callMethod<jboolean>("requestConnectionUpdatePriority",
+ "(D)Z", params.minimumInterval());
+ if (!result)
+ qCWarning(QT_BT_ANDROID) << "Cannot set connection update priority";
}
// Conversion: QBluetoothUuid -> java.util.UUID