修复读取 CCCD 报错的问题,写入时更新特征值 (#50)

* 修复 CCCD 无法读取的问题

* 优化代码

* 调整部分必需参数为可空参数

* 调整接口

* 写入时更新特征值

* 调整接口

* 适配新接口

* 调整依赖项
This commit is contained in:
iAMD
2024-02-01 19:16:42 +08:00
committed by GitHub
parent 63bbc1a732
commit 44efce78df
32 changed files with 521 additions and 231 deletions

View File

@ -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.

View File

@ -993,7 +993,7 @@ class _AdvertiserViewState extends State<AdvertiserView>
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<AdvertiserView>
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(

View File

@ -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"

View File

@ -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:

View File

@ -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.

View File

@ -1077,21 +1077,6 @@ class MyPeripheralManagerFlutterApi(private val binaryMessenger: BinaryMessenger
}
}
}
fun onExecuteWrite(addressArgsArg: String, idArgsArg: Long, executeArgsArg: Boolean, callback: (Result<Unit>) -> Unit) {
val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite"
val channel = BasicMessageChannel<Any?>(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>) -> Unit) {
val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onCharacteristicNotifyStateChanged"
val channel = BasicMessageChannel<Any?>(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>) -> Unit) {
val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorReadRequest"
val channel = BasicMessageChannel<Any?>(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>) -> Unit) {
val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onDescriptorWriteRequest"
val channel = BasicMessageChannel<Any?>(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>) -> Unit) {
val channelName = "dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onExecuteWrite"
val channel = BasicMessageChannel<Any?>(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)))
}
}
}
}

View File

@ -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) {}
}
}

View File

@ -993,32 +993,32 @@ class _AdvertiserViewState extends State<AdvertiserView>
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: [],
),
],

View File

@ -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"

View File

@ -204,17 +204,13 @@ extension MyGattDescriptorX on MyGattDescriptor {
}
extension MyGattCharacteristicX on MyGattCharacteristic {
MyGattCharacteristicArgs toArgs() {
MyGattCharacteristicArgs toArgs(List<MyGattDescriptorArgs> 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<MyGattDescriptor>()
.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<MyGattCharacteristicArgs> characteristicsArgs) {
final hashCodeArgs = hashCode;
final uuidArgs = uuid.toArgs();
final characteristicsArgs = characteristics
.cast<MyGattCharacteristic>()
.map((characteristic) => characteristic.toArgs())
.toList();
return MyGattServiceArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,

View File

@ -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<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
@ -1248,37 +1252,6 @@ abstract class MyPeripheralManagerFlutterApi {
});
}
}
{
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
'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<Object?> args = (message as List<Object?>?)!;
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<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
'dev.flutter.pigeon.bluetooth_low_energy_android.MyPeripheralManagerFlutterApi.onCharacteristicNotifyStateChanged', pigeonChannelCodec,
@ -1310,5 +1283,113 @@ abstract class MyPeripheralManagerFlutterApi {
});
}
}
{
final BasicMessageChannel<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
'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<Object?> args = (message as List<Object?>?)!;
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<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
'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<Object?> args = (message as List<Object?>?)!;
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<Object?> __pigeon_channel = BasicMessageChannel<Object?>(
'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<Object?> args = (message as List<Object?>?)!;
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()));
}
});
}
}
}
}

View File

@ -21,9 +21,11 @@ class MyPeripheralManager extends PeripheralManager
final Map<String, MyCentral2> _centrals;
final Map<int, Map<int, MyGattCharacteristic>> _characteristics;
final Map<int, Map<int, MyGattDescriptor>> _descriptors;
final Map<String, int> _mtus;
final Map<String, Map<int, bool>> _confirms;
final Map<String, MyGattCharacteristic> _preparedCharacteristics;
final Map<String, MyGattDescriptor> _preparedDescriptors;
final Map<String, List<int>> _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 = <int, MyGattCharacteristic>{};
final descriptors = <int, MyGattDescriptor>{};
final characteristicsArgs = <MyGattCharacteristicArgs>[];
for (var characteristic in service.characteristics) {
final descriptorsArgs = <MyGattDescriptorArgs>[];
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,

View File

@ -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,
);
}

View File

@ -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:

View File

@ -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.

View File

@ -993,32 +993,32 @@ class _AdvertiserViewState extends State<AdvertiserView>
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: [],
),
],

View File

@ -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"

View File

@ -203,17 +203,13 @@ extension MyGattDescriptorX on MyGattDescriptor {
}
extension MyGattCharacteristicX on MyGattCharacteristic {
MyGattCharacteristicArgs toArgs() {
MyGattCharacteristicArgs toArgs(List<MyGattDescriptorArgs> 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<MyGattDescriptor>()
.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<MyGattCharacteristicArgs> characteristicsArgs) {
final hashCodeArgs = hashCode;
final uuidArgs = uuid.toArgs();
final characteristicsArgs = characteristics
.cast<MyGattCharacteristic>()
.map((characteristic) => characteristic.toArgs())
.toList();
return MyGattServiceArgs(
hashCodeArgs: hashCodeArgs,
uuidArgs: uuidArgs,

View File

@ -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 = <int, MyGattCharacteristic>{};
final characteristicsArgs = <MyGattCharacteristicArgs>[];
for (var characteristic in service.characteristics) {
final descriptorsArgs = <MyGattDescriptorArgs>[];
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,

View File

@ -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:

View File

@ -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.

View File

@ -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"

View File

@ -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:

View File

@ -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.

View File

@ -19,7 +19,7 @@ abstract class GattCharacteristic extends GattAttribute {
factory GattCharacteristic({
required UUID uuid,
required List<GattCharacteristicProperty> properties,
required Uint8List value,
Uint8List? value,
required List<GattDescriptor> descriptors,
}) =>
MyGattCharacteristic(

View File

@ -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,

View File

@ -7,9 +7,9 @@ import 'my_gatt_descriptor.dart';
class MyGattCharacteristic extends MyGattAttribute
implements GattCharacteristic {
Uint8List _value;
@override
final List<GattCharacteristicProperty> properties;
Uint8List? _value;
@override
final List<MyGattDescriptor> 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();
}

View File

@ -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();
}

View File

@ -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:

View File

@ -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.

View File

@ -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"

View File

@ -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: