-
Notifications
You must be signed in to change notification settings - Fork 22
/
serial_port_impl.dart
139 lines (116 loc) · 3.47 KB
/
serial_port_impl.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
part of serial_port;
// TODO STOPBITS,PARITY, FLOWCONTROLS
class SerialPort {
static const int _OPEN_METHOD = 1;
static const int _CLOSE_METHOD = 2;
static const int _READ_METHOD = 3;
static const int _WRITE_METHOD = 4;
static const int _EOL = 10;
final String portname;
final int baudrate;
final int databits;
final List<StreamController<List<int>>> _onReadControllers = [];
RawReceivePort _readPort = null;
int _ttyFd = -1;
final StringBuffer _lineBuffer = new StringBuffer();
SerialPort(this.portname, {this.baudrate : 9600, this.databits: 8});
Future<bool> open() {
if(_ttyFd != -1){
throw new StateError("$portname is yet open.");
}
var replyPort = new ReceivePort();
var completer = new Completer<bool>();
_servicePort.send([replyPort.sendPort, _OPEN_METHOD, portname, baudrate, databits]);
replyPort.first.then((List result) {
if (result[0] == null) {
_ttyFd = result[1];
_read();
completer.complete(true);
} else {
completer.completeError("Cannot open $portname : ${result[0]}");
}
});
return completer.future;
}
Future<bool> close(){
_checkOpen();
var completer = new Completer<bool>();
var replyPort = new ReceivePort();
_servicePort.send([replyPort.sendPort, _CLOSE_METHOD, _ttyFd]);
replyPort.first.then((List result) {
if (result[0] == null) {
_ttyFd = -1;
completer.complete(true);
} else {
completer.completeError("Cannot close $portname : ${result[0]}");
}
});
return completer.future;
}
// TODO rename sendString
// TODO send with List<int>
Future<bool> write(String data){
_checkOpen();
var completer = new Completer<bool>();
var replyPort = new ReceivePort();
_servicePort.send([replyPort.sendPort, _WRITE_METHOD, _ttyFd, data]);
replyPort.first.then((result) {
if (result[0] == null) {
completer.complete(true);
} else {
completer.completeError("Cannot write in $portname : ${result[0]}");
}
});
return completer.future;
}
// TODO Stream a List<int>
Stream<String> get onRead {
StreamController<String> controller = new StreamController();
_onReadControllers.add(controller);
return controller.stream;
}
void _read(){
_readPort = new RawReceivePort();
_servicePort.send([_readPort.sendPort, _READ_METHOD, _ttyFd, 256]);
_readPort.handler = (List<int> result) {
_closeReadPort();
// TODO when result[0] != null
if(result[0] == null && result[1] != null){
_onReadControllers.forEach((c) => c.add(result[1]));
/* full line reader
result[1].forEach((byte) {
_lineBuffer.write(new String.fromCharCode(byte));
if(byte == _EOL){
_onReadControllers.forEach((c) => c.add(_lineBuffer.toString().substring(0, _lineBuffer.length-1)));
_lineBuffer.clear();
}
});
*/
}
// Continue to read
if(_ttyFd != -1){
_read();
}
};
}
void _closeReadPort(){
if(_readPort != null){
_readPort.close();
_readPort = null;
}
}
void _checkOpen(){
if(_ttyFd == -1){
throw new StateError("$portname is not open.");
}
}
// Communication with native part
static SendPort _port;
SendPort get _servicePort {
if (_port == null) {
_port = _newServicePort();
}
return _port;
}
SendPort _newServicePort() native "serialPortServicePort";
}