diff options
author | Alex Blasche <alexander.blasche@qt.io> | 2017-01-03 17:21:17 +0100 |
---|---|---|
committer | Alex Blasche <alexander.blasche@qt.io> | 2017-01-23 09:03:43 +0000 |
commit | d66b34100ad3e5ddd226ba85c4e974ad08e22205 (patch) | |
tree | c212ce7a0a30c9c94e17ec57986522b6186969b7 /src | |
parent | 46a776eb70d7b3e40bb80cb4f4314d3462801b62 (diff) |
Android: Implement QLEC::stateChanged() notification
Change-Id: Id2cabd9df7b5387fe5e6f1c898fe02e40f7c0a3d
Reviewed-by: Timur Pocheptsov <timur.pocheptsov@qt.io>
Reviewed-by: Alex Blasche <alexander.blasche@qt.io>
Diffstat (limited to 'src')
4 files changed, 92 insertions, 4 deletions
diff --git a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java index c4337660..685b9161 100644 --- a/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java +++ b/src/android/bluetooth/src/org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer.java @@ -45,9 +45,11 @@ import android.bluetooth.BluetoothGattDescriptor; import android.bluetooth.BluetoothGattService; import android.content.Context; import android.bluetooth.BluetoothAdapter; +import android.bluetooth.BluetoothGatt; import android.bluetooth.BluetoothGattServer; import android.bluetooth.BluetoothGattServerCallback; import android.bluetooth.BluetoothManager; +import android.bluetooth.BluetoothProfile; import android.bluetooth.le.AdvertiseCallback; import android.bluetooth.le.AdvertiseData; import android.bluetooth.le.AdvertiseData.Builder; @@ -105,7 +107,30 @@ public class QtBluetoothLEServer { { @Override public void onConnectionStateChange(BluetoothDevice device, int status, int newState) { + Log.w(TAG, "Our gatt server connection state changed, new state: " + Integer.toString(newState)); super.onConnectionStateChange(device, status, newState); + + int qtControllerState = 0; + switch (newState) { + case BluetoothProfile.STATE_DISCONNECTED: + qtControllerState = 0; // QLowEnergyController::UnconnectedState + break; + case BluetoothProfile.STATE_CONNECTED: + qtControllerState = 2; // QLowEnergyController::ConnectedState + break; + } + + int qtErrorCode; + switch (status) { + case BluetoothGatt.GATT_SUCCESS: + qtErrorCode = 0; break; + default: + Log.w(TAG, "Unhandled error code on peripheral connectionStateChanged: " + status + " " + newState); + qtErrorCode = status; + break; + } + + leServerConnectionStateChange(qtObject, qtErrorCode, qtControllerState); } @Override @@ -215,4 +240,6 @@ public class QtBluetoothLEServer { } }; + public native void leServerConnectionStateChange(long qtObject, int errorCode, int newState); + } diff --git a/src/bluetooth/android/jni_android.cpp b/src/bluetooth/android/jni_android.cpp index ae07608a..3cec0c64 100644 --- a/src/bluetooth/android/jni_android.cpp +++ b/src/bluetooth/android/jni_android.cpp @@ -227,6 +227,11 @@ static JNINativeMethod methods_le[] = { (void *) LowEnergyNotificationHub::lowEnergy_serviceError}, }; +static JNINativeMethod methods_leServer[] = { + {"leServerConnectionStateChange", "(JII)V", + (void *) LowEnergyNotificationHub::lowEnergy_connectionChange}, +}; + static JNINativeMethod methods_server[] = { {"errorOccurred", "(JI)V", (void *) QtBluetoothSocketServer_errorOccurred}, @@ -267,6 +272,11 @@ static bool registerNatives(JNIEnv *env) return false; } + FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/bluetooth/QtBluetoothLEServer"); + if (env->RegisterNatives(clazz, methods_leServer, sizeof(methods_leServer) / sizeof(methods_leServer[0])) < 0) { + __android_log_print(ANDROID_LOG_FATAL, logTag, "RegisterNatives for QBLuetoothLEServer failed"); + return false; + } FIND_AND_CHECK_CLASS("org/qtproject/qt5/android/bluetooth/QtBluetoothSocketServer"); if (env->RegisterNatives(clazz, methods_server, sizeof(methods_server) / sizeof(methods_server[0])) < 0) { diff --git a/src/bluetooth/qlowenergycontroller_android.cpp b/src/bluetooth/qlowenergycontroller_android.cpp index 613c2bed..8654fe71 100644 --- a/src/bluetooth/qlowenergycontroller_android.cpp +++ b/src/bluetooth/qlowenergycontroller_android.cpp @@ -86,6 +86,8 @@ void QLowEnergyControllerPrivate::init() hub = new LowEnergyNotificationHub(remoteDevice, isPeripheral, this); // we only connect to the peripheral role specific signals // TODO add connections as they get added later on + connect(hub, &LowEnergyNotificationHub::connectionUpdated, + this, &QLowEnergyControllerPrivate::connectionUpdated); } else { if (version < 18) { qWarning() << "Qt Bluetooth LE Central/Client support not available" @@ -341,14 +343,56 @@ void QLowEnergyControllerPrivate::connectionUpdated( QLowEnergyController::ControllerState newState, QLowEnergyController::Error errorCode) { - Q_Q(QLowEnergyController); - - const QLowEnergyController::ControllerState oldState = state; qCDebug(QT_BT_ANDROID) << "Connection updated:" << "error:" << errorCode - << "oldState:" << oldState + << "oldState:" << state << "newState:" << newState; + if (role == QLowEnergyController::PeripheralRole) + peripheralConnectionUpdated(newState, errorCode); + else + centralConnectionUpdated(newState, errorCode); +} + +// called if server/peripheral +void QLowEnergyControllerPrivate::peripheralConnectionUpdated( + QLowEnergyController::ControllerState newState, + QLowEnergyController::Error errorCode) +{ + // Java errorCode can be larger than max QLowEnergyController::Error + if (errorCode > QLowEnergyController::AdvertisingError) + errorCode = QLowEnergyController::UnknownError; + + if (errorCode != QLowEnergyController::NoError) + setError(errorCode); + + const QLowEnergyController::ControllerState oldState = state; + setState(newState); + + // disconnect implies stop of advertisement + if (newState == QLowEnergyController::UnconnectedState) + stopAdvertising(); + + + Q_Q(QLowEnergyController); + if (oldState == QLowEnergyController::ConnectedState + && newState != QLowEnergyController::ConnectedState) { + emit q->disconnected(); + } else if (newState == QLowEnergyController::ConnectedState + && oldState != QLowEnergyController::ConnectedState) { + emit q->connected(); + } +} + +// called if client/central +void QLowEnergyControllerPrivate::centralConnectionUpdated( + QLowEnergyController::ControllerState newState, + QLowEnergyController::Error errorCode) +{ + Q_Q(QLowEnergyController); + + const QLowEnergyController::ControllerState oldState = state; + if (errorCode != QLowEnergyController::NoError) { // ConnectionError if transition from Connecting to Connected if (oldState == QLowEnergyController::ConnectingState) { diff --git a/src/bluetooth/qlowenergycontroller_p.h b/src/bluetooth/qlowenergycontroller_p.h index 6375cdb3..cb781959 100644 --- a/src/bluetooth/qlowenergycontroller_p.h +++ b/src/bluetooth/qlowenergycontroller_p.h @@ -442,6 +442,13 @@ private slots: QLowEnergyService::ServiceError errorCode); void characteristicChanged(int charHandle, const QByteArray &data); void serviceError(int attributeHandle, QLowEnergyService::ServiceError errorCode); + +private: + void peripheralConnectionUpdated(QLowEnergyController::ControllerState newState, + QLowEnergyController::Error errorCode); + void centralConnectionUpdated(QLowEnergyController::ControllerState newState, + QLowEnergyController::Error errorCode); + #elif defined(QT_WINRT_BLUETOOTH) private slots: void characteristicChanged(int charHandle, const QByteArray &data); |