@@ -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 ());
0 commit comments