Improve error handling and disconnection events (#60)
* Improve Android error handling * Improve cleanup after disconnection on Apple * Update changelog
This commit is contained in:
@@ -298,14 +298,14 @@ fun Short.toByteArray(byteOrder: ByteOrder = ByteOrder.LITTLE_ENDIAN): ByteArray
|
||||
fun unknownCharacteristicError(char: String) =
|
||||
FlutterError("IllegalArgument", "Unknown error", null)
|
||||
|
||||
// Future result classes
|
||||
class BleCharacteristicFuture(
|
||||
val deviceId: String,
|
||||
val characteristicId: String,
|
||||
val serviceId: String,
|
||||
val result: (Result<ByteArray>) -> Unit,
|
||||
|
||||
val DeviceDisconnectedError: FlutterError = FlutterError(
|
||||
"DeviceDisconnected",
|
||||
"Device Disconnected",
|
||||
null
|
||||
)
|
||||
|
||||
// Future result classes
|
||||
class DiscoverServicesFuture(
|
||||
val deviceId: String,
|
||||
val result: (Result<List<UniversalBleService>>) -> Unit,
|
||||
@@ -316,6 +316,13 @@ class MtuResultFuture(
|
||||
val result: (Result<Long>) -> Unit,
|
||||
)
|
||||
|
||||
class ReadResultFuture(
|
||||
val deviceId: String,
|
||||
val characteristicId: String,
|
||||
val serviceId: String,
|
||||
val result: (Result<ByteArray>) -> Unit,
|
||||
)
|
||||
|
||||
class WriteResultFuture(
|
||||
val deviceId: String,
|
||||
val characteristicId: String,
|
||||
@@ -323,7 +330,7 @@ class WriteResultFuture(
|
||||
val result: (Result<Unit>) -> Unit,
|
||||
)
|
||||
|
||||
class CharacteristicSubscriptionFuture(
|
||||
class SubscriptionResultFuture(
|
||||
val deviceId: String,
|
||||
val characteristicId: String,
|
||||
val serviceId: String,
|
||||
|
||||
@@ -37,12 +37,11 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
private lateinit var context: Context
|
||||
private var activity: Activity? = null
|
||||
private lateinit var bluetoothManager: BluetoothManager
|
||||
private val mtuResultFutureList = mutableListOf<MtuResultFuture>()
|
||||
private val bleCharacteristicFutureList = mutableListOf<BleCharacteristicFuture>()
|
||||
private val discoverServicesFutureList = mutableListOf<DiscoverServicesFuture>()
|
||||
private val characteristicSubscriptionFutureList =
|
||||
mutableListOf<CharacteristicSubscriptionFuture>()
|
||||
private val mtuResultFutureList = mutableListOf<MtuResultFuture>()
|
||||
private val readResultFutureList = mutableListOf<ReadResultFuture>()
|
||||
private val writeResultFutureList = mutableListOf<WriteResultFuture>()
|
||||
private val subscriptionResultFutureList = mutableListOf<SubscriptionResultFuture>()
|
||||
private val cachedServicesMap = mutableMapOf<String, List<String>>()
|
||||
private val devicesStateMap = mutableMapOf<String, Int>()
|
||||
private var bluetoothEnableRequestFuture: ((Result<Boolean>) -> Unit)? = null
|
||||
@@ -240,8 +239,8 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
)
|
||||
|
||||
if (gatt.setNotifiable(gattCharacteristic, bleInputProperty)) {
|
||||
characteristicSubscriptionFutureList.add(
|
||||
CharacteristicSubscriptionFuture(
|
||||
subscriptionResultFutureList.add(
|
||||
SubscriptionResultFuture(
|
||||
gatt.device.address,
|
||||
gattCharacteristic.uuid.toString(),
|
||||
gattCharacteristic.service.uuid.toString(),
|
||||
@@ -296,8 +295,8 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
return
|
||||
}
|
||||
|
||||
bleCharacteristicFutureList.add(
|
||||
BleCharacteristicFuture(
|
||||
readResultFutureList.add(
|
||||
ReadResultFuture(
|
||||
gatt.device.address,
|
||||
gattCharacteristic.uuid.toString(),
|
||||
gattCharacteristic.service.uuid.toString(),
|
||||
@@ -325,12 +324,12 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
value: ByteArray,
|
||||
status: Int,
|
||||
) {
|
||||
bleCharacteristicFutureList.filter {
|
||||
readResultFutureList.filter {
|
||||
it.deviceId == gatt.device.address &&
|
||||
it.characteristicId == characteristic.uuid.toString() &&
|
||||
it.serviceId == characteristic.service.uuid.toString()
|
||||
}.forEach {
|
||||
bleCharacteristicFutureList.remove(it)
|
||||
readResultFutureList.remove(it)
|
||||
if (status == BluetoothGatt.GATT_SUCCESS) {
|
||||
it.result(Result.success(value))
|
||||
} else {
|
||||
@@ -641,14 +640,45 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
private fun cleanConnection(gatt: BluetoothGatt) {
|
||||
knownGatts.remove(gatt)
|
||||
gatt.disconnect()
|
||||
bleCharacteristicFutureList.removeAll {
|
||||
it.deviceId == gatt.device.address
|
||||
readResultFutureList.removeAll {
|
||||
if (it.deviceId == gatt.device.address) {
|
||||
it.result(Result.failure(DeviceDisconnectedError))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
writeResultFutureList.removeAll {
|
||||
if (it.deviceId == gatt.device.address) {
|
||||
it.result(Result.failure(DeviceDisconnectedError))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
subscriptionResultFutureList.removeAll {
|
||||
if (it.deviceId == gatt.device.address) {
|
||||
it.result(Result.failure(DeviceDisconnectedError))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
mtuResultFutureList.removeAll {
|
||||
it.deviceId == gatt.device.address
|
||||
if (it.deviceId == gatt.device.address) {
|
||||
it.result(Result.failure(DeviceDisconnectedError))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
discoverServicesFutureList.removeAll {
|
||||
it.deviceId == gatt.device.address
|
||||
if (it.deviceId == gatt.device.address) {
|
||||
it.result(Result.failure(DeviceDisconnectedError))
|
||||
true
|
||||
} else {
|
||||
false
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -752,10 +782,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
|
||||
override fun onConnectionStateChange(gatt: BluetoothGatt, status: Int, newState: Int) {
|
||||
devicesStateMap[gatt.device.address] = newState
|
||||
if (status != BluetoothGatt.GATT_SUCCESS) {
|
||||
Log.e(TAG, "Failed to update connected state: $status")
|
||||
return
|
||||
}
|
||||
Log.d(TAG, "onConnectionStateChange-> Status: ${status}, NewState: $newState")
|
||||
|
||||
if (newState == BluetoothGatt.STATE_CONNECTED) {
|
||||
mainThreadHandler?.post {
|
||||
@@ -771,8 +798,6 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
) {}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
override fun onCharacteristicChanged(
|
||||
@@ -811,12 +836,12 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(),
|
||||
service: String,
|
||||
status: Int,
|
||||
) {
|
||||
characteristicSubscriptionFutureList.filter {
|
||||
subscriptionResultFutureList.filter {
|
||||
it.deviceId == deviceId &&
|
||||
it.characteristicId == characteristic &&
|
||||
it.serviceId == service
|
||||
}.forEach {
|
||||
characteristicSubscriptionFutureList.remove(it)
|
||||
subscriptionResultFutureList.remove(it)
|
||||
val error: String? = status.parseGattErrorCode()
|
||||
if (error != null) {
|
||||
it.result(
|
||||
|
||||
Reference in New Issue
Block a user