1
/*-------------------------------------------------------------------------
2
| rxtx is a native interface to serial ports in java.
3
| Copyright 1997-2004 by Trent Jarvi taj@www.linux.org.uk.
5
| This library is free software; you can redistribute it and/or
6
| modify it under the terms of the GNU Library General Public
7
| License as published by the Free Software Foundation; either
8
| version 2 of the License, or (at your option) any later version.
10
| This library is distributed in the hope that it will be useful,
11
| but WITHOUT ANY WARRANTY; without even the implied warranty of
12
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
| Library General Public License for more details.
15
| You should have received a copy of the GNU Library General Public
16
| License along with this library; if not, write to the Free
17
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
--------------------------------------------------------------------------*/
20
import java.io.InputStream;
21
import java.io.OutputStream;
22
import java.io.IOException;
23
import java.util.TooManyListenersException;
24
import java.lang.Math;
27
* An extension of gnu.io.SerialPort
28
* @see gnu.io.SerialPort
31
final public class RXTXPort extends SerialPort
33
/* I had a report that some JRE's complain when MonitorThread
34
tries to access private variables
37
protected final static boolean debug = false;
38
protected final static boolean debug_read = false;
39
protected final static boolean debug_read_results = false;
40
protected final static boolean debug_write = false;
41
protected final static boolean debug_events = false;
42
protected final static boolean debug_verbose = false;
44
private static Zystem z;
49
z = new Zystem( Zystem.PRINT_MODE );
50
} catch ( Exception e ) {};
53
z.reportln( "RXTXPort {}");
55
System.loadLibrary( "rxtxSerial" );
60
/** Initialize the native library */
61
private native static void Initialize();
62
boolean MonitorThreadAlive=false;
66
* @param name the name of the device to open
67
* @throws PortInUseException
68
* @see gnu.io.SerialPort
70
public RXTXPort( String name ) throws PortInUseException
73
z.reportln( "RXTXPort:RXTXPort("+name+") called");
75
commapi/javadocs/API_users_guide.html specifies that whenever
76
an application tries to open a port in use by another application
77
the PortInUseException will be thrown
79
I know some didnt like it this way but I'm not sure how to avoid
80
it. We will just be writing to a bogus fd if we catch the
89
MonitorThreadLock = true;
90
monThread = new MonitorThread();
92
waitForTheNativeCodeSilly();
93
MonitorThreadAlive=true;
94
// } catch ( PortInUseException e ){}
95
timeout = -1; /* default disabled timeout */
97
z.reportln( "RXTXPort:RXTXPort("+name+") returns with fd = " +
100
private native synchronized int open( String name )
101
throws PortInUseException;
103
/** File descriptor */
104
protected int fd = 0;
105
/** a pointer to the event info structure used to share information
106
between threads so write threads can send output buffer empty
107
from a pthread if need be.
110
/** pid for lock files */
114
static boolean dsrFlag = false;
117
private final SerialOutputStream out = new SerialOutputStream();
119
* get the OutputStream
120
* @return OutputStream
122
public OutputStream getOutputStream()
125
z.reportln( "RXTXPort:getOutputStream() called and returning");
130
private final SerialInputStream in = new SerialInputStream();
132
* get the InputStream
133
* @return InputStream
134
* @see java.io.InputStream
136
public InputStream getInputStream()
139
z.reportln( "RXTXPort:getInputStream() called and returning");
144
* Set the SerialPort parameters
145
* 1.5 stop bits requires 5 databits
150
* @throws UnsupportedCommOperationException
151
* @see gnu.io.UnsupportedCommOperationException
153
* If speed is not a predifined speed it is assumed to be
154
* the actual speed desired.
156
private native int nativeGetParity( int fd );
157
private native int nativeGetFlowControlMode( int fd );
158
public synchronized void setSerialPortParams( int b, int d, int s,
160
throws UnsupportedCommOperationException
163
z.reportln( "RXTXPort:setSerialPortParams(" +
164
b + " " + d + " " + s + " " + p + ") called");
165
if ( nativeSetSerialPortParams( b, d, s, p ) )
166
throw new UnsupportedCommOperationException(
167
"Invalid Parameter" );
169
if( s== STOPBITS_1_5 ) dataBits = DATABITS_5;
174
z.reportln( "RXTXPort:setSerialPortParams(" +
175
b + " " + d + " " + s + " " + p +
180
* Set the native serial port parameters
181
* If speed is not a predifined speed it is assumed to be
182
* the actual speed desired.
184
private native boolean nativeSetSerialPortParams( int speed,
185
int dataBits, int stopBits, int parity )
186
throws UnsupportedCommOperationException;
188
/** Line speed in bits-per-second */
189
protected int speed=9600;
191
* @return int representing the baudrate
192
* This will not behave as expected with custom speeds
194
public int getBaudRate()
197
z.reportln( "RXTXPort:getBaudRate() called and returning " + speed);
201
/** Data bits port parameter */
202
protected int dataBits=DATABITS_8;
204
* @return int representing the databits
206
public int getDataBits()
209
z.reportln( "RXTXPort:getDataBits() called and returning " + dataBits);
213
/** Stop bits port parameter */
214
protected int stopBits=SerialPort.STOPBITS_1;
216
* @return int representing the stopbits
218
public int getStopBits()
221
z.reportln( "RXTXPort:getStopBits() called and returning " + stopBits);
225
/** Parity port parameter */
226
protected int parity= SerialPort.PARITY_NONE;
228
* @return int representing the parity
230
public int getParity()
233
z.reportln( "RXTXPort:getParity() called and returning " + parity );
239
protected int flowmode = SerialPort.FLOWCONTROL_NONE;
241
* @param flowcontrol FLOWCONTROL_NONE is default
242
* @see gnu.io.SerialPort#FLOWCONTROL_NONE
244
public void setFlowControlMode( int flowcontrol )
247
z.reportln( "RXTXPort:setFlowControlMode( " + flowcontrol + " ) called");
248
if(monThreadisInterrupted)
251
z.reportln( "RXTXPort:setFlowControlMode MonThread is Interrupeted returning" );
255
setflowcontrol( flowcontrol );
257
catch( IOException e )
262
flowmode=flowcontrol;
264
z.reportln( "RXTXPort:setFlowControlMode( " + flowcontrol + " ) returning");
267
* @return int representing the flowmode
269
public int getFlowControlMode()
272
z.reportln( "RXTXPort:getFlowControlMode() returning " + flowmode );
275
native void setflowcontrol( int flowcontrol ) throws IOException;
279
linux/drivers/char/n_hdlc.c? FIXME
283
* Receive framing control
285
* @throws UnsupportedCommOperationException
287
public void enableReceiveFraming( int f )
288
throws UnsupportedCommOperationException
291
z.reportln( "RXTXPort:enableReceiveFramming() throwing exception");
292
throw new UnsupportedCommOperationException( "Not supported" );
296
public void disableReceiveFraming()
299
z.reportln( "RXTXPort:disableReceiveFramming() called and returning (noop)");
302
* @returns true if framing is enabled
304
public boolean isReceiveFramingEnabled()
307
z.reportln( "RXTXPort:isReceiveFrammingEnabled() called and returning " + false );
311
* @return int representing the framing byte
313
public int getReceiveFramingByte()
316
z.reportln( "RXTXPort:getReceiveFrammingByte() called and returning " + 0 );
321
/** Receive timeout control */
322
protected int timeout;
325
* @return int the timeout
327
public native int NativegetReceiveTimeout();
329
* @return bloolean true if recieve timeout is enabled
331
private native boolean NativeisReceiveTimeoutEnabled();
337
private native void NativeEnableReceiveTimeoutThreshold(int time,
338
int threshold,int InputBuffer);
341
public void disableReceiveTimeout()
344
z.reportln( "RXTXPort:disableReceiveTimeout() called");
346
NativeEnableReceiveTimeoutThreshold( timeout , threshold, InputBuffer );
348
z.reportln( "RXTXPort:disableReceiveTimeout() returning");
353
public void enableReceiveTimeout( int time )
356
z.reportln( "RXTXPort:enableReceiveTimeout() called");
360
NativeEnableReceiveTimeoutThreshold( time , threshold,
365
throw new IllegalArgumentException
367
"Unexpected negative timeout value"
371
z.reportln( "RXTXPort:enableReceiveTimeout() returning");
374
* @return boolean true if recieve timeout is enabled
376
public boolean isReceiveTimeoutEnabled()
379
z.reportln( "RXTXPort:isReceiveTimeoutEnabled() called and returning " + NativeisReceiveTimeoutEnabled() );
380
return( NativeisReceiveTimeoutEnabled() );
383
* @return int the timeout
385
public int getReceiveTimeout()
388
z.reportln( "RXTXPort:getReceiveTimeout() called and returning " + NativegetReceiveTimeout() );
389
return(NativegetReceiveTimeout( ));
392
/** Receive threshold control */
394
private int threshold = 0;
397
* @param thresh threshold
399
public void enableReceiveThreshold( int thresh )
402
z.reportln( "RXTXPort:enableReceiveThreshold( " + thresh + " ) called");
406
NativeEnableReceiveTimeoutThreshold(timeout, threshold,
409
else /* invalid thresh */
411
throw new IllegalArgumentException
413
"Unexpected negative threshold value"
417
z.reportln( "RXTXPort:enableReceiveThreshold( " + thresh + " ) returned");
421
public void disableReceiveThreshold()
424
z.reportln( "RXTXPort:disableReceiveThreshold() called and returning");
425
enableReceiveThreshold(0);
428
* @return int the recieve threshold
430
public int getReceiveThreshold()
433
z.reportln( "RXTXPort:getReceiveThreshold() called and returning " + threshold);
437
* @return boolean true if receive threshold is enabled
439
public boolean isReceiveThresholdEnabled()
442
z.reportln( "RXTXPort:isReceiveThresholdEnable() called and returning" + (threshold > 0) );
446
/** Input/output buffers */
447
/** FIXME I think this refers to
448
FOPEN(3)/SETBUF(3)/FREAD(3)/FCLOSE(3)
451
These are native stubs...
453
private int InputBuffer=0;
454
private int OutputBuffer=0;
458
public void setInputBufferSize( int size )
461
z.reportln( "RXTXPort:setInputBufferSize( " +
464
throw new IllegalArgumentException
466
"Unexpected negative buffer size value"
468
else InputBuffer=size;
470
z.reportln( "RXTXPort:setInputBufferSize( " +
471
size + ") returning");
475
public int getInputBufferSize()
478
z.reportln( "RXTXPort:getInputBufferSize() called and returning " + InputBuffer );
484
public void setOutputBufferSize( int size )
487
z.reportln( "RXTXPort:setOutputBufferSize( " +
490
throw new IllegalArgumentException
492
"Unexpected negative buffer size value"
494
else OutputBuffer=size;
496
z.reportln( "RXTXPort:setOutputBufferSize( " +
497
size + ") returned");
501
* @return in the output buffer size
503
public int getOutputBufferSize()
506
z.reportln( "RXTXPort:getOutputBufferSize() called and returning " + OutputBuffer );
507
return(OutputBuffer);
510
/* =================== cleaned messages to here */
513
* Line status methods
516
* @returns true if DTR is set
518
public native boolean isDTR();
522
public native void setDTR( boolean state );
526
public native void setRTS( boolean state );
527
private native void setDSR( boolean state );
529
* @return boolean true if CTS is set
531
public native boolean isCTS();
533
* @return boolean true if DSR is set
535
public native boolean isDSR();
537
* @return boolean true if CD is set
539
public native boolean isCD();
541
* @return boolean true if RI is set
543
public native boolean isRI();
545
* @return boolean true if RTS is set
547
public native boolean isRTS();
554
public native void sendBreak( int duration );
555
protected native void writeByte( int b, boolean i ) throws IOException;
556
protected native void writeArray( byte b[], int off, int len, boolean i )
558
protected native boolean nativeDrain( boolean i ) throws IOException;
560
/** RXTXPort read methods */
561
protected native int nativeavailable() throws IOException;
562
protected native int readByte() throws IOException;
563
protected native int readArray( byte b[], int off, int len )
567
/** Serial Port Event listener */
568
private SerialPortEventListener SPEventListener;
570
/** Thread to monitor data */
571
private MonitorThread monThread;
573
/** Process SerialPortEvents */
574
native void eventLoop();
577
* @return boolean true if monitor thread is interrupted
579
boolean monThreadisInterrupted=true;
580
private native void interruptEventLoop( );
581
public boolean checkMonitorThread()
584
z.reportln( "RXTXPort:checkMonitorThread()");
585
if(monThread != null)
589
"monThreadisInterrupted = " +
590
monThreadisInterrupted );
591
return monThreadisInterrupted;
594
z.reportln( "monThread is null " );
601
* @return boolean true if the port is closing
603
public boolean sendEvent( int event, boolean state )
606
z.report( "RXTXPort:sendEvent(");
607
/* Let the native side know its time to die */
609
if ( fd == 0 || SPEventListener == null || monThread == null)
616
case SerialPortEvent.DATA_AVAILABLE:
618
z.reportln( "DATA_AVAILABLE " +
619
monThread.Data + ")" );
621
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
624
"OUTPUT_BUFFER_EMPTY " +
625
monThread.Output + ")" );
627
case SerialPortEvent.CTS:
630
monThread.CTS + ")" );
632
case SerialPortEvent.DSR:
635
monThread.Output + ")" );
637
case SerialPortEvent.RI:
640
monThread.RI + ")" );
642
case SerialPortEvent.CD:
645
monThread.CD + ")" );
647
case SerialPortEvent.OE:
650
monThread.OE + ")" );
652
case SerialPortEvent.PE:
655
monThread.PE + ")" );
657
case SerialPortEvent.FE:
660
monThread.FE + ")" );
662
case SerialPortEvent.BI:
665
monThread.BI + ")" );
669
z.reportln( "XXXXXXXXXXXXXX " +
673
if( debug_events && debug_verbose )
674
z.reportln( " checking flags " );
678
case SerialPortEvent.DATA_AVAILABLE:
679
if( monThread.Data ) break;
681
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
682
if( monThread.Output ) break;
684
case SerialPortEvent.CTS:
685
if( monThread.CTS ) break;
687
case SerialPortEvent.DSR:
688
if( monThread.DSR ) break;
690
case SerialPortEvent.RI:
691
if( monThread.RI ) break;
693
case SerialPortEvent.CD:
694
if( monThread.CD ) break;
696
case SerialPortEvent.OE:
697
if( monThread.OE ) break;
699
case SerialPortEvent.PE:
700
if( monThread.PE ) break;
702
case SerialPortEvent.FE:
703
if( monThread.FE ) break;
705
case SerialPortEvent.BI:
706
if( monThread.BI ) break;
709
System.err.println( "unknown event: " + event);
712
if( debug_events && debug_verbose )
713
z.reportln( " getting event" );
714
SerialPortEvent e = new SerialPortEvent(this, event, !state,
716
if( debug_events && debug_verbose )
717
z.reportln( " sending event" );
718
if(monThreadisInterrupted)
721
z.reportln( " sendEvent return" );
724
if( SPEventListener != null )
726
SPEventListener.serialEvent( e );
729
if( debug_events && debug_verbose )
730
z.reportln( " sendEvent return" );
732
if (fd == 0 || SPEventListener == null || monThread == null)
743
* Add an event listener
744
* @param lsnr SerialPortEventListener
745
* @throws TooManyListenersException
748
boolean MonitorThreadLock = true;
749
boolean MonitorThreadCloseLock = true;
751
public void addEventListener(
752
SerialPortEventListener lsnr ) throws TooManyListenersException
754
/* Don't let and notification requests happen until the
759
z.reportln( "RXTXPort:addEventListener()");
760
if( SPEventListener != null )
762
throw new TooManyListenersException();
764
SPEventListener = lsnr;
765
if( !MonitorThreadAlive )
767
MonitorThreadLock = true;
768
monThread = new MonitorThread();
770
waitForTheNativeCodeSilly();
771
MonitorThreadAlive=true;
774
z.reportln( "RXTXPort:Interrupt=false");
777
* Remove the serial port event listener
779
public void removeEventListener()
782
z.reportln( "RXTXPort:removeEventListener() called");
783
waitForTheNativeCodeSilly();
784
//if( monThread != null && monThread.isAlive() )
785
if( monThreadisInterrupted == true )
787
z.reportln( " RXTXPort:removeEventListener() already interrupted");
789
SPEventListener = null;
790
Runtime.getRuntime().gc();
793
else if( monThread != null && monThread.isAlive() )
796
z.reportln( " RXTXPort:Interrupt=true");
797
monThreadisInterrupted=true;
799
Notify all threads in this PID that something is up
800
They will call back to see if its their thread
801
using isInterrupted().
803
MonitorThreadCloseLock = true;
805
z.reportln( " RXTXPort:calling interruptEventLoop");
806
interruptEventLoop( );
808
z.reportln(" RXTXPort:waiting on closelock");
809
while( MonitorThreadCloseLock )
815
} catch( Exception e ) {}
818
z.reportln(" RXTXPort:set closelock");
820
z.reportln( " RXTXPort:calling monThread.join()");
822
monThread.join(1000);
823
} catch (Exception ex) {
825
ex.printStackTrace();
828
z.reportln( " RXTXPort:waiting on isAlive()");
829
while( monThread.isAlive() )
832
z.reportln( " MonThread is still alive!");
834
monThread.join(1000);
835
Thread.sleep( 1000 );
836
} catch( Exception e ){}
842
z.reportln( " RXTXPort:calling gc()");
844
SPEventListener = null;
845
Runtime.getRuntime().gc();
846
MonitorThreadLock = false;
847
MonitorThreadAlive=false;
849
z.reportln( "RXTXPort:removeEventListener() returning");
852
* Give the native code a chance to start listening to the hardware
853
* or should we say give the native code control of the issue.
855
* This is important for applications that flicker the Monitor
856
* thread while keeping the port open.
857
* In worst case test cases this loops once or twice every time.
860
protected void waitForTheNativeCodeSilly()
862
while( MonitorThreadLock )
866
} catch( Exception e ) {}
872
private native void nativeSetEventFlag( int fd, int event,
874
public void notifyOnDataAvailable( boolean enable )
877
z.reportln( "RXTXPort:notifyOnDataAvailable( " +
880
waitForTheNativeCodeSilly();
882
MonitorThreadLock = true;
883
nativeSetEventFlag( fd, SerialPortEvent.DATA_AVAILABLE,
885
monThread.Data = enable;
886
MonitorThreadLock = false;
892
public void notifyOnOutputEmpty( boolean enable )
895
z.reportln( "RXTXPort:notifyOnOutputEmpty( " +
897
waitForTheNativeCodeSilly();
898
MonitorThreadLock = true;
899
nativeSetEventFlag( fd, SerialPortEvent.OUTPUT_BUFFER_EMPTY,
901
monThread.Output = enable;
902
MonitorThreadLock = false;
908
public void notifyOnCTS( boolean enable )
911
z.reportln( "RXTXPort:notifyOnCTS( " +
913
waitForTheNativeCodeSilly();
914
MonitorThreadLock = true;
915
nativeSetEventFlag( fd, SerialPortEvent.CTS, enable );
916
monThread.CTS = enable;
917
MonitorThreadLock = false;
922
public void notifyOnDSR( boolean enable )
925
z.reportln( "RXTXPort:notifyOnDSR( " +
927
waitForTheNativeCodeSilly();
928
MonitorThreadLock = true;
929
nativeSetEventFlag( fd, SerialPortEvent.DSR, enable );
930
monThread.DSR = enable;
931
MonitorThreadLock = false;
936
public void notifyOnRingIndicator( boolean enable )
939
z.reportln( "RXTXPort:notifyOnRingIndicator( " +
941
waitForTheNativeCodeSilly();
942
MonitorThreadLock = true;
943
nativeSetEventFlag( fd, SerialPortEvent.RI, enable );
944
monThread.RI = enable;
945
MonitorThreadLock = false;
950
public void notifyOnCarrierDetect( boolean enable )
953
z.reportln( "RXTXPort:notifyOnCarrierDetect( " +
955
waitForTheNativeCodeSilly();
956
MonitorThreadLock = true;
957
nativeSetEventFlag( fd, SerialPortEvent.CD, enable );
958
monThread.CD = enable;
959
MonitorThreadLock = false;
964
public void notifyOnOverrunError( boolean enable )
967
z.reportln( "RXTXPort:notifyOnOverrunError( " +
969
waitForTheNativeCodeSilly();
970
MonitorThreadLock = true;
971
nativeSetEventFlag( fd, SerialPortEvent.OE, enable );
972
monThread.OE = enable;
973
MonitorThreadLock = false;
978
public void notifyOnParityError( boolean enable )
981
z.reportln( "RXTXPort:notifyOnParityError( " +
983
waitForTheNativeCodeSilly();
984
MonitorThreadLock = true;
985
nativeSetEventFlag( fd, SerialPortEvent.PE, enable );
986
monThread.PE = enable;
987
MonitorThreadLock = false;
992
public void notifyOnFramingError( boolean enable )
995
z.reportln( "RXTXPort:notifyOnFramingError( " +
997
waitForTheNativeCodeSilly();
998
MonitorThreadLock = true;
999
nativeSetEventFlag( fd, SerialPortEvent.FE, enable );
1000
monThread.FE = enable;
1001
MonitorThreadLock = false;
1006
public void notifyOnBreakInterrupt( boolean enable )
1009
z.reportln( "RXTXPort:notifyOnBreakInterrupt( " +
1011
waitForTheNativeCodeSilly();
1012
MonitorThreadLock = true;
1013
nativeSetEventFlag( fd, SerialPortEvent.BI, enable );
1014
monThread.BI = enable;
1015
MonitorThreadLock = false;
1018
/** Close the port */
1019
private native void nativeClose( String name );
1022
boolean closeLock = false;
1023
public synchronized void close()
1026
z.reportln( "RXTXPort:close( " + this.name + " )");
1027
if( closeLock ) return;
1031
z.reportln( "RXTXPort:close detected bad File Descriptor" );
1037
z.reportln( "RXTXPort:close( " + this.name + " ) setting monThreadisInterrupted");
1038
if ( ! monThreadisInterrupted )
1040
removeEventListener();
1043
z.reportln( "RXTXPort:close( " + this.name + " ) calling nativeClose");
1044
nativeClose( this.name );
1046
z.reportln( "RXTXPort:close( " + this.name + " ) calling super.close");
1049
z.reportln( "RXTXPort:close( " + this.name + " ) calling System.gc");
1052
Runtime.getRuntime().gc();
1055
z.reportln( "RXTXPort:close( " + this.name + " ) leaving");
1059
/** Finalize the port */
1060
protected void finalize()
1063
z.reportln( "RXTXPort:finalize()");
1064
if( fd > 0 ) close();
1068
/** Inner class for SerialOutputStream */
1069
class SerialOutputStream extends OutputStream
1073
* @throws IOException
1075
public void write( int b ) throws IOException
1078
z.reportln( "RXTXPort:SerialOutputStream:write(int)");
1079
if( speed == 0 ) return;
1080
/* hmm this turns out to be a very bad idea
1081
if ( monThreadisInterrupted == true )
1083
throw new IOException( "Port has been Closed" );
1086
waitForTheNativeCodeSilly();
1087
if ( fd == 0 ) throw new IOException();
1088
writeByte( b, monThreadisInterrupted );
1090
z.reportln( "Leaving RXTXPort:SerialOutputStream:write( int )");
1094
* @throws IOException
1096
public void write( byte b[] ) throws IOException
1100
z.reportln( "Entering RXTXPort:SerialOutputStream:write(" + b.length + ") "/* + new String(b)*/ );
1102
if( speed == 0 ) return;
1103
/* hmm this turns out to be a very bad idea
1104
if ( monThreadisInterrupted == true )
1106
throw new IOException( "Port has been Closed" );
1109
if ( fd == 0 ) throw new IOException();
1110
waitForTheNativeCodeSilly();
1111
writeArray( b, 0, b.length, monThreadisInterrupted );
1113
z.reportln( "Leaving RXTXPort:SerialOutputStream:write(" +b.length +")");
1119
* @throws IOException
1121
public void write( byte b[], int off, int len )
1124
if( speed == 0 ) return;
1125
if( off + len > b.length )
1127
throw new IndexOutOfBoundsException(
1128
"Invalid offset/length passed to read"
1132
byte send[] = new byte[len];
1133
System.arraycopy( b, off, send, 0, len );
1136
z.reportln( "Entering RXTXPort:SerialOutputStream:write(" + send.length + " " + off + " " + len + " " +") " /*+ new String(send) */ );
1138
if ( fd == 0 ) throw new IOException();
1139
/* hmm this turns out to be a very bad idea
1140
if ( monThreadisInterrupted == true )
1142
throw new IOException( "Port has been Closed" );
1145
waitForTheNativeCodeSilly();
1146
writeArray( send, 0, len, monThreadisInterrupted );
1148
z.reportln( "Leaving RXTXPort:SerialOutputStream:write(" + send.length + " " + off + " " + len + " " +") " /*+ new String(send)*/ );
1152
public void flush() throws IOException
1155
z.reportln( "RXTXPort:SerialOutputStream:flush() enter");
1156
if( speed == 0 ) return;
1157
if ( fd == 0 ) throw new IOException();
1158
/* hmm this turns out to be a very bad idea
1159
if ( monThreadisInterrupted == true )
1162
// FIXME Trent this breaks
1163
//throw new IOException( "flush() Port has been Closed" );
1166
waitForTheNativeCodeSilly();
1168
this is probably good on all OS's but for now
1169
just sendEvent from java on Sol
1171
if ( nativeDrain( monThreadisInterrupted ) )
1172
sendEvent( SerialPortEvent.OUTPUT_BUFFER_EMPTY, true );
1174
z.reportln( "RXTXPort:SerialOutputStream:flush() leave");
1178
/** Inner class for SerialInputStream */
1179
class SerialInputStream extends InputStream
1182
* @return int the int read
1183
* @throws IOException
1184
* @see java.io.InputStream
1186
*timeout threshold Behavior
1187
*------------------------------------------------------------------------
1188
*0 0 blocks until 1 byte is available timeout > 0,
1189
* threshold = 0, blocks until timeout occurs, returns -1
1191
*>0 >0 blocks until timeout, returns - 1 on timeout, magnitude
1192
* of threshold doesn't play a role.
1193
*0 >0 Blocks until 1 byte, magnitude of threshold doesn't
1196
public synchronized int read() throws IOException
1199
z.reportln( "RXTXPort:SerialInputStream:read() called");
1200
if ( fd == 0 ) throw new IOException();
1201
waitForTheNativeCodeSilly();
1202
if ( monThreadisInterrupted )
1203
z.reportln( "+++++++++ read() monThreadisInterrupted" );
1204
int result = readByte();
1205
if (debug_read_results)
1206
z.reportln( "RXTXPort:SerialInputStrea:read() returns byte = " + result );
1211
* @return int number of bytes read
1212
* @throws IOException
1214
*timeout threshold Behavior
1215
*------------------------------------------------------------------------
1216
*0 0 blocks until 1 byte is available
1217
*>0 0 blocks until timeout occurs, returns 0 on timeout
1218
*>0 >0 blocks until timeout or reads threshold bytes,
1219
returns 0 on timeout
1220
*0 >0 blocks until reads threshold bytes
1222
public synchronized int read( byte b[] ) throws IOException
1226
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + ") called");
1227
/* hmm this turns out to be a very bad idea
1228
if ( monThreadisInterrupted == true )
1230
throw new IOException( "Port has been Closed" );
1233
waitForTheNativeCodeSilly();
1234
result = read( b, 0, b.length);
1235
if (debug_read_results)
1236
z.reportln( "RXTXPort:SerialInputStream:read() returned " + result + " bytes" );
1240
read(byte b[], int, int)
1241
Documentation is at http://java.sun.com/products/jdk/1.2/docs/api/java/io/InputStream.html#read(byte[], int, int)
1247
* @return int number of bytes read
1248
* @throws IOException
1250
*timeout threshold Behavior
1251
*------------------------------------------------------------------------
1252
*0 0 blocks until 1 byte is available
1253
*>0 0 blocks until timeout occurs, returns 0 on timeout
1254
*>0 >0 blocks until timeout or reads threshold bytes,
1255
returns 0 on timeout
1256
*0 >0 blocks until either threshold # of bytes or len bytes,
1257
whichever was lower.
1259
public synchronized int read( byte b[], int off, int len )
1263
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + " " + off + " " + len + ") called" /*+ new String(b) */ );
1266
* Some sanity checks
1270
z.reportln("+++++++ IOException()\n");
1271
throw new IOException();
1276
z.reportln("+++++++ NullPointerException()\n");
1277
throw new NullPointerException();
1280
if( (off < 0) || (len < 0) || (off+len > b.length))
1282
z.reportln("+++++++ IndexOutOfBoundsException()\n");
1283
throw new IndexOutOfBoundsException();
1287
* Return immediately if len==0
1289
if( len==0 ) return 0;
1292
* See how many bytes we should read
1299
* If threshold is disabled, read should return as soon
1300
* as data are available (up to the amount of available
1301
* bytes in order to avoid blocking)
1302
* Read may return earlier depending of the receive time
1305
int a = nativeavailable();
1309
Minimum = Math.min( Minimum, a );
1314
* Threshold is enabled. Read should return when
1315
* 'threshold' bytes have been received (or when the
1316
* receive timeout expired)
1318
Minimum = Math.min(Minimum, threshold);
1320
/* hmm this turns out to be a very bad idea
1321
if ( monThreadisInterrupted == true )
1323
throw new IOException( "Port has been Closed" );
1326
waitForTheNativeCodeSilly();
1327
result = readArray( b, off, Minimum);
1328
if (debug_read_results)
1329
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + " " + off + " " + len + ") returned " + result + " bytes" /*+ new String(b) */);
1333
* @return int bytes available
1334
* @throws IOException
1336
public synchronized int available() throws IOException
1338
/* hmm this turns out to be a very bad idea
1339
if ( monThreadisInterrupted == true )
1341
throw new IOException( "Port has been Closed" );
1344
if ( debug_verbose )
1345
z.reportln( "RXTXPort:available() called" );
1346
int r = nativeavailable();
1347
if ( debug_verbose )
1348
z.reportln( "RXTXPort:available() returning " +
1355
class MonitorThread extends Thread
1357
/** Note: these have to be separate boolean flags because the
1358
SerialPortEvent constants are NOT bit-flags, they are just
1359
defined as integers from 1 to 10 -DPL */
1360
private volatile boolean CTS=false;
1361
private volatile boolean DSR=false;
1362
private volatile boolean RI=false;
1363
private volatile boolean CD=false;
1364
private volatile boolean OE=false;
1365
private volatile boolean PE=false;
1366
private volatile boolean FE=false;
1367
private volatile boolean BI=false;
1368
private volatile boolean Data=false;
1369
private volatile boolean Output=false;
1374
z.reportln( "RXTXPort:MontitorThread:MonitorThread()");
1377
* run the thread and call the event loop.
1382
z.reportln( "RXTXPort:MontitorThread:run()");
1383
monThreadisInterrupted=false;
1387
z.reportln( "eventLoop() returned");
1389
protected void finalize() throws Throwable
1392
z.reportln( "RXTXPort:MonitorThread exiting");
1396
* A dummy method added so RXTX compiles on Kaffee
1397
* @deprecated deprecated but used in Kaffe
1399
public void setRcvFifoTrigger(int trigger){};
1401
/*------------------------ END OF CommAPI -----------------------------*/
1403
private native static void nativeStaticSetSerialPortParams( String f,
1404
int b, int d, int s, int p )
1405
throws UnsupportedCommOperationException;
1406
private native static boolean nativeStaticSetDSR( String port,
1408
throws UnsupportedCommOperationException;
1409
private native static boolean nativeStaticSetDTR( String port,
1411
throws UnsupportedCommOperationException;
1412
private native static boolean nativeStaticSetRTS( String port,
1414
throws UnsupportedCommOperationException;
1416
private native static boolean nativeStaticIsDSR( String port )
1417
throws UnsupportedCommOperationException;
1418
private native static boolean nativeStaticIsDTR( String port )
1419
throws UnsupportedCommOperationException;
1420
private native static boolean nativeStaticIsRTS( String port )
1421
throws UnsupportedCommOperationException;
1422
private native static boolean nativeStaticIsCTS( String port )
1423
throws UnsupportedCommOperationException;
1424
private native static boolean nativeStaticIsCD( String port )
1425
throws UnsupportedCommOperationException;
1426
private native static boolean nativeStaticIsRI( String port )
1427
throws UnsupportedCommOperationException;
1429
private native static int nativeStaticGetBaudRate( String port )
1430
throws UnsupportedCommOperationException;
1431
private native static int nativeStaticGetDataBits( String port )
1432
throws UnsupportedCommOperationException;
1433
private native static int nativeStaticGetParity( String port )
1434
throws UnsupportedCommOperationException;
1435
private native static int nativeStaticGetStopBits( String port )
1436
throws UnsupportedCommOperationException;
1439
private native byte nativeGetParityErrorChar( )
1440
throws UnsupportedCommOperationException;
1441
private native boolean nativeSetParityErrorChar( byte b )
1442
throws UnsupportedCommOperationException;
1443
private native byte nativeGetEndOfInputChar( )
1444
throws UnsupportedCommOperationException;
1445
private native boolean nativeSetEndOfInputChar( byte b )
1446
throws UnsupportedCommOperationException;
1447
private native boolean nativeSetUartType(String type, boolean test)
1448
throws UnsupportedCommOperationException;
1449
native String nativeGetUartType()
1450
throws UnsupportedCommOperationException;
1451
private native boolean nativeSetBaudBase(int BaudBase)
1452
throws UnsupportedCommOperationException;
1453
private native int nativeGetBaudBase()
1454
throws UnsupportedCommOperationException;
1455
private native boolean nativeSetDivisor(int Divisor)
1456
throws UnsupportedCommOperationException;
1457
private native int nativeGetDivisor()
1458
throws UnsupportedCommOperationException;
1459
private native boolean nativeSetLowLatency()
1460
throws UnsupportedCommOperationException;
1461
private native boolean nativeGetLowLatency()
1462
throws UnsupportedCommOperationException;
1463
private native boolean nativeSetCallOutHangup(boolean NoHup)
1464
throws UnsupportedCommOperationException;
1465
private native boolean nativeGetCallOutHangup()
1466
throws UnsupportedCommOperationException;
1469
* Extension to CommAPI
1470
* This is an extension to CommAPI. It may not be supported on
1471
* all operating systems.
1473
* This is only accurate up to 38600 baud currently.
1475
* @param port the name of the port thats been preopened
1476
* @return BaudRate on success
1477
* @throws UnsupportedCommOperationException;
1478
* This will not behave as expected with custom speeds
1481
public static int staticGetBaudRate( String port )
1482
throws UnsupportedCommOperationException
1486
"RXTXPort:staticGetBaudRate( " + port + " )");
1487
return(nativeStaticGetBaudRate( port ));
1490
* Extension to CommAPI
1491
* This is an extension to CommAPI. It may not be supported on
1492
* all operating systems.
1494
* @param port the name of the port thats been preopened
1495
* @return DataBits on success
1496
* @throws UnsupportedCommOperationException;
1499
public static int staticGetDataBits( String port )
1500
throws UnsupportedCommOperationException
1504
"RXTXPort:staticGetDataBits( " + port + " )");
1505
return(nativeStaticGetDataBits( port ) );
1509
* Extension to CommAPI
1510
* This is an extension to CommAPI. It may not be supported on
1511
* all operating systems.
1513
* @param port the name of the port thats been preopened
1514
* @return Parity on success
1515
* @throws UnsupportedCommOperationException;
1518
public static int staticGetParity( String port )
1519
throws UnsupportedCommOperationException
1523
"RXTXPort:staticGetParity( " + port + " )");
1524
return( nativeStaticGetParity( port ) );
1528
* Extension to CommAPI
1529
* This is an extension to CommAPI. It may not be supported on
1530
* all operating systems.
1532
* @param port the name of the port thats been preopened
1533
* @return StopBits on success
1534
* @throws UnsupportedCommOperationException;
1537
public static int staticGetStopBits( String port )
1538
throws UnsupportedCommOperationException
1542
"RXTXPort:staticGetStopBits( " + port + " )");
1543
return(nativeStaticGetStopBits( port ) );
1547
* Extension to CommAPI
1548
* This is an extension to CommAPI. It may not be supported on
1549
* all operating systems.
1551
* Set the SerialPort parameters
1552
* 1.5 stop bits requires 5 databits
1559
* @throws UnsupportedCommOperationException
1560
* @see gnu.io.UnsupportedCommOperationException
1563
public static void staticSetSerialPortParams( String f, int b, int d,
1565
throws UnsupportedCommOperationException
1569
"RXTXPort:staticSetSerialPortParams( " +
1570
f + " " + b + " " + d + " " + s + " " + p );
1571
nativeStaticSetSerialPortParams( f, b, d, s, p );
1575
* Extension to CommAPI
1576
* This is an extension to CommAPI. It may not be supported on
1577
* all operating systems.
1579
* Open the port and set DSR. remove lockfile and do not close
1580
* This is so some software can appear to set the DSR before 'opening'
1581
* the port a second time later on.
1583
* @return true on success
1584
* @throws UnsupportedCommOperationException;
1588
public static boolean staticSetDSR( String port, boolean flag )
1589
throws UnsupportedCommOperationException
1592
z.reportln( "RXTXPort:staticSetDSR( " + port +
1594
return( nativeStaticSetDSR( port, flag ) );
1598
* Extension to CommAPI
1599
* This is an extension to CommAPI. It may not be supported on
1600
* all operating systems.
1602
* Open the port and set DTR. remove lockfile and do not close
1603
* This is so some software can appear to set the DTR before 'opening'
1604
* the port a second time later on.
1606
* @return true on success
1607
* @throws UnsupportedCommOperationException;
1611
public static boolean staticSetDTR( String port, boolean flag )
1612
throws UnsupportedCommOperationException
1615
z.reportln( "RXTXPort:staticSetDTR( " + port +
1617
return( nativeStaticSetDTR( port, flag ) );
1621
* Extension to CommAPI
1622
* This is an extension to CommAPI. It may not be supported on
1623
* all operating systems.
1625
* Open the port and set RTS. remove lockfile and do not close
1626
* This is so some software can appear to set the RTS before 'opening'
1627
* the port a second time later on.
1630
* @throws UnsupportedCommOperationException;
1634
public static boolean staticSetRTS( String port, boolean flag )
1635
throws UnsupportedCommOperationException
1638
z.reportln( "RXTXPort:staticSetRTS( " + port +
1640
return( nativeStaticSetRTS( port, flag ) );
1644
* Extension to CommAPI
1645
* This is an extension to CommAPI. It may not be supported on
1646
* all operating systems.
1648
* find the fd and return RTS without using a Java open() call
1650
* @param String port
1651
* @return boolean true if asserted
1652
* @throws UnsupportedCommOperationException;
1656
public static boolean staticIsRTS( String port )
1657
throws UnsupportedCommOperationException
1660
z.reportln( "RXTXPort:staticIsRTS( " + port + " )" );
1661
return( nativeStaticIsRTS( port ) );
1664
* Extension to CommAPI
1665
* This is an extension to CommAPI. It may not be supported on
1666
* all operating systems.
1668
* find the fd and return CD without using a Java open() call
1670
* @param String port
1671
* @return boolean true if asserted
1672
* @throws UnsupportedCommOperationException;
1676
public static boolean staticIsCD( String port )
1677
throws UnsupportedCommOperationException
1680
z.reportln( "RXTXPort:staticIsCD( " + port + " )" );
1681
return( nativeStaticIsCD( port ) );
1684
* Extension to CommAPI
1685
* This is an extension to CommAPI. It may not be supported on
1686
* all operating systems.
1688
* find the fd and return CTS without using a Java open() call
1690
* @param String port
1691
* @return boolean true if asserted
1692
* @throws UnsupportedCommOperationException;
1696
public static boolean staticIsCTS( String port )
1697
throws UnsupportedCommOperationException
1700
z.reportln( "RXTXPort:staticIsCTS( " + port + " )" );
1701
return( nativeStaticIsCTS( port ) );
1704
* Extension to CommAPI
1705
* This is an extension to CommAPI. It may not be supported on
1706
* all operating systems.
1708
* find the fd and return DSR without using a Java open() call
1710
* @param String port
1711
* @return boolean true if asserted
1712
* @throws UnsupportedCommOperationException;
1716
public static boolean staticIsDSR( String port )
1717
throws UnsupportedCommOperationException
1720
z.reportln( "RXTXPort:staticIsDSR( " + port + " )" );
1721
return( nativeStaticIsDSR( port ) );
1724
* Extension to CommAPI
1725
* This is an extension to CommAPI. It may not be supported on
1726
* all operating systems.
1728
* find the fd and return DTR without using a Java open() call
1730
* @param String port
1731
* @return boolean true if asserted
1732
* @throws UnsupportedCommOperationException;
1736
public static boolean staticIsDTR( String port )
1737
throws UnsupportedCommOperationException
1740
z.reportln( "RXTXPort:staticIsDTR( " + port + " )" );
1741
return( nativeStaticIsDTR( port ) );
1744
* Extension to CommAPI
1745
* This is an extension to CommAPI. It may not be supported on
1746
* all operating systems.
1748
* find the fd and return RI without using a Java open() call
1750
* @param String port
1751
* @return boolean true if asserted
1752
* @throws UnsupportedCommOperationException;
1756
public static boolean staticIsRI( String port )
1757
throws UnsupportedCommOperationException
1760
z.reportln( "RXTXPort:staticIsRI( " + port + " )" );
1761
return( nativeStaticIsRI( port ) );
1766
* Extension to CommAPI
1767
* This is an extension to CommAPI. It may not be supported on
1768
* all operating systems.
1769
* @return int the Parity Error Character
1770
* @throws UnsupportedCommOperationException;
1772
* Anyone know how to do this in Unix?
1775
public byte getParityErrorChar( )
1776
throws UnsupportedCommOperationException
1780
z.reportln( "getParityErrorChar()" );
1781
ret = nativeGetParityErrorChar();
1783
z.reportln( "getParityErrorChar() returns " +
1789
* Extension to CommAPI
1790
* This is an extension to CommAPI. It may not be supported on
1791
* all operating systems.
1792
* @param b Parity Error Character
1793
* @return boolean true on success
1794
* @throws UnsupportedCommOperationException;
1796
* Anyone know how to do this in Unix?
1799
public boolean setParityErrorChar( byte b )
1800
throws UnsupportedCommOperationException
1803
z.reportln( "setParityErrorChar(" + b + ")" );
1804
return( nativeSetParityErrorChar( b ) );
1808
* Extension to CommAPI
1809
* This is an extension to CommAPI. It may not be supported on
1810
* all operating systems.
1811
* @return int the End of Input Character
1812
* @throws UnsupportedCommOperationException;
1814
* Anyone know how to do this in Unix?
1817
public byte getEndOfInputChar( )
1818
throws UnsupportedCommOperationException
1822
z.reportln( "getEndOfInputChar()" );
1823
ret = nativeGetEndOfInputChar();
1825
z.reportln( "getEndOfInputChar() returns " +
1831
* Extension to CommAPI
1832
* This is an extension to CommAPI. It may not be supported on
1833
* all operating systems.
1834
* @param b End Of Input Character
1835
* @return boolean true on success
1836
* @throws UnsupportedCommOperationException;
1839
public boolean setEndOfInputChar( byte b )
1840
throws UnsupportedCommOperationException
1843
z.reportln( "setEndOfInputChar(" + b + ")" );
1844
return( nativeSetEndOfInputChar( b ) );
1848
* Extension to CommAPI
1849
* This is an extension to CommAPI. It may not be supported on
1850
* all operating systems.
1851
* @param type String representation of the UART type which mayb
1852
* be "none", "8250", "16450", "16550", "16550A", "16650", "16550V2"
1854
* @param test boolean flag to determin if the UART should be tested.
1855
* @return boolean true on success
1856
* @throws UnsupportedCommOperationException;
1858
public boolean setUARTType(String type, boolean test)
1859
throws UnsupportedCommOperationException
1862
z.reportln( "RXTXPort:setUARTType()");
1863
return nativeSetUartType(type, test);
1866
* Extension to CommAPI
1867
* This is an extension to CommAPI. It may not be supported on
1868
* all operating systems.
1869
* @return type String representation of the UART type which mayb
1870
* be "none", "8250", "16450", "16550", "16550A", "16650", "16550V2"
1872
* @throws UnsupportedCommOperationException;
1874
public String getUARTType() throws UnsupportedCommOperationException
1876
return nativeGetUartType();
1880
* Extension to CommAPI
1881
* @param int BaudBase The clock frequency divided by 16. Default
1882
* BaudBase is 115200.
1883
* @return boolean true on success
1884
* @throws UnsupportedCommOperationException
1887
public boolean setBaudBase(int BaudBase)
1888
throws UnsupportedCommOperationException
1891
z.reportln( "RXTXPort:setBaudBase()");
1892
return nativeSetBaudBase(BaudBase);
1896
* Extension to CommAPI
1897
* @return int BaudBase
1898
* @throws UnsupportedCommOperationException
1901
public int getBaudBase() throws UnsupportedCommOperationException
1904
z.reportln( "RXTXPort:getBaudBase()");
1905
return nativeGetBaudBase();
1909
* Extension to CommAPI
1910
* @param int Divisor;
1911
* @throws UnsupportedCommOperationException
1914
public boolean setDivisor(int Divisor)
1915
throws UnsupportedCommOperationException
1918
z.reportln( "RXTXPort:setDivisor()");
1919
return nativeSetDivisor(Divisor);
1923
* Extension to CommAPI
1924
* @returns int Divisor;
1925
* @throws UnsupportedCommOperationException
1928
public int getDivisor() throws UnsupportedCommOperationException
1931
z.reportln( "RXTXPort:getDivisor()");
1932
return nativeGetDivisor();
1936
* Extension to CommAPI
1937
* returns boolean true on success
1938
* @throws UnsupportedCommOperationException
1941
public boolean setLowLatency() throws UnsupportedCommOperationException
1944
z.reportln( "RXTXPort:setLowLatency()");
1945
return nativeSetLowLatency();
1949
* Extension to CommAPI
1950
* returns boolean true on success
1951
* @throws UnsupportedCommOperationException
1954
public boolean getLowLatency() throws UnsupportedCommOperationException
1957
z.reportln( "RXTXPort:getLowLatency()");
1958
return nativeGetLowLatency();
1962
* Extension to CommAPI
1963
* returns boolean true on success
1964
* @throws UnsupportedCommOperationException
1967
public boolean setCallOutHangup(boolean NoHup)
1968
throws UnsupportedCommOperationException
1971
z.reportln( "RXTXPort:setCallOutHangup()");
1972
return nativeSetCallOutHangup(NoHup);
1976
* Extension to CommAPI
1977
* returns boolean true on success
1978
* @throws UnsupportedCommOperationException
1981
public boolean getCallOutHangup()
1982
throws UnsupportedCommOperationException
1985
z.reportln( "RXTXPort:getCallOutHangup()");
1986
return nativeGetCallOutHangup();
1989
/*------------------------ END OF CommAPI Extensions -----------------------*/