-
Notifications
You must be signed in to change notification settings - Fork 11
Expand file tree
/
Copy pathledger_gatt_reader.dart
More file actions
94 lines (77 loc) · 2.1 KB
/
ledger_gatt_reader.dart
File metadata and controls
94 lines (77 loc) · 2.1 KB
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
import 'dart:async';
import 'dart:typed_data';
import 'package:ledger_flutter/src/utils/buffer.dart';
class LedgerGattReader {
/// The APDU command tag 0x05 is used to transfer application specific data.
static const dataCla = 0x05;
/// The GET MTU command tag 0x08 is used to query the negociated MTU and
/// optimize the size of fragments
static const mtuCla = 0x08;
/// The GET VERSION command tag 0x00 is used to query the current version of
/// the protocol being used
static const versionCla = 0x00;
var currentSequence = 0;
var remainingBytes = 0;
var payload = <int>[];
StreamSubscription? subscription;
void read(
Stream<List<int>> stream, {
void Function(Uint8List event)? onData,
Function? onError,
}) {
subscription?.cancel();
subscription = stream.listen(
(data) {
// Packets always start with the command & sequence
final reader = ByteDataReader();
reader.add(data);
final command = reader.readUint8();
if (command != dataCla) {
return;
}
final sequence = reader.readUint16();
if (sequence != currentSequence) {
reset();
return;
}
if (currentSequence == 0) {
// Read the length
remainingBytes = reader.readUint16();
}
remainingBytes -= reader.remainingLength;
payload.addAll(reader.read(reader.remainingLength));
if (remainingBytes == 0) {
_handleData(
Uint8List.fromList(payload),
onData: onData,
);
} else if (remainingBytes > 0) {
// wait for next message
currentSequence += 1;
} else {
reset();
}
},
onError: (ex) {
onError?.call(ex);
},
);
}
void _handleData(
Uint8List data, {
void Function(Uint8List event)? onData,
}) {
reset();
onData?.call(data);
}
/// Reset the reader
void reset() {
currentSequence = 0;
remainingBytes = 0;
payload = <int>[];
}
Future<void> close() async {
reset();
subscription?.cancel();
}
}