BT Classic: Fix connection

This commit is contained in:
José Rebelo
2025-06-26 20:26:27 +02:00
committed by José Rebelo
parent 453eaee4c1
commit 43116ade24
3 changed files with 50 additions and 40 deletions
@@ -621,12 +621,15 @@ public class DeviceCommunicationService extends Service implements SharedPrefere
}
if (gbDevs.isEmpty()) {
LOG.warn("No devices to connect to");
return;
}
for (final GBDevice gbDevice : gbDevs) {
final String deviceAddress = gbDevice.getAddress();
LOG.debug("Will attempt to connect to {}", gbDevice);
if (!gbDevice.getDeviceCoordinator().isConnectable()) {
// we cannot connect to beacons, skip this device
LOG.debug("connectToDevice - {} isn't connectable", deviceAddress);
@@ -33,6 +33,7 @@ import java.io.OutputStream;
import java.net.SocketTimeoutException;
import java.util.UUID;
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
import nodomain.freeyourgadget.gadgetbridge.deviceevents.GBDeviceEvent;
import nodomain.freeyourgadget.gadgetbridge.impl.GBDevice;
import nodomain.freeyourgadget.gadgetbridge.service.serial.AbstractSerialDeviceSupport;
@@ -55,18 +56,11 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
@Override
public void quit() {
mQuit = true;
if (mBtSocket != null) {
try {
mBtSocket.close();
} catch (IOException e) {
LOG.error(e.getMessage());
}
}
cleanup();
}
private boolean mIsConnected = false;
public BtClassicIoThread(GBDevice gbDevice, Context context, GBDeviceProtocol deviceProtocol, AbstractSerialDeviceSupport deviceSupport, BluetoothAdapter btAdapter) {
super(gbDevice, context);
mProtocol = deviceProtocol;
@@ -87,7 +81,7 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
mOutStream.write(bytes);
mOutStream.flush();
} catch (IOException e) {
LOG.error("Error writing.", e);
LOG.error("Error writing", e);
}
}
@@ -104,7 +98,7 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
LOG.info("Ready for a new message exchange.");
try {
GBDeviceEvent deviceEvents[] = mProtocol.decodeResponse(parseIncoming(mInStream));
GBDeviceEvent[] deviceEvents = mProtocol.decodeResponse(parseIncoming(mInStream));
if (deviceEvents == null) {
LOG.info("unhandled message");
} else {
@@ -118,25 +112,17 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
} catch (SocketTimeoutException ignore) {
LOG.debug("socket timeout, we can't help but ignore this");
} catch (IOException e) {
LOG.info(e.getMessage());
LOG.error("Bluetooth socket closed, will quit IO Thread", e);
mIsConnected = false;
mBtSocket = null;
mInStream = null;
mOutStream = null;
LOG.info("Bluetooth socket closed, will quit IO Thread");
break;
}
}
mIsConnected = false;
if (mBtSocket != null) {
try {
mBtSocket.close();
} catch (IOException e) {
LOG.error(e.getMessage());
}
mBtSocket = null;
}
cleanup();
setUpdateState(GBDevice.State.NOT_CONNECTED);
}
@@ -147,13 +133,13 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
try {
BluetoothDevice btDevice = mBtAdapter.getRemoteDevice(gbDevice.getAddress());
ParcelUuid uuids[] = btDevice.getUuids();
ParcelUuid[] uuids = btDevice.getUuids();
if (uuids == null) {
LOG.warn("Device provided no UUIDs to connect to, giving up: " + gbDevice);
LOG.warn("Device provided no UUIDs to connect to, giving up: {}", gbDevice);
return false;
}
for (ParcelUuid uuid : uuids) {
LOG.info("found service UUID " + uuid);
LOG.info("found service UUID {}", uuid);
}
mBtSocket = btDevice.createRfcommSocketToServiceRecord(getUuidToConnect(uuids));
mBtSocket.connect();
@@ -162,18 +148,13 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
setUpdateState(GBDevice.State.CONNECTED);
} catch (IOException e) {
LOG.error("Server socket cannot be started.", e);
//LOG.error(e.getMessage());
cleanup();
setUpdateState(originalState);
mInStream = null;
mOutStream = null;
mBtSocket = null;
return false;
} catch (SecurityException e) {
LOG.error("Could not connect to device.", e);
cleanup();
setUpdateState(originalState);
mInStream = null;
mOutStream = null;
mBtSocket = null;
return false;
}
@@ -191,8 +172,6 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
* Returns the uuid to connect to.
* Default implementation returns the first of the given uuids that were
* read from the remote device.
* @param uuids
* @return
*/
@NonNull
protected UUID getUuidToConnect(@NonNull ParcelUuid[] uuids) {
@@ -203,11 +182,34 @@ public abstract class BtClassicIoThread extends GBDeviceIoThread {
gbDevice.setUpdateState(state, getContext());
}
private void cleanup() {
if (mOutStream != null) {
try {
mOutStream.close();
} catch (final Exception ignored) {
}
mOutStream = null;
}
if (mInStream != null) {
try {
mInStream.close();
} catch (final Exception ignored) {
}
mInStream = null;
}
if (mBtSocket != null) {
try {
mBtSocket.close();
} catch (final IOException ignored) {
}
mBtSocket = null;
}
}
/**
* Returns an incoming message for consuming by the GBDeviceProtocol
* @return
* @throws IOException
* @param inStream
*/
protected abstract byte[] parseIncoming(InputStream inStream) throws IOException;
}
@@ -18,7 +18,9 @@
package nodomain.freeyourgadget.gadgetbridge.service.serial;
import android.location.Location;
import android.os.Bundle;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.util.ArrayList;
import java.util.UUID;
@@ -52,6 +54,8 @@ import nodomain.freeyourgadget.gadgetbridge.service.AbstractDeviceSupport;
* to create the device specific message for the respective events and sends them to the device via {@link #sendToDevice(byte[])}.
*/
public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport {
private static final Logger LOG = LoggerFactory.getLogger(AbstractSerialDeviceSupport.class);
private GBDeviceProtocol gbDeviceProtocol;
protected GBDeviceIoThread gbDeviceIOThread;
@@ -89,7 +93,8 @@ public abstract class AbstractSerialDeviceSupport extends AbstractDeviceSupport
* Lazily creates and returns the GBDeviceIoThread instance to be used.
*/
public synchronized GBDeviceIoThread getDeviceIOThread() {
if (gbDeviceIOThread == null) {
if (gbDeviceIOThread == null || !gbDeviceIOThread.isAlive()) {
LOG.debug("Creating new IO thread");
gbDeviceIOThread = createDeviceIOThread();
}
return gbDeviceIOThread;