mirror of
https://codeberg.org/Freeyourgadget/Gadgetbridge
synced 2024-08-16 20:31:00 +02:00
Pebble 2: fixes for experimental client only gatt code
This basically makes sure that - only one gatt write operation is in progress - data is not sent from within callbacks to prevent a deadlock when waiting for a nre callback that cant happen yet beause the current has not been retuned
This commit is contained in:
parent
f6131772d6
commit
cdf6039d4c
@ -28,6 +28,7 @@ import org.slf4j.LoggerFactory;
|
||||
|
||||
import java.lang.reflect.Method;
|
||||
import java.util.UUID;
|
||||
import java.util.concurrent.CountDownLatch;
|
||||
|
||||
import nodomain.freeyourgadget.gadgetbridge.GBApplication;
|
||||
import nodomain.freeyourgadget.gadgetbridge.util.GB;
|
||||
@ -62,6 +63,8 @@ class PebbleGATTClient extends BluetoothGattCallback {
|
||||
private boolean removeBond = false;
|
||||
private BluetoothGatt mBluetoothGatt;
|
||||
|
||||
private CountDownLatch mWaitWriteCompleteLatch;
|
||||
|
||||
PebbleGATTClient(PebbleLESupport pebbleLESupport, Context context, BluetoothDevice btDevice) {
|
||||
mContext = context;
|
||||
mPebbleLESupport = pebbleLESupport;
|
||||
@ -119,9 +122,16 @@ class PebbleGATTClient extends BluetoothGattCallback {
|
||||
if (!mPebbleLESupport.isExpectedDevice(gatt.getDevice())) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.info("onCharacteristicWrite() " + characteristic.getUuid());
|
||||
if (characteristic.getUuid().equals(PAIRING_TRIGGER_CHARACTERISTIC) || characteristic.getUuid().equals(CONNECTIVITY_CHARACTERISTIC)) {
|
||||
if (characteristic.getUuid().equals(PPOGATT_CHARACTERISTIC_WRITE)) {
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
LOG.error("something went wrong when writing to PPoGATT characteristics");
|
||||
}
|
||||
if (mWaitWriteCompleteLatch != null) {
|
||||
mWaitWriteCompleteLatch.countDown();
|
||||
} else {
|
||||
LOG.warn("mWaitWriteCompleteLatch is null!");
|
||||
}
|
||||
} else if (characteristic.getUuid().equals(PAIRING_TRIGGER_CHARACTERISTIC) || characteristic.getUuid().equals(CONNECTIVITY_CHARACTERISTIC)) {
|
||||
//mBtDevice.createBond(); // did not work when last tried
|
||||
|
||||
if (oldPebble) {
|
||||
@ -266,13 +276,20 @@ class PebbleGATTClient extends BluetoothGattCallback {
|
||||
}
|
||||
|
||||
synchronized void sendDataToPebble(byte[] data) {
|
||||
mWaitWriteCompleteLatch = new CountDownLatch(1);
|
||||
writeCharacteristics.setValue(data.clone());
|
||||
mBluetoothGatt.writeCharacteristic(writeCharacteristics);
|
||||
}
|
||||
|
||||
synchronized void sendAckToPebble(int serial) {
|
||||
writeCharacteristics.setValue(new byte[]{(byte) (((serial << 3) | 1) & 0xff)});
|
||||
mBluetoothGatt.writeCharacteristic(writeCharacteristics);
|
||||
boolean success = mBluetoothGatt.writeCharacteristic(writeCharacteristics);
|
||||
if (!success) {
|
||||
LOG.error("could not send data to pebble (error writing characteristic)");
|
||||
} else {
|
||||
try {
|
||||
mWaitWriteCompleteLatch.await();
|
||||
} catch (InterruptedException e) {
|
||||
LOG.warn("interrupted while waiting for write complete latch");
|
||||
}
|
||||
}
|
||||
mWaitWriteCompleteLatch = null;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
|
@ -52,7 +52,9 @@ class PebbleGATTServer extends BluetoothGattServerCallback {
|
||||
|
||||
boolean initialize() {
|
||||
BluetoothManager bluetoothManager = (BluetoothManager) mContext.getSystemService(Context.BLUETOOTH_SERVICE);
|
||||
|
||||
if (bluetoothManager == null) {
|
||||
return false;
|
||||
}
|
||||
mBluetoothGattServer = bluetoothManager.openGattServer(mContext, this);
|
||||
if (mBluetoothGattServer == null) {
|
||||
return false;
|
||||
@ -76,12 +78,6 @@ class PebbleGATTServer extends BluetoothGattServerCallback {
|
||||
mBluetoothGattServer.notifyCharacteristicChanged(mBtDevice, writeCharacteristics, false);
|
||||
}
|
||||
|
||||
synchronized void sendAckToPebble(int serial) {
|
||||
writeCharacteristics.setValue(new byte[]{(byte) (((serial << 3) | 1) & 0xff)});
|
||||
|
||||
mBluetoothGattServer.notifyCharacteristicChanged(mBtDevice, writeCharacteristics, false);
|
||||
}
|
||||
|
||||
public void onCharacteristicReadRequest(BluetoothDevice device, int requestId, int offset, BluetoothGattCharacteristic characteristic) {
|
||||
if (!mPebbleLESupport.isExpectedDevice(device)) {
|
||||
return;
|
||||
|
@ -18,6 +18,8 @@ package nodomain.freeyourgadget.gadgetbridge.service.devices.pebble.ble;
|
||||
|
||||
import android.bluetooth.BluetoothDevice;
|
||||
import android.content.Context;
|
||||
import android.os.Handler;
|
||||
import android.os.HandlerThread;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
@ -39,9 +41,11 @@ public class PebbleLESupport {
|
||||
private PipedOutputStream mPipedOutputStream;
|
||||
private int mMTU = 20;
|
||||
private int mMTULimit = Integer.MAX_VALUE;
|
||||
public boolean clientOnly = false; // currently broken, and only possible for Pebble 2
|
||||
public boolean clientOnly = false; // currently experimental, and only possible for Pebble 2
|
||||
private boolean mIsConnected = false;
|
||||
private CountDownLatch mPPAck;
|
||||
private HandlerThread mWriteHandlerThread;
|
||||
private Handler mWriteHandler;
|
||||
|
||||
public PebbleLESupport(Context context, final BluetoothDevice btDevice, PipedInputStream pipedInputStream, PipedOutputStream pipedOutputStream) throws IOException {
|
||||
mBtDevice = btDevice;
|
||||
@ -53,6 +57,11 @@ public class PebbleLESupport {
|
||||
} catch (IOException e) {
|
||||
LOG.warn("could not connect input stream");
|
||||
}
|
||||
|
||||
mWriteHandlerThread = new HandlerThread("write handler thread");
|
||||
mWriteHandlerThread.start();
|
||||
mWriteHandler = new Handler(mWriteHandlerThread.getLooper());
|
||||
|
||||
mMTULimit = GBApplication.getPrefs().getInt("pebble_mtu_limit", 512);
|
||||
mMTULimit = Math.max(mMTULimit, 20);
|
||||
mMTULimit = Math.min(mMTULimit, 512);
|
||||
@ -102,6 +111,9 @@ public class PebbleLESupport {
|
||||
mPipedOutputStream.close();
|
||||
} catch (IOException ignore) {
|
||||
}
|
||||
if (mWriteHandlerThread != null) {
|
||||
mWriteHandlerThread.quit();
|
||||
}
|
||||
}
|
||||
|
||||
private synchronized void createPipedInputReader() {
|
||||
@ -166,19 +178,21 @@ public class PebbleLESupport {
|
||||
}
|
||||
|
||||
private void sendAckToPebble(int serial) {
|
||||
if (mPebbleGATTServer != null) {
|
||||
mPebbleGATTServer.sendAckToPebble(serial);
|
||||
} else {
|
||||
mPebbleGATTClient.sendAckToPebble(serial);
|
||||
}
|
||||
sendDataToPebble(new byte[]{(byte) (((serial << 3) | 1) & 0xff)});
|
||||
}
|
||||
|
||||
private void sendDataToPebble(byte[] bytes) {
|
||||
private synchronized void sendDataToPebble(final byte[] bytes) {
|
||||
if (mPebbleGATTServer != null) {
|
||||
mPebbleGATTServer.sendDataToPebble(bytes);
|
||||
} else {
|
||||
// For now only in experimental client only code
|
||||
mWriteHandler.post(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
mPebbleGATTClient.sendDataToPebble(bytes);
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private class PipeReader extends Thread {
|
||||
|
Loading…
Reference in New Issue
Block a user