From 05697b7d30044eaad80a1920b6025b98e47cb05a Mon Sep 17 00:00:00 2001 From: Rohit Sangwan Date: Fri, 10 May 2024 16:29:10 +0530 Subject: [PATCH] Improve setNotifiation completion (#42) * Improve setNotifiation completion * Implement Windows * Minor android fixes * Few more fixes * Update changelog --------- Co-authored-by: Foti Dim --- CHANGELOG.md | 1 + .../navideck/universal_ble/UniversalBle.g.kt | 179 +++++++++-------- .../universal_ble/UniversalBleHelper.kt | 25 ++- .../universal_ble/UniversalBlePlugin.kt | 183 ++++++++++++++---- darwin/Classes/UniversalBle.g.swift | 110 ++++++----- darwin/Classes/UniversalBleHelper.swift | 14 ++ darwin/Classes/UniversalBlePlugin.swift | 51 +++-- example/ios/Podfile.lock | 2 +- example/ios/Runner.xcodeproj/project.pbxproj | 2 +- .../xcshareddata/xcschemes/Runner.xcscheme | 2 +- example/pubspec.lock | 2 +- .../universal_ble_pigeon/universal_ble.g.dart | 90 +++++---- .../universal_ble_pigeon_channel.dart | 2 +- pigeon/universal_ble.dart | 1 + pubspec.yaml | 2 +- windows/src/generated/universal_ble.g.cpp | 76 +++++--- windows/src/generated/universal_ble.g.h | 15 +- windows/src/universal_ble_plugin.cpp | 32 ++- windows/src/universal_ble_plugin.h | 8 +- 19 files changed, 507 insertions(+), 290 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1180ed7..7e8941a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,7 @@ ## 0.9.10 * Fix Windows scan filter * Improve service discovery on Linux +* Use asynchronous callbacks for SetNotifiable ## 0.9.9 * Improve service discovery on Apple diff --git a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt index 24e9128..b44969c 100644 --- a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt +++ b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBle.g.kt @@ -1,5 +1,6 @@ -// Autogenerated from Pigeon (v17.1.1), do not edit directly. +// Autogenerated from Pigeon (v18.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon +@file:Suppress("UNCHECKED_CAST", "ArrayInDataClass") package com.navideck.universal_ble @@ -16,14 +17,14 @@ private fun wrapResult(result: Any?): List { } private fun wrapError(exception: Throwable): List { - if (exception is FlutterError) { - return listOf( + return if (exception is FlutterError) { + listOf( exception.code, exception.message, exception.details ) } else { - return listOf( + listOf( exception.javaClass.simpleName, exception.toString(), "Cause: " + exception.cause + ", Stacktrace: " + Log.getStackTraceString(exception) @@ -58,15 +59,15 @@ data class UniversalBleScanResult ( ) { companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): UniversalBleScanResult { - val deviceId = list[0] as String - val name = list[1] as String? - val isPaired = list[2] as Boolean? - val rssi = list[3].let { if (it is Int) it.toLong() else it as Long? } - val manufacturerData = list[4] as ByteArray? - val manufacturerDataHead = list[5] as ByteArray? - val services = list[6] as List? + @Suppress("LocalVariableName") + fun fromList(__pigeon_list: List): UniversalBleScanResult { + val deviceId = __pigeon_list[0] as String + val name = __pigeon_list[1] as String? + val isPaired = __pigeon_list[2] as Boolean? + val rssi = __pigeon_list[3].let { num -> if (num is Int) num.toLong() else num as Long? } + val manufacturerData = __pigeon_list[4] as ByteArray? + val manufacturerDataHead = __pigeon_list[5] as ByteArray? + val services = __pigeon_list[6] as List? return UniversalBleScanResult(deviceId, name, isPaired, rssi, manufacturerData, manufacturerDataHead, services) } } @@ -90,10 +91,10 @@ data class UniversalBleService ( ) { companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): UniversalBleService { - val uuid = list[0] as String - val characteristics = list[1] as List? + @Suppress("LocalVariableName") + fun fromList(__pigeon_list: List): UniversalBleService { + val uuid = __pigeon_list[0] as String + val characteristics = __pigeon_list[1] as List? return UniversalBleService(uuid, characteristics) } } @@ -112,10 +113,10 @@ data class UniversalBleCharacteristic ( ) { companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): UniversalBleCharacteristic { - val uuid = list[0] as String - val properties = list[1] as List + @Suppress("LocalVariableName") + fun fromList(__pigeon_list: List): UniversalBleCharacteristic { + val uuid = __pigeon_list[0] as String + val properties = __pigeon_list[1] as List return UniversalBleCharacteristic(uuid, properties) } } @@ -138,10 +139,10 @@ data class UniversalScanFilter ( ) { companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): UniversalScanFilter { - val withServices = list[0] as List - val withManufacturerData = list[1] as List + @Suppress("LocalVariableName") + fun fromList(__pigeon_list: List): UniversalScanFilter { + val withServices = __pigeon_list[0] as List + val withManufacturerData = __pigeon_list[1] as List return UniversalScanFilter(withServices, withManufacturerData) } } @@ -161,11 +162,11 @@ data class UniversalManufacturerDataFilter ( ) { companion object { - @Suppress("UNCHECKED_CAST") - fun fromList(list: List): UniversalManufacturerDataFilter { - val companyIdentifier = list[0].let { if (it is Int) it.toLong() else it as Long? } - val data = list[1] as ByteArray? - val mask = list[2] as ByteArray? + @Suppress("LocalVariableName") + fun fromList(__pigeon_list: List): UniversalManufacturerDataFilter { + val companyIdentifier = __pigeon_list[0].let { num -> if (num is Int) num.toLong() else num as Long? } + val data = __pigeon_list[1] as ByteArray? + val mask = __pigeon_list[2] as ByteArray? return UniversalManufacturerDataFilter(companyIdentifier, data, mask) } } @@ -178,7 +179,6 @@ data class UniversalManufacturerDataFilter ( } } -@Suppress("UNCHECKED_CAST") private object UniversalBlePlatformChannelCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { return when (type) { @@ -249,7 +249,7 @@ interface UniversalBlePlatformChannel { fun stopScan() fun connect(deviceId: String) fun disconnect(deviceId: String) - fun setNotifiable(deviceId: String, service: String, characteristic: String, bleInputProperty: Long) + fun setNotifiable(deviceId: String, service: String, characteristic: String, bleInputProperty: Long, callback: (Result) -> Unit) fun discoverServices(deviceId: String, callback: (Result>) -> Unit) fun readValue(deviceId: String, service: String, characteristic: String, callback: (Result) -> Unit) fun requestMtu(deviceId: String, expectedMtu: Long, callback: (Result) -> Unit) @@ -265,10 +265,10 @@ interface UniversalBlePlatformChannel { UniversalBlePlatformChannelCodec } /** Sets up an instance of `UniversalBlePlatformChannel` to handle messages through the `binaryMessenger`. */ - @Suppress("UNCHECKED_CAST") - fun setUp(binaryMessenger: BinaryMessenger, api: UniversalBlePlatformChannel?) { + fun setUp(binaryMessenger: BinaryMessenger, api: UniversalBlePlatformChannel?, messageChannelSuffix: String = "") { + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { _, reply -> api.getBluetoothAvailabilityState() { result: Result -> @@ -286,7 +286,7 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { _, reply -> api.enableBluetooth() { result: Result -> @@ -304,17 +304,16 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val filterArg = args[0] as UniversalScanFilter? - var wrapped: List - try { + val wrapped: List = try { api.startScan(filterArg) - wrapped = listOf(null) + listOf(null) } catch (exception: Throwable) { - wrapped = wrapError(exception) + wrapError(exception) } reply.reply(wrapped) } @@ -323,15 +322,14 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { _, reply -> - var wrapped: List - try { + val wrapped: List = try { api.stopScan() - wrapped = listOf(null) + listOf(null) } catch (exception: Throwable) { - wrapped = wrapError(exception) + wrapError(exception) } reply.reply(wrapped) } @@ -340,17 +338,16 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val deviceIdArg = args[0] as String - var wrapped: List - try { + val wrapped: List = try { api.connect(deviceIdArg) - wrapped = listOf(null) + listOf(null) } catch (exception: Throwable) { - wrapped = wrapError(exception) + wrapError(exception) } reply.reply(wrapped) } @@ -359,17 +356,16 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val deviceIdArg = args[0] as String - var wrapped: List - try { + val wrapped: List = try { api.disconnect(deviceIdArg) - wrapped = listOf(null) + listOf(null) } catch (exception: Throwable) { - wrapped = wrapError(exception) + wrapError(exception) } reply.reply(wrapped) } @@ -378,29 +374,29 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val deviceIdArg = args[0] as String val serviceArg = args[1] as String val characteristicArg = args[2] as String - val bleInputPropertyArg = args[3].let { if (it is Int) it.toLong() else it as Long } - var wrapped: List - try { - api.setNotifiable(deviceIdArg, serviceArg, characteristicArg, bleInputPropertyArg) - wrapped = listOf(null) - } catch (exception: Throwable) { - wrapped = wrapError(exception) + val bleInputPropertyArg = args[3].let { num -> if (num is Int) num.toLong() else num as Long } + api.setNotifiable(deviceIdArg, serviceArg, characteristicArg, bleInputPropertyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + reply.reply(wrapResult(null)) + } } - reply.reply(wrapped) } } else { channel.setMessageHandler(null) } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List @@ -420,7 +416,7 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List @@ -442,12 +438,12 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val deviceIdArg = args[0] as String - val expectedMtuArg = args[1].let { if (it is Int) it.toLong() else it as Long } + val expectedMtuArg = args[1].let { num -> if (num is Int) num.toLong() else num as Long } api.requestMtu(deviceIdArg, expectedMtuArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { @@ -463,7 +459,7 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List @@ -471,7 +467,7 @@ interface UniversalBlePlatformChannel { val serviceArg = args[1] as String val characteristicArg = args[2] as String val valueArg = args[3] as ByteArray - val bleOutputPropertyArg = args[4].let { if (it is Int) it.toLong() else it as Long } + val bleOutputPropertyArg = args[4].let { num -> if (num is Int) num.toLong() else num as Long } api.writeValue(deviceIdArg, serviceArg, characteristicArg, valueArg, bleOutputPropertyArg) { result: Result -> val error = result.exceptionOrNull() if (error != null) { @@ -486,7 +482,7 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List @@ -506,17 +502,16 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val deviceIdArg = args[0] as String - var wrapped: List - try { + val wrapped: List = try { api.pair(deviceIdArg) - wrapped = listOf(null) + listOf(null) } catch (exception: Throwable) { - wrapped = wrapError(exception) + wrapError(exception) } reply.reply(wrapped) } @@ -525,17 +520,16 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List val deviceIdArg = args[0] as String - var wrapped: List - try { + val wrapped: List = try { api.unPair(deviceIdArg) - wrapped = listOf(null) + listOf(null) } catch (exception: Throwable) { - wrapped = wrapError(exception) + wrapError(exception) } reply.reply(wrapped) } @@ -544,7 +538,7 @@ interface UniversalBlePlatformChannel { } } run { - val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices", codec) + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices$separatedMessageChannelSuffix", codec) if (api != null) { channel.setMessageHandler { message, reply -> val args = message as List @@ -566,7 +560,6 @@ interface UniversalBlePlatformChannel { } } } -@Suppress("UNCHECKED_CAST") private object UniversalBleCallbackChannelCodec : StandardMessageCodec() { override fun readValueOfType(type: Byte, buffer: ByteBuffer): Any? { return when (type) { @@ -594,8 +587,7 @@ private object UniversalBleCallbackChannelCodec : StandardMessageCodec() { * * Generated class from Pigeon that represents Flutter messages that can be called from Kotlin. */ -@Suppress("UNCHECKED_CAST") -class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger) { +class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger, private val messageChannelSuffix: String = "") { companion object { /** The codec used by UniversalBleCallbackChannel. */ val codec: MessageCodec by lazy { @@ -604,7 +596,8 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger) } fun onAvailabilityChanged(stateArg: Long, callback: (Result) -> Unit) { - val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged" + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) channel.send(listOf(stateArg)) { if (it is List<*>) { @@ -620,7 +613,8 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger) } fun onPairStateChange(deviceIdArg: String, isPairedArg: Boolean, errorArg: String?, callback: (Result) -> Unit) { - val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange" + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) channel.send(listOf(deviceIdArg, isPairedArg, errorArg)) { if (it is List<*>) { @@ -636,7 +630,8 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger) } fun onScanResult(resultArg: UniversalBleScanResult, callback: (Result) -> Unit) { - val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult" + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) channel.send(listOf(resultArg)) { if (it is List<*>) { @@ -652,7 +647,8 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger) } fun onValueChanged(deviceIdArg: String, characteristicIdArg: String, valueArg: ByteArray, callback: (Result) -> Unit) { - val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged" + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) channel.send(listOf(deviceIdArg, characteristicIdArg, valueArg)) { if (it is List<*>) { @@ -668,7 +664,8 @@ class UniversalBleCallbackChannel(private val binaryMessenger: BinaryMessenger) } fun onConnectionChanged(deviceIdArg: String, stateArg: Long, callback: (Result) -> Unit) { - val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged" + val separatedMessageChannelSuffix = if (messageChannelSuffix.isNotEmpty()) ".$messageChannelSuffix" else "" + val channelName = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged$separatedMessageChannelSuffix" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) channel.send(listOf(deviceIdArg, stateArg)) { if (it is List<*>) { diff --git a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBleHelper.kt b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBleHelper.kt index b224a07..db5fc48 100644 --- a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBleHelper.kt +++ b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBleHelper.kt @@ -15,6 +15,7 @@ import android.bluetooth.le.ScanCallback.SCAN_FAILED_OUT_OF_HARDWARE_RESOURCES import android.bluetooth.le.ScanCallback.SCAN_FAILED_SCANNING_TOO_FREQUENTLY import android.bluetooth.le.ScanFilter import android.bluetooth.le.ScanResult +import android.os.Build import android.os.ParcelUuid import android.util.Log import java.nio.ByteBuffer @@ -24,7 +25,7 @@ import java.util.UUID private const val TAG = "UniversalBlePlugin" val knownGatts = mutableListOf() - +val ccdCharacteristic = "00002902-0000-1000-8000-00805f9b34fb" enum class BleConnectionState(val value: Long) { Connected(0), @@ -216,12 +217,12 @@ fun BluetoothGatt.getCharacteristic( @SuppressLint("MissingPermission") +@Suppress("DEPRECATION") fun BluetoothGatt.setNotifiable( gattCharacteristic: BluetoothGattCharacteristic, bleInputProperty: Long, -) { - val descClientCharConfirmation = - UUID.fromString("00002902-0000-1000-8000-00805f9b34fb") +): Boolean { + val descClientCharConfirmation = UUID.fromString(ccdCharacteristic) val descriptor = gattCharacteristic.getDescriptor(descClientCharConfirmation) val bleInputPropertyEnum: BleInputProperty = BleInputProperty.values().first { it.value == bleInputProperty } @@ -230,8 +231,13 @@ fun BluetoothGatt.setNotifiable( BleInputProperty.Indication -> BluetoothGattDescriptor.ENABLE_INDICATION_VALUE to true else -> BluetoothGattDescriptor.DISABLE_NOTIFICATION_VALUE to false } - descriptor.value = value - setCharacteristicNotification(descriptor.characteristic, enable) && writeDescriptor(descriptor) + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + writeDescriptor(descriptor, value) + } else { + descriptor.value = value + writeDescriptor(descriptor) + } + return setCharacteristicNotification(descriptor.characteristic, enable) } fun BluetoothDevice.removeBond() { @@ -303,4 +309,11 @@ class WriteResultFuture( val characteristicId: String, val serviceId: String, val result: (Result) -> Unit, +) + +class CharacteristicSubscriptionFuture( + val deviceId: String, + val characteristicId: String, + val serviceId: String, + val result: (Result) -> Unit, ) \ No newline at end of file diff --git a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt index 78580fa..aba8cb2 100644 --- a/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt +++ b/android/src/main/kotlin/com/navideck/universal_ble/UniversalBlePlugin.kt @@ -17,13 +17,11 @@ import android.content.IntentFilter import android.os.Build import android.os.Handler import android.os.Looper -import android.os.ParcelUuid import android.util.Log import io.flutter.embedding.engine.plugins.FlutterPlugin import io.flutter.embedding.engine.plugins.activity.ActivityAware import io.flutter.embedding.engine.plugins.activity.ActivityPluginBinding import io.flutter.plugin.common.* -import java.util.* import java.util.concurrent.CountDownLatch import java.util.concurrent.TimeUnit @@ -42,6 +40,8 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), private val mtuResultFutureList = mutableListOf() private val bleCharacteristicFutureList = mutableListOf() private val discoverServicesFutureList = mutableListOf() + private val characteristicSubscriptionFutureList = + mutableListOf() private val writeResultFutureList = mutableListOf() private val cachedServicesMap = mutableMapOf>() private val devicesStateMap = mutableMapOf() @@ -56,7 +56,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), val intentFilter = IntentFilter(BluetoothAdapter.ACTION_STATE_CHANGED) intentFilter.addAction(BluetoothDevice.ACTION_BOND_STATE_CHANGED) - if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) { + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { context.registerReceiver(broadcastReceiver, intentFilter, RECEIVER_EXPORTED) } else { context.registerReceiver(broadcastReceiver, intentFilter) @@ -225,15 +225,50 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), service: String, characteristic: String, bleInputProperty: Long, + callback: (Result) -> Unit, ) { - val gatt = deviceId.toBluetoothGatt() - val gattCharacteristic = gatt.getCharacteristic(service, characteristic) - ?: throw FlutterError( - "IllegalArgument", - "Unknown characteristic: $characteristic", - null + try { + val gatt = deviceId.toBluetoothGatt() + val gattCharacteristic = gatt.getCharacteristic(service, characteristic) + ?: throw FlutterError( + "IllegalArgument", + "Unknown characteristic: $characteristic", + null + ) + + if (gatt.setNotifiable(gattCharacteristic, bleInputProperty)) { + characteristicSubscriptionFutureList.add( + CharacteristicSubscriptionFuture( + gatt.device.address, + gattCharacteristic.uuid.toString(), + gattCharacteristic.service.uuid.toString(), + callback + ) + ) + } else { + callback( + Result.failure( + FlutterError( + "Failed", + "Failed to update subscription state", + null + ) + ) + ) + } + } catch (e: FlutterError) { + callback(Result.failure(e)) + } catch (e: Exception) { + callback( + Result.failure( + FlutterError( + "Failed", + "Failed to update subscription state", + e.toString() + ) + ) ) - gatt.setNotifiable(gattCharacteristic, bleInputProperty) + } } override fun readValue( @@ -268,6 +303,16 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), ) } catch (e: FlutterError) { callback(Result.failure(e)) + } catch (e: Exception) { + callback( + Result.failure( + FlutterError( + "Failed", + "Failed to read value", + e.toString() + ) + ) + ) } } @@ -300,16 +345,6 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), } } - override fun onCharacteristicRead( - gatt: BluetoothGatt, - characteristic: BluetoothGattCharacteristic, - status: Int, - ) { - // Pass data to new api - onCharacteristicRead(gatt, characteristic, characteristic.value, status) - } - - override fun writeValue( deviceId: String, service: String, @@ -356,18 +391,23 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), } writeType = BluetoothGattCharacteristic.WRITE_TYPE_NO_RESPONSE } -// if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { -// val result = gatt.writeCharacteristic(gattCharacteristic, value, writeType) -// Log.v(TAG,"writeResult $characteristic: $result => ${result.parseBluetoothStatusCodeError()}") -// return -// } - gattCharacteristic.value = value - gattCharacteristic.writeType = writeType - val result = gatt.writeCharacteristic(gattCharacteristic) + + val result = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + val writeResult = gatt.writeCharacteristic(gattCharacteristic, value, writeType) + writeResult == BluetoothGatt.GATT_SUCCESS + } else { + @Suppress("DEPRECATION") + gattCharacteristic.value = value + gattCharacteristic.writeType = writeType + @Suppress("DEPRECATION") + gatt.writeCharacteristic(gattCharacteristic) + } + if (!result) { callback(Result.failure(FlutterError("Failed", "Failed to write", null))) return } + if (writeType == BluetoothGattCharacteristic.WRITE_TYPE_DEFAULT) { // wait for the result writeResultFutureList.add( @@ -535,13 +575,13 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), } // If its a known gatt, just discover services - knownGatts.find { it.device.address == device.address }?.let { - it.services?.let { services -> + knownGatts.find { it.device.address == device.address }?.let { gatt -> + gatt.services?.let { services -> updateCallback(services.map { service -> service.uuid.toString() }) return } - if (it.discoverServices()) { + if (gatt.discoverServices()) { discoverServicesFutureList.add( DiscoverServicesFuture(device.address) { uuids: Result> -> if (uuids.isSuccess) { @@ -616,7 +656,16 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), } } else if (intent.action == BluetoothDevice.ACTION_BOND_STATE_CHANGED) { val device: BluetoothDevice = - intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) ?: return + if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.TIRAMISU) { + intent.getParcelableExtra( + BluetoothDevice.EXTRA_DEVICE, + BluetoothDevice::class.java + ) + ?: return + } else { + @Suppress("DEPRECATION") + intent.getParcelableExtra(BluetoothDevice.EXTRA_DEVICE) ?: return + } // get pairing failed error when (intent.getIntExtra(BluetoothDevice.EXTRA_BOND_STATE, BluetoothDevice.ERROR)) { BluetoothDevice.BOND_BONDING -> { @@ -665,7 +714,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), override fun onScanResult(callbackType: Int, result: ScanResult) { // Log.v(TAG, "onScanResult: $result") - var serviceUuids: Array = arrayOf() + var serviceUuids: Array = arrayOf() result.device.uuids?.forEach { serviceUuids += it.uuid.toString() } @@ -687,7 +736,7 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), ) {} } } - + override fun onBatchScanResults(results: MutableList?) { Log.v(TAG, "onBatchScanResults: $results") } @@ -717,16 +766,62 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), override fun onCharacteristicChanged( gatt: BluetoothGatt, characteristic: BluetoothGattCharacteristic, + value: ByteArray, ) { mainThreadHandler?.post { callbackChannel?.onValueChanged( deviceIdArg = gatt.device.address, characteristicIdArg = characteristic.uuid.toString(), - valueArg = characteristic.value + valueArg = value ) {} } } + override fun onDescriptorWrite( + gatt: BluetoothGatt?, + descriptor: BluetoothGattDescriptor?, + status: Int, + ) { + super.onDescriptorWrite(gatt, descriptor, status) + if (descriptor?.uuid.toString() == ccdCharacteristic) { + val char: String? = descriptor?.characteristic?.uuid?.toString() + val service: String? = descriptor?.characteristic?.service?.uuid?.toString() + val deviceId: String? = gatt?.device?.address; + if (deviceId != null && char != null && service != null) { + updateSubscriptionState(deviceId, char, service, status) + } + } + } + + private fun updateSubscriptionState( + deviceId: String, + characteristic: String, + service: String, + status: Int, + ) { + characteristicSubscriptionFutureList.filter { + it.deviceId == deviceId && + it.characteristicId == characteristic && + it.serviceId == service + }.forEach { + characteristicSubscriptionFutureList.remove(it) + val error: String? = status.parseGattErrorCode() + if (error != null) { + it.result( + Result.failure( + FlutterError( + status.toString(), + "Failed to update subscription state: $error", + null, + ) + ) + ) + } else { + it.result(Result.success(Unit)) + } + } + } + private fun isBluetoothAvailable(): Boolean { return bluetoothManager.adapter.isEnabled } @@ -750,6 +845,24 @@ class UniversalBlePlugin : UniversalBlePlatformChannel, BluetoothGattCallback(), } } + /// Depreciated Members, ( Requires to support older android devices ) + @Suppress("OVERRIDE_DEPRECATION", "DEPRECATION") + override fun onCharacteristicRead( + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic, + status: Int, + ) { + onCharacteristicRead(gatt, characteristic, characteristic.value, status) + } + + @Suppress("OVERRIDE_DEPRECATION", "DEPRECATION") + override fun onCharacteristicChanged( + gatt: BluetoothGatt, + characteristic: BluetoothGattCharacteristic, + ) { + onCharacteristicChanged(gatt, characteristic, characteristic.value) + } + override fun onActivityResult(requestCode: Int, resultCode: Int, data: Intent?): Boolean { if (requestCode == bluetoothEnableRequestCode) { val future = bluetoothEnableRequestFuture ?: return false diff --git a/darwin/Classes/UniversalBle.g.swift b/darwin/Classes/UniversalBle.g.swift index ca44193..c88c702 100644 --- a/darwin/Classes/UniversalBle.g.swift +++ b/darwin/Classes/UniversalBle.g.swift @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v17.1.1), do not edit directly. +// Autogenerated from Pigeon (v18.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon import Foundation @@ -53,14 +53,15 @@ struct UniversalBleScanResult { var manufacturerDataHead: FlutterStandardTypedData? = nil var services: [String?]? = nil - static func fromList(_ list: [Any?]) -> UniversalBleScanResult? { - let deviceId = list[0] as! String - let name: String? = nilOrValue(list[1]) - let isPaired: Bool? = nilOrValue(list[2]) - let rssi: Int64? = isNullish(list[3]) ? nil : (list[3] is Int64? ? list[3] as! Int64? : Int64(list[3] as! Int32)) - let manufacturerData: FlutterStandardTypedData? = nilOrValue(list[4]) - let manufacturerDataHead: FlutterStandardTypedData? = nilOrValue(list[5]) - let services: [String?]? = nilOrValue(list[6]) + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ __pigeon_list: [Any?]) -> UniversalBleScanResult? { + let deviceId = __pigeon_list[0] as! String + let name: String? = nilOrValue(__pigeon_list[1]) + let isPaired: Bool? = nilOrValue(__pigeon_list[2]) + let rssi: Int64? = isNullish(__pigeon_list[3]) ? nil : (__pigeon_list[3] is Int64? ? __pigeon_list[3] as! Int64? : Int64(__pigeon_list[3] as! Int32)) + let manufacturerData: FlutterStandardTypedData? = nilOrValue(__pigeon_list[4]) + let manufacturerDataHead: FlutterStandardTypedData? = nilOrValue(__pigeon_list[5]) + let services: [String?]? = nilOrValue(__pigeon_list[6]) return UniversalBleScanResult( deviceId: deviceId, @@ -90,9 +91,10 @@ struct UniversalBleService { var uuid: String var characteristics: [UniversalBleCharacteristic?]? = nil - static func fromList(_ list: [Any?]) -> UniversalBleService? { - let uuid = list[0] as! String - let characteristics: [UniversalBleCharacteristic?]? = nilOrValue(list[1]) + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ __pigeon_list: [Any?]) -> UniversalBleService? { + let uuid = __pigeon_list[0] as! String + let characteristics: [UniversalBleCharacteristic?]? = nilOrValue(__pigeon_list[1]) return UniversalBleService( uuid: uuid, @@ -112,9 +114,10 @@ struct UniversalBleCharacteristic { var uuid: String var properties: [Int64?] - static func fromList(_ list: [Any?]) -> UniversalBleCharacteristic? { - let uuid = list[0] as! String - let properties = list[1] as! [Int64?] + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ __pigeon_list: [Any?]) -> UniversalBleCharacteristic? { + let uuid = __pigeon_list[0] as! String + let properties = __pigeon_list[1] as! [Int64?] return UniversalBleCharacteristic( uuid: uuid, @@ -136,9 +139,10 @@ struct UniversalScanFilter { var withServices: [String?] var withManufacturerData: [UniversalManufacturerDataFilter?] - static func fromList(_ list: [Any?]) -> UniversalScanFilter? { - let withServices = list[0] as! [String?] - let withManufacturerData = list[1] as! [UniversalManufacturerDataFilter?] + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ __pigeon_list: [Any?]) -> UniversalScanFilter? { + let withServices = __pigeon_list[0] as! [String?] + let withManufacturerData = __pigeon_list[1] as! [UniversalManufacturerDataFilter?] return UniversalScanFilter( withServices: withServices, @@ -159,10 +163,11 @@ struct UniversalManufacturerDataFilter { var data: FlutterStandardTypedData? = nil var mask: FlutterStandardTypedData? = nil - static func fromList(_ list: [Any?]) -> UniversalManufacturerDataFilter? { - let companyIdentifier: Int64? = isNullish(list[0]) ? nil : (list[0] is Int64? ? list[0] as! Int64? : Int64(list[0] as! Int32)) - let data: FlutterStandardTypedData? = nilOrValue(list[1]) - let mask: FlutterStandardTypedData? = nilOrValue(list[2]) + // swift-format-ignore: AlwaysUseLowerCamelCase + static func fromList(_ __pigeon_list: [Any?]) -> UniversalManufacturerDataFilter? { + let companyIdentifier: Int64? = isNullish(__pigeon_list[0]) ? nil : (__pigeon_list[0] is Int64? ? __pigeon_list[0] as! Int64? : Int64(__pigeon_list[0] as! Int32)) + let data: FlutterStandardTypedData? = nilOrValue(__pigeon_list[1]) + let mask: FlutterStandardTypedData? = nilOrValue(__pigeon_list[2]) return UniversalManufacturerDataFilter( companyIdentifier: companyIdentifier, @@ -245,7 +250,7 @@ protocol UniversalBlePlatformChannel { func stopScan() throws func connect(deviceId: String) throws func disconnect(deviceId: String) throws - func setNotifiable(deviceId: String, service: String, characteristic: String, bleInputProperty: Int64) throws + func setNotifiable(deviceId: String, service: String, characteristic: String, bleInputProperty: Int64, completion: @escaping (Result) -> Void) func discoverServices(deviceId: String, completion: @escaping (Result<[UniversalBleService], Error>) -> Void) func readValue(deviceId: String, service: String, characteristic: String, completion: @escaping (Result) -> Void) func requestMtu(deviceId: String, expectedMtu: Int64, completion: @escaping (Result) -> Void) @@ -261,8 +266,9 @@ class UniversalBlePlatformChannelSetup { /// The codec used by UniversalBlePlatformChannel. static var codec: FlutterStandardMessageCodec { UniversalBlePlatformChannelCodec.shared } /// Sets up an instance of `UniversalBlePlatformChannel` to handle messages through the `binaryMessenger`. - static func setUp(binaryMessenger: FlutterBinaryMessenger, api: UniversalBlePlatformChannel?) { - let getBluetoothAvailabilityStateChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState", binaryMessenger: binaryMessenger, codec: codec) + static func setUp(binaryMessenger: FlutterBinaryMessenger, api: UniversalBlePlatformChannel?, messageChannelSuffix: String = "") { + let channelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" + let getBluetoothAvailabilityStateChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getBluetoothAvailabilityStateChannel.setMessageHandler { _, reply in api.getBluetoothAvailabilityState { result in @@ -277,7 +283,7 @@ class UniversalBlePlatformChannelSetup { } else { getBluetoothAvailabilityStateChannel.setMessageHandler(nil) } - let enableBluetoothChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth", binaryMessenger: binaryMessenger, codec: codec) + let enableBluetoothChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { enableBluetoothChannel.setMessageHandler { _, reply in api.enableBluetooth { result in @@ -292,7 +298,7 @@ class UniversalBlePlatformChannelSetup { } else { enableBluetoothChannel.setMessageHandler(nil) } - let startScanChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", binaryMessenger: binaryMessenger, codec: codec) + let startScanChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { startScanChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -307,7 +313,7 @@ class UniversalBlePlatformChannelSetup { } else { startScanChannel.setMessageHandler(nil) } - let stopScanChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan", binaryMessenger: binaryMessenger, codec: codec) + let stopScanChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { stopScanChannel.setMessageHandler { _, reply in do { @@ -320,7 +326,7 @@ class UniversalBlePlatformChannelSetup { } else { stopScanChannel.setMessageHandler(nil) } - let connectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect", binaryMessenger: binaryMessenger, codec: codec) + let connectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { connectChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -335,7 +341,7 @@ class UniversalBlePlatformChannelSetup { } else { connectChannel.setMessageHandler(nil) } - let disconnectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect", binaryMessenger: binaryMessenger, codec: codec) + let disconnectChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { disconnectChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -350,7 +356,7 @@ class UniversalBlePlatformChannelSetup { } else { disconnectChannel.setMessageHandler(nil) } - let setNotifiableChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable", binaryMessenger: binaryMessenger, codec: codec) + let setNotifiableChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { setNotifiableChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -358,17 +364,19 @@ class UniversalBlePlatformChannelSetup { let serviceArg = args[1] as! String let characteristicArg = args[2] as! String let bleInputPropertyArg = args[3] is Int64 ? args[3] as! Int64 : Int64(args[3] as! Int32) - do { - try api.setNotifiable(deviceId: deviceIdArg, service: serviceArg, characteristic: characteristicArg, bleInputProperty: bleInputPropertyArg) - reply(wrapResult(nil)) - } catch { - reply(wrapError(error)) + api.setNotifiable(deviceId: deviceIdArg, service: serviceArg, characteristic: characteristicArg, bleInputProperty: bleInputPropertyArg) { result in + switch result { + case .success: + reply(wrapResult(nil)) + case .failure(let error): + reply(wrapError(error)) + } } } } else { setNotifiableChannel.setMessageHandler(nil) } - let discoverServicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices", binaryMessenger: binaryMessenger, codec: codec) + let discoverServicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { discoverServicesChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -385,7 +393,7 @@ class UniversalBlePlatformChannelSetup { } else { discoverServicesChannel.setMessageHandler(nil) } - let readValueChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue", binaryMessenger: binaryMessenger, codec: codec) + let readValueChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { readValueChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -404,7 +412,7 @@ class UniversalBlePlatformChannelSetup { } else { readValueChannel.setMessageHandler(nil) } - let requestMtuChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu", binaryMessenger: binaryMessenger, codec: codec) + let requestMtuChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { requestMtuChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -422,7 +430,7 @@ class UniversalBlePlatformChannelSetup { } else { requestMtuChannel.setMessageHandler(nil) } - let writeValueChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue", binaryMessenger: binaryMessenger, codec: codec) + let writeValueChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { writeValueChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -443,7 +451,7 @@ class UniversalBlePlatformChannelSetup { } else { writeValueChannel.setMessageHandler(nil) } - let isPairedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired", binaryMessenger: binaryMessenger, codec: codec) + let isPairedChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { isPairedChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -460,7 +468,7 @@ class UniversalBlePlatformChannelSetup { } else { isPairedChannel.setMessageHandler(nil) } - let pairChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair", binaryMessenger: binaryMessenger, codec: codec) + let pairChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { pairChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -475,7 +483,7 @@ class UniversalBlePlatformChannelSetup { } else { pairChannel.setMessageHandler(nil) } - let unPairChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair", binaryMessenger: binaryMessenger, codec: codec) + let unPairChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { unPairChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -490,7 +498,7 @@ class UniversalBlePlatformChannelSetup { } else { unPairChannel.setMessageHandler(nil) } - let getConnectedDevicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices", binaryMessenger: binaryMessenger, codec: codec) + let getConnectedDevicesChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices\(channelSuffix)", binaryMessenger: binaryMessenger, codec: codec) if let api = api { getConnectedDevicesChannel.setMessageHandler { message, reply in let args = message as! [Any?] @@ -557,14 +565,16 @@ protocol UniversalBleCallbackChannelProtocol { } class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol { private let binaryMessenger: FlutterBinaryMessenger - init(binaryMessenger: FlutterBinaryMessenger) { + private let messageChannelSuffix: String + init(binaryMessenger: FlutterBinaryMessenger, messageChannelSuffix: String = "") { self.binaryMessenger = binaryMessenger + self.messageChannelSuffix = messageChannelSuffix.count > 0 ? ".\(messageChannelSuffix)" : "" } var codec: FlutterStandardMessageCodec { return UniversalBleCallbackChannelCodec.shared } func onAvailabilityChanged(state stateArg: Int64, completion: @escaping (Result) -> Void) { - let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged" + let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([stateArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -582,7 +592,7 @@ class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol { } } func onPairStateChange(deviceId deviceIdArg: String, isPaired isPairedArg: Bool, error errorArg: String?, completion: @escaping (Result) -> Void) { - let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange" + let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([deviceIdArg, isPairedArg, errorArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -600,7 +610,7 @@ class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol { } } func onScanResult(result resultArg: UniversalBleScanResult, completion: @escaping (Result) -> Void) { - let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult" + let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([resultArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -618,7 +628,7 @@ class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol { } } func onValueChanged(deviceId deviceIdArg: String, characteristicId characteristicIdArg: String, value valueArg: FlutterStandardTypedData, completion: @escaping (Result) -> Void) { - let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged" + let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([deviceIdArg, characteristicIdArg, valueArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { @@ -636,7 +646,7 @@ class UniversalBleCallbackChannel: UniversalBleCallbackChannelProtocol { } } func onConnectionChanged(deviceId deviceIdArg: String, state stateArg: Int64, completion: @escaping (Result) -> Void) { - let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged" + let channelName: String = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged\(messageChannelSuffix)" let channel = FlutterBasicMessageChannel(name: channelName, binaryMessenger: binaryMessenger, codec: codec) channel.sendMessage([deviceIdArg, stateArg] as [Any?]) { response in guard let listResponse = response as? [Any?] else { diff --git a/darwin/Classes/UniversalBleHelper.swift b/darwin/Classes/UniversalBleHelper.swift index 6a35497..aa9d48a 100644 --- a/darwin/Classes/UniversalBleHelper.swift +++ b/darwin/Classes/UniversalBleHelper.swift @@ -227,6 +227,20 @@ class CharacteristicWriteFuture { } } +class CharacteristicNotifyFuture { + let deviceId: String + let characteristicId: String + let serviceId: String? + let result: (Result) -> Void + + init(deviceId: String, characteristicId: String, serviceId: String?, result: @escaping (Result) -> Void) { + self.deviceId = deviceId + self.characteristicId = characteristicId + self.serviceId = serviceId + self.result = result + } +} + class DiscoverServicesFuture { let deviceId: String let result: (Result<[UniversalBleService], Error>) -> Void diff --git a/darwin/Classes/UniversalBlePlugin.swift b/darwin/Classes/UniversalBlePlugin.swift index a034378..c684444 100644 --- a/darwin/Classes/UniversalBlePlugin.swift +++ b/darwin/Classes/UniversalBlePlugin.swift @@ -31,6 +31,7 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral private var discoveredServicesProgressMap: [String: [UniversalBleService]] = [:] private var characteristicReadFutures = [CharacteristicReadFuture]() private var characteristicWriteFutures = [CharacteristicWriteFuture]() + private var characteristicNotifyFutures = [CharacteristicNotifyFuture]() private var discoverServicesFutures = [DiscoverServicesFuture]() private var bluetoothAvailabilityStateCallback: ((Result) -> Void)? { didSet { @@ -122,13 +123,13 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral ) return } - + if discoveredServicesProgressMap[deviceId] != nil { print("Services discovery already in progress for :\(deviceId), waiting for completion.") discoverServicesFutures.append(DiscoverServicesFuture(deviceId: deviceId, result: completion)) return } - + if let cachedServices = peripheral.services { // If services already discovered no need to discover again if !cachedServices.isEmpty { @@ -138,8 +139,7 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral return } } - - + peripheral.discoverServices(nil) discoverServicesFutures.append(DiscoverServicesFuture(deviceId: deviceId, result: completion)) } @@ -154,23 +154,30 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral } } - func setNotifiable(deviceId: String, service: String, characteristic: String, bleInputProperty: Int64) throws { - let peripheral = try deviceId.getPeripheral() - - guard let c = peripheral.getCharacteristic(characteristic, of: service) else { - throw FlutterError(code: "IllegalArgument", message: "Unknown characteristic:\(characteristic)", details: nil) + func setNotifiable(deviceId: String, service: String, characteristic: String, bleInputProperty: Int64, completion: @escaping (Result) -> Void) { + guard let peripheral = discoveredPeripherals[deviceId] else { + completion(Result.failure(FlutterError(code: "IllegalArgument", message: "Unknown deviceId:\(self)", details: nil))) + return } - if bleInputProperty == BleInputProperty.notification.rawValue && !c.properties.contains(.notify) { - throw FlutterError(code: "InvalidAction", message: "Characteristic does not support notify", details: nil) + guard let gattCharacteristic = peripheral.getCharacteristic(characteristic, of: service) else { + completion(Result.failure(FlutterError(code: "IllegalArgument", message: "Unknown characteristic:\(characteristic)", details: nil))) + return } - if bleInputProperty == BleInputProperty.indication.rawValue && !c.properties.contains(.indicate) { - throw FlutterError(code: "InvalidAction", message: "Characteristic does not support indicate", details: nil) + if bleInputProperty == BleInputProperty.notification.rawValue && !gattCharacteristic.properties.contains(.notify) { + completion(Result.failure(FlutterError(code: "InvalidAction", message: "Characteristic does not support notify", details: nil))) + return + } + + if bleInputProperty == BleInputProperty.indication.rawValue && !gattCharacteristic.properties.contains(.indicate) { + completion(Result.failure(FlutterError(code: "InvalidAction", message: "Characteristic does not support indicate", details: nil))) + return } let shouldNotify = bleInputProperty != BleInputProperty.disabled.rawValue - peripheral.setNotifyValue(shouldNotify, for: c) + peripheral.setNotifyValue(shouldNotify, for: gattCharacteristic) + characteristicNotifyFutures.append(CharacteristicNotifyFuture(deviceId: deviceId, characteristicId: gattCharacteristic.uuid.uuidStr, serviceId: gattCharacteristic.service?.uuid.uuidStr, result: completion)) } func readValue(deviceId: String, service: String, characteristic: String, completion: @escaping (Result) -> Void) { @@ -338,8 +345,6 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral } public func peripheral(_ peripheral: CBPeripheral, didWriteValueFor characteristic: CBCharacteristic, error: Error?) { - // print("peripheral:didWriteValueForCharacteristic \(characteristic.uuid.uuidStr) error: \(String(describing: error))") - // Update futures for writeValue characteristicWriteFutures.removeAll { future in if future.deviceId == peripheral.uuid.uuidString && future.characteristicId == characteristic.uuid.uuidStr && future.serviceId == characteristic.service?.uuid.uuidStr { if let flutterError = error?.toFlutterError() { @@ -353,6 +358,20 @@ private class BleCentralDarwin: NSObject, UniversalBlePlatformChannel, CBCentral } } + public func peripheral(_ peripheral: CBPeripheral, didUpdateNotificationStateFor characteristic: CBCharacteristic, error: Error?) { + characteristicNotifyFutures.removeAll { future in + if future.deviceId == peripheral.uuid.uuidString && future.characteristicId == characteristic.uuid.uuidStr && future.serviceId == characteristic.service?.uuid.uuidStr { + if let flutterError = error?.toFlutterError() { + future.result(Result.failure(flutterError)) + } else { + future.result(Result.success({}())) + } + return true + } + return false + } + } + public func peripheral(_ peripheral: CBPeripheral, didUpdateValueFor characteristic: CBCharacteristic, error: Error?) { // Update callbackChannel if notifying if characteristic.isNotifying { diff --git a/example/ios/Podfile.lock b/example/ios/Podfile.lock index f33a4b0..1b112c7 100644 --- a/example/ios/Podfile.lock +++ b/example/ios/Podfile.lock @@ -38,4 +38,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: 819463e6a0290f5a72f145ba7cde16e8b6ef0796 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/example/ios/Runner.xcodeproj/project.pbxproj b/example/ios/Runner.xcodeproj/project.pbxproj index c486ea0..ee051a4 100644 --- a/example/ios/Runner.xcodeproj/project.pbxproj +++ b/example/ios/Runner.xcodeproj/project.pbxproj @@ -215,7 +215,7 @@ isa = PBXProject; attributes = { BuildIndependentTargetsInParallel = YES; - LastUpgradeCheck = 1430; + LastUpgradeCheck = 1510; ORGANIZATIONNAME = ""; TargetAttributes = { 331C8080294A63A400263BE5 = { diff --git a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme index 87131a0..8e3ca5d 100644 --- a/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme +++ b/example/ios/Runner.xcodeproj/xcshareddata/xcschemes/Runner.xcscheme @@ -1,6 +1,6 @@ pigeonChannelCodec = _UniversalBlePlatformChannelCodec(); + final String __pigeon_messageChannelSuffix; + Future getBluetoothAvailabilityState() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -274,8 +279,8 @@ class UniversalBlePlatformChannel { } Future enableBluetooth() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -303,8 +308,8 @@ class UniversalBlePlatformChannel { } Future startScan(UniversalScanFilter? filter) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -327,8 +332,8 @@ class UniversalBlePlatformChannel { } Future stopScan() async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -351,8 +356,8 @@ class UniversalBlePlatformChannel { } Future connect(String deviceId) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -375,8 +380,8 @@ class UniversalBlePlatformChannel { } Future disconnect(String deviceId) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -400,8 +405,8 @@ class UniversalBlePlatformChannel { Future setNotifiable(String deviceId, String service, String characteristic, int bleInputProperty) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -425,8 +430,8 @@ class UniversalBlePlatformChannel { } Future> discoverServices(String deviceId) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -456,8 +461,8 @@ class UniversalBlePlatformChannel { Future readValue( String deviceId, String service, String characteristic) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -485,8 +490,8 @@ class UniversalBlePlatformChannel { } Future requestMtu(String deviceId, int expectedMtu) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -515,8 +520,8 @@ class UniversalBlePlatformChannel { Future writeValue(String deviceId, String service, String characteristic, Uint8List value, int bleOutputProperty) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -545,8 +550,8 @@ class UniversalBlePlatformChannel { } Future isPaired(String deviceId) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -574,8 +579,8 @@ class UniversalBlePlatformChannel { } Future pair(String deviceId) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -598,8 +603,8 @@ class UniversalBlePlatformChannel { } Future unPair(String deviceId) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -623,8 +628,8 @@ class UniversalBlePlatformChannel { Future> getConnectedDevices( List withServices) async { - const String __pigeon_channelName = - 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices'; + final String __pigeon_channelName = + 'dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices$__pigeon_messageChannelSuffix'; final BasicMessageChannel __pigeon_channel = BasicMessageChannel( __pigeon_channelName, @@ -692,12 +697,17 @@ abstract class UniversalBleCallbackChannel { void onConnectionChanged(String deviceId, int state); - static void setup(UniversalBleCallbackChannel? api, - {BinaryMessenger? binaryMessenger}) { + static void setUp( + UniversalBleCallbackChannel? api, { + BinaryMessenger? binaryMessenger, + String messageChannelSuffix = '', + }) { + messageChannelSuffix = + messageChannelSuffix.isNotEmpty ? '.$messageChannelSuffix' : ''; { final BasicMessageChannel __pigeon_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged', + 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { @@ -725,7 +735,7 @@ abstract class UniversalBleCallbackChannel { { final BasicMessageChannel __pigeon_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange', + 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { @@ -757,7 +767,7 @@ abstract class UniversalBleCallbackChannel { { final BasicMessageChannel __pigeon_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult', + 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { @@ -786,7 +796,7 @@ abstract class UniversalBleCallbackChannel { { final BasicMessageChannel __pigeon_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged', + 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { @@ -821,7 +831,7 @@ abstract class UniversalBleCallbackChannel { { final BasicMessageChannel __pigeon_channel = BasicMessageChannel< Object?>( - 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged', + 'dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged$messageChannelSuffix', pigeonChannelCodec, binaryMessenger: binaryMessenger); if (api == null) { diff --git a/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart b/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart index 845472b..d843fe3 100644 --- a/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart +++ b/lib/src/universal_ble_pigeon/universal_ble_pigeon_channel.dart @@ -115,7 +115,7 @@ class UniversalBlePigeonChannel extends UniversalBlePlatform { /// To set listeners void _setupListeners() { - UniversalBleCallbackChannel.setup(_UniversalBleCallbackHandler( + UniversalBleCallbackChannel.setUp(_UniversalBleCallbackHandler( scanResult: (BleScanResult scanResult) => onScanResult?.call(scanResult), availabilityChange: (AvailabilityState state) => onAvailabilityChange?.call(state), diff --git a/pigeon/universal_ble.dart b/pigeon/universal_ble.dart index 7de5361..6a6c5a7 100644 --- a/pigeon/universal_ble.dart +++ b/pigeon/universal_ble.dart @@ -35,6 +35,7 @@ abstract class UniversalBlePlatformChannel { void disconnect(String deviceId); + @async void setNotifiable( String deviceId, String service, diff --git a/pubspec.yaml b/pubspec.yaml index 0c7fde3..9be132b 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -32,7 +32,7 @@ dev_dependencies: flutter_test: sdk: flutter flutter_lints: ^2.0.0 - pigeon: ^17.1.1 + pigeon: ^18.0.1 flutter: plugin: diff --git a/windows/src/generated/universal_ble.g.cpp b/windows/src/generated/universal_ble.g.cpp index cc924f2..5ab3c9b 100644 --- a/windows/src/generated/universal_ble.g.cpp +++ b/windows/src/generated/universal_ble.g.cpp @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v17.1.1), do not edit directly. +// Autogenerated from Pigeon (v18.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #undef _HAS_EXCEPTIONS @@ -453,8 +453,16 @@ const flutter::StandardMessageCodec& UniversalBlePlatformChannel::GetCodec() { void UniversalBlePlatformChannel::SetUp( flutter::BinaryMessenger* binary_messenger, UniversalBlePlatformChannel* api) { + UniversalBlePlatformChannel::SetUp(binary_messenger, api, ""); +} + +void UniversalBlePlatformChannel::SetUp( + flutter::BinaryMessenger* binary_messenger, + UniversalBlePlatformChannel* api, + const std::string& message_channel_suffix) { + const std::string prepended_suffix = message_channel_suffix.length() > 0 ? std::string(".") + message_channel_suffix : ""; { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getBluetoothAvailabilityState" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -476,7 +484,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.enableBluetooth" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -498,7 +506,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.startScan" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -522,7 +530,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.stopScan" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -543,7 +551,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.connect" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -571,7 +579,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.disconnect" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -599,7 +607,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.setNotifiable" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -628,14 +636,15 @@ void UniversalBlePlatformChannel::SetUp( return; } const int64_t ble_input_property_arg = encodable_ble_input_property_arg.LongValue(); - std::optional output = api->SetNotifiable(device_id_arg, service_arg, characteristic_arg, ble_input_property_arg); - if (output.has_value()) { - reply(WrapError(output.value())); - return; - } - EncodableList wrapped; - wrapped.push_back(EncodableValue()); - reply(EncodableValue(std::move(wrapped))); + api->SetNotifiable(device_id_arg, service_arg, characteristic_arg, ble_input_property_arg, [reply](std::optional&& output) { + if (output.has_value()) { + reply(WrapError(output.value())); + return; + } + EncodableList wrapped; + wrapped.push_back(EncodableValue()); + reply(EncodableValue(std::move(wrapped))); + }); } catch (const std::exception& exception) { reply(WrapError(exception.what())); } @@ -645,7 +654,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.discoverServices" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -674,7 +683,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.readValue" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -715,7 +724,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.requestMtu" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -750,7 +759,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.writeValue" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -803,7 +812,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.isPaired" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -832,7 +841,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.pair" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -860,7 +869,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.unPair" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -888,7 +897,7 @@ void UniversalBlePlatformChannel::SetUp( } } { - BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices", &GetCodec()); + BasicMessageChannel<> channel(binary_messenger, "dev.flutter.pigeon.universal_ble.UniversalBlePlatformChannel.getConnectedDevices" + prepended_suffix, &GetCodec()); if (api != nullptr) { channel.SetMessageHandler([api](const EncodableValue& message, const flutter::MessageReply& reply) { try { @@ -963,7 +972,14 @@ void UniversalBleCallbackChannelCodecSerializer::WriteValue( // Generated class from Pigeon that represents Flutter messages that can be called from C++. UniversalBleCallbackChannel::UniversalBleCallbackChannel(flutter::BinaryMessenger* binary_messenger) - : binary_messenger_(binary_messenger) {} + : binary_messenger_(binary_messenger), + message_channel_suffix_("") {} + +UniversalBleCallbackChannel::UniversalBleCallbackChannel( + flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix) + : binary_messenger_(binary_messenger), + message_channel_suffix_(message_channel_suffix.length() > 0 ? std::string(".") + message_channel_suffix : "") {} const flutter::StandardMessageCodec& UniversalBleCallbackChannel::GetCodec() { return flutter::StandardMessageCodec::GetInstance(&UniversalBleCallbackChannelCodecSerializer::GetInstance()); @@ -973,7 +989,7 @@ void UniversalBleCallbackChannel::OnAvailabilityChanged( int64_t state_arg, std::function&& on_success, std::function&& on_error) { - const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged"; + const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onAvailabilityChanged" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ EncodableValue(state_arg), @@ -1000,7 +1016,7 @@ void UniversalBleCallbackChannel::OnPairStateChange( const std::string* error_arg, std::function&& on_success, std::function&& on_error) { - const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange"; + const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onPairStateChange" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ EncodableValue(device_id_arg), @@ -1027,7 +1043,7 @@ void UniversalBleCallbackChannel::OnScanResult( const UniversalBleScanResult& result_arg, std::function&& on_success, std::function&& on_error) { - const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult"; + const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onScanResult" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ CustomEncodableValue(result_arg), @@ -1054,7 +1070,7 @@ void UniversalBleCallbackChannel::OnValueChanged( const std::vector& value_arg, std::function&& on_success, std::function&& on_error) { - const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged"; + const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onValueChanged" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ EncodableValue(device_id_arg), @@ -1082,7 +1098,7 @@ void UniversalBleCallbackChannel::OnConnectionChanged( int64_t state_arg, std::function&& on_success, std::function&& on_error) { - const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged"; + const std::string channel_name = "dev.flutter.pigeon.universal_ble.UniversalBleCallbackChannel.onConnectionChanged" + message_channel_suffix_; BasicMessageChannel<> channel(binary_messenger_, channel_name, &GetCodec()); EncodableValue encoded_api_arguments = EncodableValue(EncodableList{ EncodableValue(device_id_arg), diff --git a/windows/src/generated/universal_ble.g.h b/windows/src/generated/universal_ble.g.h index 35375bb..89f5b75 100644 --- a/windows/src/generated/universal_ble.g.h +++ b/windows/src/generated/universal_ble.g.h @@ -1,4 +1,4 @@ -// Autogenerated from Pigeon (v17.1.1), do not edit directly. +// Autogenerated from Pigeon (v18.0.1), do not edit directly. // See also: https://pub.dev/packages/pigeon #ifndef PIGEON_UNIVERSAL_BLE_G_H_ @@ -280,11 +280,12 @@ class UniversalBlePlatformChannel { virtual std::optional StopScan() = 0; virtual std::optional Connect(const std::string& device_id) = 0; virtual std::optional Disconnect(const std::string& device_id) = 0; - virtual std::optional SetNotifiable( + virtual void SetNotifiable( const std::string& device_id, const std::string& service, const std::string& characteristic, - int64_t ble_input_property) = 0; + int64_t ble_input_property, + std::function reply)> result) = 0; virtual void DiscoverServices( const std::string& device_id, std::function reply)> result) = 0; @@ -319,6 +320,10 @@ class UniversalBlePlatformChannel { static void SetUp( flutter::BinaryMessenger* binary_messenger, UniversalBlePlatformChannel* api); + static void SetUp( + flutter::BinaryMessenger* binary_messenger, + UniversalBlePlatformChannel* api, + const std::string& message_channel_suffix); static flutter::EncodableValue WrapError(std::string_view error_message); static flutter::EncodableValue WrapError(const FlutterError& error); @@ -351,6 +356,9 @@ class UniversalBleCallbackChannelCodecSerializer : public flutter::StandardCodec class UniversalBleCallbackChannel { public: UniversalBleCallbackChannel(flutter::BinaryMessenger* binary_messenger); + UniversalBleCallbackChannel( + flutter::BinaryMessenger* binary_messenger, + const std::string& message_channel_suffix); static const flutter::StandardMessageCodec& GetCodec(); void OnAvailabilityChanged( int64_t state, @@ -380,6 +388,7 @@ class UniversalBleCallbackChannel { private: flutter::BinaryMessenger* binary_messenger_; + std::string message_channel_suffix_; }; } // namespace universal_ble diff --git a/windows/src/universal_ble_plugin.cpp b/windows/src/universal_ble_plugin.cpp index 5350f14..9add74c 100644 --- a/windows/src/universal_ble_plugin.cpp +++ b/windows/src/universal_ble_plugin.cpp @@ -206,17 +206,21 @@ namespace universal_ble } } - std::optional UniversalBlePlugin::SetNotifiable( + void UniversalBlePlugin::SetNotifiable( const std::string &device_id, const std::string &service, const std::string &characteristic, - int64_t ble_input_property) + int64_t ble_input_property, + std::function reply)> result) { try { auto it = connectedDevices.find(_str_to_mac_address(device_id)); if (it == connectedDevices.end()) - return FlutterError("IllegalArgument", "Unknown devicesId:" + device_id); + { + result(FlutterError("IllegalArgument", "Unknown devicesId:" + device_id)); + return; + } auto bluetoothAgent = *it->second; GattCharacteristicObject &gatt_characteristic_holder = bluetoothAgent._fetch_characteristic(service, characteristic); GattCharacteristic gattCharacteristic = gatt_characteristic_holder.obj; @@ -228,7 +232,8 @@ namespace universal_ble descriptorValue = GattClientCharacteristicConfigurationDescriptorValue::Notify; if ((properties & GattCharacteristicProperties::Notify) == GattCharacteristicProperties::None) { - return FlutterError("Characteristic does not support notify"); + result(FlutterError("Characteristic does not support notify")); + return; } } else if (ble_input_property == static_cast(BleInputProperty::indication)) @@ -236,21 +241,21 @@ namespace universal_ble descriptorValue = GattClientCharacteristicConfigurationDescriptorValue::Indicate; if ((properties & GattCharacteristicProperties::Indicate) == GattCharacteristicProperties::None) { - return FlutterError("Characteristic does not support indicate"); + result(FlutterError("Characteristic does not support indicate")); + return; } } - SetNotifiableAsync(bluetoothAgent, service, characteristic, descriptorValue); - return std::nullopt; + SetNotifiableAsync(bluetoothAgent, service, characteristic, descriptorValue, result); } catch (const FlutterError &err) { - return err; + return result(err); } catch (...) { std::cout << "SetNotifiableLog: Unknown error" << std::endl; - return FlutterError("Unknown error"); + return result(FlutterError("Unknown error")); } }; @@ -1178,7 +1183,9 @@ namespace universal_ble }; winrt::fire_and_forget UniversalBlePlugin::SetNotifiableAsync(BluetoothDeviceAgent &bluetoothDeviceAgent, const std::string &service, - const std::string &characteristic, GattClientCharacteristicConfigurationDescriptorValue descriptorValue) + const std::string &characteristic, + GattClientCharacteristicConfigurationDescriptorValue descriptorValue, + std::function reply)> result) { GattCharacteristicObject &gatt_characteristic_holder = bluetoothDeviceAgent._fetch_characteristic(service, characteristic); GattCharacteristic gattCharacteristic = gatt_characteristic_holder.obj; @@ -1205,11 +1212,15 @@ namespace universal_ble std::cout << "FailedToSubscribe: Unknown" << to_uuidstr(gattCharacteristic.Uuid()) << std::endl; } if (status != GattCommunicationStatus::Success) + { + result(FlutterError("Failed to update notification state")); co_return; + } } catch (...) { std::cout << "FailedToPerformThisOperationOn: " << to_uuidstr(gattCharacteristic.Uuid()) << std::endl; + result(FlutterError("Failed to update notification state")); co_return; } // create uniqKey with uuid and deviceId @@ -1239,6 +1250,7 @@ namespace universal_ble } characteristicsTokens[uniqTokenKey] = gattCharacteristic.ValueChanged({this, &UniversalBlePlugin::GattCharacteristic_ValueChanged}); } + result(std::nullopt); } void UniversalBlePlugin::GattCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args) diff --git a/windows/src/universal_ble_plugin.h b/windows/src/universal_ble_plugin.h index daf2683..e1267df 100644 --- a/windows/src/universal_ble_plugin.h +++ b/windows/src/universal_ble_plugin.h @@ -113,7 +113,8 @@ namespace universal_ble void CleanConnection(uint64_t bluetoothAddress); void DiscoverServicesAsync(BluetoothDeviceAgent &bluetoothDeviceAgent, std::function reply)>); winrt::fire_and_forget SetNotifiableAsync(BluetoothDeviceAgent &bluetoothDeviceAgent, const std::string &service, - const std::string &characteristic, GattClientCharacteristicConfigurationDescriptorValue descriptorValue); + const std::string &characteristic, GattClientCharacteristicConfigurationDescriptorValue descriptorValue, + std::function reply)> result ); void GattCharacteristic_ValueChanged(GattCharacteristic sender, GattValueChangedEventArgs args); AvailabilityState getAvailabilityStateFromRadio(RadioState radioState); std::string parsePairingFailError(Enumeration::DevicePairingResult result); @@ -135,11 +136,12 @@ namespace universal_ble void DiscoverServices( const std::string &device_id, std::function reply)> result) override; - std::optional SetNotifiable( + void SetNotifiable( const std::string &device_id, const std::string &service, const std::string &characteristic, - int64_t ble_input_property) override; + int64_t ble_input_property, + std::function reply)> result) override; void ReadValue( const std::string &device_id, const std::string &service,