001package com.pi4j.io.serial;
002
003/*
004 * #%L
005 * **********************************************************************
006 * ORGANIZATION  :  Pi4J
007 * PROJECT       :  Pi4J :: Java Library (Core)
008 * FILENAME      :  Serial.java
009 *
010 * This file is part of the Pi4J project. More information about
011 * this project can be found here:  https://www.pi4j.com/
012 * **********************************************************************
013 * %%
014 * Copyright (C) 2012 - 2021 Pi4J
015 * %%
016 * This program is free software: you can redistribute it and/or modify
017 * it under the terms of the GNU Lesser General Public License as
018 * published by the Free Software Foundation, either version 3 of the
019 * License, or (at your option) any later version.
020 *
021 * This program is distributed in the hope that it will be useful,
022 * but WITHOUT ANY WARRANTY; without even the implied warranty of
023 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
024 * GNU General Lesser Public License for more details.
025 *
026 * You should have received a copy of the GNU General Lesser Public
027 * License along with this program.  If not, see
028 * <http://www.gnu.org/licenses/lgpl-3.0.html>.
029 * #L%
030 */
031
032
033import java.io.Closeable;
034import java.io.IOException;
035import java.io.InputStream;
036import java.io.OutputStream;
037
038/**
039 * <p>This interface provides a set of functions for 'Serial' communication.</p>
040 *
041 * <p>
042 * Before using the Pi4J library, you need to ensure that the Java VM in configured with access to
043 * the following system libraries:
044 * <ul>
045 * <li>pi4j</li>
046 * <li>wiringPi</li>
047 * </ul>
048 * <blockquote> This library depends on the wiringPi native system library.</br> (developed by
049 * Gordon Henderson @ <a href="http://wiringpi.com/">http://wiringpi.com/</a>)
050 * </blockquote>
051 * </p>
052 *
053 * @see com.pi4j.io.serial.SerialFactory
054 * @see com.pi4j.io.serial.SerialDataEvent
055 * @see SerialDataEventListener
056 *
057 * @see <a href="https://www.pi4j.com/">https://www.pi4j.com/</a>
058 * @author Robert Savage (<a
059 *         href="http://www.savagehomeautomation.com">http://www.savagehomeautomation.com</a>)
060 */
061@SuppressWarnings("unused")
062public interface Serial extends SerialDataReader, SerialDataWriter, AutoCloseable {
063
064    /**
065     * The default hardware COM port provided via the Raspberry Pi GPIO header.
066     *
067     * @see #open(String, int)
068     */
069    public static final String DEFAULT_COM_PORT = RaspberryPiSerial.DEFAULT_COM_PORT;
070    public static final String FIRST_USB_COM_PORT = "/dev/ttyUSB0";
071    public static final String SECOND_USB_COM_PORT = "/dev/ttyUSB1";
072
073    // REF: https://www.raspberrypi.org/documentation/configuration/uart.md
074    // added new symbolic device links included in Raspberry Pi OS.
075    public static final String PRIMARY_COM_PORT = "/dev/serial0";
076    public static final String SECONDARY_COM_PORT = "/dev/serial1";
077
078    /**
079     * <p>
080     * This opens and initializes the serial port/device and sets the communication parameters.
081     * It sets the port into raw mode (character at a time and no translations).
082     * </p>
083     *
084     * <p>
085     * (ATTENTION: the 'device' argument can only be a maximum of 128 characters.)
086     * </p>
087     *
088     * @see #DEFAULT_COM_PORT
089     *
090     * @param device
091     *          The device address of the serial port to access. You can use constant
092     *          'DEFAULT_COM_PORT' if you wish to access the default serial port provided via the
093     *          GPIO header.
094     * @param baud
095     *          The baud rate to use with the serial port. (Custom baud rate are not supported)
096     * @param dataBits
097     *          The data bits to use for serial communication. (5,6,7,8)
098     * @param parity
099     *          The parity setting to use for serial communication. (None, Event, Odd, Mark, Space)
100     * @param stopBits
101     *          The stop bits to use for serial communication. (1,2)
102     * @param flowControl
103     *          The flow control option to use for serial communication. (none, hardware, software)
104     *
105     * @throws IOException thrown on any error.
106     */
107    public void open(String device, int baud, int dataBits, int parity, int stopBits, int flowControl)
108            throws IOException;
109
110
111    /**
112     * <p>
113     * This opens and initializes the serial port/device and sets the communication parameters.
114     * It sets the port into raw mode (character at a time and no translations).
115     *
116     * This method will use the following default serial configuration parameters:
117     *  - DATA BITS    = 8
118     *  - PARITY       = NONE
119     *  - STOP BITS    = 1
120     *  - FLOW CONTROL = NONE
121     *
122     * </p>
123     *
124     * <p>
125     * (ATTENTION: the 'device' argument can only be a maximum of 128 characters.)
126     * </p>
127     *
128     * @see #DEFAULT_COM_PORT
129     *
130     * @param device
131     *          The device address of the serial port to access. You can use constant
132     *          'DEFAULT_COM_PORT' if you wish to access the default serial port provided via the
133     *          GPIO header.
134     * @param baud
135     *          The baud rate to use with the serial port.
136     *
137     * @throws IOException thrown on any error.
138     */
139    public void open(String device, int baud) throws IOException;
140
141    /**
142     * <p>
143     * This opens and initializes the serial port/device and sets the communication parameters.
144     * It sets the port into raw mode (character at a time and no translations).
145     * </p>
146     *
147     * <p>
148     * (ATTENTION: the 'device' argument can only be a maximum of 128 characters.)
149     * </p>
150     *
151     * @see #DEFAULT_COM_PORT
152     *
153     * @param device
154     *          The device address of the serial port to access. You can use constant
155     *          'DEFAULT_COM_PORT' if you wish to access the default serial port provided via the
156     *          GPIO header.
157     * @param baud
158     *          The baud rate to use with the serial port.
159     * @param dataBits
160     *          The data bits to use for serial communication. (5,6,7,8)
161     * @param parity
162     *          The parity setting to use for serial communication. (None, Event, Odd, Mark, Space)
163     * @param stopBits
164     *          The stop bits to use for serial communication. (1,2)
165     * @param flowControl
166     *          The flow control option to use for serial communication. (none, hardware, software)
167     *
168     * @throws IOException thrown on any error.
169     */
170    public void open(String device, Baud baud, DataBits dataBits, Parity parity, StopBits stopBits,
171                     FlowControl flowControl) throws IOException;
172
173    /**
174     * <p>
175     * This opens and initializes the serial port/device and sets the communication parameters.
176     * It sets the port into raw mode (character at a time and no translations).
177     * </p>
178     *
179     * <p>
180     * (ATTENTION: the 'device' argument can only be a maximum of 128 characters.)
181     * </p>
182     *
183     * @see #DEFAULT_COM_PORT
184     *
185     * @param serialConfig
186     *          A serial configuration object that contains the device, baud rate, data bits, parity,
187     *          stop bits, and flow control settings.
188     *
189     * @throws IOException thrown on any error.
190     */
191    public void open(SerialConfig serialConfig) throws IOException;
192
193    /**
194     * This method is called to close a currently open open serial port.
195     *
196     * @throws IllegalStateException thrown if the serial port is not already open.
197     * @throws IOException thrown on any error.
198     */
199    public void close() throws IllegalStateException, IOException;
200
201    /**
202     * This method is called to determine if the serial port is already open.
203     *
204     * @see #open(String, int)
205     * @return a value of 'true' is returned if the serial port is already open.
206     */
207    public boolean isOpen();
208
209    /**
210     * This method is called to determine if the serial port is already closed.
211     *
212     * @see #open(String, int)
213     * @return a value of 'true' is returned if the serial port is already in the closed state.
214     */
215    public boolean isClosed();
216
217    /**
218     * <p>
219     *     Forces the transmission of any remaining data in the serial port transmit buffer.
220     * </p>
221     *
222     * @throws IllegalStateException thrown if the serial port is not already open.
223     * @throws IOException thrown on any error.
224     */
225    public void flush() throws IllegalStateException, IOException;
226
227    /**
228     * <p>
229     *     Discards any data in the serial receive (input) buffer.
230     * </p>
231     *
232     * @throws IllegalStateException thrown if the serial port is not already open.
233     * @throws IOException thrown on any error.
234     */
235    public void discardInput() throws IllegalStateException, IOException;
236
237    /**
238     * <p>
239     *     Discards any data in the serial transmit (output) buffer.
240     * </p>
241     *
242     * @throws IllegalStateException thrown if the serial port is not already open.
243     * @throws IOException thrown on any error.
244     */
245    public void discardOutput() throws IllegalStateException, IOException;
246
247    /**
248     * <p>
249     *     Discards any data in  both the serial receive and transmit buffers.
250     *     Please note that this does not force the transmission of data, it discards it!
251     * </p>
252     *
253     * @throws IllegalStateException thrown if the serial port is not already open.
254     * @throws IOException thrown on any error.
255     */
256    public void discardAll() throws IllegalStateException, IOException;
257
258    /**
259     * <p>
260     *     Send a BREAK signal to connected device.
261     * </p>
262     *
263     * @param duration
264     *          The length of time (milliseconds) to send the BREAK signal
265     * @throws IllegalStateException thrown if the serial port is not already open.
266     * @throws IOException thrown on any error.
267     */
268    public void sendBreak(int duration) throws IllegalStateException, IOException;
269
270    /**
271     * <p>
272     *     Send a BREAK signal to connected device for at least 0.25 seconds, and not more than 0.5 seconds
273     * </p>
274     *
275     * @throws IllegalStateException thrown if the serial port is not already open.
276     * @throws IOException thrown on any error.
277     */
278    public void sendBreak() throws IllegalStateException, IOException;
279
280    /**
281     * <p>
282     *     Send a constant BREAK signal to connected device. (Turn break on/off)
283     *     When enabled this will send a steady stream of zero bits.
284     *     When enabled, no (other) data transmitting is possible.
285     * </p>
286     *
287     * @param enabled
288     *          The enable or disable state to control the BREAK signal
289     * @throws IllegalStateException thrown if the serial port is not already open.
290     * @throws IOException thrown on any error.
291     */
292    public void setBreak(boolean enabled) throws IllegalStateException, IOException;
293
294    /**
295     * <p>
296     *     Control the RTS (request-to-send) pin state.
297     *     When enabled this will set the RTS pin to the HIGH state.
298     * </p>
299     *
300     * @param enabled
301     *          The enable or disable state to control the RTS pin state.
302     * @throws IllegalStateException thrown if the serial port is not already open.
303     * @throws IOException thrown on any error.
304     */
305    public void setRTS(boolean enabled) throws IllegalStateException, IOException;
306
307    /**
308     * <p>
309     *     Control the DTR (data-terminal-ready) pin state.
310     *     When enabled this will set the DTR pin to the HIGH state.
311     * </p>
312     *
313     * @param enabled
314     *          The enable or disable state to control the RTS pin state.
315     * @throws IllegalStateException thrown if the serial port is not already open.
316     * @throws IOException thrown on any error.
317     */
318    public void setDTR(boolean enabled) throws IllegalStateException, IOException;
319
320    /**
321     * <p>
322     *     Get the RTS (request-to-send) pin state.
323     * </p>
324     *
325     * @throws IllegalStateException thrown if the serial port is not already open.
326     * @throws IOException thrown on any error.
327     */
328    public boolean getRTS() throws IllegalStateException, IOException;
329
330    /**
331     * <p>
332     *     Get the DTR (data-terminal-ready) pin state.
333     * </p>
334     *
335     * @throws IllegalStateException thrown if the serial port is not already open.
336     * @throws IOException thrown on any error.
337     */
338    public boolean getDTR() throws IllegalStateException, IOException;
339
340    /**
341     * <p>
342     *     Get the CTS (clean-to-send) pin state.
343     * </p>
344     *
345     * @throws IllegalStateException thrown if the serial port is not already open.
346     * @throws IOException thrown on any error.
347     */
348    public boolean getCTS() throws IllegalStateException, IOException;
349
350    /**
351     * <p>
352     *     Get the DSR (data-set-ready) pin state.
353     * </p>
354     *
355     * @throws IllegalStateException thrown if the serial port is not already open.
356     * @throws IOException thrown on any error.
357     */
358    public boolean getDSR() throws IllegalStateException, IOException;
359
360    /**
361     * <p>
362     *     Get the RI (ring-indicator) pin state.
363     * </p>
364     *
365     * @throws IllegalStateException thrown if the serial port is not already open.
366     * @throws IOException thrown on any error.
367     */
368    public boolean getRI() throws IllegalStateException, IOException;
369
370    /**
371     * <p>
372     *     Get the CD (carrier-detect) pin state.
373     * </p>
374     *
375     * @throws IllegalStateException thrown if the serial port is not already open.
376     * @throws IOException thrown on any error.
377     */
378    public boolean getCD() throws IllegalStateException, IOException;
379
380
381    // ----------------------------------------
382    // EVENT OPERATIONS
383    // ----------------------------------------
384
385    /**
386     * <p>
387     * Java consumer code can call this method to register itself as a listener for serial data
388     * events.
389     * </p>
390     *
391     * @see SerialDataEventListener
392     * @see com.pi4j.io.serial.SerialDataEvent
393     *
394     * @param listener  A class instance that implements the SerialListener interface.
395     */
396    public void addListener(SerialDataEventListener... listener);
397
398    /**
399     * <p> Java consumer code can call this method to unregister itself as a listener for serial data
400     * events. </p>
401     *
402     * @see SerialDataEventListener
403     * @see com.pi4j.io.serial.SerialDataEvent
404     *
405     * @param listener A class instance that implements the SerialListener interface.
406     */
407    public void removeListener(SerialDataEventListener... listener);
408
409
410    // ----------------------------------------
411    // FILE OPERATIONS
412    // ----------------------------------------
413
414    /**
415     * This method returns the serial device file descriptor
416     * @return fileDescriptor file descriptor
417     */
418    public int getFileDescriptor();
419
420    /**
421     * This method returns the input data stream for the serial port's receive buffer
422     * @return InputStream input stream
423     */
424    public InputStream getInputStream();
425
426    /**
427     * This method returns the output data stream for the serial port's transmit buffer
428     * @return OutputStream output stream
429     */
430    public OutputStream getOutputStream();
431
432    /**
433     * This method returns the buffering state for data received from the serial device/port.
434     * @return 'true' if buffering is enabled; else 'false'
435     */
436    public boolean isBufferingDataReceived();
437
438    /**
439     * <p>
440     *     This method controls the buffering state for data received from the serial device/port.
441     * </p>
442     * <p>
443     *   If the buffering state is enabled, then all data bytes received from the serial port will
444     *   get copied into a data receive buffer.  You can use the 'getInputStream()' or and of the 'read()'
445     *   methods to access this data.  The data will also be available via the 'SerialDataEvent' event.
446     *   It is important to know that if you are using data buffering, the data will continue to grow
447     *   in memory until your program consume it from the data reader/stream.
448     * </p>
449     * <p>
450     *   If the buffering state is disabled, then all data bytes received from the serial port will NOT
451     *   get copied into the data receive buffer, but will be included in the 'SerialDataEvent' event's
452     *   data payload.  If you program does not care about or use data received from the serial port,
453     *   then you should disable the data buffering state to prevent memory waste/leak.
454     * </p>
455     *
456     * @param enabled
457     *   Sets the buffering behavior state.
458     *
459     */
460    public void setBufferingDataReceived(boolean enabled);
461
462}