-
Notifications
You must be signed in to change notification settings - Fork 60
/
method_channel_quick_blue.dart
149 lines (126 loc) · 5.07 KB
/
method_channel_quick_blue.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
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
import 'dart:async';
import 'dart:typed_data';
import 'package:flutter/services.dart';
import 'package:logging/logging.dart';
import 'quick_blue_platform_interface.dart';
class MethodChannelQuickBlue extends QuickBluePlatform {
static const _method = MethodChannel('quick_blue/method');
static const _eventScanResult = EventChannel('quick_blue/event.scanResult');
static const _eventAvailabilityChange = EventChannel('quick_blue/event.availabilityChange');
static const _messageConnector = BasicMessageChannel('quick_blue/message.connector', StandardMessageCodec());
MethodChannelQuickBlue() {
_messageConnector.setMessageHandler(_handleConnectorMessage);
}
QuickLogger? _logger;
@override
void setLogger(QuickLogger logger) {
_logger = logger;
}
void _log(String message, {Level logLevel = Level.INFO}) {
_logger?.log(logLevel, message);
}
@override
Future<bool> isBluetoothAvailable() async {
bool result = await _method.invokeMethod('isBluetoothAvailable');
return result;
}
final Stream<int> _availabilityChangeStream = _eventAvailabilityChange.receiveBroadcastStream({'name': 'availabilityChange'}).cast();
@override
Stream<int> get availabilityChangeStream => _availabilityChangeStream;
@override
Future<void> startScan() async {
await _method.invokeMethod('startScan');
_log('startScan invokeMethod success');
}
@override
Future<void> stopScan() async {
await _method.invokeMethod('stopScan');
_log('stopScan invokeMethod success');
}
final Stream<dynamic> _scanResultStream = _eventScanResult.receiveBroadcastStream({'name': 'scanResult'});
@override
Stream<dynamic> get scanResultStream => _scanResultStream;
@override
void connect(String deviceId) {
_method.invokeMethod('connect', {
'deviceId': deviceId,
}).then((_) => _log('connect invokeMethod success'));
}
@override
void disconnect(String deviceId) {
_method.invokeMethod('disconnect', {
'deviceId': deviceId,
}).then((_) => _log('disconnect invokeMethod success'));
}
@override
void discoverServices(String deviceId) {
_method.invokeMethod('discoverServices', {
'deviceId': deviceId,
}).then((_) => _log('discoverServices invokeMethod success'));
}
Future<void> _handleConnectorMessage(dynamic message) async {
_log('_handleConnectorMessage $message', logLevel: Level.ALL);
if (message['ConnectionState'] != null) {
String deviceId = message['deviceId'];
BlueConnectionState connectionState = BlueConnectionState.parse(message['ConnectionState']);
onConnectionChanged?.call(deviceId, connectionState);
} else if (message['ServiceState'] != null) {
if (message['ServiceState'] == 'discovered') {
String deviceId = message['deviceId'];
String service = message['service'];
List<String> characteristics = (message['characteristics'] as List).cast();
onServiceDiscovered?.call(deviceId, service, characteristics);
}
} else if (message['characteristicValue'] != null) {
String deviceId = message['deviceId'];
var characteristicValue = message['characteristicValue'];
String characteristic = characteristicValue['characteristic'];
Uint8List value = Uint8List.fromList(characteristicValue['value']); // In case of _Uint8ArrayView
onValueChanged?.call(deviceId, characteristic, value);
} else if (message['mtuConfig'] != null) {
_mtuConfigController.add(message['mtuConfig']);
}
}
@override
Future<void> setNotifiable(String deviceId, String service, String characteristic, BleInputProperty bleInputProperty) async {
_method.invokeMethod('setNotifiable', {
'deviceId': deviceId,
'service': service,
'characteristic': characteristic,
'bleInputProperty': bleInputProperty.value,
}).then((_) => _log('setNotifiable invokeMethod success'));
}
@override
Future<void> readValue(String deviceId, String service, String characteristic) async {
_method.invokeMethod('readValue', {
'deviceId': deviceId,
'service': service,
'characteristic': characteristic,
}).then((_) => _log('readValue invokeMethod success'));
}
@override
Future<void> writeValue(String deviceId, String service, String characteristic, Uint8List value, BleOutputProperty bleOutputProperty) async {
_method.invokeMethod('writeValue', {
'deviceId': deviceId,
'service': service,
'characteristic': characteristic,
'value': value,
'bleOutputProperty': bleOutputProperty.value,
}).then((_) {
_log('writeValue invokeMethod success', logLevel: Level.ALL);
}).catchError((onError) {
// Characteristic sometimes unavailable on Android
throw onError;
});
}
// FIXME Close
final _mtuConfigController = StreamController<int>.broadcast();
@override
Future<int> requestMtu(String deviceId, int expectedMtu) async {
_method.invokeMethod('requestMtu', {
'deviceId': deviceId,
'expectedMtu': expectedMtu,
}).then((_) => _log('requestMtu invokeMethod success'));
return await _mtuConfigController.stream.first;
}
}