part of flutter_blue_plus;
class BluetoothDescriptor {
final DeviceIdentifier remoteId;
final Guid serviceUuid;
final Guid characteristicUuid;
final Guid descriptorUuid;
BluetoothDescriptor({
required this.remoteId,
required this.serviceUuid,
required this.characteristicUuid,
required this.descriptorUuid,
});
BluetoothDescriptor.fromProto(BmBluetoothDescriptor p)
: remoteId = p.remoteId,
serviceUuid = p.serviceUuid,
characteristicUuid = p.characteristicUuid,
descriptorUuid = p.descriptorUuid;
Guid get uuid => descriptorUuid;
BluetoothDevice get device => BluetoothDevice(remoteId: remoteId);
List<int> get lastValue {
String key = "$serviceUuid:$characteristicUuid:$descriptorUuid";
return FlutterBluePlus._lastDescs[remoteId]?[key] ?? [];
}
Stream<List<int>> get lastValueStream => FlutterBluePlus._methodStream.stream
.where((m) => m.method == "OnDescriptorRead" || m.method == "OnDescriptorWritten")
.map((m) => m.arguments)
.map((args) => BmDescriptorData.fromMap(args))
.where((p) => p.remoteId == remoteId)
.where((p) => p.characteristicUuid == characteristicUuid)
.where((p) => p.serviceUuid == serviceUuid)
.where((p) => p.descriptorUuid == descriptorUuid)
.where((p) => p.success == true)
.map((p) => p.value)
.newStreamWithInitialValue(lastValue);
Stream<List<int>> get onValueReceived => FlutterBluePlus._methodStream.stream
.where((m) => m.method == "OnDescriptorRead")
.map((m) => m.arguments)
.map((args) => BmDescriptorData.fromMap(args))
.where((p) => p.remoteId == remoteId)
.where((p) => p.characteristicUuid == characteristicUuid)
.where((p) => p.serviceUuid == serviceUuid)
.where((p) => p.descriptorUuid == descriptorUuid)
.where((p) => p.success == true)
.map((p) => p.value);
Future<List<int>> read({int timeout = 15}) async {
if (device.isDisconnected) {
throw FlutterBluePlusException(
ErrorPlatform.fbp, "readDescriptor", FbpErrorCode.deviceIsDisconnected.index, "device is not connected");
}
_Mutex mtx = _MutexFactory.getMutexForKey("global");
await mtx.take();
List<int> readValue = [];
try {
var request = BmReadDescriptorRequest(
remoteId: remoteId,
serviceUuid: serviceUuid,
secondaryServiceUuid: null,
characteristicUuid: characteristicUuid,
descriptorUuid: descriptorUuid,
);
Stream<BmDescriptorData> responseStream = FlutterBluePlus._methodStream.stream
.where((m) => m.method == "OnDescriptorRead")
.map((m) => m.arguments)
.map((args) => BmDescriptorData.fromMap(args))
.where((p) => p.remoteId == request.remoteId)
.where((p) => p.serviceUuid == request.serviceUuid)
.where((p) => p.characteristicUuid == request.characteristicUuid)
.where((p) => p.descriptorUuid == request.descriptorUuid);
Future<BmDescriptorData> futureResponse = responseStream.first;
await FlutterBluePlus._invokeMethod('readDescriptor', request.toMap());
BmDescriptorData response = await futureResponse
.fbpEnsureAdapterIsOn("readDescriptor")
.fbpEnsureDeviceIsConnected(device, "readDescriptor")
.fbpTimeout(timeout, "readDescriptor");
if (!response.success) {
throw FlutterBluePlusException(_nativeError, "readDescriptor", response.errorCode, response.errorString);
}
readValue = response.value;
} finally {
mtx.give();
}
return readValue;
}
Future<void> write(List<int> value, {int timeout = 15}) async {
if (device.isDisconnected) {
throw FlutterBluePlusException(
ErrorPlatform.fbp, "writeDescriptor", FbpErrorCode.deviceIsDisconnected.index, "device is not connected");
}
_Mutex mtx = _MutexFactory.getMutexForKey("global");
await mtx.take();
try {
var request = BmWriteDescriptorRequest(
remoteId: remoteId,
serviceUuid: serviceUuid,
secondaryServiceUuid: null,
characteristicUuid: characteristicUuid,
descriptorUuid: descriptorUuid,
value: value,
);
Stream<BmDescriptorData> responseStream = FlutterBluePlus._methodStream.stream
.where((m) => m.method == "OnDescriptorWritten")
.map((m) => m.arguments)
.map((args) => BmDescriptorData.fromMap(args))
.where((p) => p.remoteId == request.remoteId)
.where((p) => p.serviceUuid == request.serviceUuid)
.where((p) => p.characteristicUuid == request.characteristicUuid)
.where((p) => p.descriptorUuid == request.descriptorUuid);
Future<BmDescriptorData> futureResponse = responseStream.first;
await FlutterBluePlus._invokeMethod('writeDescriptor', request.toMap());
BmDescriptorData response = await futureResponse
.fbpEnsureAdapterIsOn("writeDescriptor")
.fbpEnsureDeviceIsConnected(device, "writeDescriptor")
.fbpTimeout(timeout, "writeDescriptor");
if (!response.success) {
throw FlutterBluePlusException(_nativeError, "writeDescriptor", response.errorCode, response.errorString);
}
} finally {
mtx.give();
}
return Future.value();
}
@override
String toString() {
return 'BluetoothDescriptor{'
'remoteId: $remoteId, '
'serviceUuid: $serviceUuid, '
'characteristicUuid: $characteristicUuid, '
'descriptorUuid: $descriptorUuid, '
'lastValue: $lastValue'
'}';
}
@Deprecated('Use onValueReceived instead')
Stream<List<int>> get value => onValueReceived;
@Deprecated('Use remoteId instead')
DeviceIdentifier get deviceId => remoteId;
}