From 44efce78dfd7718bad005f108ca67aafd181773a Mon Sep 17 00:00:00 2001 From: iAMD Date: Thu, 1 Feb 2024 19:16:42 +0800 Subject: [PATCH] =?UTF-8?q?=E4=BF=AE=E5=A4=8D=E8=AF=BB=E5=8F=96=20CCCD=20?= =?UTF-8?q?=E6=8A=A5=E9=94=99=E7=9A=84=E9=97=AE=E9=A2=98=EF=BC=8C=E5=86=99?= =?UTF-8?q?=E5=85=A5=E6=97=B6=E6=9B=B4=E6=96=B0=E7=89=B9=E5=BE=81=E5=80=BC?= =?UTF-8?q?=20(#50)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * 修复 CCCD 无法读取的问题 * 优化代码 * 调整部分必需参数为可空参数 * 调整接口 * 写入时更新特征值 * 调整接口 * 适配新接口 * 调整依赖项 --- bluetooth_low_energy/CHANGELOG.md | 6 + bluetooth_low_energy/example/lib/main.dart | 16 +- bluetooth_low_energy/example/pubspec.lock | 24 +-- bluetooth_low_energy/pubspec.yaml | 14 +- bluetooth_low_energy_android/CHANGELOG.md | 10 + .../bluetooth_low_energy_android/MyApi.g.kt | 60 ++++-- .../MyPeripheralManager.kt | 68 +++--- .../example/lib/main.dart | 12 +- .../example/pubspec.lock | 8 +- .../lib/src/my_api.dart | 12 +- .../lib/src/my_api.g.dart | 147 ++++++++++--- .../lib/src/my_peripheral_manager.dart | 199 ++++++++++++++---- bluetooth_low_energy_android/my_api.dart | 25 ++- bluetooth_low_energy_android/pubspec.yaml | 6 +- bluetooth_low_energy_darwin/CHANGELOG.md | 9 + .../example/lib/main.dart | 12 +- .../example/pubspec.lock | 8 +- .../lib/src/my_api.dart | 12 +- .../lib/src/my_peripheral_manager.dart | 25 ++- bluetooth_low_energy_darwin/pubspec.yaml | 6 +- bluetooth_low_energy_linux/CHANGELOG.md | 8 + .../example/pubspec.lock | 8 +- bluetooth_low_energy_linux/pubspec.yaml | 6 +- .../CHANGELOG.md | 9 + .../lib/src/gatt_characteristic.dart | 2 +- .../lib/src/gatt_descriptor.dart | 2 +- .../lib/src/my_gatt_characteristic.dart | 6 +- .../lib/src/my_gatt_descriptor.dart | 6 +- .../pubspec.yaml | 4 +- bluetooth_low_energy_windows/CHANGELOG.md | 8 + .../example/pubspec.lock | 8 +- bluetooth_low_energy_windows/pubspec.yaml | 6 +- 32 files changed, 521 insertions(+), 231 deletions(-) diff --git a/bluetooth_low_energy/CHANGELOG.md b/bluetooth_low_energy/CHANGELOG.md index 98074bd..7751b7e 100644 --- a/bluetooth_low_energy/CHANGELOG.md +++ b/bluetooth_low_energy/CHANGELOG.md @@ -1,3 +1,9 @@ +## 5.0.6 + +* `Android` Fix the issue that [throws when read the CCCD(Client Characteristic Config Descriptor, 0x2902)](https://github.com/yanshouwang/bluetooth_low_energy/issues/47). +* `Android` `iOS` Update characteristic's value when write by centrals. +* Implements new Api. + ## 5.0.5 * `Windows` Fix the [`CentralManager#discoverGATT`, `CentralManager#readCharacteristic` and `CentralManager#readDescriptor` issue](https://github.com/yanshouwang/bluetooth_low_energy/issues/42) caused by cache mode. diff --git a/bluetooth_low_energy/example/lib/main.dart b/bluetooth_low_energy/example/lib/main.dart index 4dbf7a9..4165eb0 100644 --- a/bluetooth_low_energy/example/lib/main.dart +++ b/bluetooth_low_energy/example/lib/main.dart @@ -993,7 +993,7 @@ class _AdvertiserViewState extends State await PeripheralManager.instance.addService(batteryService); final elements = List.generate(1000, (i) => i % 256); final value = Uint8List.fromList(elements); - final myService = GattService( + final service = GattService( uuid: UUID.short(100), characteristics: [ GattCharacteristic( @@ -1010,37 +1010,37 @@ class _AdvertiserViewState extends State GattCharacteristicProperty.write, GattCharacteristicProperty.writeWithoutResponse, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(202), properties: [ GattCharacteristicProperty.notify, - GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(203), properties: [ - GattCharacteristicProperty.notify, + GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(204), properties: [ + GattCharacteristicProperty.read, + GattCharacteristicProperty.write, + GattCharacteristicProperty.writeWithoutResponse, + GattCharacteristicProperty.notify, GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), + value: value, descriptors: [], ), ], ); - await PeripheralManager.instance.addService(myService); + await PeripheralManager.instance.addService(service); final advertisement = Advertisement( name: 'le12138', manufacturerSpecificData: ManufacturerSpecificData( diff --git a/bluetooth_low_energy/example/pubspec.lock b/bluetooth_low_energy/example/pubspec.lock index 32c2684..5fcdcf4 100644 --- a/bluetooth_low_energy/example/pubspec.lock +++ b/bluetooth_low_energy/example/pubspec.lock @@ -23,47 +23,47 @@ packages: path: ".." relative: true source: path - version: "5.0.5" + version: "5.0.6" bluetooth_low_energy_android: dependency: transitive description: name: bluetooth_low_energy_android - sha256: "703faeeecce61887af4fa34bce5e0f5c25019d585f2e05723948332512c4eedc" + sha256: b06da128d4a15e094dac67e52e701fd331441c81425b0c776598aab01a07ccfe url: "https://pub.dev" source: hosted - version: "5.0.2" + version: "5.0.4" bluetooth_low_energy_darwin: dependency: transitive description: name: bluetooth_low_energy_darwin - sha256: e85bc6e97a087f2bb934a1b12953a0f6aab8dfdbe57302cb2bf6d61b996fa2ee + sha256: d8c37f27c48ad523e5c32d1002d8e67570b1f4e6d69c54e09bca152a07f6ab3f url: "https://pub.dev" source: hosted - version: "5.0.3" + version: "5.0.5" bluetooth_low_energy_linux: dependency: transitive description: name: bluetooth_low_energy_linux - sha256: "100dc824a9b409442e7018994de74d56d65faa95b8c6fbbf5a8c0ae70cd58286" + sha256: "2809830a8b67eac5d53fdc6e907aa878ec61884d6e6a42da2b79b826410c8327" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.2" bluetooth_low_energy_platform_interface: dependency: transitive description: name: bluetooth_low_energy_platform_interface - sha256: "54f92ab2d7746fb6f2b4a40a48cd7eb8e3bf772f3ee89e1979d4d7b741fb2a05" + sha256: "5af74eb8f97a896dfdbcff2da284d4fe5b4e2e49ebb2f46f826ac1810f66e4d7" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.2" bluetooth_low_energy_windows: dependency: transitive description: name: bluetooth_low_energy_windows - sha256: e2b812e00ff808feb5dca9404a5310f21fceecd2656f0a2d51f0bbeb9e8b258b + sha256: "5a0b22003d14dc84f3f16e73a77f2645df034badb9003f368e6f9bc02e8b249a" url: "https://pub.dev" source: hosted - version: "5.0.1" + version: "5.0.3" bluez: dependency: transitive description: @@ -392,4 +392,4 @@ packages: version: "6.5.0" sdks: dart: ">=3.2.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" diff --git a/bluetooth_low_energy/pubspec.yaml b/bluetooth_low_energy/pubspec.yaml index ee0c923..15d8a86 100644 --- a/bluetooth_low_energy/pubspec.yaml +++ b/bluetooth_low_energy/pubspec.yaml @@ -1,20 +1,20 @@ name: bluetooth_low_energy description: A Flutter plugin for controlling the bluetooth low energy, supports central and peripheral apis. -version: 5.0.5 +version: 5.0.6 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^5.0.0 - bluetooth_low_energy_android: ^5.0.2 - bluetooth_low_energy_darwin: ^5.0.3 - bluetooth_low_energy_windows: ^5.0.1 - bluetooth_low_energy_linux: ^5.0.0 + bluetooth_low_energy_platform_interface: ^5.0.2 + bluetooth_low_energy_android: ^5.0.4 + bluetooth_low_energy_darwin: ^5.0.5 + bluetooth_low_energy_windows: ^5.0.3 + bluetooth_low_energy_linux: ^5.0.2 dev_dependencies: flutter_test: diff --git a/bluetooth_low_energy_android/CHANGELOG.md b/bluetooth_low_energy_android/CHANGELOG.md index adc1d3c..fb26642 100644 --- a/bluetooth_low_energy_android/CHANGELOG.md +++ b/bluetooth_low_energy_android/CHANGELOG.md @@ -1,3 +1,13 @@ +## 5.0.4 + +* Change flutter minimum version to 3.0.0. + +## 5.0.3 + +* Fix the issue that [throws when read the CCCD(Client Characteristic Config Descriptor, 0x2902)](https://github.com/yanshouwang/bluetooth_low_energy/issues/47). +* Update characteristic's value when write by centrals. +* Implements new Api. + ## 5.0.2 * Fix the ConcurrentModificationException when `PeripheralManager#clearServices` is called. diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyApi.g.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyApi.g.kt index 0f0bb8d..0be0287 100644 --- a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyApi.g.kt +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyApi.g.kt @@ -1077,21 +1077,6 @@ class MyPeripheralManagerFlutterApi(private val binaryMessenger: BinaryMessenger } } } - fun onExecuteWrite(addressArgsArg: String, idArgsArg: Long, executeArgsArg: Boolean, callback: (Result) -> Unit) { - val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite" - val channel = BasicMessageChannel(binaryMessenger, channelName, codec) - channel.send(listOf(addressArgsArg, idArgsArg, executeArgsArg)) { - if (it is List<*>) { - if (it.size > 1) { - callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) - } else { - callback(Result.success(Unit)) - } - } else { - callback(Result.failure(createConnectionError(channelName))) - } - } - } fun onCharacteristicNotifyStateChanged(addressArgsArg: String, hashCodeArgsArg: Long, stateNumberArgsArg: Long, callback: (Result) -> Unit) { val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onCharacteristicNotifyStateChanged" val channel = BasicMessageChannel(binaryMessenger, channelName, codec) @@ -1107,4 +1092,49 @@ class MyPeripheralManagerFlutterApi(private val binaryMessenger: BinaryMessenger } } } + fun onDescriptorReadRequest(addressArgsArg: String, hashCodeArgsArg: Long, idArgsArg: Long, offsetArgsArg: Long, callback: (Result) -> Unit) { + val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(addressArgsArg, hashCodeArgsArg, idArgsArg, offsetArgsArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + fun onDescriptorWriteRequest(addressArgsArg: String, hashCodeArgsArg: Long, idArgsArg: Long, offsetArgsArg: Long, valueArgsArg: ByteArray, preparedWriteArgsArg: Boolean, responseNeededArgsArg: Boolean, callback: (Result) -> Unit) { + val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(addressArgsArg, hashCodeArgsArg, idArgsArg, offsetArgsArg, valueArgsArg, preparedWriteArgsArg, responseNeededArgsArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } + fun onExecuteWrite(addressArgsArg: String, idArgsArg: Long, executeArgsArg: Boolean, callback: (Result) -> Unit) { + val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite" + val channel = BasicMessageChannel(binaryMessenger, channelName, codec) + channel.send(listOf(addressArgsArg, idArgsArg, executeArgsArg)) { + if (it is List<*>) { + if (it.size > 1) { + callback(Result.failure(FlutterError(it[0] as String, it[1] as String, it[2] as String?))) + } else { + callback(Result.success(Unit)) + } + } else { + callback(Result.failure(createConnectionError(channelName))) + } + } + } } diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyPeripheralManager.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyPeripheralManager.kt index 68d531d..d1b1daf 100644 --- a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyPeripheralManager.kt +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyPeripheralManager.kt @@ -13,7 +13,6 @@ import android.bluetooth.le.AdvertiseCallback import android.bluetooth.le.AdvertiseSettings import android.content.Context import android.os.Build -import android.util.Log import io.flutter.plugin.common.BinaryMessenger class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) : @@ -116,21 +115,9 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) : val characteristicsArgs = serviceArgs.characteristicsArgs.filterNotNull() for (characteristicArgs in characteristicsArgs) { val characteristic = characteristicArgs.toCharacteristic() - val cccDescriptor = BluetoothGattDescriptor( - CLIENT_CHARACTERISTIC_CONFIG_UUID, - BluetoothGattDescriptor.PERMISSION_READ or BluetoothGattDescriptor.PERMISSION_WRITE - ) - val cccDescriptorAdded = characteristic.addDescriptor(cccDescriptor) - if (!cccDescriptorAdded) { - throw IllegalStateException() - } val descriptorsArgs = characteristicArgs.descriptorsArgs.filterNotNull() for (descriptorArgs in descriptorsArgs) { val descriptor = descriptorArgs.toDescriptor() - if (descriptor.uuid == CLIENT_CHARACTERISTIC_CONFIG_UUID) { - // Already added. - continue - } val descriptorHashCodeArgs = descriptorArgs.hashCodeArgs val descriptorHashCode = descriptor.hashCode() this.mDescriptorsArgs[descriptorHashCode] = descriptorArgs @@ -235,7 +222,7 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) : val offset = offsetArgs.toInt() val sent = mServer.sendResponse(device, requestId, status, offset, valueArgs) if (!sent) { - throw IllegalStateException("Send read characteristic reply failed.") + throw IllegalStateException("Send response failed.") } } @@ -366,14 +353,13 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) : fun onDescriptorReadRequest( device: BluetoothDevice, requestId: Int, offset: Int, descriptor: BluetoothGattDescriptor ) { - val status = BluetoothGatt.GATT_SUCCESS + val addressArgs = device.address val hashCode = descriptor.hashCode() - val descriptorArgs = mDescriptorsArgs[hashCode] as MyGattDescriptorArgs - val value = descriptorArgs.valueArgs - val sent = mServer.sendResponse(device, requestId, status, offset, value) - if (!sent) { - Log.e(TAG, "onDescriptorReadRequest: send response failed.") - } + val descriptorArgs = mDescriptorsArgs[hashCode] ?: return + val hashCodeArgs = descriptorArgs.hashCodeArgs + val idArgs = requestId.toLong() + val offsetArgs = offset.toLong() + mApi.onDescriptorReadRequest(addressArgs, hashCodeArgs, idArgs, offsetArgs) {} } fun onDescriptorWriteRequest( @@ -385,24 +371,18 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) : offset: Int, value: ByteArray ) { + val addressArgs = device.address + val hashCode = descriptor.hashCode() + val descriptorArgs = mDescriptorsArgs[hashCode] ?: return + val hashCodeArgs = descriptorArgs.hashCodeArgs + val idArgs = requestId.toLong() + val offsetArgs = offset.toLong() + mApi.onDescriptorWriteRequest( + addressArgs, hashCodeArgs, idArgs, offsetArgs, value, preparedWrite, responseNeeded + ) {} if (descriptor.uuid == CLIENT_CHARACTERISTIC_CONFIG_UUID) { - val addressArgs = device.address val characteristic = descriptor.characteristic - val hashCode = characteristic.hashCode() - val characteristicArgs = mCharacteristicsArgs[hashCode] ?: return - val hashCodeArgs = characteristicArgs.hashCodeArgs - val stateArgs = value.toNotifyStateArgs() - val stateNumberArgs = stateArgs.raw.toLong() - mApi.onCharacteristicNotifyStateChanged( - addressArgs, hashCodeArgs, stateNumberArgs - ) {} - } - if (responseNeeded) { - val status = BluetoothGatt.GATT_SUCCESS - val sent = mServer.sendResponse(device, requestId, status, offset, value) - if (!sent) { - Log.e(TAG, "onDescriptorReadRequest: send response failed.") - } + mOnCharacteristicNotifyStateChanged(device, characteristic, value) } } @@ -464,4 +444,18 @@ class MyPeripheralManager(context: Context, binaryMessenger: BinaryMessenger) : mServer.close() mOpening = false } + + private fun mOnCharacteristicNotifyStateChanged( + device: BluetoothDevice, + characteristic: BluetoothGattCharacteristic, + value: ByteArray + ) { + val addressArgs = device.address + val hashCode = characteristic.hashCode() + val characteristicArgs = mCharacteristicsArgs[hashCode] ?: return + val hashCodeArgs = characteristicArgs.hashCodeArgs + val stateArgs = value.toNotifyStateArgs() + val stateNumberArgs = stateArgs.raw.toLong() + mApi.onCharacteristicNotifyStateChanged(addressArgs, hashCodeArgs, stateNumberArgs) {} + } } \ No newline at end of file diff --git a/bluetooth_low_energy_android/example/lib/main.dart b/bluetooth_low_energy_android/example/lib/main.dart index f6e2074..3cfddfa 100644 --- a/bluetooth_low_energy_android/example/lib/main.dart +++ b/bluetooth_low_energy_android/example/lib/main.dart @@ -993,32 +993,32 @@ class _AdvertiserViewState extends State GattCharacteristicProperty.write, GattCharacteristicProperty.writeWithoutResponse, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(202), properties: [ GattCharacteristicProperty.notify, - GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(203), properties: [ - GattCharacteristicProperty.notify, + GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(204), properties: [ + GattCharacteristicProperty.read, + GattCharacteristicProperty.write, + GattCharacteristicProperty.writeWithoutResponse, + GattCharacteristicProperty.notify, GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), + value: value, descriptors: [], ), ], diff --git a/bluetooth_low_energy_android/example/pubspec.lock b/bluetooth_low_energy_android/example/pubspec.lock index c93eb73..9a79d04 100644 --- a/bluetooth_low_energy_android/example/pubspec.lock +++ b/bluetooth_low_energy_android/example/pubspec.lock @@ -15,15 +15,15 @@ packages: path: ".." relative: true source: path - version: "5.0.1" + version: "5.0.4" bluetooth_low_energy_platform_interface: dependency: "direct main" description: name: bluetooth_low_energy_platform_interface - sha256: "54f92ab2d7746fb6f2b4a40a48cd7eb8e3bf772f3ee89e1979d4d7b741fb2a05" + sha256: "5af74eb8f97a896dfdbcff2da284d4fe5b4e2e49ebb2f46f826ac1810f66e4d7" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.2" boolean_selector: dependency: transitive description: @@ -312,4 +312,4 @@ packages: version: "3.0.2" sdks: dart: ">=3.2.0-194.0.dev <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" diff --git a/bluetooth_low_energy_android/lib/src/my_api.dart b/bluetooth_low_energy_android/lib/src/my_api.dart index dc4882c..ebd30ab 100644 --- a/bluetooth_low_energy_android/lib/src/my_api.dart +++ b/bluetooth_low_energy_android/lib/src/my_api.dart @@ -204,17 +204,13 @@ extension MyGattDescriptorX on MyGattDescriptor { } extension MyGattCharacteristicX on MyGattCharacteristic { - MyGattCharacteristicArgs toArgs() { + MyGattCharacteristicArgs toArgs(List descriptorsArgs) { final hashCodeArgs = hashCode; final uuidArgs = uuid.toArgs(); final propertyNumbersArgs = properties.map((property) { final propertyArgs = property.toArgs(); return propertyArgs.index; }).toList(); - final descriptorsArgs = descriptors - .cast() - .map((descriptor) => descriptor.toArgs()) - .toList(); return MyGattCharacteristicArgs( hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, @@ -225,13 +221,9 @@ extension MyGattCharacteristicX on MyGattCharacteristic { } extension MyGattServiceX on MyGattService { - MyGattServiceArgs toArgs() { + MyGattServiceArgs toArgs(List characteristicsArgs) { final hashCodeArgs = hashCode; final uuidArgs = uuid.toArgs(); - final characteristicsArgs = characteristics - .cast() - .map((characteristic) => characteristic.toArgs()) - .toList(); return MyGattServiceArgs( hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, diff --git a/bluetooth_low_energy_android/lib/src/my_api.g.dart b/bluetooth_low_energy_android/lib/src/my_api.g.dart index d9a27be..c5adf3d 100644 --- a/bluetooth_low_energy_android/lib/src/my_api.g.dart +++ b/bluetooth_low_energy_android/lib/src/my_api.g.dart @@ -1085,10 +1085,14 @@ abstract class MyPeripheralManagerFlutterApi { void onCharacteristicWriteRequest(String addressArgs, int hashCodeArgs, int idArgs, int offsetArgs, Uint8List valueArgs, bool preparedWriteArgs, bool responseNeededArgs); - void onExecuteWrite(String addressArgs, int idArgs, bool executeArgs); - void onCharacteristicNotifyStateChanged(String addressArgs, int hashCodeArgs, int stateNumberArgs); + void onDescriptorReadRequest(String addressArgs, int hashCodeArgs, int idArgs, int offsetArgs); + + void onDescriptorWriteRequest(String addressArgs, int hashCodeArgs, int idArgs, int offsetArgs, Uint8List valueArgs, bool preparedWriteArgs, bool responseNeededArgs); + + void onExecuteWrite(String addressArgs, int idArgs, bool executeArgs); + static void setup(MyPeripheralManagerFlutterApi? api, {BinaryMessenger? binaryMessenger}) { { final BasicMessageChannel __pigeon_channel = BasicMessageChannel( @@ -1248,37 +1252,6 @@ abstract class MyPeripheralManagerFlutterApi { }); } } - { - final BasicMessageChannel __pigeon_channel = BasicMessageChannel( - 'dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite', pigeonChannelCodec, - binaryMessenger: binaryMessenger); - if (api == null) { - __pigeon_channel.setMessageHandler(null); - } else { - __pigeon_channel.setMessageHandler((Object? message) async { - assert(message != null, - 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null.'); - final List args = (message as List?)!; - final String? arg_addressArgs = (args[0] as String?); - assert(arg_addressArgs != null, - 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null, expected non-null String.'); - final int? arg_idArgs = (args[1] as int?); - assert(arg_idArgs != null, - 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null, expected non-null int.'); - final bool? arg_executeArgs = (args[2] as bool?); - assert(arg_executeArgs != null, - 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null, expected non-null bool.'); - try { - api.onExecuteWrite(arg_addressArgs!, arg_idArgs!, arg_executeArgs!); - return wrapResponse(empty: true); - } on PlatformException catch (e) { - return wrapResponse(error: e); - } catch (e) { - return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); - } - }); - } - } { final BasicMessageChannel __pigeon_channel = BasicMessageChannel( 'dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onCharacteristicNotifyStateChanged', pigeonChannelCodec, @@ -1310,5 +1283,113 @@ abstract class MyPeripheralManagerFlutterApi { }); } } + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest', pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest was null.'); + final List args = (message as List?)!; + final String? arg_addressArgs = (args[0] as String?); + assert(arg_addressArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest was null, expected non-null String.'); + final int? arg_hashCodeArgs = (args[1] as int?); + assert(arg_hashCodeArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest was null, expected non-null int.'); + final int? arg_idArgs = (args[2] as int?); + assert(arg_idArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest was null, expected non-null int.'); + final int? arg_offsetArgs = (args[3] as int?); + assert(arg_offsetArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest was null, expected non-null int.'); + try { + api.onDescriptorReadRequest(arg_addressArgs!, arg_hashCodeArgs!, arg_idArgs!, arg_offsetArgs!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest', pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null.'); + final List args = (message as List?)!; + final String? arg_addressArgs = (args[0] as String?); + assert(arg_addressArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null String.'); + final int? arg_hashCodeArgs = (args[1] as int?); + assert(arg_hashCodeArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null int.'); + final int? arg_idArgs = (args[2] as int?); + assert(arg_idArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null int.'); + final int? arg_offsetArgs = (args[3] as int?); + assert(arg_offsetArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null int.'); + final Uint8List? arg_valueArgs = (args[4] as Uint8List?); + assert(arg_valueArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null Uint8List.'); + final bool? arg_preparedWriteArgs = (args[5] as bool?); + assert(arg_preparedWriteArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null bool.'); + final bool? arg_responseNeededArgs = (args[6] as bool?); + assert(arg_responseNeededArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest was null, expected non-null bool.'); + try { + api.onDescriptorWriteRequest(arg_addressArgs!, arg_hashCodeArgs!, arg_idArgs!, arg_offsetArgs!, arg_valueArgs!, arg_preparedWriteArgs!, arg_responseNeededArgs!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } + { + final BasicMessageChannel __pigeon_channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite', pigeonChannelCodec, + binaryMessenger: binaryMessenger); + if (api == null) { + __pigeon_channel.setMessageHandler(null); + } else { + __pigeon_channel.setMessageHandler((Object? message) async { + assert(message != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null.'); + final List args = (message as List?)!; + final String? arg_addressArgs = (args[0] as String?); + assert(arg_addressArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null, expected non-null String.'); + final int? arg_idArgs = (args[1] as int?); + assert(arg_idArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null, expected non-null int.'); + final bool? arg_executeArgs = (args[2] as bool?); + assert(arg_executeArgs != null, + 'Argument for dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite was null, expected non-null bool.'); + try { + api.onExecuteWrite(arg_addressArgs!, arg_idArgs!, arg_executeArgs!); + return wrapResponse(empty: true); + } on PlatformException catch (e) { + return wrapResponse(error: e); + } catch (e) { + return wrapResponse(error: PlatformException(code: 'error', message: e.toString())); + } + }); + } + } } } diff --git a/bluetooth_low_energy_android/lib/src/my_peripheral_manager.dart b/bluetooth_low_energy_android/lib/src/my_peripheral_manager.dart index dac84d1..4280b13 100644 --- a/bluetooth_low_energy_android/lib/src/my_peripheral_manager.dart +++ b/bluetooth_low_energy_android/lib/src/my_peripheral_manager.dart @@ -21,9 +21,11 @@ class MyPeripheralManager extends PeripheralManager final Map _centrals; final Map> _characteristics; + final Map> _descriptors; final Map _mtus; final Map> _confirms; final Map _preparedCharacteristics; + final Map _preparedDescriptors; final Map> _preparedValue; BluetoothLowEnergyState _state; @@ -37,9 +39,11 @@ class MyPeripheralManager extends PeripheralManager StreamController.broadcast(), _centrals = {}, _characteristics = {}, + _descriptors = {}, _mtus = {}, _confirms = {}, _preparedCharacteristics = {}, + _preparedDescriptors = {}, _preparedValue = {}, _state = BluetoothLowEnergyState.unknown; @@ -75,14 +79,39 @@ class MyPeripheralManager extends PeripheralManager if (service is! MyGattService) { throw TypeError(); } - final serviceArgs = service.toArgs(); - final hashCodeArgs = serviceArgs.hashCodeArgs; - logger.info('addService: $hashCodeArgs'); + final characteristics = {}; + final descriptors = {}; + final characteristicsArgs = []; + for (var characteristic in service.characteristics) { + final descriptorsArgs = []; + final properties = characteristic.properties; + final canNotify = + properties.contains(GattCharacteristicProperty.notify) || + properties.contains(GattCharacteristicProperty.indicate); + if (canNotify) { + // CLIENT_CHARACTERISTIC_CONFIG + final cccDescriptor = MyGattDescriptor( + uuid: UUID.short(0x2902), + value: Uint8List.fromList([0x00, 0x00]), + ); + final cccDescriptorArgs = cccDescriptor.toArgs(); + descriptorsArgs.add(cccDescriptorArgs); + descriptors[cccDescriptorArgs.hashCodeArgs] = cccDescriptor; + } + for (var descriptor in characteristic.descriptors) { + final descriptorArgs = descriptor.toArgs(); + descriptorsArgs.add(descriptorArgs); + descriptors[descriptorArgs.hashCodeArgs] = descriptor; + } + final characteristicArgs = characteristic.toArgs(descriptorsArgs); + characteristicsArgs.add(characteristicArgs); + characteristics[characteristicArgs.hashCodeArgs] = characteristic; + } + final serviceArgs = service.toArgs(characteristicsArgs); + logger.info('addService: $serviceArgs'); await _api.addService(serviceArgs); - _characteristics[hashCodeArgs] = { - for (var characteristics in service.characteristics) - characteristics.hashCode: characteristics - }; + _characteristics[serviceArgs.hashCodeArgs] = characteristics; + _descriptors[serviceArgs.hashCodeArgs] = descriptors; } @override @@ -91,6 +120,7 @@ class MyPeripheralManager extends PeripheralManager logger.info('removeService: $hashCodeArgs'); await _api.removeService(hashCodeArgs); _characteristics.remove(hashCodeArgs); + _descriptors.remove(hashCodeArgs); } @override @@ -98,6 +128,7 @@ class MyPeripheralManager extends PeripheralManager logger.info('clearServices'); await _api.clearServices(); _characteristics.clear(); + _descriptors.clear(); } @override @@ -241,11 +272,11 @@ class MyPeripheralManager extends PeripheralManager int idArgs, int offsetArgs, Uint8List valueArgs, - bool preparedWrite, - bool responseNeeded, + bool preparedWriteArgs, + bool responseNeededArgs, ) async { logger.info( - 'onCharacteristicWriteRequest: $addressArgs.$hashCodeArgs - $idArgs, $offsetArgs, $valueArgs, $preparedWrite, $responseNeeded'); + 'onCharacteristicWriteRequest: $addressArgs.$hashCodeArgs - $idArgs, $offsetArgs, $valueArgs, $preparedWriteArgs, $responseNeededArgs'); final central = _centrals[addressArgs]; if (central == null) { return; @@ -255,7 +286,7 @@ class MyPeripheralManager extends PeripheralManager return; } final MyGattStatusArgs statusArgs; - if (preparedWrite) { + if (preparedWriteArgs) { final preparedCharacteristic = _preparedCharacteristics[addressArgs]; if (preparedCharacteristic != null && preparedCharacteristic != characteristic) { @@ -276,7 +307,7 @@ class MyPeripheralManager extends PeripheralManager _onCharacteristicWritten(central, characteristic, value); statusArgs = MyGattStatusArgs.success; } - if (responseNeeded) { + if (responseNeededArgs) { await _trySendResponse( addressArgs, idArgs, @@ -287,29 +318,6 @@ class MyPeripheralManager extends PeripheralManager } } - @override - void onExecuteWrite(String addressArgs, int idArgs, bool executeArgs) async { - logger.info('onExecuteWrite: $addressArgs - $idArgs, $executeArgs'); - final central = _centrals[addressArgs]; - final characteristic = _preparedCharacteristics.remove(addressArgs); - final elements = _preparedValue.remove(addressArgs); - if (central == null || characteristic == null || elements == null) { - return; - } - final value = Uint8List.fromList(elements); - final execute = executeArgs; - if (execute) { - _onCharacteristicWritten(central, characteristic, value); - } - await _trySendResponse( - addressArgs, - idArgs, - MyGattStatusArgs.success, - 0, - null, - ); - } - @override void onCharacteristicNotifyStateChanged( String addressArgs, @@ -344,12 +352,130 @@ class MyPeripheralManager extends PeripheralManager _characteristicNotifyStateChangedController.add(eventArgs); } + @override + void onDescriptorReadRequest( + String addressArgs, + int hashCodeArgs, + int idArgs, + int offsetArgs, + ) async { + logger.info( + 'onDescriptorReadRequest: $addressArgs.$hashCodeArgs - $idArgs, $offsetArgs'); + final central = _centrals[addressArgs]; + if (central == null) { + return; + } + final descriptor = _retrieveDescriptor(hashCodeArgs); + if (descriptor == null) { + return; + } + const statusArgs = MyGattStatusArgs.success; + final offset = offsetArgs; + final valueArgs = descriptor.value.sublist(offset); + await _trySendResponse( + addressArgs, + idArgs, + statusArgs, + offsetArgs, + valueArgs, + ); + } + + @override + void onDescriptorWriteRequest( + String addressArgs, + int hashCodeArgs, + int idArgs, + int offsetArgs, + Uint8List valueArgs, + bool preparedWriteArgs, + bool responseNeededArgs, + ) async { + logger.info( + 'onDescriptorWriteRequest: $addressArgs.$hashCodeArgs - $idArgs, $offsetArgs, $valueArgs, $preparedWriteArgs, $responseNeededArgs'); + final central = _centrals[addressArgs]; + if (central == null) { + return; + } + final descriptor = _retrieveDescriptor(hashCodeArgs); + if (descriptor == null) { + return; + } + final MyGattStatusArgs statusArgs; + if (preparedWriteArgs) { + final preparedDescriptor = _preparedCharacteristics[addressArgs]; + if (preparedDescriptor != null && preparedDescriptor != descriptor) { + statusArgs = MyGattStatusArgs.connectionCongested; + } else { + final preparedValueArgs = _preparedValue[addressArgs]; + if (preparedValueArgs == null) { + _preparedDescriptors[addressArgs] = descriptor; + // Change the immutable Uint8List to mutable. + _preparedValue[addressArgs] = [...valueArgs]; + } else { + preparedValueArgs.insertAll(offsetArgs, valueArgs); + } + statusArgs = MyGattStatusArgs.success; + } + } else { + descriptor.value = valueArgs; + statusArgs = MyGattStatusArgs.success; + } + if (responseNeededArgs) { + await _trySendResponse( + addressArgs, + idArgs, + statusArgs, + offsetArgs, + null, + ); + } + } + + @override + void onExecuteWrite(String addressArgs, int idArgs, bool executeArgs) async { + logger.info('onExecuteWrite: $addressArgs - $idArgs, $executeArgs'); + final central = _centrals[addressArgs]; + final characteristic = _preparedCharacteristics.remove(addressArgs); + final descriptor = _preparedDescriptors.remove(addressArgs); + final elements = _preparedValue.remove(addressArgs); + if (central == null || elements == null) { + return; + } + final value = Uint8List.fromList(elements); + final execute = executeArgs; + if (execute) { + if (characteristic == null && descriptor == null) { + return; + } + if (characteristic != null) { + _onCharacteristicWritten(central, characteristic, value); + } + if (descriptor != null) { + descriptor.value = value; + } + } + await _trySendResponse( + addressArgs, + idArgs, + MyGattStatusArgs.success, + 0, + null, + ); + } + MyGattCharacteristic? _retrieveCharacteristic(int hashCodeArgs) { final characteristics = _characteristics.values .reduce((value, element) => value..addAll(element)); return characteristics[hashCodeArgs]; } + MyGattDescriptor? _retrieveDescriptor(int hashCodeArgs) { + final descriptors = + _descriptors.values.reduce((value, element) => value..addAll(element)); + return descriptors[hashCodeArgs]; + } + bool? _retrieveConfirm(String addressArgs, int hashCodeArgs) { final confirms = _confirms[addressArgs]; if (confirms == null) { @@ -402,7 +528,8 @@ class MyPeripheralManager extends PeripheralManager MyGattCharacteristic characteristic, Uint8List value, ) async { - final trimmedValue = value.trimGATT(); + characteristic.value = value; + final trimmedValue = characteristic.value; final eventArgs = GattCharacteristicWrittenEventArgs( central, characteristic, diff --git a/bluetooth_low_energy_android/my_api.dart b/bluetooth_low_energy_android/my_api.dart index 5d1c84f..f3ebee6 100644 --- a/bluetooth_low_energy_android/my_api.dart +++ b/bluetooth_low_energy_android/my_api.dart @@ -230,14 +230,29 @@ abstract class MyPeripheralManagerFlutterApi { bool preparedWriteArgs, bool responseNeededArgs, ); - void onExecuteWrite( - String addressArgs, - int idArgs, - bool executeArgs, - ); void onCharacteristicNotifyStateChanged( String addressArgs, int hashCodeArgs, int stateNumberArgs, ); + void onDescriptorReadRequest( + String addressArgs, + int hashCodeArgs, + int idArgs, + int offsetArgs, + ); + void onDescriptorWriteRequest( + String addressArgs, + int hashCodeArgs, + int idArgs, + int offsetArgs, + Uint8List valueArgs, + bool preparedWriteArgs, + bool responseNeededArgs, + ); + void onExecuteWrite( + String addressArgs, + int idArgs, + bool executeArgs, + ); } diff --git a/bluetooth_low_energy_android/pubspec.yaml b/bluetooth_low_energy_android/pubspec.yaml index 0069f82..5e63862 100644 --- a/bluetooth_low_energy_android/pubspec.yaml +++ b/bluetooth_low_energy_android/pubspec.yaml @@ -1,16 +1,16 @@ name: bluetooth_low_energy_android description: Android implementation of the bluetooth_low_energy plugin. -version: 5.0.2 +version: 5.0.4 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^5.0.0 + bluetooth_low_energy_platform_interface: ^5.0.2 dev_dependencies: flutter_test: diff --git a/bluetooth_low_energy_darwin/CHANGELOG.md b/bluetooth_low_energy_darwin/CHANGELOG.md index b7118d4..85f4e2d 100644 --- a/bluetooth_low_energy_darwin/CHANGELOG.md +++ b/bluetooth_low_energy_darwin/CHANGELOG.md @@ -1,3 +1,12 @@ +## 5.0.5 + +* Change flutter minimum version to 3.0.0. + +## 5.0.4 + +* Update characteristic's value when write by centrals. +* Implements new Api. + ## 5.0.3 * Fix issues caused by CoW. diff --git a/bluetooth_low_energy_darwin/example/lib/main.dart b/bluetooth_low_energy_darwin/example/lib/main.dart index f6e2074..3cfddfa 100644 --- a/bluetooth_low_energy_darwin/example/lib/main.dart +++ b/bluetooth_low_energy_darwin/example/lib/main.dart @@ -993,32 +993,32 @@ class _AdvertiserViewState extends State GattCharacteristicProperty.write, GattCharacteristicProperty.writeWithoutResponse, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(202), properties: [ GattCharacteristicProperty.notify, - GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(203), properties: [ - GattCharacteristicProperty.notify, + GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), descriptors: [], ), GattCharacteristic( uuid: UUID.short(204), properties: [ + GattCharacteristicProperty.read, + GattCharacteristicProperty.write, + GattCharacteristicProperty.writeWithoutResponse, + GattCharacteristicProperty.notify, GattCharacteristicProperty.indicate, ], - value: Uint8List.fromList([]), + value: value, descriptors: [], ), ], diff --git a/bluetooth_low_energy_darwin/example/pubspec.lock b/bluetooth_low_energy_darwin/example/pubspec.lock index 688c6ed..475b366 100644 --- a/bluetooth_low_energy_darwin/example/pubspec.lock +++ b/bluetooth_low_energy_darwin/example/pubspec.lock @@ -15,15 +15,15 @@ packages: path: ".." relative: true source: path - version: "5.0.3" + version: "5.0.5" bluetooth_low_energy_platform_interface: dependency: "direct main" description: name: bluetooth_low_energy_platform_interface - sha256: "54f92ab2d7746fb6f2b4a40a48cd7eb8e3bf772f3ee89e1979d4d7b741fb2a05" + sha256: "5af74eb8f97a896dfdbcff2da284d4fe5b4e2e49ebb2f46f826ac1810f66e4d7" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.2" boolean_selector: dependency: transitive description: @@ -312,4 +312,4 @@ packages: version: "3.0.2" sdks: dart: ">=3.2.0-194.0.dev <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" diff --git a/bluetooth_low_energy_darwin/lib/src/my_api.dart b/bluetooth_low_energy_darwin/lib/src/my_api.dart index 2f6f5ed..4ef66a6 100644 --- a/bluetooth_low_energy_darwin/lib/src/my_api.dart +++ b/bluetooth_low_energy_darwin/lib/src/my_api.dart @@ -203,17 +203,13 @@ extension MyGattDescriptorX on MyGattDescriptor { } extension MyGattCharacteristicX on MyGattCharacteristic { - MyGattCharacteristicArgs toArgs() { + MyGattCharacteristicArgs toArgs(List descriptorsArgs) { final hashCodeArgs = hashCode; final uuidArgs = uuid.toArgs(); final propertyNumbersArgs = properties.map((property) { final propertyArgs = property.toArgs(); return propertyArgs.index; }).toList(); - final descriptorsArgs = descriptors - .cast() - .map((descriptor) => descriptor.toArgs()) - .toList(); return MyGattCharacteristicArgs( hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, @@ -224,13 +220,9 @@ extension MyGattCharacteristicX on MyGattCharacteristic { } extension MyGattServiceX on MyGattService { - MyGattServiceArgs toArgs() { + MyGattServiceArgs toArgs(List characteristicsArgs) { final hashCodeArgs = hashCode; final uuidArgs = uuid.toArgs(); - final characteristicsArgs = characteristics - .cast() - .map((characteristic) => characteristic.toArgs()) - .toList(); return MyGattServiceArgs( hashCodeArgs: hashCodeArgs, uuidArgs: uuidArgs, diff --git a/bluetooth_low_energy_darwin/lib/src/my_peripheral_manager.dart b/bluetooth_low_energy_darwin/lib/src/my_peripheral_manager.dart index 491a28a..4b00d92 100644 --- a/bluetooth_low_energy_darwin/lib/src/my_peripheral_manager.dart +++ b/bluetooth_low_energy_darwin/lib/src/my_peripheral_manager.dart @@ -65,14 +65,22 @@ class MyPeripheralManager extends PeripheralManager if (service is! MyGattService) { throw TypeError(); } - final serviceArgs = service.toArgs(); - final hashCodeArgs = serviceArgs.hashCodeArgs; - logger.info('addService: $hashCodeArgs'); + final characteristics = {}; + final characteristicsArgs = []; + for (var characteristic in service.characteristics) { + final descriptorsArgs = []; + for (var descriptor in characteristic.descriptors) { + final descriptorArgs = descriptor.toArgs(); + descriptorsArgs.add(descriptorArgs); + } + final characteristicArgs = characteristic.toArgs(descriptorsArgs); + characteristicsArgs.add(characteristicArgs); + characteristics[characteristicArgs.hashCodeArgs] = characteristic; + } + final serviceArgs = service.toArgs(characteristicsArgs); + logger.info('addService: $serviceArgs'); await _api.addService(serviceArgs); - _characteristics[hashCodeArgs] = { - for (var characteristics in service.characteristics) - characteristics.hashCode: characteristics - }; + _characteristics[serviceArgs.hashCodeArgs] = characteristics; } @override @@ -304,7 +312,8 @@ class MyPeripheralManager extends PeripheralManager MyGattCharacteristic characteristic, Uint8List value, ) async { - final trimmedValue = value.trimGATT(); + characteristic.value = value; + final trimmedValue = characteristic.value; final eventArgs = GattCharacteristicWrittenEventArgs( central, characteristic, diff --git a/bluetooth_low_energy_darwin/pubspec.yaml b/bluetooth_low_energy_darwin/pubspec.yaml index 1f79d24..9b4856d 100644 --- a/bluetooth_low_energy_darwin/pubspec.yaml +++ b/bluetooth_low_energy_darwin/pubspec.yaml @@ -1,16 +1,16 @@ name: bluetooth_low_energy_darwin description: iOS and macOS implementation of the bluetooth_low_energy plugin. -version: 5.0.3 +version: 5.0.5 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^5.0.0 + bluetooth_low_energy_platform_interface: ^5.0.2 dev_dependencies: flutter_test: diff --git a/bluetooth_low_energy_linux/CHANGELOG.md b/bluetooth_low_energy_linux/CHANGELOG.md index bd776b2..217dc16 100644 --- a/bluetooth_low_energy_linux/CHANGELOG.md +++ b/bluetooth_low_energy_linux/CHANGELOG.md @@ -1,3 +1,11 @@ +## 5.0.2 + +* Change flutter minimum version to 3.0.0. + +## 5.0.1 + +* Implements new Api. + ## 5.0.0 * Now `CentralManager#writeCharacteristic` will fragment the value automatically, the maximum write length is 512 bytes. diff --git a/bluetooth_low_energy_linux/example/pubspec.lock b/bluetooth_low_energy_linux/example/pubspec.lock index 7659b54..21191c5 100644 --- a/bluetooth_low_energy_linux/example/pubspec.lock +++ b/bluetooth_low_energy_linux/example/pubspec.lock @@ -23,15 +23,15 @@ packages: path: ".." relative: true source: path - version: "5.0.0" + version: "5.0.2" bluetooth_low_energy_platform_interface: dependency: "direct main" description: name: bluetooth_low_energy_platform_interface - sha256: "54f92ab2d7746fb6f2b4a40a48cd7eb8e3bf772f3ee89e1979d4d7b741fb2a05" + sha256: "5af74eb8f97a896dfdbcff2da284d4fe5b4e2e49ebb2f46f826ac1810f66e4d7" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.2" bluez: dependency: transitive description: @@ -360,4 +360,4 @@ packages: version: "6.5.0" sdks: dart: ">=3.2.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" diff --git a/bluetooth_low_energy_linux/pubspec.yaml b/bluetooth_low_energy_linux/pubspec.yaml index ad9b15b..ea07e58 100644 --- a/bluetooth_low_energy_linux/pubspec.yaml +++ b/bluetooth_low_energy_linux/pubspec.yaml @@ -1,16 +1,16 @@ name: bluetooth_low_energy_linux description: Linux implementation of the bluetooth_low_energy plugin. -version: 5.0.0 +version: 5.0.2 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^5.0.0 + bluetooth_low_energy_platform_interface: ^5.0.2 bluez: ^0.8.1 dev_dependencies: diff --git a/bluetooth_low_energy_platform_interface/CHANGELOG.md b/bluetooth_low_energy_platform_interface/CHANGELOG.md index 61b8593..bf817fd 100644 --- a/bluetooth_low_energy_platform_interface/CHANGELOG.md +++ b/bluetooth_low_energy_platform_interface/CHANGELOG.md @@ -1,3 +1,12 @@ +## 5.0.2 + +* Revert GATT characteristic's `descriptors` arguments to required. + +## 5.0.1 + +* Change GATT characteristic and descriptor's `value` arguments to optional. +* Change GATT characteristic's `descriptors` arguments to optional. + ## 5.0.0 * Now `CentralManager#writeCharacteristic` and `PeripheralManager#writeCharacteristic` will fragment the value automatically, the maximum write length is 512 bytes. diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart index be9ca64..456b291 100644 --- a/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_characteristic.dart @@ -19,7 +19,7 @@ abstract class GattCharacteristic extends GattAttribute { factory GattCharacteristic({ required UUID uuid, required List properties, - required Uint8List value, + Uint8List? value, required List descriptors, }) => MyGattCharacteristic( diff --git a/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart b/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart index 75b8b72..1a8dbec 100644 --- a/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart +++ b/bluetooth_low_energy_platform_interface/lib/src/gatt_descriptor.dart @@ -9,7 +9,7 @@ abstract class GattDescriptor extends GattAttribute { /// Constructs a [GattDescriptor]. factory GattDescriptor({ required UUID uuid, - required Uint8List value, + Uint8List? value, }) => MyGattDescriptor( uuid: uuid, diff --git a/bluetooth_low_energy_platform_interface/lib/src/my_gatt_characteristic.dart b/bluetooth_low_energy_platform_interface/lib/src/my_gatt_characteristic.dart index 082ab43..24fc16c 100644 --- a/bluetooth_low_energy_platform_interface/lib/src/my_gatt_characteristic.dart +++ b/bluetooth_low_energy_platform_interface/lib/src/my_gatt_characteristic.dart @@ -7,9 +7,9 @@ import 'my_gatt_descriptor.dart'; class MyGattCharacteristic extends MyGattAttribute implements GattCharacteristic { + Uint8List _value; @override final List properties; - Uint8List? _value; @override final List descriptors; @@ -18,9 +18,9 @@ class MyGattCharacteristic extends MyGattAttribute required this.properties, Uint8List? value, required this.descriptors, - }) : _value = value?.trimGATT(); + }) : _value = value?.trimGATT() ?? Uint8List(0); - Uint8List get value => _value ?? Uint8List.fromList([]); + Uint8List get value => _value; set value(Uint8List value) { _value = value.trimGATT(); } diff --git a/bluetooth_low_energy_platform_interface/lib/src/my_gatt_descriptor.dart b/bluetooth_low_energy_platform_interface/lib/src/my_gatt_descriptor.dart index 3ea7b3f..5054e67 100644 --- a/bluetooth_low_energy_platform_interface/lib/src/my_gatt_descriptor.dart +++ b/bluetooth_low_energy_platform_interface/lib/src/my_gatt_descriptor.dart @@ -4,14 +4,14 @@ import 'gatt_descriptor.dart'; import 'my_gatt_attribute.dart'; class MyGattDescriptor extends MyGattAttribute implements GattDescriptor { - Uint8List? _value; + Uint8List _value; MyGattDescriptor({ required super.uuid, Uint8List? value, - }) : _value = value?.trimGATT(); + }) : _value = value?.trimGATT() ?? Uint8List(0); - Uint8List get value => _value ?? Uint8List.fromList([]); + Uint8List get value => _value; set value(Uint8List value) { _value = value.trimGATT(); } diff --git a/bluetooth_low_energy_platform_interface/pubspec.yaml b/bluetooth_low_energy_platform_interface/pubspec.yaml index cdcc7aa..9afa4f8 100644 --- a/bluetooth_low_energy_platform_interface/pubspec.yaml +++ b/bluetooth_low_energy_platform_interface/pubspec.yaml @@ -1,11 +1,11 @@ name: bluetooth_low_energy_platform_interface description: A common platform interface for the bluetooth_low_energy plugin. -version: 5.0.0 +version: 5.0.2 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: sdk: '>=3.0.0 <4.0.0' - flutter: ">=3.3.0" + flutter: ">=3.0.0" dependencies: flutter: diff --git a/bluetooth_low_energy_windows/CHANGELOG.md b/bluetooth_low_energy_windows/CHANGELOG.md index 7b73900..712a68d 100644 --- a/bluetooth_low_energy_windows/CHANGELOG.md +++ b/bluetooth_low_energy_windows/CHANGELOG.md @@ -1,3 +1,11 @@ +## 5.0.3 + +* Change flutter minimum version to 3.0.0. + +## 5.0.2 + +* Implements new Api. + ## 5.0.1 * Fix the [`CentralManager#discoverGATT`, `CentralManager#readCharacteristic` and `CentralManager#readDescriptor` issue](https://github.com/yanshouwang/bluetooth_low_energy/issues/42) caused by cache mode. diff --git a/bluetooth_low_energy_windows/example/pubspec.lock b/bluetooth_low_energy_windows/example/pubspec.lock index 4a73ba1..d0c18e3 100644 --- a/bluetooth_low_energy_windows/example/pubspec.lock +++ b/bluetooth_low_energy_windows/example/pubspec.lock @@ -13,17 +13,17 @@ packages: dependency: "direct main" description: name: bluetooth_low_energy_platform_interface - sha256: "54f92ab2d7746fb6f2b4a40a48cd7eb8e3bf772f3ee89e1979d4d7b741fb2a05" + sha256: "5af74eb8f97a896dfdbcff2da284d4fe5b4e2e49ebb2f46f826ac1810f66e4d7" url: "https://pub.dev" source: hosted - version: "5.0.0" + version: "5.0.2" bluetooth_low_energy_windows: dependency: "direct main" description: path: ".." relative: true source: path - version: "5.0.1" + version: "5.0.3" boolean_selector: dependency: transitive description: @@ -312,4 +312,4 @@ packages: version: "3.0.2" sdks: dart: ">=3.2.0-194.0.dev <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" diff --git a/bluetooth_low_energy_windows/pubspec.yaml b/bluetooth_low_energy_windows/pubspec.yaml index 3ae203e..f1cf8cc 100644 --- a/bluetooth_low_energy_windows/pubspec.yaml +++ b/bluetooth_low_energy_windows/pubspec.yaml @@ -1,16 +1,16 @@ name: bluetooth_low_energy_windows description: Windows implementation of the bluetooth_low_energy plugin. -version: 5.0.1 +version: 5.0.3 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: sdk: ">=3.0.0 <4.0.0" - flutter: ">=3.3.0" + flutter: ">=3.0.0" dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^5.0.0 + bluetooth_low_energy_platform_interface: ^5.0.2 dev_dependencies: flutter_test: