forked from chipweinberger/flutter_blue_plus
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbluetooth_descriptor.dart
127 lines (97 loc) · 4.54 KB
/
bluetooth_descriptor.dart
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
// Copyright 2017, Paul DeMarco.
// All rights reserved. Use of this source code is governed by a
// BSD-style license that can be found in the LICENSE file.
part of flutter_blue_plus;
class BluetoothDescriptor
{
static final Guid cccd = Guid("00002902-0000-1000-8000-00805f9b34fb");
final Guid uuid;
final DeviceIdentifier deviceId;
final Guid serviceUuid;
final Guid characteristicUuid;
final _BehaviorSubject<List<int>> _value;
Stream<List<int>> get value => _value.stream;
List<int> get lastValue => _value.latestValue;
final _Mutex _readWriteMutex = _Mutex();
BluetoothDescriptor.fromProto(protos.BluetoothDescriptor p)
: uuid = Guid(p.uuid),
deviceId = DeviceIdentifier(p.remoteId),
serviceUuid = Guid(p.serviceUuid),
characteristicUuid = Guid(p.characteristicUuid),
_value = _BehaviorSubject(p.value);
/// Retrieves the value of a specified descriptor
Future<List<int>> read() async
{
List<int> readValue = [];
// Only allow a single read or write operation
// at a time, to prevent race conditions.
await _readWriteMutex.synchronized(() async {
var request = protos.ReadDescriptorRequest.create()
..remoteId = deviceId.toString()
..descriptorUuid = uuid.toString()
..characteristicUuid = characteristicUuid.toString()
..serviceUuid = serviceUuid.toString();
Stream<protos.ReadDescriptorResponse> responseStream = FlutterBluePlus.instance._methodStream
.where((m) => m.method == "ReadDescriptorResponse")
.map((m) => m.arguments)
.map((buffer) => protos.ReadDescriptorResponse.fromBuffer(buffer))
.where((p) =>
(p.request.remoteId == request.remoteId) &&
(p.request.descriptorUuid == request.descriptorUuid) &&
(p.request.characteristicUuid == request.characteristicUuid) &&
(p.request.serviceUuid == request.serviceUuid));
// Start listening now, before invokeMethod, to ensure we don't miss the response
Future<protos.ReadDescriptorResponse> futureResponse = responseStream.first;
await FlutterBluePlus.instance._channel
.invokeMethod('readDescriptor', request.writeToBuffer());
protos.ReadDescriptorResponse response = await futureResponse;
readValue = response.value;
_value.add(readValue);
});
return readValue;
}
/// Writes the value of a descriptor
Future<void> write(List<int> value) async
{
// Only allow a single read or write operation
// at a time, to prevent race conditions.
await _readWriteMutex.synchronized(() async {
var request = protos.WriteDescriptorRequest.create()
..remoteId = deviceId.toString()
..descriptorUuid = uuid.toString()
..characteristicUuid = characteristicUuid.toString()
..serviceUuid = serviceUuid.toString()
..value = value;
Stream<protos.WriteDescriptorResponse> responseStream = FlutterBluePlus.instance._methodStream
.where((m) => m.method == "WriteDescriptorResponse")
.map((m) => m.arguments)
.map((buffer) => protos.WriteDescriptorResponse.fromBuffer(buffer))
.where((p) =>
(p.request.remoteId == request.remoteId) &&
(p.request.descriptorUuid == request.descriptorUuid) &&
(p.request.characteristicUuid == request.characteristicUuid) &&
(p.request.serviceUuid == request.serviceUuid));
// Start listening now, before invokeMethod, to ensure we don't miss the response
Future<protos.WriteDescriptorResponse> futureResponse = responseStream.first;
await FlutterBluePlus.instance._channel
.invokeMethod('writeDescriptor', request.writeToBuffer());
protos.WriteDescriptorResponse response = await futureResponse;
if (!response.success) {
throw Exception('Failed to write the descriptor');
}
_value.add(value);
});
return Future.value();
}
@override
String toString()
{
return 'BluetoothDescriptor{'
'uuid: $uuid, '
'deviceId: $deviceId, '
'serviceUuid: $serviceUuid, '
'characteristicUuid: $characteristicUuid, '
'value: ${_value.value}'
'}';
}
}