Merge "Fix long characteristic write concurrency bug."
This commit is contained in:
@@ -75,6 +75,9 @@ public final class BluetoothGatt implements BluetoothProfile {
|
|||||||
private static final int CONN_STATE_DISCONNECTING = 3;
|
private static final int CONN_STATE_DISCONNECTING = 3;
|
||||||
private static final int CONN_STATE_CLOSED = 4;
|
private static final int CONN_STATE_CLOSED = 4;
|
||||||
|
|
||||||
|
private static final int WRITE_CHARACTERISTIC_MAX_RETRIES = 5;
|
||||||
|
private static final int WRITE_CHARACTERISTIC_TIME_TO_WAIT = 1000; // milliseconds
|
||||||
|
|
||||||
private List<BluetoothGattService> mServices;
|
private List<BluetoothGattService> mServices;
|
||||||
|
|
||||||
/** A GATT operation completed successfully */
|
/** A GATT operation completed successfully */
|
||||||
@@ -126,6 +129,27 @@ public final class BluetoothGatt implements BluetoothProfile {
|
|||||||
/** Connection parameter update - Request low power, reduced data rate connection parameters. */
|
/** Connection parameter update - Request low power, reduced data rate connection parameters. */
|
||||||
public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
|
public static final int CONNECTION_PRIORITY_LOW_POWER = 2;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A GATT writeCharacteristic request is started successfully.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int GATT_WRITE_REQUEST_SUCCESS = 0;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A GATT writeCharacteristic request failed to start.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int GATT_WRITE_REQUEST_FAIL = 1;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A GATT writeCharacteristic request is issued to a busy remote device.
|
||||||
|
*
|
||||||
|
* @hide
|
||||||
|
*/
|
||||||
|
public static final int GATT_WRITE_REQUEST_BUSY = 2;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* No authentication required.
|
* No authentication required.
|
||||||
*
|
*
|
||||||
@@ -428,9 +452,19 @@ public final class BluetoothGatt implements BluetoothProfile {
|
|||||||
try {
|
try {
|
||||||
final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
|
final int authReq = (mAuthRetryState == AUTH_RETRY_STATE_IDLE)
|
||||||
? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
|
? AUTHENTICATION_NO_MITM : AUTHENTICATION_MITM;
|
||||||
mService.writeCharacteristic(mClientIf, address, handle,
|
int requestStatus = GATT_WRITE_REQUEST_FAIL;
|
||||||
characteristic.getWriteType(), authReq,
|
for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
|
||||||
characteristic.getValue());
|
requestStatus = mService.writeCharacteristic(mClientIf, address,
|
||||||
|
handle, characteristic.getWriteType(), authReq,
|
||||||
|
characteristic.getValue());
|
||||||
|
if (requestStatus != GATT_WRITE_REQUEST_BUSY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(WRITE_CHARACTERISTIC_TIME_TO_WAIT);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
mAuthRetryState++;
|
mAuthRetryState++;
|
||||||
return;
|
return;
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
@@ -1228,14 +1262,26 @@ public final class BluetoothGatt implements BluetoothProfile {
|
|||||||
if (device == null) return false;
|
if (device == null) return false;
|
||||||
|
|
||||||
synchronized (mDeviceBusyLock) {
|
synchronized (mDeviceBusyLock) {
|
||||||
if (mDeviceBusy) return false;
|
if (mDeviceBusy) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
mDeviceBusy = true;
|
mDeviceBusy = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int requestStatus = GATT_WRITE_REQUEST_FAIL;
|
||||||
try {
|
try {
|
||||||
mService.writeCharacteristic(mClientIf, device.getAddress(),
|
for (int i = 0; i < WRITE_CHARACTERISTIC_MAX_RETRIES; i++) {
|
||||||
|
requestStatus = mService.writeCharacteristic(mClientIf, device.getAddress(),
|
||||||
characteristic.getInstanceId(), characteristic.getWriteType(),
|
characteristic.getInstanceId(), characteristic.getWriteType(),
|
||||||
AUTHENTICATION_NONE, characteristic.getValue());
|
AUTHENTICATION_NONE, characteristic.getValue());
|
||||||
|
if (requestStatus != GATT_WRITE_REQUEST_BUSY) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
Thread.sleep(WRITE_CHARACTERISTIC_TIME_TO_WAIT);
|
||||||
|
} catch (InterruptedException e) {
|
||||||
|
}
|
||||||
|
}
|
||||||
} catch (RemoteException e) {
|
} catch (RemoteException e) {
|
||||||
Log.e(TAG, "", e);
|
Log.e(TAG, "", e);
|
||||||
synchronized (mDeviceBusyLock) {
|
synchronized (mDeviceBusyLock) {
|
||||||
@@ -1244,7 +1290,7 @@ public final class BluetoothGatt implements BluetoothProfile {
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return requestStatus == GATT_WRITE_REQUEST_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
Reference in New Issue
Block a user