From 78bcb88563fe9c030aa2d372494f58d53479f762 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mr=E5=89=91=E4=BE=A0=E5=AE=A2?= Date: Fri, 8 Sep 2023 15:25:59 +0800 Subject: [PATCH] =?UTF-8?q?feat:=20=E6=94=AF=E6=8C=81=E8=8E=B7=E5=8F=96=20?= =?UTF-8?q?maximumWrtieLength=20(#14)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- bluetooth_low_energy/CHANGELOG.md | 54 +++++++------ bluetooth_low_energy/example/lib/main.dart | 78 +++++++++++++++++-- bluetooth_low_energy/example/pubspec.lock | 38 ++++----- bluetooth_low_energy/pubspec.yaml | 12 +-- bluetooth_low_energy_android/CHANGELOG.md | 22 +++--- .../bluetooth_low_energy_android/MyApi.g.kt | 21 +++++ .../MyBluetoothGattCallback.kt | 7 ++ .../MyCentralController.kt | 35 ++++++++- .../lib/src/my_api.g.dart | 27 +++++++ .../lib/src/my_central_controller.dart | 19 ++++- bluetooth_low_energy_android/my_api.dart | 2 + bluetooth_low_energy_android/pubspec.yaml | 4 +- bluetooth_low_energy_darwin/CHANGELOG.md | 12 ++- .../darwin/Classes/MyApi.g.swift | 17 ++++ .../darwin/Classes/MyCentralController.swift | 15 ++++ .../lib/src/my_api.g.dart | 27 +++++++ .../lib/src/my_central_controller.dart | 22 +++++- bluetooth_low_energy_darwin/my_api.dart | 1 + bluetooth_low_energy_darwin/pubspec.yaml | 4 +- bluetooth_low_energy_linux/CHANGELOG.md | 22 +++--- .../lib/src/my_central_controller.dart | 9 +++ bluetooth_low_energy_linux/pubspec.yaml | 4 +- .../CHANGELOG.md | 34 +++++--- .../lib/src/central_controller.dart | 6 ++ .../pubspec.yaml | 2 +- bluetooth_low_energy_windows/CHANGELOG.md | 22 +++--- .../lib/src/my_central_controller.dart | 9 +++ bluetooth_low_energy_windows/pubspec.yaml | 4 +- 28 files changed, 417 insertions(+), 112 deletions(-) diff --git a/bluetooth_low_energy/CHANGELOG.md b/bluetooth_low_energy/CHANGELOG.md index 249b009..aa4f4e9 100644 --- a/bluetooth_low_energy/CHANGELOG.md +++ b/bluetooth_low_energy/CHANGELOG.md @@ -1,51 +1,55 @@ +## 2.2.0 + +* Add `CentralController#getMaximumWriteLength` method. + ## 2.0.3 -- `Android` Migrate to Android 13. -- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) +* `Android` Migrate to Android 13. +* `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) ## 2.0.2 -- Combine iOS and macOS projects. -- Optimize project structure. +* Combine iOS and macOS projects. +* Optimize project structure. ## 2.0.1 -- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. -- Fix the issue that create UUID form peripheral's address failed on Linux. -- Fix the issue that instance match failed on Linux. +* Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. +* Fix the issue that create UUID form peripheral's address failed on Linux. +* Fix the issue that instance match failed on Linux. ## 2.0.0 -- Rewrite the whole project with federated plugins. -- Support macOS and Linux. +* Rewrite the whole project with federated plugins. +* Support macOS and Linux. ## 1.1.0 -- Fix the crash by onMtuChanged called multi-times on Android. -- Fix the finalizer doesn't work issue. -- Make some break changes. +* Fix the crash by onMtuChanged called multi-times on Android. +* Fix the finalizer doesn't work issue. +* Make some break changes. ## 1.0.0 -- Upgrade to flutter 3.x. -- Rewrite the whole project with pigeon. +* Upgrade to flutter 3.x. +* Rewrite the whole project with pigeon. ## 0.1.0 -- Add implementations on iOS. -- Combine available and state for Bluetooth. -- Add connectable for Discovery. -- Add maximumWriteLength for GATT. +* Add implementations on iOS. +* Combine available and state for Bluetooth. +* Add connectable for Discovery. +* Add maximumWriteLength for GATT. ## 0.0.2 -- Fix connect blocked when bluetooth closed. -- Fix wrong repository url. -- Move all example files to main.dart. +* Fix connect blocked when bluetooth closed. +* Fix wrong repository url. +* Move all example files to main.dart. ## 0.0.1 -- Add central APIs. -- Add implementations on Android. -- Add example. -- Add test. +* Add central APIs. +* Add implementations on Android. +* Add example. +* Add test. diff --git a/bluetooth_low_energy/example/lib/main.dart b/bluetooth_low_energy/example/lib/main.dart index b5617b6..85fdb29 100644 --- a/bluetooth_low_energy/example/lib/main.dart +++ b/bluetooth_low_energy/example/lib/main.dart @@ -162,10 +162,10 @@ class _HomeViewState extends State { return ValueListenableBuilder( valueListenable: discoveredEventArgs, builder: (context, discoveredEventArgs, child) { - // final items = discoveredEventArgs - // .where((eventArgs) => eventArgs.advertisement.name != null) - // .toList(); - final items = discoveredEventArgs; + // final items = discoveredEventArgs; + final items = discoveredEventArgs + .where((eventArgs) => eventArgs.advertisement.name != null) + .toList(); return ListView.separated( itemBuilder: (context, i) { final theme = Theme.of(context); @@ -303,8 +303,10 @@ class _PeripheralViewState extends State { late final ValueNotifier> characteristics; late final ValueNotifier service; late final ValueNotifier characteristic; - late final TextEditingController writeController; + late final ValueNotifier writeType; + late final ValueNotifier maximumWriteLength; late final ValueNotifier> logs; + late final TextEditingController writeController; late final StreamSubscription stateChangedSubscription; late final StreamSubscription valueChangedSubscription; @@ -317,8 +319,10 @@ class _PeripheralViewState extends State { characteristics = ValueNotifier([]); service = ValueNotifier(null); characteristic = ValueNotifier(null); - writeController = TextEditingController(); + writeType = ValueNotifier(GattCharacteristicWriteType.withResponse); + maximumWriteLength = ValueNotifier(20); logs = ValueNotifier([]); + writeController = TextEditingController(); stateChangedSubscription = centralController.peripheralStateChanged.listen( (eventArgs) { if (eventArgs.peripheral != this.eventArgs.peripheral) { @@ -519,6 +523,64 @@ class _PeripheralViewState extends State { }, ), ), + Row( + children: [ + Expanded( + child: Center( + child: ValueListenableBuilder( + valueListenable: writeType, + builder: (context, writeType, child) { + final items = + GattCharacteristicWriteType.values.map((type) { + return DropdownMenuItem( + value: type, + child: Text( + type.name, + style: theme.textTheme.bodyMedium, + ), + ); + }).toList(); + return DropdownButton( + items: items, + onChanged: (type) { + if (type == null) { + return; + } + this.writeType.value = type; + }, + value: writeType, + underline: const Offstage(), + ); + }, + ), + ), + ), + Expanded( + child: ValueListenableBuilder( + valueListenable: state, + builder: (context, state, child) { + return TextButton( + onPressed: state + ? () async { + maximumWriteLength.value = + await centralController.getMaximumWriteLength( + eventArgs.peripheral, + type: writeType.value, + ); + } + : null, + child: ValueListenableBuilder( + valueListenable: maximumWriteLength, + builder: (context, maximumWriteLength, child) { + return Text('MTU: $maximumWriteLength'); + }, + ), + ); + }, + ), + ), + ], + ), Container( margin: const EdgeInsets.symmetric(vertical: 16.0), height: 160.0, @@ -626,6 +688,10 @@ class _PeripheralViewState extends State { characteristics.dispose(); service.dispose(); characteristic.dispose(); + writeType.dispose(); + maximumWriteLength.dispose(); + logs.dispose(); + writeController.dispose(); } } diff --git a/bluetooth_low_energy/example/pubspec.lock b/bluetooth_low_energy/example/pubspec.lock index b603525..f05bd76 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: "2.0.3" + version: "2.2.0" bluetooth_low_energy_android: dependency: transitive description: name: bluetooth_low_energy_android - sha256: e740179e5143c74e2f308c78d395d49054c941b95eb776884d52192b80ccfcee + sha256: fde30d9ef058f6859266a8e6d4218136958366de5978f69df2bb37d2b24679eb url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.2.0" bluetooth_low_energy_darwin: dependency: transitive description: name: bluetooth_low_energy_darwin - sha256: "49e9dc08281fb25f91472252dfbdf7d1d6d94983bf2e746382ad4b2dd8ba05fe" + sha256: "876f2d4a288739091296bc22ea574e64451f592154e4201b5999f174120a8b55" url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.2.0" bluetooth_low_energy_linux: dependency: transitive description: name: bluetooth_low_energy_linux - sha256: d9576d89471e31b76cb2495dbb72aabaadc3aa093ad607f5aedb15518d5c20cb + sha256: dc3062991e0a408941829326f0a3b2e1244a8138dca7f6c4c6beadbc26deecb2 url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.2.0" bluetooth_low_energy_platform_interface: dependency: transitive description: name: bluetooth_low_energy_platform_interface - sha256: dbc05f604e379ea7570db718a9ae7cf7fa08a20ee088a6f66de17b4acc7d9260 + sha256: eecaa2c37ebd536339c292d5566cf4360c9ea3861188342791eb3a0cf65cc64c url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.2.0" bluetooth_low_energy_windows: dependency: transitive description: name: bluetooth_low_energy_windows - sha256: c4d11b2769da214b5ea20f50980c00f3c3229450e46f9d075cd64298e5a27057 + sha256: a1b5d5d5ad935f15618e6a86334c1ec682c40ffbe6a78173c3f19b67ff0edcfb url: "https://pub.dev" source: hosted - version: "2.0.3" + version: "2.2.0" bluez: dependency: transitive description: @@ -116,10 +116,10 @@ packages: dependency: "direct main" description: name: cupertino_icons - sha256: e35129dc44c9118cee2a5603506d823bab99c68393879edb440e0090d07586be + sha256: d57953e10f9f8327ce64a508a355f0b1ec902193f66288e8cb5070e7c47eeb2d url: "https://pub.dev" source: hosted - version: "1.0.5" + version: "1.0.6" dbus: dependency: transitive description: @@ -166,10 +166,10 @@ packages: dependency: "direct dev" description: name: flutter_lints - sha256: "2118df84ef0c3ca93f96123a616ae8540879991b8b57af2f81b76a7ada49b2a4" + sha256: a25a15ebbdfc33ab1cd26c63a6ee519df92338a9c10f122adda92938253bef04 url: "https://pub.dev" source: hosted - version: "2.0.2" + version: "2.0.3" flutter_test: dependency: "direct dev" description: flutter @@ -253,10 +253,10 @@ packages: dependency: transitive description: name: plugin_platform_interface - sha256: "43798d895c929056255600343db8f049921cbec94d31ec87f1dc5c16c01935dd" + sha256: da3fdfeccc4d4ff2da8f8c556704c08f912542c5fb3cf2233ed75372384a034d url: "https://pub.dev" source: hosted - version: "2.1.5" + version: "2.1.6" process: dependency: transitive description: @@ -370,10 +370,10 @@ packages: dependency: transitive description: name: win32 - sha256: f2add6fa510d3ae152903412227bda57d0d5a8da61d2c39c1fb022c9429a41c0 + sha256: "9e82a402b7f3d518fb9c02d0e9ae45952df31b9bf34d77baf19da2de03fc2aaa" url: "https://pub.dev" source: hosted - version: "5.0.6" + version: "5.0.7" xml: dependency: transitive description: diff --git a/bluetooth_low_energy/pubspec.yaml b/bluetooth_low_energy/pubspec.yaml index 6cab240..026a654 100644 --- a/bluetooth_low_energy/pubspec.yaml +++ b/bluetooth_low_energy/pubspec.yaml @@ -1,6 +1,6 @@ name: bluetooth_low_energy description: A Flutter plugin for controlling the bluetooth low energy. -version: 2.0.3 +version: 2.2.0 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: @@ -10,11 +10,11 @@ environment: dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^2.0.3 - bluetooth_low_energy_android: ^2.0.3 - bluetooth_low_energy_darwin: ^2.0.3 - bluetooth_low_energy_linux: ^2.0.3 - bluetooth_low_energy_windows: ^2.0.3 + bluetooth_low_energy_platform_interface: ^2.2.0 + bluetooth_low_energy_android: ^2.2.0 + bluetooth_low_energy_darwin: ^2.2.0 + bluetooth_low_energy_linux: ^2.2.0 + bluetooth_low_energy_windows: ^2.2.0 dev_dependencies: flutter_test: diff --git a/bluetooth_low_energy_android/CHANGELOG.md b/bluetooth_low_energy_android/CHANGELOG.md index cd9ca34..af53ab5 100644 --- a/bluetooth_low_energy_android/CHANGELOG.md +++ b/bluetooth_low_energy_android/CHANGELOG.md @@ -1,20 +1,24 @@ +## 2.2.0 + +* Add `CentralController#getMaximumWriteLength` method. + ## 2.0.3 -- `Android` Migrate to Android 13. -- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) +* `Android` Migrate to Android 13. +* `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) ## 2.0.2 -- Combine iOS and macOS projects. -- Optimize project structure. +* Combine iOS and macOS projects. +* Optimize project structure. ## 2.0.1 -- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. -- Fix the issue that create UUID form peripheral's address failed on Linux. -- Fix the issue that instance match failed on Linux. +* Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. +* Fix the issue that create UUID form peripheral's address failed on Linux. +* Fix the issue that instance match failed on Linux. ## 2.0.0 -- Rewrite the whole project with federated plugins. -- Support macOS and Linux. +* Rewrite the whole project with federated plugins. +* Support macOS and Linux. 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 68180d8..0cd40f3 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 @@ -278,6 +278,7 @@ interface MyCentralControllerHostApi { fun stopDiscovery() fun connect(myPeripheralKey: Long, callback: (Result) -> Unit) fun disconnect(myPeripheralKey: Long, callback: (Result) -> Unit) + fun getMaximumWriteLength(myPeripheralKey: Long, callback: (Result) -> Unit) fun discoverGATT(myPeripheralKey: Long, callback: (Result) -> Unit) fun getServices(myPeripheralKey: Long): List fun getCharacteristics(myServiceKey: Long): List @@ -403,6 +404,26 @@ interface MyCentralControllerHostApi { channel.setMessageHandler(null) } } + run { + val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getMaximumWriteLength", codec) + if (api != null) { + channel.setMessageHandler { message, reply -> + val args = message as List + val myPeripheralKeyArg = args[0].let { if (it is Int) it.toLong() else it as Long } + api.getMaximumWriteLength(myPeripheralKeyArg) { result: Result -> + val error = result.exceptionOrNull() + if (error != null) { + reply.reply(wrapError(error)) + } else { + val data = result.getOrNull() + reply.reply(wrapResult(data)) + } + } + } + } else { + channel.setMessageHandler(null) + } + } run { val channel = BasicMessageChannel(binaryMessenger, "dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.discoverGATT", codec) if (api != null) { diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyBluetoothGattCallback.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyBluetoothGattCallback.kt index b28e75f..869aa9a 100644 --- a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyBluetoothGattCallback.kt +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyBluetoothGattCallback.kt @@ -15,6 +15,13 @@ class MyBluetoothGattCallback(private val myCentralController: MyCentralControll } } + override fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) { + super.onMtuChanged(gatt, mtu, status) + executor.execute { + myCentralController.onMtuChanged(gatt, mtu, status) + } + } + override fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { super.onServicesDiscovered(gatt, status) executor.execute { diff --git a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyCentralController.kt b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyCentralController.kt index c131bef..22caa4c 100644 --- a/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyCentralController.kt +++ b/bluetooth_low_energy_android/android/src/main/kotlin/dev/yanshouwang/bluetooth_low_energy_android/MyCentralController.kt @@ -59,6 +59,7 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM private var startDiscoveryCallback: ((Result) -> Unit)? = null private val connectCallbacks = mutableMapOf) -> Unit>() private val disconnectCallbacks = mutableMapOf) -> Unit>() + private val getMaximumWriteLengthCallbacks = mutableMapOf) -> Unit>() private val discoverGattCallbacks = mutableMapOf) -> Unit>() private val readCharacteristicCallbacks = mutableMapOf) -> Unit>() private val writeCharacteristicCallbacks = mutableMapOf) -> Unit>() @@ -179,6 +180,24 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM } } + override fun getMaximumWriteLength(myPeripheralKey: Long, callback: (Result) -> Unit) { + try { + val deviceKey = myPeripheralKey.toInt() + val unfinishedCallback = getMaximumWriteLengthCallbacks[deviceKey] + if (unfinishedCallback != null) { + throw IllegalStateException() + } + val gatt = cachedGATTs[deviceKey] as BluetoothGatt + val requesting = gatt.requestMtu(512) + if (!requesting) { + throw IllegalStateException() + } + getMaximumWriteLengthCallbacks[deviceKey] = callback + } catch (e: Throwable) { + callback(Result.failure(e)) + } + } + override fun discoverGATT(myPeripheralKey: Long, callback: (Result) -> Unit) { try { val deviceKey = myPeripheralKey.toInt() @@ -493,6 +512,19 @@ class MyCentralController(private val context: Context, binaryMessenger: BinaryM } } + fun onMtuChanged(gatt: BluetoothGatt, mtu: Int, status: Int) { + val device = gatt.device + val deviceKey = device.hashCode() + val callback = getMaximumWriteLengthCallbacks.remove(deviceKey) ?: return + if (status == BluetoothGatt.GATT_SUCCESS) { + val maximumWriteLength = (mtu - 3).toLong() + callback(Result.success(maximumWriteLength)) + } else { + val error = IllegalStateException("Get maximum write length failed with status: $status") + callback(Result.failure(error)) + } + } + fun onServicesDiscovered(gatt: BluetoothGatt, status: Int) { val device = gatt.device val deviceKey = device.hashCode() @@ -609,7 +641,8 @@ private val ScanResult.myAdvertisementArgs: MyAdvertisementArgs } else { val name = record.deviceName val manufacturerSpecificData = record.manufacturerSpecificData.toMyArgs() - val serviceUUIDs = record.serviceUuids?.map { uuid -> uuid.toString() } ?: emptyList() + val serviceUUIDs = record.serviceUuids?.map { uuid -> uuid.toString() } + ?: emptyList() val pairs = record.serviceData.entries.map { (uuid, value) -> val key = uuid.toString() return@map Pair(key, value) 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 03e0d35..e76744a 100644 --- a/bluetooth_low_energy_android/lib/src/my_api.g.dart +++ b/bluetooth_low_energy_android/lib/src/my_api.g.dart @@ -380,6 +380,33 @@ class MyCentralControllerHostApi { } } + Future getMaximumWriteLength(int arg_myPeripheralKey) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.getMaximumWriteLength', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as int?)!; + } + } + Future discoverGATT(int arg_myPeripheralKey) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.bluetooth_low_energy_android.MyCentralControllerHostApi.discoverGATT', codec, diff --git a/bluetooth_low_energy_android/lib/src/my_central_controller.dart b/bluetooth_low_energy_android/lib/src/my_central_controller.dart index 0cc0b51..0ce6201 100644 --- a/bluetooth_low_energy_android/lib/src/my_central_controller.dart +++ b/bluetooth_low_energy_android/lib/src/my_central_controller.dart @@ -114,6 +114,19 @@ class MyCentralController extends CentralController await _myApi.disconnect(myPeripheral.hashCode); } + @override + Future getMaximumWriteLength( + Peripheral peripheral, { + required GattCharacteristicWriteType type, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final maximumWriteLength = await _myApi.getMaximumWriteLength( + myPeripheral.hashCode, + ); + return maximumWriteLength; + } + @override Future discoverGATT(Peripheral peripheral) async { await _throwWithoutState(CentralState.poweredOn); @@ -205,14 +218,14 @@ class MyCentralController extends CentralController final myCharacteristic = characteristic as MyGattCharacteristic; final myService = myCharacteristic.myService; final myPeripheral = myService.myPeripheral; - final typeArgs = type.toMyArgs(); - final typeNumber = typeArgs.index; + final myTypeArgs = type.toMyArgs(); + final myTypeNumber = myTypeArgs.index; await _myApi.writeCharacteristic( myPeripheral.hashCode, myService.hashCode, myCharacteristic.hashCode, value, - typeNumber, + myTypeNumber, ); } diff --git a/bluetooth_low_energy_android/my_api.dart b/bluetooth_low_energy_android/my_api.dart index 89766b5..10dc609 100644 --- a/bluetooth_low_energy_android/my_api.dart +++ b/bluetooth_low_energy_android/my_api.dart @@ -24,6 +24,8 @@ abstract class MyCentralControllerHostApi { @async void disconnect(int myPeripheralKey); @async + int getMaximumWriteLength(int myPeripheralKey); + @async void discoverGATT(int myPeripheralKey); List getServices(int myPeripheralKey); List getCharacteristics(int myServiceKey); diff --git a/bluetooth_low_energy_android/pubspec.yaml b/bluetooth_low_energy_android/pubspec.yaml index 9157961..e528417 100644 --- a/bluetooth_low_energy_android/pubspec.yaml +++ b/bluetooth_low_energy_android/pubspec.yaml @@ -1,6 +1,6 @@ name: bluetooth_low_energy_android description: Android implementation of the bluetooth_low_energy plugin. -version: 2.0.3 +version: 2.2.0 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: @@ -10,7 +10,7 @@ environment: dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^2.0.3 + bluetooth_low_energy_platform_interface: ^2.2.0 dev_dependencies: flutter_test: diff --git a/bluetooth_low_energy_darwin/CHANGELOG.md b/bluetooth_low_energy_darwin/CHANGELOG.md index 209f745..e57523f 100644 --- a/bluetooth_low_energy_darwin/CHANGELOG.md +++ b/bluetooth_low_energy_darwin/CHANGELOG.md @@ -1,9 +1,13 @@ +## 2.2.0 + +* Add `CentralController#getMaximumWriteLength` method. + ## 2.0.3 -- `Android` Migrate to Android 13. -- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) +* `Android` Migrate to Android 13. +* `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) ## 2.0.2 -- Combine iOS and macOS projects. -- Optimize project structure. +* Combine iOS and macOS projects. +* Optimize project structure. diff --git a/bluetooth_low_energy_darwin/darwin/Classes/MyApi.g.swift b/bluetooth_low_energy_darwin/darwin/Classes/MyApi.g.swift index 31f02f0..2376e31 100644 --- a/bluetooth_low_energy_darwin/darwin/Classes/MyApi.g.swift +++ b/bluetooth_low_energy_darwin/darwin/Classes/MyApi.g.swift @@ -254,6 +254,7 @@ protocol MyCentralControllerHostApi { func stopDiscovery() throws func connect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) func disconnect(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) + func getMaximumWriteLength(myPeripheralKey: Int64, myTypeNumber: Int64) throws -> Int64 func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) func getServices(myPeripheralKey: Int64) throws -> [MyGattServiceArgs] func getCharacteristics(myServiceKey: Int64) throws -> [MyGattCharacteristicArgs] @@ -359,6 +360,22 @@ class MyCentralControllerHostApiSetup { } else { disconnectChannel.setMessageHandler(nil) } + let getMaximumWriteLengthChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getMaximumWriteLength", binaryMessenger: binaryMessenger, codec: codec) + if let api = api { + getMaximumWriteLengthChannel.setMessageHandler { message, reply in + let args = message as! [Any?] + let myPeripheralKeyArg = args[0] is Int64 ? args[0] as! Int64 : Int64(args[0] as! Int32) + let myTypeNumberArg = args[1] is Int64 ? args[1] as! Int64 : Int64(args[1] as! Int32) + do { + let result = try api.getMaximumWriteLength(myPeripheralKey: myPeripheralKeyArg, myTypeNumber: myTypeNumberArg) + reply(wrapResult(result)) + } catch { + reply(wrapError(error)) + } + } + } else { + getMaximumWriteLengthChannel.setMessageHandler(nil) + } let discoverGATTChannel = FlutterBasicMessageChannel(name: "dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.discoverGATT", binaryMessenger: binaryMessenger, codec: codec) if let api = api { discoverGATTChannel.setMessageHandler { message, reply in diff --git a/bluetooth_low_energy_darwin/darwin/Classes/MyCentralController.swift b/bluetooth_low_energy_darwin/darwin/Classes/MyCentralController.swift index c9f57b9..b1fe0e5 100644 --- a/bluetooth_low_energy_darwin/darwin/Classes/MyCentralController.swift +++ b/bluetooth_low_energy_darwin/darwin/Classes/MyCentralController.swift @@ -122,6 +122,21 @@ class MyCentralController: MyCentralControllerHostApi { } } + func getMaximumWriteLength(myPeripheralKey: Int64, myTypeNumber: Int64) throws -> Int64 { + let peripheralKey = Int(myPeripheralKey) + guard let peripheral = cachedPeripherals[peripheralKey] else { + throw MyError.illegalArgument + } + let myTypeRawValue = Int(myTypeNumber) + guard let myTypeArgs = MyGattCharacteristicWriteTypeArgs(rawValue: myTypeRawValue) else { + throw MyError.illegalArgument + } + let type = myTypeArgs.toType() + let maximumWriteLength32 = peripheral.maximumWriteValueLength(for: type) + let maximumWriteLength = Int64(maximumWriteLength32) + return maximumWriteLength + } + func discoverGATT(myPeripheralKey: Int64, completion: @escaping (Result) -> Void) { do { let peripheralKey = Int(myPeripheralKey) diff --git a/bluetooth_low_energy_darwin/lib/src/my_api.g.dart b/bluetooth_low_energy_darwin/lib/src/my_api.g.dart index c68462f..380f6da 100644 --- a/bluetooth_low_energy_darwin/lib/src/my_api.g.dart +++ b/bluetooth_low_energy_darwin/lib/src/my_api.g.dart @@ -380,6 +380,33 @@ class MyCentralControllerHostApi { } } + Future getMaximumWriteLength(int arg_myPeripheralKey, int arg_myTypeNumber) async { + final BasicMessageChannel channel = BasicMessageChannel( + 'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.getMaximumWriteLength', codec, + binaryMessenger: _binaryMessenger); + final List? replyList = + await channel.send([arg_myPeripheralKey, arg_myTypeNumber]) as List?; + if (replyList == null) { + throw PlatformException( + code: 'channel-error', + message: 'Unable to establish connection on channel.', + ); + } else if (replyList.length > 1) { + throw PlatformException( + code: replyList[0]! as String, + message: replyList[1] as String?, + details: replyList[2], + ); + } else if (replyList[0] == null) { + throw PlatformException( + code: 'null-error', + message: 'Host platform returned null value for non-null return value.', + ); + } else { + return (replyList[0] as int?)!; + } + } + Future discoverGATT(int arg_myPeripheralKey) async { final BasicMessageChannel channel = BasicMessageChannel( 'dev.flutter.pigeon.bluetooth_low_energy_darwin.MyCentralControllerHostApi.discoverGATT', codec, diff --git a/bluetooth_low_energy_darwin/lib/src/my_central_controller.dart b/bluetooth_low_energy_darwin/lib/src/my_central_controller.dart index b717308..48d8d6c 100644 --- a/bluetooth_low_energy_darwin/lib/src/my_central_controller.dart +++ b/bluetooth_low_energy_darwin/lib/src/my_central_controller.dart @@ -114,6 +114,22 @@ class MyCentralController extends CentralController await _myApi.disconnect(myPeripheral.hashCode); } + @override + Future getMaximumWriteLength( + Peripheral peripheral, { + required GattCharacteristicWriteType type, + }) async { + await _throwWithoutState(CentralState.poweredOn); + final myPeripheral = peripheral as MyPeripheral; + final myTypeArgs = type.toMyArgs(); + final myTypeNumber = myTypeArgs.index; + final maximumWriteLength = await _myApi.getMaximumWriteLength( + myPeripheral.hashCode, + myTypeNumber, + ); + return maximumWriteLength; + } + @override Future discoverGATT(Peripheral peripheral) async { await _throwWithoutState(CentralState.poweredOn); @@ -206,14 +222,14 @@ class MyCentralController extends CentralController final myCharacteristic = characteristic as MyGattCharacteristic; final myService = myCharacteristic.myService; final myPeripheral = myService.myPeripheral; - final typeArgs = type.toMyArgs(); - final typeNumber = typeArgs.index; + final myTypeArgs = type.toMyArgs(); + final myTypeNumber = myTypeArgs.index; await _myApi.writeCharacteristic( myPeripheral.hashCode, myService.hashCode, myCharacteristic.hashCode, value, - typeNumber, + myTypeNumber, ); } diff --git a/bluetooth_low_energy_darwin/my_api.dart b/bluetooth_low_energy_darwin/my_api.dart index cf9f76b..9f01be4 100644 --- a/bluetooth_low_energy_darwin/my_api.dart +++ b/bluetooth_low_energy_darwin/my_api.dart @@ -19,6 +19,7 @@ abstract class MyCentralControllerHostApi { void connect(int myPeripheralKey); @async void disconnect(int myPeripheralKey); + int getMaximumWriteLength(int myPeripheralKey, int myTypeNumber); @async void discoverGATT(int myPeripheralKey); List getServices(int myPeripheralKey); diff --git a/bluetooth_low_energy_darwin/pubspec.yaml b/bluetooth_low_energy_darwin/pubspec.yaml index 2593e59..c17b007 100644 --- a/bluetooth_low_energy_darwin/pubspec.yaml +++ b/bluetooth_low_energy_darwin/pubspec.yaml @@ -1,6 +1,6 @@ name: bluetooth_low_energy_darwin description: iOS and macOS implementation of the bluetooth_low_energy plugin. -version: 2.0.3 +version: 2.2.0 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: @@ -10,7 +10,7 @@ environment: dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^2.0.3 + bluetooth_low_energy_platform_interface: ^2.2.0 dev_dependencies: flutter_test: diff --git a/bluetooth_low_energy_linux/CHANGELOG.md b/bluetooth_low_energy_linux/CHANGELOG.md index cd9ca34..af53ab5 100644 --- a/bluetooth_low_energy_linux/CHANGELOG.md +++ b/bluetooth_low_energy_linux/CHANGELOG.md @@ -1,20 +1,24 @@ +## 2.2.0 + +* Add `CentralController#getMaximumWriteLength` method. + ## 2.0.3 -- `Android` Migrate to Android 13. -- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) +* `Android` Migrate to Android 13. +* `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) ## 2.0.2 -- Combine iOS and macOS projects. -- Optimize project structure. +* Combine iOS and macOS projects. +* Optimize project structure. ## 2.0.1 -- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. -- Fix the issue that create UUID form peripheral's address failed on Linux. -- Fix the issue that instance match failed on Linux. +* Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. +* Fix the issue that create UUID form peripheral's address failed on Linux. +* Fix the issue that instance match failed on Linux. ## 2.0.0 -- Rewrite the whole project with federated plugins. -- Support macOS and Linux. +* Rewrite the whole project with federated plugins. +* Support macOS and Linux. diff --git a/bluetooth_low_energy_linux/lib/src/my_central_controller.dart b/bluetooth_low_energy_linux/lib/src/my_central_controller.dart index 5ca28f3..ad53fec 100644 --- a/bluetooth_low_energy_linux/lib/src/my_central_controller.dart +++ b/bluetooth_low_energy_linux/lib/src/my_central_controller.dart @@ -163,6 +163,15 @@ class MyCentralController extends CentralController { await device.disconnect(); } + @override + Future getMaximumWriteLength( + Peripheral peripheral, { + required GattCharacteristicWriteType type, + }) async { + // TODO: 当前版本 `bluez` 插件不支持获取 MTU,返回最小值 20. + return 20; + } + @override Future discoverGATT(Peripheral peripheral) async { await _throwWithoutState(CentralState.poweredOn); diff --git a/bluetooth_low_energy_linux/pubspec.yaml b/bluetooth_low_energy_linux/pubspec.yaml index 19f048e..a5dfacb 100644 --- a/bluetooth_low_energy_linux/pubspec.yaml +++ b/bluetooth_low_energy_linux/pubspec.yaml @@ -1,6 +1,6 @@ name: bluetooth_low_energy_linux description: Linux implementation of the bluetooth_low_energy plugin. -version: 2.0.3 +version: 2.2.0 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: @@ -10,7 +10,7 @@ environment: dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^2.0.3 + bluetooth_low_energy_platform_interface: ^2.2.0 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 cd9ca34..b3749bf 100644 --- a/bluetooth_low_energy_platform_interface/CHANGELOG.md +++ b/bluetooth_low_energy_platform_interface/CHANGELOG.md @@ -1,20 +1,36 @@ +## 2.2.0 + +* Add `GattCharacteristicWriteType` argument to `CentralController#getMaximumWriteLength` method. + +## 2.1.0 + +* Bump version. + +## 2.0.5 + +* Optimize project structure. + +## 2.0.4 + +* Add `CentralController#getMaximumWriteLength` method. + ## 2.0.3 -- `Android` Migrate to Android 13. -- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) +* `Android` Migrate to Android 13. +* `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) ## 2.0.2 -- Combine iOS and macOS projects. -- Optimize project structure. +* Combine iOS and macOS projects. +* Optimize project structure. ## 2.0.1 -- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. -- Fix the issue that create UUID form peripheral's address failed on Linux. -- Fix the issue that instance match failed on Linux. +* Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. +* Fix the issue that create UUID form peripheral's address failed on Linux. +* Fix the issue that instance match failed on Linux. ## 2.0.0 -- Rewrite the whole project with federated plugins. -- Support macOS and Linux. +* Rewrite the whole project with federated plugins. +* Support macOS and Linux. diff --git a/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart b/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart index 11a0be5..455235b 100644 --- a/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart +++ b/bluetooth_low_energy_platform_interface/lib/src/central_controller.dart @@ -73,6 +73,12 @@ abstract class CentralController extends PlatformInterface { /// Disconnects form the peripheral. Future disconnect(Peripheral peripheral); + /// Gets the max length in bytes for a single write type of the peripheral. + Future getMaximumWriteLength( + Peripheral peripheral, { + required GattCharacteristicWriteType type, + }); + /// Discovers GATT of the peripheral. Future discoverGATT(Peripheral peripheral); diff --git a/bluetooth_low_energy_platform_interface/pubspec.yaml b/bluetooth_low_energy_platform_interface/pubspec.yaml index 09c37ee..83ce398 100644 --- a/bluetooth_low_energy_platform_interface/pubspec.yaml +++ b/bluetooth_low_energy_platform_interface/pubspec.yaml @@ -1,6 +1,6 @@ name: bluetooth_low_energy_platform_interface description: A common platform interface for the bluetooth_low_energy plugin. -version: 2.0.3 +version: 2.2.0 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: diff --git a/bluetooth_low_energy_windows/CHANGELOG.md b/bluetooth_low_energy_windows/CHANGELOG.md index cd9ca34..af53ab5 100644 --- a/bluetooth_low_energy_windows/CHANGELOG.md +++ b/bluetooth_low_energy_windows/CHANGELOG.md @@ -1,20 +1,24 @@ +## 2.2.0 + +* Add `CentralController#getMaximumWriteLength` method. + ## 2.0.3 -- `Android` Migrate to Android 13. -- `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) +* `Android` Migrate to Android 13. +* `Android` Fix the issuce that receive wrong values caused by unsafe memory, see https://developer.android.com/reference/android/bluetooth/BluetoothGattCallback#onCharacteristicChanged(android.bluetooth.BluetoothGatt,%20android.bluetooth.BluetoothGattCharacteristic) ## 2.0.2 -- Combine iOS and macOS projects. -- Optimize project structure. +* Combine iOS and macOS projects. +* Optimize project structure. ## 2.0.1 -- Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. -- Fix the issue that create UUID form peripheral's address failed on Linux. -- Fix the issue that instance match failed on Linux. +* Fix the issue that GATTs is cleared after peripheral disconnected on iOS and macOS. +* Fix the issue that create UUID form peripheral's address failed on Linux. +* Fix the issue that instance match failed on Linux. ## 2.0.0 -- Rewrite the whole project with federated plugins. -- Support macOS and Linux. +* Rewrite the whole project with federated plugins. +* Support macOS and Linux. diff --git a/bluetooth_low_energy_windows/lib/src/my_central_controller.dart b/bluetooth_low_energy_windows/lib/src/my_central_controller.dart index 2e855dd..6c4fe5a 100644 --- a/bluetooth_low_energy_windows/lib/src/my_central_controller.dart +++ b/bluetooth_low_energy_windows/lib/src/my_central_controller.dart @@ -59,6 +59,15 @@ class MyCentralController extends CentralController { throw UnimplementedError(); } + @override + Future getMaximumWriteLength( + Peripheral peripheral, { + required GattCharacteristicWriteType type, + }) { + // TODO: implement getMaximumWriteLength + throw UnimplementedError(); + } + @override Future discoverGATT(Peripheral peripheral) { // TODO: implement discoverGATT diff --git a/bluetooth_low_energy_windows/pubspec.yaml b/bluetooth_low_energy_windows/pubspec.yaml index ba3bb67..3a83613 100644 --- a/bluetooth_low_energy_windows/pubspec.yaml +++ b/bluetooth_low_energy_windows/pubspec.yaml @@ -1,6 +1,6 @@ name: bluetooth_low_energy_windows description: Windows implementation of the bluetooth_low_energy plugin. -version: 2.0.3 +version: 2.2.0 homepage: https://github.com/yanshouwang/bluetooth_low_energy environment: @@ -10,7 +10,7 @@ environment: dependencies: flutter: sdk: flutter - bluetooth_low_energy_platform_interface: ^2.0.3 + bluetooth_low_energy_platform_interface: ^2.2.0 win32: ^5.0.6 dev_dependencies: