This repository was archived by the owner on Jan 1, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathSerial.java
More file actions
425 lines (388 loc) · 15.1 KB
/
Copy pathSerial.java
File metadata and controls
425 lines (388 loc) · 15.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
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
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
/*
* Copyright (c) Steven P. Goldsmith. All rights reserved.
*/
package com.codeferm.periphery;
import static com.codeferm.periphery.Common.MAX_CHAR_ARRAY_LEN;
import static com.codeferm.periphery.Common.jString;
import static com.codeferm.periphery.Common.memMove;
import static org.fusesource.hawtjni.runtime.FieldFlag.CONSTANT;
import org.fusesource.hawtjni.runtime.JniClass;
import org.fusesource.hawtjni.runtime.JniField;
import org.fusesource.hawtjni.runtime.JniMethod;
import org.fusesource.hawtjni.runtime.Library;
import static org.fusesource.hawtjni.runtime.MethodFlag.CONSTANT_INITIALIZER;
/**
* c-periphery Serial wrapper functions for Linux userspace termios tty devices.
*
* @author Steven P. Goldsmith
* @version 1.0.0
* @since 1.0.0
*/
@JniClass
public class Serial implements AutoCloseable {
/**
* Function was successful.
*/
public static final int SERIAL_SUCCESS = 0;
/**
* java-periphery library.
*/
private static final Library LIBRARY = new Library("java-periphery", Serial.class);
/**
* Serial handle.
*/
final private long handle;
/**
* Load library.
*/
static {
LIBRARY.load();
init();
}
/**
* Load constants.
*/
@JniMethod(flags = {CONSTANT_INITIALIZER})
private static native void init();
/**
* Error constants.
*/
@JniField(flags = {CONSTANT})
public static int SERIAL_ERROR_ARG;
@JniField(flags = {CONSTANT})
public static int SERIAL_ERROR_OPEN;
@JniField(flags = {CONSTANT})
public static int SERIAL_ERROR_QUERY;
@JniField(flags = {CONSTANT})
public static int SERIAL_ERROR_CONFIGURE;
@JniField(flags = {CONSTANT})
public static int SERIAL_ERROR_IO;
@JniField(flags = {CONSTANT})
public static int SERIAL_ERROR_CLOSE;
/**
* Parity constants.
*/
@JniField(flags = {CONSTANT})
public static int PARITY_NONE;
@JniField(flags = {CONSTANT})
public static int PARITY_ODD;
@JniField(flags = {CONSTANT})
public static int PARITY_EVEN;
/**
* Open the tty device at the specified path (e.g. "/dev/ttyUSB0"), with the specified baudrate, and the defaults of 8 data
* bits, no parity, 1 stop bit, software flow control (xonxoff) off, hardware flow control (rtscts) off.
*
* @param path Serial device path.
* @param baudrate Baud rate.
*/
public Serial(final String path, final int baudrate) {
// Allocate handle
handle = serialNew();
if (handle == 0) {
throw new RuntimeException("Handle cannot be NULL");
}
// Open device
if (serialOpen(handle, path, baudrate) != SERIAL_SUCCESS) {
// Free handle before throwing exception
serialFree(handle);
throw new RuntimeException(serialErrMessage(handle));
}
}
/**
* Close and free handle.
*/
@Override
public void close() {
serialClose(handle);
serialFree(handle);
}
/**
* Handle accessor.
*
* @return Handle.
*/
public long getHandle() {
return handle;
}
/**
* Allocate a Serial handle. Returns a valid handle on success, or NULL on failure.
*
* @return A valid handle on success, or NULL on failure.
*/
@JniMethod(accessor = "serial_new")
public static final native long serialNew();
/**
* Open the tty device at the specified path (e.g. "/dev/ttyUSB0"), with the specified baudrate, and the defaults of 8 data
* bits, no parity, 1 stop bit, software flow control (xonxoff) off, hardware flow control (rtscts) off.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param path Serial device path.
* @param baudrate Baud rate.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_open")
public static native int serialOpen(long serial, String path, int baudrate);
/**
* Open the tty device at the specified path (e.g. "/dev/ttyUSB0"), with the specified baudrate, data bits, parity, stop bits,
* software flow control (xonxoff), and hardware flow control (rtscts) settings.
*
* serial should be a valid pointer to an allocated Serial handle structure. databits can be 5, 6, 7, or 8. parity can be
* PARITY_NONE, PARITY_ODD, or PARITY_EVEN as defined above. stopbits can be 1 or 2.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param path Serial device path.
* @param baudrate Baud rate.
* @param databits Data bits.
* @param parity Parity.
* @param stopbits Stop bits.
* @param xonXoff Software flow control.
* @param rtsCts Hardware flow control.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_open_advanced")
public static native int serialOpenAdvanced(long serial, String path, int baudrate, int databits, int parity, int stopbits,
boolean xonXoff, boolean rtsCts);
/**
* Read up to len number of bytes from the serial port into the buf buffer with the specified millisecond timeout. A 0 timeout
* can be specified for a non-blocking read. A negative timeout can be specified for a blocking read that will read until all of
* the requested number of bytes are read. A positive timeout in milliseconds can be specified for a blocking read with timeout.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param buf Read buffer.
* @param len Amount of data to read.
* @param timeoutMs can be positive for a timeout in milliseconds, 0 for a non-blocking read, or a negative number for a
* blocking read.
* @return number of bytes read on success, 0 on timeout, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_read")
public static native int serialRead(long serial, byte[] buf, int len, int timeoutMs);
/**
* Write len number of bytes from the buf buffer to the serial port.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param buf Write buffer.
* @param len Amount of data to write.
* @return Number of bytes written on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_write")
public static native int serialWrite(long serial, byte[] buf, int len);
/**
* Flush the write buffer of the serial port (i.e. force its write immediately).
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_flush")
public static native int serialFlush(long serial);
/**
* Get the number of bytes waiting to be read from the serial port.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param count Byte count.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_input_waiting")
public static native int serialInputWaiting(long serial, int[] count);
/**
* Get the number of bytes waiting to be written to the serial port.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param count Byte count.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_output_waiting")
public static native int serialOutputWaiting(long serial, int[] count);
/**
* Poll for data available for reading from the serial port.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param timeoutMs can be positive for a timeout in milliseconds, 0 for a non-blocking poll, or a negative number for a
* blocking poll.
* @return 1 on success (data available for reading), 0 on timeout, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_poll")
public static native int serialPoll(long serial, int timeoutMs);
/**
* Close the tty device.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_close")
public static native int serialClose(long serial);
/**
* Free a GPIO handle.
*
* @param serial Valid pointer to an allocated Serial handle structure.
*/
@JniMethod(accessor = "serial_free")
public static native void serialFree(long serial);
/**
* Get baud rate.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param baudRate Baud rate.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_get_baudrate")
public static native int serialGetBaudRate(long serial, int[] baudRate);
/**
* Get data bits.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param dataBits Data bits.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_get_databits")
public static native int serialGetDataBits(long serial, int[] dataBits);
/**
* Get parity.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param parity Parity.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_get_parity")
public static native int serialGetParity(long serial, int[] parity);
/**
* Get stop bits.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param stopBits Stop bits.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_get_stopbits")
public static native int serialGetStopBits(long serial, int[] stopBits);
/**
* Get Xon/Xoff.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param xonXoff Xon/Xoff.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_get_stopbits")
public static native int serialGetXonXoff(long serial, boolean[] xonXoff);
/**
* Get RTS/CTS.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param rtsCts RTS/CTS.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_get_rtscts")
public static native int serialGetRtsCts(long serial, boolean[] rtsCts);
/**
* Set baud rate.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param baudRate Baud rate.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_set_baudrate")
public static native int serialSetBaudRate(long serial, int baudRate);
/**
* Set data bits.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param dataBits Data bits.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_set_databits")
public static native int serialSetDataBits(long serial, int dataBits);
/**
* Set parity.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param parity Parity.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_set_parity")
public static native int serialSetParity(long serial, int parity);
/**
* Set stop bits.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param stopBits Stop bits.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_set_stopbits")
public static native int serialSetStopBits(long serial, int stopBits);
/**
* Set Xon/Xoff.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param xonXoff Xon/Xoff.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_set_stopbits")
public static native int serialSetXonXoff(long serial, boolean xonXoff);
/**
* Set RTS/CTS.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @param rtsCts RTS/CTS.
* @return 0 on success, or a negative Serial error code on failure.
*/
@JniMethod(accessor = "serial_set_rtscts")
public static native int serialSetRtsCts(long serial, boolean rtsCts);
/**
* Return the file descriptor (for the underlying tty device) of the Serial handle.
*
* @param serial Valid pointer to an allocated Serial handle structure.
* @return File descriptor (for the underlying tty device) of the Serial handle.
*/
@JniMethod(accessor = "serial_fd")
public static native int serialFd(long serial);
/**
* Return a string representation of the serial handle.
*
* @param serial Valid pointer to an allocated serial handle structure.
* @param str String representation of the serial handle.
* @param len Length of char array.
* @return 0 on success, or a negative serial error code on failure.
*/
@JniMethod(accessor = "serial_tostring")
public static native int serialToString(long serial, byte[] str, long len);
/**
* Return a string representation of the serial handle. Wraps native method and simplifies.
*
* @param serial Valid pointer to an allocated serial handle structure.
* @return Serial handle as String.
*/
public static String serialToString(long serial) {
var str = new byte[MAX_CHAR_ARRAY_LEN];
if (serialToString(serial, str, str.length) < 0) {
throw new RuntimeException(serialErrMessage(serial));
}
return jString(str);
}
/**
* Return the libc errno of the last failure that occurred.
*
* @param serial Valid pointer to an allocated serial handle structure.
* @return libc errno.
*/
@JniMethod(accessor = "serial_errno")
public static native int serialErrNo(long serial);
/**
* Return a human readable error message pointer of the last failure that occurred.
*
* @param serial Valid pointer to an allocated serial handle structure.
* @return Error message pointer.
*/
@JniMethod(accessor = "serial_errmsg")
public static native long serialErrMsg(long serial);
/**
* Return a human readable error message of the last failure that occurred. Converts const char * returned by serial_errmsg to a
* Java String.
*
* @param serial Valid pointer to an allocated serial handle structure.
* @return Error message.
*/
public static String serialErrMessage(long serial) {
var ptr = serialErrMsg(serial);
var str = new byte[MAX_CHAR_ARRAY_LEN];
memMove(str, ptr, str.length);
return jString(str);
}
}