Loading android/app/src/com/android/bluetooth/gatt/GattService.java +55 −6 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.TimeUnit; /** Loading Loading @@ -212,6 +213,12 @@ public class GattService extends ProfileService { */ private Set<String> mReliableQueue = new HashSet<String>(); /** * HashMap used to synchronize writeCharacteristic calls mapping remote device address to * available permit (either 1 or 0). */ private final HashMap<String, AtomicBoolean> mPermits = new HashMap<>(); static { classInitNative(); } Loading Loading @@ -630,13 +637,14 @@ public class GattService extends ProfileService { } @Override public void writeCharacteristic(int clientIf, String address, int handle, int writeType, public int writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, byte[] value) { GattService service = getService(); if (service == null) { return; return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } service.writeCharacteristic(clientIf, address, handle, writeType, authReq, value); return service.writeCharacteristic(clientIf, address, handle, writeType, authReq, value); } @Override Loading Loading @@ -1223,6 +1231,13 @@ public class GattService extends ProfileService { if (status == 0) { mClientMap.addConnection(clientIf, connId, address); // Allow one writeCharacteristic operation at a time for each connected remote device. synchronized (mPermits) { Log.d(TAG, "onConnected() - adding permit for address=" + address); mPermits.putIfAbsent(address, new AtomicBoolean(true)); } } ClientMap.App app = mClientMap.getById(clientIf); if (app != null) { Loading @@ -1241,6 +1256,17 @@ public class GattService extends ProfileService { mClientMap.removeConnection(clientIf, connId); ClientMap.App app = mClientMap.getById(clientIf); // Remove AtomicBoolean representing permit if no other connections rely on // this remote device. if (!mClientMap.getConnectedDevices().contains(address)) { synchronized (mPermits) { Log.d(TAG, "onDisconnected() - removing permit for address=" + address); mPermits.remove(address); } } if (app != null) { app.callback.onClientConnectionState(status, clientIf, false, address); } Loading Loading @@ -1532,6 +1558,11 @@ public class GattService extends ProfileService { void onWriteCharacteristic(int connId, int status, int handle) throws RemoteException { String address = mClientMap.addressByConnId(connId); synchronized (mPermits) { Log.d(TAG, "onWriteCharacteristic() - increasing permit for address=" + address); mPermits.get(address).set(true); } if (VDBG) { Log.d(TAG, "onWriteCharacteristic() - address=" + address + ", status=" + status); Loading Loading @@ -2557,7 +2588,7 @@ public class GattService extends ProfileService { uuid.getMostSignificantBits(), startHandle, endHandle, authReq); } void writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, int writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, byte[] value) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); Loading @@ -2572,15 +2603,33 @@ public class GattService extends ProfileService { Integer connId = mClientMap.connIdByAddress(clientIf, address); if (connId == null) { Log.e(TAG, "writeCharacteristic() - No connection for " + address + "..."); return; return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } if (!permissionCheck(connId, handle)) { Log.w(TAG, "writeCharacteristic() - permission check failed!"); return; return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } Log.d(TAG, "writeCharacteristic() - trying to acquire permit."); // Lock the thread until onCharacteristicWrite callback comes back. synchronized (mPermits) { AtomicBoolean atomicBoolean = mPermits.get(address); if (atomicBoolean == null) { Log.d(TAG, "writeCharacteristic() - atomicBoolean uninitialized!"); return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } boolean success = atomicBoolean.get(); if (!success) { Log.d(TAG, "writeCharacteristic() - no permit available."); return BluetoothGatt.GATT_WRITE_REQUEST_BUSY; } atomicBoolean.set(false); } gattClientWriteCharacteristicNative(connId, handle, writeType, authReq, value); return BluetoothGatt.GATT_WRITE_REQUEST_SUCCESS; } void readDescriptor(int clientIf, String address, int handle, int authReq) { Loading Loading
android/app/src/com/android/bluetooth/gatt/GattService.java +55 −6 Original line number Diff line number Diff line Loading @@ -80,6 +80,7 @@ import java.util.List; import java.util.Map; import java.util.Set; import java.util.UUID; import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.TimeUnit; /** Loading Loading @@ -212,6 +213,12 @@ public class GattService extends ProfileService { */ private Set<String> mReliableQueue = new HashSet<String>(); /** * HashMap used to synchronize writeCharacteristic calls mapping remote device address to * available permit (either 1 or 0). */ private final HashMap<String, AtomicBoolean> mPermits = new HashMap<>(); static { classInitNative(); } Loading Loading @@ -630,13 +637,14 @@ public class GattService extends ProfileService { } @Override public void writeCharacteristic(int clientIf, String address, int handle, int writeType, public int writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, byte[] value) { GattService service = getService(); if (service == null) { return; return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } service.writeCharacteristic(clientIf, address, handle, writeType, authReq, value); return service.writeCharacteristic(clientIf, address, handle, writeType, authReq, value); } @Override Loading Loading @@ -1223,6 +1231,13 @@ public class GattService extends ProfileService { if (status == 0) { mClientMap.addConnection(clientIf, connId, address); // Allow one writeCharacteristic operation at a time for each connected remote device. synchronized (mPermits) { Log.d(TAG, "onConnected() - adding permit for address=" + address); mPermits.putIfAbsent(address, new AtomicBoolean(true)); } } ClientMap.App app = mClientMap.getById(clientIf); if (app != null) { Loading @@ -1241,6 +1256,17 @@ public class GattService extends ProfileService { mClientMap.removeConnection(clientIf, connId); ClientMap.App app = mClientMap.getById(clientIf); // Remove AtomicBoolean representing permit if no other connections rely on // this remote device. if (!mClientMap.getConnectedDevices().contains(address)) { synchronized (mPermits) { Log.d(TAG, "onDisconnected() - removing permit for address=" + address); mPermits.remove(address); } } if (app != null) { app.callback.onClientConnectionState(status, clientIf, false, address); } Loading Loading @@ -1532,6 +1558,11 @@ public class GattService extends ProfileService { void onWriteCharacteristic(int connId, int status, int handle) throws RemoteException { String address = mClientMap.addressByConnId(connId); synchronized (mPermits) { Log.d(TAG, "onWriteCharacteristic() - increasing permit for address=" + address); mPermits.get(address).set(true); } if (VDBG) { Log.d(TAG, "onWriteCharacteristic() - address=" + address + ", status=" + status); Loading Loading @@ -2557,7 +2588,7 @@ public class GattService extends ProfileService { uuid.getMostSignificantBits(), startHandle, endHandle, authReq); } void writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, int writeCharacteristic(int clientIf, String address, int handle, int writeType, int authReq, byte[] value) { enforceCallingOrSelfPermission(BLUETOOTH_PERM, "Need BLUETOOTH permission"); Loading @@ -2572,15 +2603,33 @@ public class GattService extends ProfileService { Integer connId = mClientMap.connIdByAddress(clientIf, address); if (connId == null) { Log.e(TAG, "writeCharacteristic() - No connection for " + address + "..."); return; return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } if (!permissionCheck(connId, handle)) { Log.w(TAG, "writeCharacteristic() - permission check failed!"); return; return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } Log.d(TAG, "writeCharacteristic() - trying to acquire permit."); // Lock the thread until onCharacteristicWrite callback comes back. synchronized (mPermits) { AtomicBoolean atomicBoolean = mPermits.get(address); if (atomicBoolean == null) { Log.d(TAG, "writeCharacteristic() - atomicBoolean uninitialized!"); return BluetoothGatt.GATT_WRITE_REQUEST_FAIL; } boolean success = atomicBoolean.get(); if (!success) { Log.d(TAG, "writeCharacteristic() - no permit available."); return BluetoothGatt.GATT_WRITE_REQUEST_BUSY; } atomicBoolean.set(false); } gattClientWriteCharacteristicNative(connId, handle, writeType, authReq, value); return BluetoothGatt.GATT_WRITE_REQUEST_SUCCESS; } void readDescriptor(int clientIf, String address, int handle, int authReq) { Loading