Skip to content

Commit 2c5b148

Browse files
committed
New failure reason - PHY request fail (unsupported configuration)
1 parent 2c88f2f commit 2c5b148

File tree

3 files changed

+47
-3
lines changed

3 files changed

+47
-3
lines changed

ble/src/main/java/no/nordicsemi/android/ble/BleManagerHandler.java

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -180,6 +180,11 @@ abstract class BleManagerHandler extends RequestHandler {
180180
* Current connection parameters. Those values are only available starting from Android Oreo.
181181
*/
182182
private int interval, latency, timeout;
183+
/**
184+
* Samsung S8 with Android 9 fails to reconnect to devices requesting PHY LE 2M just after
185+
* connection. Workaround would be to disable PHY LE 2M on the device side.
186+
*/
187+
private boolean earlyPhyLe2MRequest;
183188
/**
184189
* Last received battery value or -1 if value wasn't received.
185190
*
@@ -753,6 +758,7 @@ private boolean internalConnect(@NonNull final BluetoothDevice device,
753758
postConnectionStateChange(o -> o.onDeviceConnecting(device));
754759
}
755760
connectionTime = SystemClock.elapsedRealtime();
761+
earlyPhyLe2MRequest = false;
756762
if (Build.VERSION.SDK_INT > Build.VERSION_CODES.O) {
757763
// connectRequest will never be null here.
758764
final int preferredPhy = connectRequest.getPreferredPhy();
@@ -2301,7 +2307,10 @@ public void onConnectionStateChange(@NonNull final BluetoothGatt gatt,
23012307
// ...because the next method sets them to false.
23022308

23032309
// notifyDeviceDisconnected(...) may call close()
2304-
if (timeout) {
2310+
2311+
if (status == GattError.GATT_CONN_TIMEOUT && earlyPhyLe2MRequest) {
2312+
notifyDeviceDisconnected(gatt.getDevice(), ConnectionObserver.REASON_UNSUPPORTED_CONFIGURATION);
2313+
} else if (timeout) {
23052314
notifyDeviceDisconnected(gatt.getDevice(), ConnectionObserver.REASON_TIMEOUT);
23062315
} else if (notSupported) {
23072316
notifyDeviceDisconnected(gatt.getDevice(), ConnectionObserver.REASON_NOT_SUPPORTED);
@@ -2332,7 +2341,9 @@ public void onConnectionStateChange(@NonNull final BluetoothGatt gatt,
23322341
}
23332342
if (cr != null) {
23342343
int reason;
2335-
if (notSupported)
2344+
if (status == GattError.GATT_CONN_TIMEOUT && earlyPhyLe2MRequest)
2345+
reason = FailCallback.REASON_UNSUPPORTED_CONFIGURATION;
2346+
else if (notSupported)
23362347
reason = FailCallback.REASON_DEVICE_NOT_SUPPORTED;
23372348
else if (status == BluetoothGatt.GATT_SUCCESS)
23382349
reason = FailCallback.REASON_DEVICE_DISCONNECTED;
@@ -2948,6 +2959,9 @@ public void onPhyUpdate(@NonNull final BluetoothGatt gatt,
29482959
log(Log.INFO, () ->
29492960
"PHY updated (TX: " + ParserUtils.phyToString(txPhy) +
29502961
", RX: " + ParserUtils.phyToString(rxPhy) + ")");
2962+
// Samsung S8 fails to reconnect when PHY LE 2M request is sent before service discovery.
2963+
earlyPhyLe2MRequest = earlyPhyLe2MRequest ||
2964+
(txPhy == BluetoothDevice.PHY_LE_2M && !servicesDiscovered);
29512965
if (request instanceof final PhyRequest pr) {
29522966
pr.notifyPhyChanged(gatt.getDevice(), txPhy, rxPhy);
29532967
pr.notifySuccess(gatt.getDevice());

ble/src/main/java/no/nordicsemi/android/ble/callback/FailCallback.java

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,19 +23,37 @@
2323
package no.nordicsemi.android.ble.callback;
2424

2525
import android.bluetooth.BluetoothDevice;
26+
import android.bluetooth.BluetoothGatt;
27+
import no.nordicsemi.android.ble.BleManager;
2628

2729
import androidx.annotation.NonNull;
2830

2931
@FunctionalInterface
3032
public interface FailCallback {
3133
int REASON_DEVICE_DISCONNECTED = -1;
34+
/**
35+
* Returned when the {@link BleManager#isRequiredServiceSupported(BluetoothGatt)}
36+
* returns false, that is when at least required GATT service was not discovered
37+
* on the connected device.
38+
*/
3239
int REASON_DEVICE_NOT_SUPPORTED = -2;
3340
int REASON_NULL_ATTRIBUTE = -3;
3441
int REASON_REQUEST_FAILED = -4;
3542
int REASON_TIMEOUT = -5;
3643
int REASON_VALIDATION = -6;
3744
int REASON_CANCELLED = -7;
3845
int REASON_NOT_ENABLED = -8;
46+
/**
47+
* The Android device is unable to reconnect to the peripheral because of internal failure.
48+
* Most probably it cannot respond properly to PHY LE 2M update procedure, causing the
49+
* remote device to terminate the connection.
50+
* <p>
51+
* Try disabling PHY LE 2M on the peripheral side, or update the Android version.
52+
* If that's not possible, the connection to your device may not work on the given
53+
* Android device at all. If the device is bonded, try removing bonding and connect,
54+
* but this seems to fix the problem only before a new bond is created.
55+
*/
56+
int REASON_UNSUPPORTED_CONFIGURATION = -9;
3957
int REASON_BLUETOOTH_DISABLED = -100;
4058

4159
/**
@@ -47,7 +65,8 @@ public interface FailCallback {
4765
* {@link #REASON_DEVICE_DISCONNECTED}, {@link #REASON_TIMEOUT},
4866
* {@link #REASON_DEVICE_NOT_SUPPORTED} (only for Connect request),
4967
* {@link #REASON_BLUETOOTH_DISABLED}, {@link #REASON_NULL_ATTRIBUTE},
50-
* {@link #REASON_VALIDATION}, {@link #REASON_CANCELLED}, {@link #REASON_NOT_ENABLED}
68+
* {@link #REASON_VALIDATION}, {@link #REASON_CANCELLED}, {@link #REASON_NOT_ENABLED},
69+
* {@link #REASON_UNSUPPORTED_CONFIGURATION},
5170
* or {@link #REASON_REQUEST_FAILED} (for other reason).
5271
*/
5372
void onRequestFailed(@NonNull final BluetoothDevice device, final int status);

ble/src/main/java/no/nordicsemi/android/ble/observer/ConnectionObserver.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -58,6 +58,17 @@ public interface ConnectionObserver {
5858
* or doesn't respond for another reason.
5959
*/
6060
int REASON_TIMEOUT = 10;
61+
/**
62+
* The Android device is unable to reconnect to the peripheral because of internal failure.
63+
* Most probably it cannot respond properly to PHY LE 2M update procedure, causing the
64+
* remote device to terminate the connection.
65+
* <p>
66+
* Try disabling PHY LE 2M on the peripheral side, or update the Android version.
67+
* If that's not possible, the connection to your device may not work on the given
68+
* Android device at all. If the device is bonded, try removing bonding and connect,
69+
* but this seems to fix the problem only before a new bond is created.
70+
*/
71+
int REASON_UNSUPPORTED_CONFIGURATION = 11;
6172

6273
/**
6374
* Called when the Android device started connecting to given device.

0 commit comments

Comments
 (0)