0 )
term[l++] ="term/";
/*
dev = new File( "/dev/cua0" );
if( dev.list().length > 0 )
term[l++] = "cua/";
*/
String[] temp = new String[l];
for(l--;l >= 0;l--)
temp[l] = term[l];
CandidateDeviceNames=temp;
}
else
{
File dev = new File( deviceDirectory );
String[] temp = dev.list();
CandidateDeviceNames=temp;
}
if (CandidateDeviceNames==null)
{
if (debug)
System.out.println("RXTXCommDriver:registerScannedPorts() no Device files to check ");
return;
}
String CandidatePortPrefixes[] = {};
switch (PortType) {
case CommPortIdentifier.PORT_SERIAL:
if (debug)
System.out.println("scanning for serial ports for os "+osName);
/* There are _many_ possible ports that can be used
on Linux. See below in the fake Linux-all-ports
case for a list. You may add additional ports
here but be warned that too many will significantly
slow down port enumeration. Linux 2.6 has udev
support which should be faster as only ports the
kernel finds should be exposed in /dev
See also how to override port enumeration and
specifying port in INSTALL.
taj
*/
if(osName.equals("Linux"))
{
String[] Temp = {
"ttyS", // linux Serial Ports
"ttySA", // for the IPAQs
"ttyUSB", // for USB frobs
"rfcomm", // bluetooth serial device
"ttyircomm", // linux IrCommdevices (IrDA serial emu)
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("Linux-all-ports"))
{
/* if you want to enumerate all ports ~5000
possible, then replace the above with this
*/
String[] Temp = {
"comx", // linux COMMX synchronous serial card
"holter", // custom card for heart monitoring
"modem", // linux symbolic link to modem.
"rfcomm", // bluetooth serial device
"ttyircomm", // linux IrCommdevices (IrDA serial emu)
"ttycosa0c", // linux COSA/SRP synchronous serial card
"ttycosa1c", // linux COSA/SRP synchronous serial card
"ttyACM",// linux CDC ACM devices
"ttyC", // linux cyclades cards
"ttyCH",// linux Chase Research AT/PCI-Fast serial card
"ttyD", // linux Digiboard serial card
"ttyE", // linux Stallion serial card
"ttyF", // linux Computone IntelliPort serial card
"ttyH", // linux Chase serial card
"ttyI", // linux virtual modems
"ttyL", // linux SDL RISCom serial card
"ttyM", // linux PAM Software's multimodem boards
// linux ISI serial card
"ttyMX",// linux Moxa Smart IO cards
"ttyP", // linux Hayes ESP serial card
"ttyR", // linux comtrol cards
// linux Specialix RIO serial card
"ttyS", // linux Serial Ports
"ttySI",// linux SmartIO serial card
"ttySR",// linux Specialix RIO serial card 257+
"ttyT", // linux Technology Concepts serial card
"ttyUSB",//linux USB serial converters
"ttyV", // linux Comtrol VS-1000 serial controller
"ttyW", // linux specialix cards
"ttyX" // linux SpecialX serial card
};
CandidatePortPrefixes=Temp;
}
else if(osName.toLowerCase().indexOf("qnx") != -1 )
{
String[] Temp = {
"ser"
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("Irix"))
{
String[] Temp = {
"ttyc", // irix raw character devices
"ttyd", // irix basic serial ports
"ttyf", // irix serial ports with hardware flow
"ttym", // irix modems
"ttyq", // irix pseudo ttys
"tty4d",// irix RS422
"tty4f",// irix RS422 with HSKo/HSki
"midi", // irix serial midi
"us" // irix mapped interface
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("FreeBSD")) //FIXME this is probably wrong
{
String[] Temp = {
"ttyd", //general purpose serial ports
"cuaa", //dialout serial ports
"ttyA", //Specialix SI/XIO dialin ports
"cuaA", //Specialix SI/XIO dialout ports
"ttyD", //Digiboard - 16 dialin ports
"cuaD", //Digiboard - 16 dialout ports
"ttyE", //Stallion EasyIO (stl) dialin ports
"cuaE", //Stallion EasyIO (stl) dialout ports
"ttyF", //Stallion Brumby (stli) dialin ports
"cuaF", //Stallion Brumby (stli) dialout ports
"ttyR", //Rocketport dialin ports
"cuaR", //Rocketport dialout ports
"stl" //Stallion EasyIO board or Brumby N
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("NetBSD")) // FIXME this is probably wrong
{
String[] Temp = {
"tty0" // netbsd serial ports
};
CandidatePortPrefixes=Temp;
}
else if ( osName.equals("Solaris")
|| osName.equals("SunOS"))
{
String[] Temp = {
"term/",
"cua/"
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("HP-UX"))
{
String[] Temp = {
"tty0p",// HP-UX serial ports
"tty1p" // HP-UX serial ports
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("UnixWare") ||
osName.equals("OpenUNIX"))
{
String[] Temp = {
"tty00s", // UW7/OU8 serial ports
"tty01s",
"tty02s",
"tty03s"
};
CandidatePortPrefixes=Temp;
}
else if (osName.equals("OpenServer"))
{
String[] Temp = {
"tty1A", // OSR5 serial ports
"tty2A",
"tty3A",
"tty4A",
"tty5A",
"tty6A",
"tty7A",
"tty8A",
"tty9A",
"tty10A",
"tty11A",
"tty12A",
"tty13A",
"tty14A",
"tty15A",
"tty16A",
"ttyu1A", // OSR5 USB-serial ports
"ttyu2A",
"ttyu3A",
"ttyu4A",
"ttyu5A",
"ttyu6A",
"ttyu7A",
"ttyu8A",
"ttyu9A",
"ttyu10A",
"ttyu11A",
"ttyu12A",
"ttyu13A",
"ttyu14A",
"ttyu15A",
"ttyu16A"
};
CandidatePortPrefixes=Temp;
}
else if (osName.equals("Compaq's Digital UNIX") || osName.equals("OSF1"))
{
String[] Temp = {
"tty0" // Digital Unix serial ports
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("BeOS"))
{
String[] Temp = {
"serial" // BeOS serial ports
};
CandidatePortPrefixes=Temp;
}
else if(osName.equals("Mac OS X"))
{
String[] Temp = {
// Keyspan USA-28X adapter, USB port 1
"cu.KeyUSA28X191.",
// Keyspan USA-28X adapter, USB port 1
"tty.KeyUSA28X191.",
// Keyspan USA-28X adapter, USB port 2
"cu.KeyUSA28X181.",
// Keyspan USA-28X adapter, USB port 2
"tty.KeyUSA28X181.",
// Keyspan USA-19 adapter
"cu.KeyUSA19181.",
// Keyspan USA-19 adapter
"tty.KeyUSA19181."
};
CandidatePortPrefixes=Temp;
}
else if(osName.toLowerCase().indexOf("windows") != -1 )
{
String[] Temp = {
"COM" // win32 serial ports
//"//./COM" // win32 serial ports
};
CandidatePortPrefixes=Temp;
}
else
{
if (debug)
System.out.println("No valid prefixes for serial ports have been entered for "+osName + " in RXTXCommDriver.java. This may just be a typo in the method registerScanPorts().");
}
break;
case CommPortIdentifier.PORT_PARALLEL:
if (debug)
System.out.println("scanning for parallel ports for os "+osName);
/** Get the Parallel port prefixes for the running os
* Holger Lehmann
* July 12, 1999
* IBM
*/
if(osName.equals("Linux")
/*
|| osName.equals("NetBSD") FIXME
|| osName.equals("HP-UX") FIXME
|| osName.equals("Irix") FIXME
|| osName.equals("BeOS") FIXME
|| osName.equals("Compaq's Digital UNIX") FIXME
*/
)
{
String[] temp={
"lp" // linux printer port
};
CandidatePortPrefixes=temp;
}
else if(osName.equals("FreeBSD"))
{
String[] temp={
"lpt"
};
CandidatePortPrefixes=temp;
}
else if(osName.toLowerCase().indexOf("windows") != -1 )
{
String[] temp={
"LPT"
};
CandidatePortPrefixes=temp;
}
else /* printer support is green */
{
String [] temp={};
CandidatePortPrefixes=temp;
}
break;
default:
if (debug)
System.out.println("Unknown PortType "+PortType+" passed to RXTXCommDriver.registerScannedPorts()");
}
registerValidPorts(CandidateDeviceNames, CandidatePortPrefixes, PortType);
}
/*
* From the NullDriver.java CommAPI sample.
*/
/**
* @param PortName The name of the port the OS recognizes
* @param PortType CommPortIdentifier.PORT_SERIAL or PORT_PARALLEL
* @return CommPort
* getCommPort() will be called by CommPortIdentifier from its
* openPort() method. PortName is a string that was registered earlier
* using the CommPortIdentifier.addPortName() method. getCommPort()
* returns an object that extends either SerialPort or ParallelPort.
*/
public CommPort getCommPort( String PortName, int PortType )
{
if (debug) System.out.println("RXTXCommDriver:getCommPort("
+PortName+","+PortType+")");
try {
switch (PortType) {
case CommPortIdentifier.PORT_SERIAL:
if(osName.toLowerCase().indexOf("windows") == -1 )
{
return new RXTXPort( PortName );
}
else
{
return new RXTXPort( deviceDirectory + PortName );
}
case CommPortIdentifier.PORT_PARALLEL:
return new LPRPort( PortName );
default:
if (debug)
System.out.println("unknown PortType "+PortType+" passed to RXTXCommDriver.getCommPort()");
}
} catch( PortInUseException e ) {
if (debug)
System.out.println(
"Port "+PortName+" in use by another application");
}
return null;
}
/* Yikes. Trying to call println from C for odd reasons */
public void Report( String arg )
{
System.out.println(arg);
}
}
./rxtx-2.2pre2/src/gnu/io/SerialPortEvent.java 0000644 0001750 0001750 00000010506 10614033756 021175 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class SerialPortEvent extends EventObject
{
public static final int DATA_AVAILABLE =1;
public static final int OUTPUT_BUFFER_EMPTY =2;
public static final int CTS =3;
public static final int DSR =4;
public static final int RI =5;
public static final int CD =6;
public static final int OE =7;
public static final int PE =8;
public static final int FE =9;
public static final int BI =10;
private boolean OldValue;
private boolean NewValue;
private int eventType;
/*public int eventType =0; depricated */
public SerialPortEvent(SerialPort srcport, int eventtype, boolean oldvalue, boolean newvalue)
{
super( srcport );
OldValue=oldvalue;
NewValue=newvalue;
eventType=eventtype;
}
public int getEventType()
{
return(eventType);
}
public boolean getNewValue()
{
return( NewValue );
}
public boolean getOldValue()
{
return( OldValue );
}
}
./rxtx-2.2pre2/src/gnu/io/CommDriver.java 0000644 0001750 0001750 00000006711 10614033754 020157 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public interface CommDriver
{
public abstract CommPort getCommPort(String portName,int portType);
public abstract void initialize();
}
./rxtx-2.2pre2/src/gnu/io/I2CPortEventListener.java 0000644 0001750 0001750 00000006751 10614033755 022047 0 ustar twerner twerner /* Non functional contact tjarvi@qbang for details */
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public interface I2CPortEventListener extends EventListener
{
public abstract void I2CEvent( I2CPortEvent ev );
}
./rxtx-2.2pre2/src/gnu/io/RawPortEventListener.java 0000644 0001750 0001750 00000006753 10614033755 022225 0 ustar twerner twerner /* Non functional contact tjavi@qbang.org for details */
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public interface RawPortEventListener extends EventListener
{
public abstract void RawEvent( RawPortEvent ev );
}
./rxtx-2.2pre2/src/gnu/io/RS485Port.java 0000644 0001750 0001750 00000013565 10614033755 017550 0 ustar twerner twerner /* Non functional contact tjarvi@qbang.org for details */
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.*;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
abstract class RS485Port extends CommPort {
public static final int DATABITS_5 =5;
public static final int DATABITS_6 =6;
public static final int DATABITS_7 =7;
public static final int DATABITS_8 =8;
public static final int PARITY_NONE =0;
public static final int PARITY_ODD =1;
public static final int PARITY_EVEN =2;
public static final int PARITY_MARK =3;
public static final int PARITY_SPACE =4;
public static final int STOPBITS_1 =1;
public static final int STOPBITS_1_5 =0; //wrong
public static final int STOPBITS_2 =2;
public static final int FLOWCONTROL_NONE =0;
public static final int FLOWCONTROL_RTSCTS_IN =1;
public static final int FLOWCONTROL_RTSCTS_OUT =2;
public static final int FLOWCONTROL_XONXOFF_IN =4;
public static final int FLOWCONTROL_XONXOFF_OUT=8;
public abstract void setRS485PortParams( int b, int d, int s, int p ) throws UnsupportedCommOperationException;
public abstract int getBaudRate();
public abstract int getDataBits();
public abstract int getStopBits();
public abstract int getParity();
public abstract void setFlowControlMode( int flowcontrol ) throws UnsupportedCommOperationException;
public abstract int getFlowControlMode();
public abstract boolean isDTR();
public abstract void setDTR( boolean state );
public abstract void setRTS( boolean state );
public abstract boolean isCTS();
public abstract boolean isDSR();
public abstract boolean isCD();
public abstract boolean isRI();
public abstract boolean isRTS();
public abstract void sendBreak( int duration );
public abstract void addEventListener( RS485PortEventListener lsnr ) throws TooManyListenersException;
public abstract void removeEventListener();
public abstract void notifyOnDataAvailable( boolean enable );
public abstract void notifyOnOutputEmpty( boolean enable );
public abstract void notifyOnCTS( boolean enable );
public abstract void notifyOnDSR( boolean enable );
public abstract void notifyOnRingIndicator( boolean enable );
public abstract void notifyOnCarrierDetect( boolean enable );
public abstract void notifyOnOverrunError( boolean enable );
public abstract void notifyOnParityError( boolean enable );
public abstract void notifyOnFramingError( boolean enable );
public abstract void notifyOnBreakInterrupt( boolean enable );
/*
public abstract void setRcvFifoTrigger(int trigger);
deprecated
*/
}
./rxtx-2.2pre2/src/gnu/io/Raw.java 0000644 0001750 0001750 00000033326 11063310112 016624 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.*;
import java.util.*;
import java.lang.Math;
/**
* @author Trent Jarvi
* @version $Id: Raw.java,v 1.1.2.17 2008-09-14 22:29:30 jarvi Exp $
* @since JDK1.0
*/
final class Raw extends RawPort {
static
{
System.loadLibrary( "rxtxRaw" );
Initialize();
}
/** Initialize the native library */
private native static void Initialize();
/** Actual RawPort wrapper class */
/** Open the named port */
public Raw( String name ) throws PortInUseException {
ciAddress=Integer.parseInt(name);
open( ciAddress );
}
private native int open( int ciAddress ) throws PortInUseException;
/** File descriptor */
private int ciAddress;
/** DSR flag **/
static boolean dsrFlag = false;
/** Output stream */
private final RawOutputStream out = new RawOutputStream();
public OutputStream getOutputStream() { return out; }
/** Input stream */
private final RawInputStream in = new RawInputStream();
public InputStream getInputStream() { return in; }
/** Set the RawPort parameters */
public void setRawPortParams( int b, int d, int s, int p )
throws UnsupportedCommOperationException
{
nativeSetRawPortParams( b, d, s, p );
speed = b;
dataBits = d;
stopBits = s;
parity = p;
}
/** Set the native Raw port parameters */
private native void nativeSetRawPortParams( int speed, int dataBits,
int stopBits, int parity ) throws UnsupportedCommOperationException;
/** Line speed in bits-per-second */
private int speed=9600;
public int getBaudRate() { return speed; }
/** Data bits port parameter */
private int dataBits=DATABITS_8;
public int getDataBits() { return dataBits; }
/** Stop bits port parameter */
private int stopBits=RawPort.STOPBITS_1;
public int getStopBits() { return stopBits; }
/** Parity port parameter */
private int parity= RawPort.PARITY_NONE;
public int getParity() { return parity; }
/** Flow control */
private int flowmode = RawPort.FLOWCONTROL_NONE;
public void setFlowControlMode( int flowcontrol ) {
try { setflowcontrol( flowcontrol ); }
catch( IOException e ) {
e.printStackTrace();
return;
}
flowmode=flowcontrol;
}
public int getFlowControlMode() { return flowmode; }
native void setflowcontrol( int flowcontrol ) throws IOException;
/*
linux/drivers/char/n_hdlc.c? FIXME
taj@www.linux.org.uk
*/
/** Receive framing control
*/
public void enableReceiveFraming( int f )
throws UnsupportedCommOperationException
{
throw new UnsupportedCommOperationException( "Not supported" );
}
public void disableReceiveFraming() {}
public boolean isReceiveFramingEnabled() { return false; }
public int getReceiveFramingByte() { return 0; }
/** Receive timeout control */
private int timeout = 0;
public native int NativegetReceiveTimeout();
public native boolean NativeisReceiveTimeoutEnabled();
public native void NativeEnableReceiveTimeoutThreshold(int time, int threshold,int InputBuffer);
public void disableReceiveTimeout(){
enableReceiveTimeout(0);
}
public void enableReceiveTimeout( int time ){
if( time >= 0 ) {
timeout = time;
NativeEnableReceiveTimeoutThreshold( time , threshold, InputBuffer );
}
else {
System.out.println("Invalid timeout");
}
}
public boolean isReceiveTimeoutEnabled(){
return(NativeisReceiveTimeoutEnabled());
}
public int getReceiveTimeout(){
return(NativegetReceiveTimeout( ));
}
/** Receive threshold control */
private int threshold = 0;
public void enableReceiveThreshold( int thresh ){
if(thresh >=0)
{
threshold=thresh;
NativeEnableReceiveTimeoutThreshold(timeout, threshold, InputBuffer);
}
else /* invalid thresh */
{
System.out.println("Invalid Threshold");
}
}
public void disableReceiveThreshold() {
enableReceiveThreshold(0);
}
public int getReceiveThreshold(){
return threshold;
}
public boolean isReceiveThresholdEnabled(){
return(threshold>0);
}
/** Input/output buffers */
/** FIXME I think this refers to
FOPEN(3)/SETBUF(3)/FREAD(3)/FCLOSE(3)
taj@www.linux.org.uk
These are native stubs...
*/
private int InputBuffer=0;
private int OutputBuffer=0;
public void setInputBufferSize( int size )
{
InputBuffer=size;
}
public int getInputBufferSize()
{
return(InputBuffer);
}
public void setOutputBufferSize( int size )
{
OutputBuffer=size;
}
public int getOutputBufferSize()
{
return(OutputBuffer);
}
/** Line status methods */
public native boolean isDTR();
public native void setDTR( boolean state );
public native void setRTS( boolean state );
private native void setDSR( boolean state );
public native boolean isCTS();
public native boolean isDSR();
public native boolean isCD();
public native boolean isRI();
public native boolean isRTS();
/** Write to the port */
public native void sendBreak( int duration );
private native void writeByte( int b ) throws IOException;
private native void writeArray( byte b[], int off, int len )
throws IOException;
private native void drain() throws IOException;
/** Raw read methods */
private native int nativeavailable() throws IOException;
private native int readByte() throws IOException;
private native int readArray( byte b[], int off, int len )
throws IOException;
/** Raw Port Event listener */
private RawPortEventListener SPEventListener;
/** Thread to monitor data */
private MonitorThread monThread;
/** Process RawPortEvents */
native void eventLoop();
private int dataAvailable=0;
public void sendEvent( int event, boolean state ) {
switch( event ) {
case RawPortEvent.DATA_AVAILABLE:
dataAvailable=1;
if( monThread.Data ) break;
return;
case RawPortEvent.OUTPUT_BUFFER_EMPTY:
if( monThread.Output ) break;
return;
/*
if( monThread.DSR ) break;
return;
if (isDSR())
{
if (!dsrFlag)
{
dsrFlag = true;
RawPortEvent e = new RawPortEvent(this, RawPortEvent.DSR, !dsrFlag, dsrFlag );
}
}
else if (dsrFlag)
{
dsrFlag = false;
RawPortEvent e = new RawPortEvent(this, RawPortEvent.DSR, !dsrFlag, dsrFlag );
}
*/
case RawPortEvent.CTS:
if( monThread.CTS ) break;
return;
case RawPortEvent.DSR:
if( monThread.DSR ) break;
return;
case RawPortEvent.RI:
if( monThread.RI ) break;
return;
case RawPortEvent.CD:
if( monThread.CD ) break;
return;
case RawPortEvent.OE:
if( monThread.OE ) break;
return;
case RawPortEvent.PE:
if( monThread.PE ) break;
return;
case RawPortEvent.FE:
if( monThread.FE ) break;
return;
case RawPortEvent.BI:
if( monThread.BI ) break;
return;
default:
System.err.println("unknown event:"+event);
return;
}
RawPortEvent e = new RawPortEvent(this, event, !state, state );
if( SPEventListener != null ) SPEventListener.RawEvent( e );
}
/** Add an event listener */
public void addEventListener( RawPortEventListener lsnr )
throws TooManyListenersException
{
if( SPEventListener != null ) throw new TooManyListenersException();
SPEventListener = lsnr;
monThread = new MonitorThread();
monThread.start();
}
/** Remove the Raw port event listener */
public void removeEventListener() {
SPEventListener = null;
if( monThread != null ) {
monThread.interrupt();
monThread = null;
}
}
public void notifyOnDataAvailable( boolean enable ) { monThread.Data = enable; }
public void notifyOnOutputEmpty( boolean enable ) { monThread.Output = enable; }
public void notifyOnCTS( boolean enable ) { monThread.CTS = enable; }
public void notifyOnDSR( boolean enable ) { monThread.DSR = enable; }
public void notifyOnRingIndicator( boolean enable ) { monThread.RI = enable; }
public void notifyOnCarrierDetect( boolean enable ) { monThread.CD = enable; }
public void notifyOnOverrunError( boolean enable ) { monThread.OE = enable; }
public void notifyOnParityError( boolean enable ) { monThread.PE = enable; }
public void notifyOnFramingError( boolean enable ) { monThread.FE = enable; }
public void notifyOnBreakInterrupt( boolean enable ) { monThread.BI = enable; }
/** Close the port */
private native int nativeClose();
public void close() {
setDTR(false);
setDSR(false);
nativeClose();
super.close();
ciAddress = 0;
}
/** Finalize the port */
protected void finalize() {
close();
}
/** Inner class for RawOutputStream */
class RawOutputStream extends OutputStream {
public void write( int b ) throws IOException {
writeByte( b );
}
public void write( byte b[] ) throws IOException {
writeArray( b, 0, b.length );
}
public void write( byte b[], int off, int len ) throws IOException {
writeArray( b, off, len );
}
public void flush() throws IOException {
drain();
}
}
/** Inner class for RawInputStream */
class RawInputStream extends InputStream {
public int read() throws IOException {
dataAvailable=0;
return readByte();
}
public int read( byte b[] ) throws IOException
{
return read ( b, 0, b.length);
}
public int read( byte b[], int off, int len ) throws IOException
{
dataAvailable=0;
int i=0, Minimum=0;
int intArray[] =
{
b.length,
InputBuffer,
len
};
/*
find the lowest nonzero value
timeout and threshold are handled on the native side
see NativeEnableReceiveTimeoutThreshold in
RawImp.c
*/
while(intArray[i]==0 && i < intArray.length) i++;
Minimum=intArray[i];
while( i < intArray.length )
{
if(intArray[i] > 0 )
{
Minimum=Math.min(Minimum,intArray[i]);
}
i++;
}
Minimum=Math.min(Minimum,threshold);
if(Minimum == 0) Minimum=1;
int Available=available();
int Ret = readArray( b, off, Minimum);
return Ret;
}
public int available() throws IOException {
return nativeavailable();
}
}
class MonitorThread extends Thread {
/** Note: these have to be separate boolean flags because the
RawPortEvent constants are NOT bit-flags, they are just
defined as integers from 1 to 10 -DPL */
private boolean CTS=false;
private boolean DSR=false;
private boolean RI=false;
private boolean CD=false;
private boolean OE=false;
private boolean PE=false;
private boolean FE=false;
private boolean BI=false;
private boolean Data=false;
private boolean Output=false;
MonitorThread() { }
public void run() {
eventLoop();
}
}
public String getVersion()
{
String Version="$Id: Raw.java,v 1.1.2.17 2008-09-14 22:29:30 jarvi Exp $";
return(Version);
}
}
./rxtx-2.2pre2/src/gnu/io/CommPortEnumerator.java 0000644 0001750 0001750 00000011304 10614033755 021705 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.Enumeration;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
class CommPortEnumerator implements Enumeration
{
private CommPortIdentifier index;
private final static boolean debug = false;
static
{
if (debug)
System.out.println("CommPortEnumerator:{}");
}
CommPortEnumerator()
{
}
/*------------------------------------------------------------------------------
nextElement()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public Object nextElement()
{
if(debug) System.out.println("CommPortEnumerator:nextElement()");
synchronized (CommPortIdentifier.Sync)
{
if(index != null) index = index.next;
else index=CommPortIdentifier.CommPortIndex;
return(index);
}
}
/*------------------------------------------------------------------------------
hasMoreElements()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public boolean hasMoreElements()
{
if(debug) System.out.println("CommPortEnumerator:hasMoreElements() " + CommPortIdentifier.CommPortIndex == null ? false : true );
synchronized (CommPortIdentifier.Sync)
{
if(index != null) return index.next == null ? false : true;
else return CommPortIdentifier.CommPortIndex == null ?
false : true;
}
}
}
./rxtx-2.2pre2/src/gnu/io/CommPort.java 0000644 0001750 0001750 00000012047 10614033755 017650 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
/**
* CommPort
*/
public abstract class CommPort extends Object {
protected String name;
private final static boolean debug = false;
public abstract void enableReceiveFraming( int f )
throws UnsupportedCommOperationException;
public abstract void disableReceiveFraming();
public abstract boolean isReceiveFramingEnabled();
public abstract int getReceiveFramingByte();
public abstract void disableReceiveTimeout();
public abstract void enableReceiveTimeout( int time )
throws UnsupportedCommOperationException;
public abstract boolean isReceiveTimeoutEnabled();
public abstract int getReceiveTimeout();
public abstract void enableReceiveThreshold( int thresh )
throws UnsupportedCommOperationException;
public abstract void disableReceiveThreshold();
public abstract int getReceiveThreshold();
public abstract boolean isReceiveThresholdEnabled();
public abstract void setInputBufferSize( int size );
public abstract int getInputBufferSize();
public abstract void setOutputBufferSize( int size );
public abstract int getOutputBufferSize();
public void close()
{
if (debug) System.out.println("CommPort:close()");
try
{
CommPortIdentifier cp =
CommPortIdentifier.getPortIdentifier(this);
if ( cp != null )
cp.getPortIdentifier(this).internalClosePort();
}
catch (NoSuchPortException e)
{
}
};
public abstract InputStream getInputStream() throws IOException;
public abstract OutputStream getOutputStream() throws IOException;
public String getName()
{
if (debug) System.out.println("CommPort:getName()");
return( name );
}
public String toString()
{
if (debug) System.out.println("CommPort:toString()");
return( name );
}
}
./rxtx-2.2pre2/src/gnu/io/Configure.java 0000644 0001750 0001750 00000016000 10720136611 020013 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.awt.*;
import java.awt.event.*;
import java.io.*;
class Configure extends Frame
{
Checkbox cb[];
Panel p1;
static final int PORT_SERIAL = 1;
static final int PORT_PARALLEL = 2;
int PortType = PORT_SERIAL;
private void saveSpecifiedPorts()
{
String filename;
String javaHome= System.getProperty( "java.home" );
String pathSep = System.getProperty( "path.separator", ":" );
String fileSep = System.getProperty( "file.separator", "/" );
String lineSep = System.getProperty( "line.separator" );
String output;
if( PortType == PORT_SERIAL )
filename = javaHome +
fileSep + "lib" + fileSep +
"gnu.io.rxtx.SerialPorts";
else if ( PortType == PORT_PARALLEL )
filename = javaHome +
"gnu.io.rxtx.ParallelPorts";
else
{
System.out.println( "Bad Port Type!" );
return;
}
System.out.println(filename);
try {
FileOutputStream out = new FileOutputStream( filename );
for( int i = 0; i < 128; i++)
{
if( cb[i].getState() )
{
output = cb[i].getLabel() +
pathSep;
out.write( output.getBytes() );
}
}
out.write(lineSep.getBytes());
out.close();
}
catch ( IOException e )
{
System.out.println("IOException!");
}
}
void addCheckBoxes( String PortName )
{
for ( int i = 0; i < 128 ; i++ )
if( cb[i] != null )
p1.remove( cb[i] );
for (int i=1;i<129;i++)
{
cb[i-1]=new Checkbox(PortName+i);
p1.add( "NORTH", cb[i-1] );
}
}
public Configure()
{
int Width= 640;
int Height= 480;
cb = new Checkbox[128];
final Frame f = new Frame(
"Configure gnu.io.rxtx.properties");
String fileSep = System.getProperty( "file.separator", "/" );
String devPath;
if( fileSep.compareTo( "/" ) != 0 )
devPath="COM";
else
devPath="/dev/";
f.setBounds(100,50,Width,Height);
f.setLayout(new BorderLayout());
p1 = new Panel();
p1.setLayout(new GridLayout(16,4));
ActionListener l = new ActionListener() {
public void actionPerformed( ActionEvent e ) {
{
String res = e.getActionCommand();
if ( res.equals( "Save" ) )
saveSpecifiedPorts();
}
}
};
addCheckBoxes( devPath );
TextArea t = new TextArea( EnumMessage, 5, 50,
TextArea.SCROLLBARS_NONE );
t.setSize(50,Width);
t.setEditable(false);
final Panel p2 = new Panel();
p2.add(new Label("Port Name:"));
TextField tf = new TextField(devPath, 8);
tf.addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e )
{
addCheckBoxes(e.getActionCommand());
f.setVisible(true);
}
});
p2.add(tf);
Checkbox Keep = new Checkbox("Keep Ports");
p2.add(Keep);
Button b[] = new Button[6];
for(int j=0, i = 4;i<129;i*=2, j++)
{
b[j] = new Button("1-" + i);
b[j].addActionListener( new ActionListener() {
public void actionPerformed( ActionEvent e )
{
int k = Integer.parseInt(
e.getActionCommand().substring(2));
for(int x = 0; x < k; x++)
{
cb[x].setState(
!cb[x].getState());
f.setVisible(true);
}
}
});
p2.add(b[j]);
}
Button b1 = new Button("More");
Button b2 = new Button("Save");
b1.addActionListener(l);
b2.addActionListener(l);
p2.add(b1);
p2.add(b2);
f.add("South", p2);
f.add("Center", p1);
f.add("North", t);
f.addWindowListener(
new WindowAdapter() {
public void windowClosing( WindowEvent e )
{
System.exit( 0 );
}
}
);
f.setVisible(true);
}
public static void main (String[] args)
{
new Configure();
}
String EnumMessage = "gnu.io.rxtx.properties has not been detected.\n\nThere is no consistant means of detecting ports on this operating System. It is necessary to indicate which ports are valid on this system before proper port enumeration can happen. Please check the ports that are valid on this system and select Save";
}
./rxtx-2.2pre2/src/gnu/io/UnSupportedLoggerException.java 0000644 0001750 0001750 00000007521 10614033756 023421 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* Exception thrown when a method does not support the requested functionality.
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class UnSupportedLoggerException extends Exception
{
/**
* create an instances with no message about why the Exception was thrown.
* @since JDK1.0
*/
public UnSupportedLoggerException()
{
super();
}
/**
* create an instance with a message about why the Exception was thrown.
* @param str A detailed message explaining the reason for the Exception.
* @since JDK1.0
*/
public UnSupportedLoggerException( String str )
{
super( str );
}
}
./rxtx-2.2pre2/src/gnu/io/SerialPort.java 0000644 0001750 0001750 00000016703 10614033756 020200 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.*;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public abstract class SerialPort extends CommPort {
public static final int DATABITS_5 =5;
public static final int DATABITS_6 =6;
public static final int DATABITS_7 =7;
public static final int DATABITS_8 =8;
public static final int PARITY_NONE =0;
public static final int PARITY_ODD =1;
public static final int PARITY_EVEN =2;
public static final int PARITY_MARK =3;
public static final int PARITY_SPACE =4;
public static final int STOPBITS_1 =1;
public static final int STOPBITS_2 =2;
public static final int STOPBITS_1_5 =3;
public static final int FLOWCONTROL_NONE =0;
public static final int FLOWCONTROL_RTSCTS_IN =1;
public static final int FLOWCONTROL_RTSCTS_OUT =2;
public static final int FLOWCONTROL_XONXOFF_IN =4;
public static final int FLOWCONTROL_XONXOFF_OUT=8;
public abstract void setSerialPortParams( int b, int d, int s, int p )
throws UnsupportedCommOperationException;
public abstract int getBaudRate();
public abstract int getDataBits();
public abstract int getStopBits();
public abstract int getParity();
public abstract void setFlowControlMode( int flowcontrol )
throws UnsupportedCommOperationException;
public abstract int getFlowControlMode();
public abstract boolean isDTR();
public abstract void setDTR( boolean state );
public abstract void setRTS( boolean state );
public abstract boolean isCTS();
public abstract boolean isDSR();
public abstract boolean isCD();
public abstract boolean isRI();
public abstract boolean isRTS();
public abstract void sendBreak( int duration );
public abstract void addEventListener( SerialPortEventListener lsnr )
throws TooManyListenersException;
public abstract void removeEventListener();
public abstract void notifyOnDataAvailable( boolean enable );
public abstract void notifyOnOutputEmpty( boolean enable );
public abstract void notifyOnCTS( boolean enable );
public abstract void notifyOnDSR( boolean enable );
public abstract void notifyOnRingIndicator( boolean enable );
public abstract void notifyOnCarrierDetect( boolean enable );
public abstract void notifyOnOverrunError( boolean enable );
public abstract void notifyOnParityError( boolean enable );
public abstract void notifyOnFramingError( boolean enable );
public abstract void notifyOnBreakInterrupt( boolean enable );
/*
public abstract void setRcvFifoTrigger(int trigger);
deprecated
*/
/* ---------------------- end of commapi ------------------------ */
/*
can't have static abstract?
public abstract static boolean staticSetDTR( String port, boolean flag )
throws UnsupportedCommOperationException;
public abstract static boolean staticSetRTS( String port, boolean flag )
throws UnsupportedCommOperationException;
*/
public abstract byte getParityErrorChar( )
throws UnsupportedCommOperationException;
public abstract boolean setParityErrorChar( byte b )
throws UnsupportedCommOperationException;
public abstract byte getEndOfInputChar( )
throws UnsupportedCommOperationException;
public abstract boolean setEndOfInputChar( byte b )
throws UnsupportedCommOperationException;
public abstract boolean setUARTType(String type, boolean test)
throws UnsupportedCommOperationException;
public abstract String getUARTType()
throws UnsupportedCommOperationException;
public abstract boolean setBaudBase(int BaudBase)
throws UnsupportedCommOperationException,
IOException;
public abstract int getBaudBase()
throws UnsupportedCommOperationException,
IOException;
public abstract boolean setDivisor(int Divisor)
throws UnsupportedCommOperationException,
IOException;
public abstract int getDivisor()
throws UnsupportedCommOperationException,
IOException;
public abstract boolean setLowLatency()
throws UnsupportedCommOperationException;
public abstract boolean getLowLatency()
throws UnsupportedCommOperationException;
public abstract boolean setCallOutHangup(boolean NoHup)
throws UnsupportedCommOperationException;
public abstract boolean getCallOutHangup()
throws UnsupportedCommOperationException;
}
./rxtx-2.2pre2/src/gnu/io/RS485.java 0000644 0001750 0001750 00000033135 10614033755 016676 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.*;
import java.util.*;
import java.lang.Math;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
final class RS485 extends RS485Port {
static
{
System.loadLibrary( "rxtxRS485" );
Initialize();
}
/** Initialize the native library */
private native static void Initialize();
/** Actual RS485Port wrapper class */
/** Open the named port */
public RS485( String name ) throws PortInUseException {
fd = open( name );
}
private native int open( String name ) throws PortInUseException;
/** File descriptor */
private int fd;
/** DSR flag **/
static boolean dsrFlag = false;
/** Output stream */
private final RS485OutputStream out = new RS485OutputStream();
public OutputStream getOutputStream() { return out; }
/** Input stream */
private final RS485InputStream in = new RS485InputStream();
public InputStream getInputStream() { return in; }
/** Set the RS485Port parameters */
public void setRS485PortParams( int b, int d, int s, int p )
throws UnsupportedCommOperationException
{
nativeSetRS485PortParams( b, d, s, p );
speed = b;
dataBits = d;
stopBits = s;
parity = p;
}
/** Set the native RS485 port parameters */
private native void nativeSetRS485PortParams( int speed, int dataBits,
int stopBits, int parity ) throws UnsupportedCommOperationException;
/** Line speed in bits-per-second */
private int speed=9600;
public int getBaudRate() { return speed; }
/** Data bits port parameter */
private int dataBits=DATABITS_8;
public int getDataBits() { return dataBits; }
/** Stop bits port parameter */
private int stopBits=RS485Port.STOPBITS_1;
public int getStopBits() { return stopBits; }
/** Parity port parameter */
private int parity= RS485Port.PARITY_NONE;
public int getParity() { return parity; }
/** Flow control */
private int flowmode = RS485Port.FLOWCONTROL_NONE;
public void setFlowControlMode( int flowcontrol ) {
try { setflowcontrol( flowcontrol ); }
catch( IOException e ) {
e.printStackTrace();
return;
}
flowmode=flowcontrol;
}
public int getFlowControlMode() { return flowmode; }
native void setflowcontrol( int flowcontrol ) throws IOException;
/*
linux/drivers/char/n_hdlc.c? FIXME
taj@www.linux.org.uk
*/
/** Receive framing control
*/
public void enableReceiveFraming( int f )
throws UnsupportedCommOperationException
{
throw new UnsupportedCommOperationException( "Not supported" );
}
public void disableReceiveFraming() {}
public boolean isReceiveFramingEnabled() { return false; }
public int getReceiveFramingByte() { return 0; }
/** Receive timeout control */
private int timeout = 0;
public native int NativegetReceiveTimeout();
public native boolean NativeisReceiveTimeoutEnabled();
public native void NativeEnableReceiveTimeoutThreshold(int time, int threshold,int InputBuffer);
public void disableReceiveTimeout(){
enableReceiveTimeout(0);
}
public void enableReceiveTimeout( int time ){
if( time >= 0 ) {
timeout = time;
NativeEnableReceiveTimeoutThreshold( time , threshold, InputBuffer );
}
else {
System.out.println("Invalid timeout");
}
}
public boolean isReceiveTimeoutEnabled(){
return(NativeisReceiveTimeoutEnabled());
}
public int getReceiveTimeout(){
return(NativegetReceiveTimeout( ));
}
/** Receive threshold control */
private int threshold = 0;
public void enableReceiveThreshold( int thresh ){
if(thresh >=0)
{
threshold=thresh;
NativeEnableReceiveTimeoutThreshold(timeout, threshold, InputBuffer);
}
else /* invalid thresh */
{
System.out.println("Invalid Threshold");
}
}
public void disableReceiveThreshold() {
enableReceiveThreshold(0);
}
public int getReceiveThreshold(){
return threshold;
}
public boolean isReceiveThresholdEnabled(){
return(threshold>0);
}
/** Input/output buffers */
/** FIXME I think this refers to
FOPEN(3)/SETBUF(3)/FREAD(3)/FCLOSE(3)
taj@www.linux.org.uk
These are native stubs...
*/
private int InputBuffer=0;
private int OutputBuffer=0;
public void setInputBufferSize( int size )
{
InputBuffer=size;
}
public int getInputBufferSize()
{
return(InputBuffer);
}
public void setOutputBufferSize( int size )
{
OutputBuffer=size;
}
public int getOutputBufferSize()
{
return(OutputBuffer);
}
/** Line status methods */
public native boolean isDTR();
public native void setDTR( boolean state );
public native void setRTS( boolean state );
private native void setDSR( boolean state );
public native boolean isCTS();
public native boolean isDSR();
public native boolean isCD();
public native boolean isRI();
public native boolean isRTS();
/** Write to the port */
public native void sendBreak( int duration );
private native void writeByte( int b ) throws IOException;
private native void writeArray( byte b[], int off, int len )
throws IOException;
private native void drain() throws IOException;
/** RS485 read methods */
private native int nativeavailable() throws IOException;
private native int readByte() throws IOException;
private native int readArray( byte b[], int off, int len )
throws IOException;
/** RS485 Port Event listener */
private RS485PortEventListener SPEventListener;
/** Thread to monitor data */
private MonitorThread monThread;
/** Process RS485PortEvents */
native void eventLoop();
private int dataAvailable=0;
public void sendEvent( int event, boolean state ) {
switch( event ) {
case RS485PortEvent.DATA_AVAILABLE:
dataAvailable=1;
if( monThread.Data ) break;
return;
case RS485PortEvent.OUTPUT_BUFFER_EMPTY:
if( monThread.Output ) break;
return;
/*
if( monThread.DSR ) break;
return;
if (isDSR())
{
if (!dsrFlag)
{
dsrFlag = true;
RS485PortEvent e = new RS485PortEvent(this, RS485PortEvent.DSR, !dsrFlag, dsrFlag );
}
}
else if (dsrFlag)
{
dsrFlag = false;
RS485PortEvent e = new RS485PortEvent(this, RS485PortEvent.DSR, !dsrFlag, dsrFlag );
}
*/
case RS485PortEvent.CTS:
if( monThread.CTS ) break;
return;
case RS485PortEvent.DSR:
if( monThread.DSR ) break;
return;
case RS485PortEvent.RI:
if( monThread.RI ) break;
return;
case RS485PortEvent.CD:
if( monThread.CD ) break;
return;
case RS485PortEvent.OE:
if( monThread.OE ) break;
return;
case RS485PortEvent.PE:
if( monThread.PE ) break;
return;
case RS485PortEvent.FE:
if( monThread.FE ) break;
return;
case RS485PortEvent.BI:
if( monThread.BI ) break;
return;
default:
System.err.println("unknown event:"+event);
return;
}
RS485PortEvent e = new RS485PortEvent(this, event, !state, state );
if( SPEventListener != null ) SPEventListener.RS485Event( e );
}
/** Add an event listener */
public void addEventListener( RS485PortEventListener lsnr )
throws TooManyListenersException
{
if( SPEventListener != null ) throw new TooManyListenersException();
SPEventListener = lsnr;
monThread = new MonitorThread();
monThread.start();
}
/** Remove the RS485 port event listener */
public void removeEventListener() {
SPEventListener = null;
if( monThread != null ) {
monThread.interrupt();
monThread = null;
}
}
public void notifyOnDataAvailable( boolean enable ) { monThread.Data = enable; }
public void notifyOnOutputEmpty( boolean enable ) { monThread.Output = enable; }
public void notifyOnCTS( boolean enable ) { monThread.CTS = enable; }
public void notifyOnDSR( boolean enable ) { monThread.DSR = enable; }
public void notifyOnRingIndicator( boolean enable ) { monThread.RI = enable; }
public void notifyOnCarrierDetect( boolean enable ) { monThread.CD = enable; }
public void notifyOnOverrunError( boolean enable ) { monThread.OE = enable; }
public void notifyOnParityError( boolean enable ) { monThread.PE = enable; }
public void notifyOnFramingError( boolean enable ) { monThread.FE = enable; }
public void notifyOnBreakInterrupt( boolean enable ) { monThread.BI = enable; }
/** Close the port */
private native void nativeClose();
public void close() {
setDTR(false);
setDSR(false);
nativeClose();
super.close();
fd = 0;
}
/** Finalize the port */
protected void finalize() {
if( fd > 0 ) close();
}
/** Inner class for RS485OutputStream */
class RS485OutputStream extends OutputStream {
public void write( int b ) throws IOException {
writeByte( b );
}
public void write( byte b[] ) throws IOException {
writeArray( b, 0, b.length );
}
public void write( byte b[], int off, int len ) throws IOException {
writeArray( b, off, len );
}
public void flush() throws IOException {
drain();
}
}
/** Inner class for RS485InputStream */
class RS485InputStream extends InputStream {
public int read() throws IOException {
dataAvailable=0;
return readByte();
}
public int read( byte b[] ) throws IOException
{
return read ( b, 0, b.length);
}
public int read( byte b[], int off, int len ) throws IOException
{
dataAvailable=0;
int i=0, Minimum=0;
int intArray[] =
{
b.length,
InputBuffer,
len
};
/*
find the lowest nonzero value
timeout and threshold are handled on the native side
see NativeEnableReceiveTimeoutThreshold in
RS485Imp.c
*/
while(intArray[i]==0 && i < intArray.length) i++;
Minimum=intArray[i];
while( i < intArray.length )
{
if(intArray[i] > 0 )
{
Minimum=Math.min(Minimum,intArray[i]);
}
i++;
}
Minimum=Math.min(Minimum,threshold);
if(Minimum == 0) Minimum=1;
int Available=available();
int Ret = readArray( b, off, Minimum);
return Ret;
}
public int available() throws IOException {
return nativeavailable();
}
}
class MonitorThread extends Thread {
/** Note: these have to be separate boolean flags because the
RS485PortEvent constants are NOT bit-flags, they are just
defined as integers from 1 to 10 -DPL */
private boolean CTS=false;
private boolean DSR=false;
private boolean RI=false;
private boolean CD=false;
private boolean OE=false;
private boolean PE=false;
private boolean FE=false;
private boolean BI=false;
private boolean Data=false;
private boolean Output=false;
MonitorThread() { }
public void run() {
eventLoop();
}
}
}
./rxtx-2.2pre2/src/gnu/io/CommPortIdentifier.java 0000644 0001750 0001750 00000042121 11113576332 021645 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.FileDescriptor;
import java.util.HashMap;
import java.util.Vector;
import java.util.Enumeration;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class CommPortIdentifier extends Object /* extends Vector? */
{
public static final int PORT_SERIAL = 1; // rs232 Port
public static final int PORT_PARALLEL = 2; // Parallel Port
public static final int PORT_I2C = 3; // i2c Port
public static final int PORT_RS485 = 4; // rs485 Port
public static final int PORT_RAW = 5; // Raw Port
private String PortName;
private boolean Available = true;
private String Owner;
private CommPort commport;
private CommDriver RXTXDriver;
static CommPortIdentifier CommPortIndex;
CommPortIdentifier next;
private int PortType;
private final static boolean debug = false;
static Object Sync;
Vector ownershipListener;
/*------------------------------------------------------------------------------
static {} aka initialization
accept: -
perform: load the rxtx driver
return: -
exceptions: Throwable
comments: static block to initialize the class
------------------------------------------------------------------------------*/
// initialization only done once....
static
{
if(debug) System.out.println("CommPortIdentifier:static initialization()");
Sync = new Object();
try
{
CommDriver RXTXDriver = (CommDriver) Class.forName("gnu.io.RXTXCommDriver").newInstance();
RXTXDriver.initialize();
}
catch (Throwable e)
{
System.err.println(e + " thrown while loading " + "gnu.io.RXTXCommDriver");
}
String OS;
OS = System.getProperty("os.name");
if(OS.toLowerCase().indexOf("linux") == -1)
{
if (debug)
System.out.println("Have not implemented native_psmisc_report_owner(PortName)); in CommPortIdentifier");
}
System.loadLibrary( "rxtxSerial" );
}
CommPortIdentifier ( String pn, CommPort cp, int pt, CommDriver driver)
{
PortName = pn;
commport = cp;
PortType = pt;
next = null;
RXTXDriver = driver;
}
/*------------------------------------------------------------------------------
addPortName()
accept: Name of the port s, Port type,
reverence to RXTXCommDriver.
perform: place a new CommPortIdentifier in the linked list
return: none.
exceptions: none.
comments:
------------------------------------------------------------------------------*/
public static void addPortName(String s, int type, CommDriver c)
{
if(debug) System.out.println("CommPortIdentifier:addPortName("+s+")");
AddIdentifierToList(new CommPortIdentifier(s, null, type, c));
}
/*------------------------------------------------------------------------------
AddIdentifierToList()
accept: The cpi to add to the list.
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
private static void AddIdentifierToList( CommPortIdentifier cpi)
{
if(debug) System.out.println("CommPortIdentifier:AddIdentifierToList()");
synchronized (Sync)
{
if (CommPortIndex == null)
{
CommPortIndex = cpi;
if(debug) System.out.println("CommPortIdentifier:AddIdentifierToList() null");
}
else
{
CommPortIdentifier index = CommPortIndex;
while (index.next != null)
{
index = index.next;
if(debug) System.out.println("CommPortIdentifier:AddIdentifierToList() index.next");
}
index.next = cpi;
}
}
}
/*------------------------------------------------------------------------------
addPortOwnershipListener()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public void addPortOwnershipListener(CommPortOwnershipListener c)
{
if(debug) System.out.println("CommPortIdentifier:addPortOwnershipListener()");
/* is the Vector instantiated? */
if( ownershipListener == null )
{
ownershipListener = new Vector();
}
/* is the ownership listener already in the list? */
if ( ownershipListener.contains(c) == false)
{
ownershipListener.addElement(c);
}
}
/*------------------------------------------------------------------------------
getCurrentOwner()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public String getCurrentOwner()
{
if(debug) System.out.println("CommPortIdentifier:getCurrentOwner()");
return( Owner );
}
/*------------------------------------------------------------------------------
getName()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public String getName()
{
if(debug) System.out.println("CommPortIdentifier:getName()");
return( PortName );
}
/*------------------------------------------------------------------------------
getPortIdentifier()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
static public CommPortIdentifier getPortIdentifier(String s) throws NoSuchPortException
{
if(debug) System.out.println("CommPortIdentifier:getPortIdentifier(" + s +")");
CommPortIdentifier index;
synchronized (Sync)
{
index = CommPortIndex;
while (index != null && !index.PortName.equals(s)) {
index = index.next;
}
if (index == null) {
/* This may slow things down but if you pass the string for the port after
a device is plugged in, you can find it now.
http://bugzilla.qbang.org/show_bug.cgi?id=48
*/
getPortIdentifiers();
index = CommPortIndex;
while (index != null && !index.PortName.equals(s)) {
index = index.next;
}
}
}
if (index != null) return index;
else
{
if ( debug )
System.out.println("not found!" + s);
throw new NoSuchPortException();
}
}
/*------------------------------------------------------------------------------
getPortIdentifier()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
static public CommPortIdentifier getPortIdentifier(CommPort p)
throws NoSuchPortException
{
if(debug) System.out.println("CommPortIdentifier:getPortIdentifier(CommPort)");
CommPortIdentifier c;
synchronized( Sync )
{
c = CommPortIndex;
while ( c != null && c.commport != p )
c = c.next;
}
if ( c != null )
return (c);
if ( debug )
System.out.println("not found!" + p.getName());
throw new NoSuchPortException();
}
/*------------------------------------------------------------------------------
getPortIdentifiers()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
static public Enumeration getPortIdentifiers()
{
if(debug) System.out.println("static CommPortIdentifier:getPortIdentifiers()");
//Do not allow anybody get any ports while we are re-initializing
//because the CommPortIndex points to invalid instances during that time
synchronized(Sync) {
//Remember old ports in order to restore them for ownership events later
HashMap oldPorts = new HashMap();
CommPortIdentifier p = CommPortIndex;
while(p!=null) {
oldPorts.put(p.PortName, p);
p = p.next;
}
CommPortIndex = null;
try
{
//Initialize RXTX: This leads to detecting all ports
//and writing them into our CommPortIndex through our method
//{@link #addPortName(java.lang.String, int, gnu.io.CommDriver)}
//This works while lock on Sync is held
CommDriver RXTXDriver = (CommDriver) Class.forName("gnu.io.RXTXCommDriver").newInstance();
RXTXDriver.initialize();
//Restore old CommPortIdentifier objects where possible,
//in order to support proper ownership event handling.
//Clients might still have references to old identifiers!
CommPortIdentifier curPort = CommPortIndex;
CommPortIdentifier prevPort = null;
while(curPort!=null) {
CommPortIdentifier matchingOldPort = (CommPortIdentifier)oldPorts.get(curPort.PortName);
if(matchingOldPort!=null && matchingOldPort.PortType == curPort.PortType) {
//replace new port by old one
matchingOldPort.RXTXDriver = curPort.RXTXDriver;
matchingOldPort.next = curPort.next;
if(prevPort==null) {
CommPortIndex = matchingOldPort;
} else {
prevPort.next = matchingOldPort;
}
prevPort = matchingOldPort;
} else {
prevPort = curPort;
}
curPort = curPort.next;
}
}
catch (Throwable e)
{
System.err.println(e + " thrown while loading " + "gnu.io.RXTXCommDriver");
System.err.flush();
}
}
return new CommPortEnumerator();
}
/*------------------------------------------------------------------------------
getPortType()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public int getPortType()
{
if(debug) System.out.println("CommPortIdentifier:getPortType()");
return( PortType );
}
/*------------------------------------------------------------------------------
isCurrentlyOwned()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public synchronized boolean isCurrentlyOwned()
{
if(debug) System.out.println("CommPortIdentifier:isCurrentlyOwned()");
return(!Available);
}
/*------------------------------------------------------------------------------
open()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public synchronized CommPort open(FileDescriptor f) throws UnsupportedCommOperationException
{
if(debug) System.out.println("CommPortIdentifier:open(FileDescriptor)");
throw new UnsupportedCommOperationException();
}
private native String native_psmisc_report_owner(String PortName);
/*------------------------------------------------------------------------------
open()
accept: application making the call and milliseconds to block
during open.
perform: open the port if possible
return: CommPort if successful
exceptions: PortInUseException if in use.
comments:
------------------------------------------------------------------------------*/
private boolean HideOwnerEvents;
public CommPort open(String TheOwner, int i)
throws gnu.io.PortInUseException
{
if(debug) System.out.println("CommPortIdentifier:open("+TheOwner + ", " +i+")");
boolean isAvailable;
synchronized(this) {
isAvailable = this.Available;
if (isAvailable) {
//assume ownership inside the synchronized block
this.Available = false;
this.Owner = TheOwner;
}
}
if (!isAvailable)
{
long waitTimeEnd = System.currentTimeMillis() + i;
//fire the ownership event outside the synchronized block
fireOwnershipEvent(CommPortOwnershipListener.PORT_OWNERSHIP_REQUESTED);
long waitTimeCurr;
synchronized(this) {
while(!Available && (waitTimeCurr=System.currentTimeMillis()) < waitTimeEnd) {
try
{
wait(waitTimeEnd - waitTimeCurr);
}
catch ( InterruptedException e )
{
Thread.currentThread().interrupt();
break;
}
}
isAvailable = this.Available;
if (isAvailable) {
//assume ownership inside the synchronized block
this.Available = false;
this.Owner = TheOwner;
}
}
}
if (!isAvailable)
{
throw new gnu.io.PortInUseException(getCurrentOwner());
}
//At this point, the CommPortIdentifier is owned by us.
try {
if(commport == null)
{
commport = RXTXDriver.getCommPort(PortName,PortType);
}
if(commport != null)
{
fireOwnershipEvent(CommPortOwnershipListener.PORT_OWNED);
return commport;
}
else
{
throw new gnu.io.PortInUseException(
native_psmisc_report_owner(PortName));
}
} finally {
if(commport == null) {
//something went wrong reserving the commport -> unown the port
synchronized(this) {
this.Available = true;
this.Owner = null;
}
}
}
}
/*------------------------------------------------------------------------------
removePortOwnership()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
public void removePortOwnershipListener(CommPortOwnershipListener c)
{
if(debug) System.out.println("CommPortIdentifier:removePortOwnershipListener()");
/* why is this called twice? */
if(ownershipListener != null)
ownershipListener.removeElement(c);
}
/*------------------------------------------------------------------------------
internalClosePort()
accept: None
perform: clean up the Ownership information and send the event
return: None
exceptions: None
comments: None
------------------------------------------------------------------------------*/
void internalClosePort()
{
synchronized(this) {
if(debug) System.out.println("CommPortIdentifier:internalClosePort()");
Owner = null;
Available = true;
commport = null;
/* this tosses null pointer?? */
notifyAll();
}
fireOwnershipEvent(CommPortOwnershipListener.PORT_UNOWNED);
}
/*------------------------------------------------------------------------------
fireOwnershipEvent()
accept:
perform:
return:
exceptions:
comments:
------------------------------------------------------------------------------*/
void fireOwnershipEvent(int eventType)
{
if(debug) System.out.println("CommPortIdentifier:fireOwnershipEvent( " + eventType + " )");
if (ownershipListener != null)
{
CommPortOwnershipListener c;
for ( Enumeration e = ownershipListener.elements();
e.hasMoreElements();
c.ownershipChange(eventType))
c = (CommPortOwnershipListener) e.nextElement();
}
}
}
./rxtx-2.2pre2/src/gnu/io/RS485PortEvent.java 0000644 0001750 0001750 00000010576 10614033755 020551 0 ustar twerner twerner /* Non functional contact tjarvi@qbang.org for details */
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class RS485PortEvent extends EventObject
{
public static final int DATA_AVAILABLE =1;
public static final int OUTPUT_BUFFER_EMPTY =2;
public static final int CTS =3;
public static final int DSR =4;
public static final int RI =5;
public static final int CD =6;
public static final int OE =7;
public static final int PE =8;
public static final int FE =9;
public static final int BI =10;
private boolean OldValue;
private boolean NewValue;
private int eventType;
/*public int eventType =0; depricated */
public RS485PortEvent(RS485Port srcport, int eventtype, boolean oldvalue, boolean newvalue)
{
super( srcport );
OldValue=oldvalue;
NewValue=newvalue;
eventType=eventtype;
}
public int getEventType()
{
return(eventType);
}
public boolean getNewValue()
{
return( NewValue );
}
public boolean getOldValue()
{
return( OldValue );
}
}
./rxtx-2.2pre2/src/gnu/io/RawPortEvent.java 0000644 0001750 0001750 00000010570 10614033755 020507 0 ustar twerner twerner /* Non functional contact tjarvi@qbang.org for details */
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class RawPortEvent extends EventObject
{
public static final int DATA_AVAILABLE =1;
public static final int OUTPUT_BUFFER_EMPTY =2;
public static final int CTS =3;
public static final int DSR =4;
public static final int RI =5;
public static final int CD =6;
public static final int OE =7;
public static final int PE =8;
public static final int FE =9;
public static final int BI =10;
private boolean OldValue;
private boolean NewValue;
private int eventType;
/*public int eventType =0; depricated */
public RawPortEvent(RawPort srcport, int eventtype, boolean oldvalue, boolean newvalue)
{
super( srcport );
OldValue=oldvalue;
NewValue=newvalue;
eventType=eventtype;
}
public int getEventType()
{
return(eventType);
}
public boolean getNewValue()
{
return( NewValue );
}
public boolean getOldValue()
{
return( OldValue );
}
}
./rxtx-2.2pre2/src/gnu/io/Zystem.java 0000755 0001750 0001750 00000020437 10720136613 017403 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 2002-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.RandomAccessFile;
public class Zystem
{
public static final int SILENT_MODE = 0;
public static final int FILE_MODE = 1;
public static final int NET_MODE = 2;
public static final int MEX_MODE = 3;
public static final int PRINT_MODE = 4;
public static final int J2EE_MSG_MODE = 5;
public static final int J2SE_LOG_MODE = 6;
static int mode;
static
{
/*
The rxtxZystem library uses Python code and is not
included with RXTX. A seperate library will be released
to avoid potential license conflicts.
Trent Jarvi taj@www.linux.org.uk
*/
//System.loadLibrary( "rxtxZystem" );
mode = SILENT_MODE;
}
private static String target;
public Zystem( int m ) throws UnSupportedLoggerException
{
mode = m;
startLogger( "asdf" );
}
/**
* Constructor.
* Mode is taken from the java system property "gnu.io.log.mode". The available values are :
* - SILENT_MODE No logging
*
- FILE_MODE log to file
*
- NET_MODE
*
- MEX_MODE
*
- PRINT_MODE
*
- J2EE_MSG_MODE
*
- J2SE_LOG_MODE log to java.util.logging
*
*/
public Zystem () throws UnSupportedLoggerException
{
String s = System.getProperty ("gnu.io.log.mode");
if (s != null)
{
if ("SILENT_MODE".equals (s))
{
mode = SILENT_MODE;
}
else if ("FILE_MODE".equals (s))
{
mode = FILE_MODE;
}
else if ("NET_MODE".equals (s))
{
mode = NET_MODE;
}
else if ("MEX_MODE".equals (s))
{
mode = MEX_MODE;
}
else if ("PRINT_MODE".equals (s))
{
mode = PRINT_MODE;
}
else if ("J2EE_MSG_MODE".equals (s))
{
mode = J2EE_MSG_MODE;
}
else if ("J2SE_LOG_MODE".equals (s))
{
mode = J2SE_LOG_MODE;
}
else
{
try
{
mode = Integer.parseInt (s);
}
catch (NumberFormatException e)
{
mode = SILENT_MODE;
}
}
}
else
{
mode = SILENT_MODE;
}
startLogger ("asdf");
}
public void startLogger( ) throws UnSupportedLoggerException
{
if ( mode == SILENT_MODE || mode == PRINT_MODE )
{
//nativeNetInit( );
return;
}
throw new UnSupportedLoggerException( "Target Not Allowed" );
}
/* accept the host or file to log to. */
public void startLogger( String t ) throws UnSupportedLoggerException
{
target = t;
/*
if ( mode == NET_MODE )
{
nativeNetInit( );
}
if ( nativeInit( ) )
{
throw new UnSupportedLoggerException(
"Port initializion failed" );
}
*/
return;
}
public void finalize()
{
/*
if ( mode == NET_MODE )
{
nativeNetFinalize( );
}
nativeFinalize();
*/
mode = SILENT_MODE;
target = null;
}
public void filewrite( String s )
{
try {
RandomAccessFile w =
new RandomAccessFile( target, "rw" );
w.seek( w.length() );
w.writeBytes( s );
w.close();
} catch ( Exception e ) {
System.out.println("Debug output file write failed");
}
}
public boolean report( String s)
{
if ( mode == NET_MODE )
{
// return( nativeNetReportln( s ) );
}
else if ( mode == PRINT_MODE )
{
System.out.println( s );
return( true );
}
else if ( mode == MEX_MODE )
{
// return( nativeMexReport( s ) );
}
else if ( mode == SILENT_MODE )
{
return( true );
}
else if ( mode == FILE_MODE )
{
filewrite( s );
}
else if ( mode == J2EE_MSG_MODE )
{
return( false );
}
else if (mode == J2SE_LOG_MODE)
{
java.util.logging.Logger.getLogger ("gnu.io").fine (s);
return (true);
}
return( false );
}
public boolean reportln( )
{
boolean b;
if ( mode == NET_MODE )
{
// b= nativeNetReportln( "\n" );
// return(b);
}
else if ( mode == PRINT_MODE )
{
System.out.println( );
return( true );
}
else if ( mode == MEX_MODE )
{
// b = nativeMexReportln( "\n" );
// return(b);
}
else if ( mode == SILENT_MODE )
{
return( true );
}
else if ( mode == FILE_MODE )
{
filewrite( "\n" );
}
else if ( mode == J2EE_MSG_MODE )
{
return( false );
}
return( false );
}
public boolean reportln( String s)
{
boolean b;
if ( mode == NET_MODE )
{
// b= nativeNetReportln( s + "\n" );
// return(b);
}
else if ( mode == PRINT_MODE )
{
System.out.println( s );
return( true );
}
else if ( mode == MEX_MODE )
{
// b = nativeMexReportln( s + "\n" );
// return(b);
}
else if ( mode == SILENT_MODE )
{
return( true );
}
else if ( mode == FILE_MODE )
{
filewrite( s + "\n" );
}
else if ( mode == J2EE_MSG_MODE )
{
return( false );
}
else if (mode == J2SE_LOG_MODE)
{
return (true);
}
return( false );
}
/*
private native boolean nativeInit( );
private native void nativeFinalize();
*/
/* open and close the socket */
/*
private native boolean nativeNetInit( );
private native void nativeNetFinalize();
*/
/* dumping to a remote machine */
/*
public native boolean nativeNetReport( String s );
public native boolean nativeNetReportln( String s );
*/
/* specific to Matlab */
/*
public native boolean nativeMexReport( String s );
public native boolean nativeMexReportln( String s );
*/
}
./rxtx-2.2pre2/src/gnu/io/LPRPort.java 0000644 0001750 0001750 00000026213 10614033755 017412 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.TooManyListenersException;
import java.lang.Math;
/**
* LPRPort
*/
final class LPRPort extends ParallelPort
{
static {
System.loadLibrary( "rxtxParallel" );
Initialize();
}
/** Initialize the native library */
private native static void Initialize();
private final static boolean debug = false;
/** Open the named port */
public LPRPort( String name ) throws PortInUseException
{
if (debug) System.out.println("LPRPort:LPRPort("+name+")");
/*
commapi/javadocs/API_users_guide.html specifies that whenever
an application tries to open a port in use by another application
the PortInUseException will be thrown
I know some didnt like it this way but I'm not sure how to avoid
it. We will just be writing to a bogus fd if we catch the
exeption
Trent
*/
// try {
fd = open( name );
this.name = name;
// } catch ( PortInUseException e ){}
if (debug)
System.out.println("LPRPort:LPRPort("+name+") fd = " +
fd);
}
private synchronized native int open( String name )
throws PortInUseException;
/** File descriptor */
private int fd;
/** Output stream */
private final ParallelOutputStream out = new ParallelOutputStream();
public OutputStream getOutputStream() { return out; }
/** Input stream */
private final ParallelInputStream in = new ParallelInputStream();
public InputStream getInputStream() { return in; }
/** return current mode LPT_MODE_SPP, LPT_MODE_PS2, LPT_MODE_EPP,
or LPT_MODE_ECP */
private int lprmode=LPT_MODE_ANY;
public int getMode() { return lprmode; }
public int setMode(int mode) throws UnsupportedCommOperationException
{
try {
setLPRMode(mode);
} catch(UnsupportedCommOperationException e) {
e.printStackTrace();
return -1;
}
lprmode = mode;
return(0);
}
public void restart()
{
System.out.println("restart() is not implemented");
}
public void suspend()
{
System.out.println("suspend() is not implemented");
}
public native boolean setLPRMode(int mode)
throws UnsupportedCommOperationException;
public native boolean isPaperOut();
public native boolean isPrinterBusy();
public native boolean isPrinterError();
public native boolean isPrinterSelected();
public native boolean isPrinterTimedOut();
/** Close the port */
private native void nativeClose();
public synchronized void close()
{
if( fd < 0 ) return;
nativeClose();
super.close();
removeEventListener();
fd = 0;
Runtime.getRuntime().gc();
}
/** Receive framing control */
public void enableReceiveFraming( int f )
throws UnsupportedCommOperationException
{
throw new UnsupportedCommOperationException( "Not supported" );
}
public void disableReceiveFraming() {}
public boolean isReceiveFramingEnabled() { return false; }
public int getReceiveFramingByte() { return 0; }
/** Receive timeout control */
private int timeout = 0;
public void enableReceiveTimeout( int t )
{
if( t > 0 ) timeout = t;
else timeout = 0;
}
public void disableReceiveTimeout() { timeout = 0; }
public boolean isReceiveTimeoutEnabled() { return timeout > 0; }
public int getReceiveTimeout() { return timeout; }
/** Receive threshold control */
private int threshold = 1;
public void enableReceiveThreshold( int t )
{
if( t > 1 ) threshold = t;
else threshold = 1;
}
public void disableReceiveThreshold() { threshold = 1; }
public int getReceiveThreshold() { return threshold; }
public boolean isReceiveThresholdEnabled() { return threshold > 1; };
/**
Input/output buffers
These are native stubs...
*/
public native void setInputBufferSize( int size );
public native int getInputBufferSize();
public native void setOutputBufferSize( int size );
public native int getOutputBufferSize();
public native int getOutputBufferFree();
/** Write to the port */
protected native void writeByte( int b ) throws IOException;
protected native void writeArray( byte b[], int off, int len )
throws IOException;
protected native void drain() throws IOException;
/** LPRPort read methods */
protected native int nativeavailable() throws IOException;
protected native int readByte() throws IOException;
protected native int readArray( byte b[], int off, int len )
throws IOException;
/** Parallel Port Event listener */
private ParallelPortEventListener PPEventListener;
/** Thread to monitor data */
private MonitorThread monThread;
/** Process ParallelPortEvents */
native void eventLoop();
public boolean checkMonitorThread()
{
if(monThread != null)
return monThread.isInterrupted();
return(true);
}
public synchronized boolean sendEvent( int event, boolean state )
{
/* Let the native side know its time to die */
if ( fd == 0 || PPEventListener == null || monThread == null )
{
return(true);
}
switch( event )
{
case ParallelPortEvent.PAR_EV_BUFFER:
if( monThread.monBuffer ) break;
return(false);
case ParallelPortEvent.PAR_EV_ERROR:
if( monThread.monError ) break;
return(false);
default:
System.err.println("unknown event:"+event);
return(false);
}
ParallelPortEvent e = new ParallelPortEvent(this, event, !state,
state );
if( PPEventListener != null )
PPEventListener.parallelEvent( e );
if ( fd == 0 || PPEventListener == null || monThread == null )
{
return(true);
}
else
{
try{Thread.sleep(50);} catch(Exception exc){}
return(false);
}
}
/** Add an event listener */
public synchronized void addEventListener(
ParallelPortEventListener lsnr )
throws TooManyListenersException
{
if( PPEventListener != null )
throw new TooManyListenersException();
PPEventListener = lsnr;
monThread = new MonitorThread();
monThread.start();
}
/** Remove the parallel port event listener */
public synchronized void removeEventListener()
{
PPEventListener = null;
if( monThread != null )
{
monThread.interrupt();
monThread = null;
}
}
/** Note: these have to be separate boolean flags because the
ParallelPortEvent constants are NOT bit-flags, they are just
defined as integers from 1 to 10 -DPL */
public synchronized void notifyOnError( boolean enable )
{
System.out.println("notifyOnError is not implemented yet");
monThread.monError = enable;
}
public synchronized void notifyOnBuffer( boolean enable )
{
System.out.println("notifyOnBuffer is not implemented yet");
monThread.monBuffer = enable;
}
/** Finalize the port */
protected void finalize()
{
if ( fd > 0 ) close();
}
/** Inner class for ParallelOutputStream */
class ParallelOutputStream extends OutputStream
{
public synchronized void write( int b ) throws IOException
{
if ( fd == 0 ) throw new IOException();
writeByte( b );
}
public synchronized void write( byte b[] ) throws IOException
{
if ( fd == 0 ) throw new IOException();
writeArray( b, 0, b.length );
}
public synchronized void write( byte b[], int off, int len )
throws IOException
{
if ( fd == 0 ) throw new IOException();
writeArray( b, off, len );
}
public synchronized void flush() throws IOException
{
if ( fd == 0 ) throw new IOException();
//drain();
}
}
/** Inner class for ParallelInputStream */
class ParallelInputStream extends InputStream
{
public int read() throws IOException
{
if ( fd == 0 ) throw new IOException();
return readByte();
}
public int read( byte b[] ) throws IOException
{
if ( fd == 0 ) throw new IOException();
return readArray( b, 0, b.length );
}
public int read( byte b[], int off, int len )
throws IOException
{
if ( fd == 0 ) throw new IOException();
return readArray( b, off, len );
}
public int available() throws IOException
{
if ( fd == 0 ) throw new IOException();
return nativeavailable();
}
}
class MonitorThread extends Thread
{
private boolean monError = false;
private boolean monBuffer = false;
MonitorThread() { }
public void run()
{
eventLoop();
yield();
}
}
}
./rxtx-2.2pre2/src/gnu/io/I2C.java 0000644 0001750 0001750 00000033006 10614033755 016463 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.*;
import java.util.*;
import java.lang.Math;
/**
* @author Trent Jarvi
* @version,
* @since JDK1.0
*/
/**
* I2C
*/
final class I2C extends I2CPort {
static
{
System.loadLibrary( "rxtxI2C" );
Initialize();
}
/** Initialize the native library */
private native static void Initialize();
/** Actual I2CPort wrapper class */
/** Open the named port */
public I2C( String name ) throws PortInUseException {
fd = open( name );
}
private native int open( String name ) throws PortInUseException;
/** File descriptor */
private int fd;
/** DSR flag **/
static boolean dsrFlag = false;
/** Output stream */
private final I2COutputStream out = new I2COutputStream();
public OutputStream getOutputStream() { return out; }
/** Input stream */
private final I2CInputStream in = new I2CInputStream();
public InputStream getInputStream() { return in; }
/** Set the I2CPort parameters */
public void setI2CPortParams( int b, int d, int s, int p )
throws UnsupportedCommOperationException
{
nativeSetI2CPortParams( b, d, s, p );
speed = b;
dataBits = d;
stopBits = s;
parity = p;
}
/** Set the native I2C port parameters */
private native void nativeSetI2CPortParams( int speed, int dataBits,
int stopBits, int parity ) throws UnsupportedCommOperationException;
/** Line speed in bits-per-second */
private int speed=9600;
public int getBaudRate() { return speed; }
/** Data bits port parameter */
private int dataBits=DATABITS_8;
public int getDataBits() { return dataBits; }
/** Stop bits port parameter */
private int stopBits=I2CPort.STOPBITS_1;
public int getStopBits() { return stopBits; }
/** Parity port parameter */
private int parity= I2CPort.PARITY_NONE;
public int getParity() { return parity; }
/** Flow control */
private int flowmode = I2CPort.FLOWCONTROL_NONE;
public void setFlowControlMode( int flowcontrol ) {
try { setflowcontrol( flowcontrol ); }
catch( IOException e ) {
e.printStackTrace();
return;
}
flowmode=flowcontrol;
}
public int getFlowControlMode() { return flowmode; }
native void setflowcontrol( int flowcontrol ) throws IOException;
/*
linux/drivers/char/n_hdlc.c? FIXME
taj@www.linux.org.uk
*/
/** Receive framing control
*/
public void enableReceiveFraming( int f )
throws UnsupportedCommOperationException
{
throw new UnsupportedCommOperationException( "Not supported" );
}
public void disableReceiveFraming() {}
public boolean isReceiveFramingEnabled() { return false; }
public int getReceiveFramingByte() { return 0; }
/** Receive timeout control */
private int timeout = 0;
public native int NativegetReceiveTimeout();
public native boolean NativeisReceiveTimeoutEnabled();
public native void NativeEnableReceiveTimeoutThreshold(int time, int threshold,int InputBuffer);
public void disableReceiveTimeout(){
enableReceiveTimeout(0);
}
public void enableReceiveTimeout( int time ){
if( time >= 0 ) {
timeout = time;
NativeEnableReceiveTimeoutThreshold( time , threshold, InputBuffer );
}
else {
System.out.println("Invalid timeout");
}
}
public boolean isReceiveTimeoutEnabled(){
return(NativeisReceiveTimeoutEnabled());
}
public int getReceiveTimeout(){
return(NativegetReceiveTimeout( ));
}
/** Receive threshold control */
private int threshold = 0;
public void enableReceiveThreshold( int thresh ){
if(thresh >=0)
{
threshold=thresh;
NativeEnableReceiveTimeoutThreshold(timeout, threshold, InputBuffer);
}
else /* invalid thresh */
{
System.out.println("Invalid Threshold");
}
}
public void disableReceiveThreshold() {
enableReceiveThreshold(0);
}
public int getReceiveThreshold(){
return threshold;
}
public boolean isReceiveThresholdEnabled(){
return(threshold>0);
}
/** Input/output buffers */
/** FIXME I think this refers to
FOPEN(3)/SETBUF(3)/FREAD(3)/FCLOSE(3)
taj@www.linux.org.uk
These are native stubs...
*/
private int InputBuffer=0;
private int OutputBuffer=0;
public void setInputBufferSize( int size )
{
InputBuffer=size;
}
public int getInputBufferSize()
{
return(InputBuffer);
}
public void setOutputBufferSize( int size )
{
OutputBuffer=size;
}
public int getOutputBufferSize()
{
return(OutputBuffer);
}
/** Line status methods */
public native boolean isDTR();
public native void setDTR( boolean state );
public native void setRTS( boolean state );
private native void setDSR( boolean state );
public native boolean isCTS();
public native boolean isDSR();
public native boolean isCD();
public native boolean isRI();
public native boolean isRTS();
/** Write to the port */
public native void sendBreak( int duration );
private native void writeByte( int b ) throws IOException;
private native void writeArray( byte b[], int off, int len )
throws IOException;
private native void drain() throws IOException;
/** I2C read methods */
private native int nativeavailable() throws IOException;
private native int readByte() throws IOException;
private native int readArray( byte b[], int off, int len )
throws IOException;
/** I2C Port Event listener */
private I2CPortEventListener SPEventListener;
/** Thread to monitor data */
private MonitorThread monThread;
/** Process I2CPortEvents */
native void eventLoop();
private int dataAvailable=0;
public void sendEvent( int event, boolean state ) {
switch( event ) {
case I2CPortEvent.DATA_AVAILABLE:
dataAvailable=1;
if( monThread.Data ) break;
return;
case I2CPortEvent.OUTPUT_BUFFER_EMPTY:
if( monThread.Output ) break;
return;
/*
if( monThread.DSR ) break;
return;
if (isDSR())
{
if (!dsrFlag)
{
dsrFlag = true;
I2CPortEvent e = new I2CPortEvent(this, I2CPortEvent.DSR, !dsrFlag, dsrFlag );
}
}
else if (dsrFlag)
{
dsrFlag = false;
I2CPortEvent e = new I2CPortEvent(this, I2CPortEvent.DSR, !dsrFlag, dsrFlag );
}
*/
case I2CPortEvent.CTS:
if( monThread.CTS ) break;
return;
case I2CPortEvent.DSR:
if( monThread.DSR ) break;
return;
case I2CPortEvent.RI:
if( monThread.RI ) break;
return;
case I2CPortEvent.CD:
if( monThread.CD ) break;
return;
case I2CPortEvent.OE:
if( monThread.OE ) break;
return;
case I2CPortEvent.PE:
if( monThread.PE ) break;
return;
case I2CPortEvent.FE:
if( monThread.FE ) break;
return;
case I2CPortEvent.BI:
if( monThread.BI ) break;
return;
default:
System.err.println("unknown event:"+event);
return;
}
I2CPortEvent e = new I2CPortEvent(this, event, !state, state );
if( SPEventListener != null ) SPEventListener.I2CEvent( e );
}
/** Add an event listener */
public void addEventListener( I2CPortEventListener lsnr )
throws TooManyListenersException
{
if( SPEventListener != null ) throw new TooManyListenersException();
SPEventListener = lsnr;
monThread = new MonitorThread();
monThread.start();
}
/** Remove the I2C port event listener */
public void removeEventListener() {
SPEventListener = null;
if( monThread != null ) {
monThread.interrupt();
monThread = null;
}
}
public void notifyOnDataAvailable( boolean enable ) { monThread.Data = enable; }
public void notifyOnOutputEmpty( boolean enable ) { monThread.Output = enable; }
public void notifyOnCTS( boolean enable ) { monThread.CTS = enable; }
public void notifyOnDSR( boolean enable ) { monThread.DSR = enable; }
public void notifyOnRingIndicator( boolean enable ) { monThread.RI = enable; }
public void notifyOnCarrierDetect( boolean enable ) { monThread.CD = enable; }
public void notifyOnOverrunError( boolean enable ) { monThread.OE = enable; }
public void notifyOnParityError( boolean enable ) { monThread.PE = enable; }
public void notifyOnFramingError( boolean enable ) { monThread.FE = enable; }
public void notifyOnBreakInterrupt( boolean enable ) { monThread.BI = enable; }
/** Close the port */
private native void nativeClose();
public void close() {
setDTR(false);
setDSR(false);
nativeClose();
super.close();
fd = 0;
}
/** Finalize the port */
protected void finalize() {
if( fd > 0 ) close();
}
/** Inner class for I2COutputStream */
class I2COutputStream extends OutputStream {
public void write( int b ) throws IOException {
writeByte( b );
}
public void write( byte b[] ) throws IOException {
writeArray( b, 0, b.length );
}
public void write( byte b[], int off, int len ) throws IOException {
writeArray( b, off, len );
}
public void flush() throws IOException {
drain();
}
}
/** Inner class for I2CInputStream */
class I2CInputStream extends InputStream {
public int read() throws IOException {
dataAvailable=0;
return readByte();
}
public int read( byte b[] ) throws IOException
{
return read ( b, 0, b.length);
}
public int read( byte b[], int off, int len ) throws IOException
{
dataAvailable=0;
int i=0, Minimum=0;
int intArray[] =
{
b.length,
InputBuffer,
len
};
/*
find the lowest nonzero value
timeout and threshold are handled on the native side
see NativeEnableReceiveTimeoutThreshold in
I2CImp.c
*/
while(intArray[i]==0 && i < intArray.length) i++;
Minimum=intArray[i];
while( i < intArray.length )
{
if(intArray[i] > 0 )
{
Minimum=Math.min(Minimum,intArray[i]);
}
i++;
}
Minimum=Math.min(Minimum,threshold);
if(Minimum == 0) Minimum=1;
int Available=available();
int Ret = readArray( b, off, Minimum);
return Ret;
}
public int available() throws IOException {
return nativeavailable();
}
}
class MonitorThread extends Thread {
/** Note: these have to be separate boolean flags because the
I2CPortEvent constants are NOT bit-flags, they are just
defined as integers from 1 to 10 -DPL */
private boolean CTS=false;
private boolean DSR=false;
private boolean RI=false;
private boolean CD=false;
private boolean OE=false;
private boolean PE=false;
private boolean FE=false;
private boolean BI=false;
private boolean Data=false;
private boolean Output=false;
MonitorThread() { }
public void run() {
eventLoop();
}
}
}
./rxtx-2.2pre2/src/gnu/io/PortInUseException.java 0000644 0001750 0001750 00000007342 10614033755 021661 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* The port requested is currently in use
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class PortInUseException extends Exception
{
/**
the owner of the port requested.
*/
public String currentOwner;
/**
* create a instance of the Exception and store the current owner
*
* @param str detailed information about the current owner
*/
PortInUseException( String str )
{
super( str );
currentOwner=str;
}
public PortInUseException()
{
super();
}
}
./rxtx-2.2pre2/src/gnu/io/RawPort.java 0000644 0001750 0001750 00000011265 10614033755 017507 0 ustar twerner twerner /* Non functional contact tjarvi@qbang.org for details */
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.*;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
abstract class RawPort extends CommPort {
public static final int DATABITS_5 =5;
public static final int DATABITS_6 =6;
public static final int DATABITS_7 =7;
public static final int DATABITS_8 =8;
public static final int PARITY_NONE =0;
public static final int PARITY_ODD =1;
public static final int PARITY_EVEN =2;
public static final int PARITY_MARK =3;
public static final int PARITY_SPACE =4;
public static final int STOPBITS_1 =1;
public static final int STOPBITS_1_5 =0; //wrong
public static final int STOPBITS_2 =2;
public static final int FLOWCONTROL_NONE =0;
public static final int FLOWCONTROL_RTSCTS_IN =1;
public static final int FLOWCONTROL_RTSCTS_OUT =2;
public static final int FLOWCONTROL_XONXOFF_IN =4;
public static final int FLOWCONTROL_XONXOFF_OUT=8;
public static final int WRITE_SIZE =8;
public static final int IO_PORT =0x378;
public abstract void setRawPortParams( int b, int d, int s, int p ) throws UnsupportedCommOperationException;
public abstract void addEventListener( RawPortEventListener lsnr ) throws TooManyListenersException;
public abstract void removeEventListener();
}
./rxtx-2.2pre2/src/gnu/io/ParallelPortEvent.java 0000644 0001750 0001750 00000007700 10614033755 021513 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public class ParallelPortEvent extends EventObject
{
static public final int PAR_EV_ERROR =1;
static public final int PAR_EV_BUFFER =2;
private boolean OldValue;
private boolean NewValue;
private int eventType;
/*public int eventType =0; depricated */
public ParallelPortEvent(ParallelPort srcport, int eventtype,
boolean oldvalue, boolean newvalue)
{
super( srcport );
OldValue=oldvalue;
NewValue=newvalue;
eventType=eventtype;
}
public int getEventType()
{
return(eventType);
}
public boolean getNewValue()
{
return( NewValue );
}
public boolean getOldValue()
{
return( OldValue );
}
}
./rxtx-2.2pre2/src/gnu/io/CVS/ 0000755 0001750 0001750 00000000000 11142441020 015655 5 ustar twerner twerner ./rxtx-2.2pre2/src/gnu/io/CVS/Tag 0000644 0001750 0001750 00000000017 11126534474 016333 0 ustar twerner twerner Tcommapi-0-0-1
./rxtx-2.2pre2/src/gnu/io/CVS/Root 0000644 0001750 0001750 00000000075 11126534472 016545 0 ustar twerner twerner :pserver:jarvi@cvs.milestonesolutions.com:/usr/local/cvsroot
./rxtx-2.2pre2/src/gnu/io/CVS/Entries 0000644 0001750 0001750 00000004431 11142441020 017213 0 ustar twerner twerner /CommDriver.java/1.2.2.7/Thu Apr 26 05:26:04 2007//Tcommapi-0-0-1
/CommPort.java/1.3.2.10/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/CommPortEnumerator.java/1.3.2.15/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/CommPortIdentifier.java/1.7.2.29/Thu Nov 27 20:02:34 2008//Tcommapi-0-0-1
/CommPortOwnershipListener.java/1.3.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/Configure.java/1.1.2.7/Sun Nov 18 22:32:41 2007//Tcommapi-0-0-1
/I2C.java/1.1.2.11/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/I2CPort.java/1.3.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/I2CPortEvent.java/1.3.2.7/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/I2CPortEventListener.java/1.3.2.7/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/LPRPort.java/1.10.2.19/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/NoSuchPortException.java/1.2.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/ParallelPort.java/1.2.2.9/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/ParallelPortEvent.java/1.3.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/ParallelPortEventListener.java/1.3.2.7/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/PortInUseException.java/1.2.2.9/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RS485.java/1.1.2.9/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RS485Port.java/1.3.2.7/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RS485PortEvent.java/1.3.2.7/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RS485PortEventListener.java/1.3.2.7/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RXTXCommDriver.java/1.16.2.61/Fri Nov 14 00:44:01 2008//Tcommapi-0-0-1
/RXTXPort.java/1.27.2.76/Thu Nov 13 23:37:45 2008//Tcommapi-0-0-1
/Raw.java/1.1.2.17/Sun Sep 14 22:29:30 2008//Tcommapi-0-0-1
/RawPort.java/1.1.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RawPortEvent.java/1.1.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/RawPortEventListener.java/1.1.2.8/Thu Apr 26 05:26:05 2007//Tcommapi-0-0-1
/SerialPort.java/1.3.2.11/Thu Apr 26 05:26:06 2007//Tcommapi-0-0-1
/SerialPortEvent.java/1.3.2.7/Thu Apr 26 05:26:06 2007//Tcommapi-0-0-1
/SerialPortEventListener.java/1.2.2.7/Thu Apr 26 05:26:06 2007//Tcommapi-0-0-1
/UnSupportedLoggerException.java/1.1.2.3/Thu Apr 26 05:26:06 2007//Tcommapi-0-0-1
/UnsupportedCommOperationException.java/1.2.2.7/Thu Apr 26 05:26:06 2007//Tcommapi-0-0-1
/Zystem.java/1.1.2.4/Sun Nov 18 22:32:43 2007//Tcommapi-0-0-1
/RXTXVersion.java/1.2.2.37/Wed Feb 4 22:02:55 2009//Tcommapi-0-0-1
D
./rxtx-2.2pre2/src/gnu/io/CVS/Repository 0000644 0001750 0001750 00000000026 11126534472 017775 0 ustar twerner twerner rxtx-devel/src/gnu/io
./rxtx-2.2pre2/src/gnu/io/RXTXPort.java 0000644 0001750 0001750 00000163153 11107135111 017552 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2008 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.util.TooManyListenersException;
import java.lang.Math;
/**
* An extension of gnu.io.SerialPort
* @see gnu.io.SerialPort
*/
final public class RXTXPort extends SerialPort
{
/* I had a report that some JRE's complain when MonitorThread
tries to access private variables
*/
protected final static boolean debug = false;
protected final static boolean debug_read = false;
protected final static boolean debug_read_results = false;
protected final static boolean debug_write = false;
protected final static boolean debug_events = false;
protected final static boolean debug_verbose = false;
private static Zystem z;
static
{
try {
z = new Zystem();
} catch ( Exception e ) {}
if(debug )
z.reportln( "RXTXPort {}");
System.loadLibrary( "rxtxSerial" );
Initialize();
}
/** Initialize the native library */
private native static void Initialize();
boolean MonitorThreadAlive=false;
/**
* Open the named port
* @param name the name of the device to open
* @throws PortInUseException
* @see gnu.io.SerialPort
*/
public RXTXPort( String name ) throws PortInUseException
{
if (debug)
z.reportln( "RXTXPort:RXTXPort("+name+") called");
/*
commapi/javadocs/API_users_guide.html specifies that whenever
an application tries to open a port in use by another application
the PortInUseException will be thrown
I know some didnt like it this way but I'm not sure how to avoid
it. We will just be writing to a bogus fd if we catch the
exeption
Trent
*/
// try {
fd = open( name );
this.name = name;
MonitorThreadLock = true;
monThread = new MonitorThread();
monThread.start();
waitForTheNativeCodeSilly();
MonitorThreadAlive=true;
// } catch ( PortInUseException e ){}
timeout = -1; /* default disabled timeout */
if (debug)
z.reportln( "RXTXPort:RXTXPort("+name+") returns with fd = " +
fd);
}
private native synchronized int open( String name )
throws PortInUseException;
/* dont close the file while accessing the fd */
int IOLocked = 0;
Object IOLockedMutex = new Object();
/** File descriptor */
private int fd = 0;
/** a pointer to the event info structure used to share information
between threads so write threads can send output buffer empty
from a pthread if need be.
long for 64 bit pointers.
*/
long eis = 0;
/** pid for lock files */
int pid = 0;
/** DSR flag **/
static boolean dsrFlag = false;
/** Output stream */
private final SerialOutputStream out = new SerialOutputStream();
/**
* get the OutputStream
* @return OutputStream
*/
public OutputStream getOutputStream()
{
if (debug)
z.reportln( "RXTXPort:getOutputStream() called and returning");
return out;
}
/** Input stream */
private final SerialInputStream in = new SerialInputStream();
/**
* get the InputStream
* @return InputStream
* @see java.io.InputStream
*/
public InputStream getInputStream()
{
if (debug)
z.reportln( "RXTXPort:getInputStream() called and returning");
return in;
}
/**
* Set the SerialPort parameters
* 1.5 stop bits requires 5 databits
* @param b baudrate
* @param d databits
* @param s stopbits
* @param p parity
* @throws UnsupportedCommOperationException
* @see gnu.io.UnsupportedCommOperationException
* If speed is not a predifined speed it is assumed to be
* the actual speed desired.
*/
private native int nativeGetParity( int fd );
private native int nativeGetFlowControlMode( int fd );
public synchronized void setSerialPortParams( int b, int d, int s,
int p )
throws UnsupportedCommOperationException
{
if (debug)
z.reportln( "RXTXPort:setSerialPortParams(" +
b + " " + d + " " + s + " " + p + ") called");
if ( nativeSetSerialPortParams( b, d, s, p ) )
throw new UnsupportedCommOperationException(
"Invalid Parameter" );
speed = b;
if( s== STOPBITS_1_5 ) dataBits = DATABITS_5;
else dataBits = d;
stopBits = s;
parity = p;
z.reportln( "RXTXPort:setSerialPortParams(" +
b + " " + d + " " + s + " " + p +
") returning");
}
/**
* Set the native serial port parameters
* If speed is not a predifined speed it is assumed to be
* the actual speed desired.
*/
private native boolean nativeSetSerialPortParams( int speed,
int dataBits, int stopBits, int parity )
throws UnsupportedCommOperationException;
/** Line speed in bits-per-second */
private int speed=9600;
/**
* @return int representing the baudrate
* This will not behave as expected with custom speeds
*/
public int getBaudRate()
{
if (debug)
z.reportln( "RXTXPort:getBaudRate() called and returning " + speed);
return speed;
}
/** Data bits port parameter */
private int dataBits=DATABITS_8;
/**
* @return int representing the databits
*/
public int getDataBits()
{
if (debug)
z.reportln( "RXTXPort:getDataBits() called and returning " + dataBits);
return dataBits;
}
/** Stop bits port parameter */
private int stopBits=SerialPort.STOPBITS_1;
/**
* @return int representing the stopbits
*/
public int getStopBits()
{
if (debug)
z.reportln( "RXTXPort:getStopBits() called and returning " + stopBits);
return stopBits;
}
/** Parity port parameter */
private int parity= SerialPort.PARITY_NONE;
/**
* @return int representing the parity
*/
public int getParity()
{
if (debug)
z.reportln( "RXTXPort:getParity() called and returning " + parity );
return parity;
}
/** Flow control */
private int flowmode = SerialPort.FLOWCONTROL_NONE;
/**
* @param flowcontrol FLOWCONTROL_NONE is default
* @see gnu.io.SerialPort#FLOWCONTROL_NONE
*/
public void setFlowControlMode( int flowcontrol )
{
if (debug)
z.reportln( "RXTXPort:setFlowControlMode( " + flowcontrol + " ) called");
if(monThreadisInterrupted)
{
if( debug_events )
z.reportln( "RXTXPort:setFlowControlMode MonThread is Interrupeted returning" );
return;
}
try {
setflowcontrol( flowcontrol );
}
catch( IOException e )
{
e.printStackTrace();
return;
}
flowmode=flowcontrol;
if (debug)
z.reportln( "RXTXPort:setFlowControlMode( " + flowcontrol + " ) returning");
}
/**
* @return int representing the flowmode
*/
public int getFlowControlMode()
{
if (debug)
z.reportln( "RXTXPort:getFlowControlMode() returning " + flowmode );
return flowmode;
}
native void setflowcontrol( int flowcontrol ) throws IOException;
/*
linux/drivers/char/n_hdlc.c? FIXME
taj@www.linux.org.uk
*/
/**
* Receive framing control
* @param f framming
* @throws UnsupportedCommOperationException
*/
public void enableReceiveFraming( int f )
throws UnsupportedCommOperationException
{
if (debug)
z.reportln( "RXTXPort:enableReceiveFramming() throwing exception");
throw new UnsupportedCommOperationException( "Not supported" );
}
/**
*/
public void disableReceiveFraming()
{
if (debug)
z.reportln( "RXTXPort:disableReceiveFramming() called and returning (noop)");
}
/**
* @return true if framing is enabled
*/
public boolean isReceiveFramingEnabled()
{
if (debug)
z.reportln( "RXTXPort:isReceiveFrammingEnabled() called and returning " + false );
return false;
}
/**
* @return int representing the framing byte
*/
public int getReceiveFramingByte()
{
if (debug)
z.reportln( "RXTXPort:getReceiveFrammingByte() called and returning " + 0 );
return 0;
}
/** Receive timeout control */
private int timeout;
/**
* @return int the timeout
*/
public native int NativegetReceiveTimeout();
/**
* @return bloolean true if recieve timeout is enabled
*/
private native boolean NativeisReceiveTimeoutEnabled();
/**
* @param time
* @param threshold
* @param InputBuffer
*/
private native void NativeEnableReceiveTimeoutThreshold(int time,
int threshold,int InputBuffer);
/**
*/
public void disableReceiveTimeout()
{
if (debug)
z.reportln( "RXTXPort:disableReceiveTimeout() called");
timeout = -1;
NativeEnableReceiveTimeoutThreshold( timeout , threshold, InputBuffer );
if (debug)
z.reportln( "RXTXPort:disableReceiveTimeout() returning");
}
/**
* @param time
*/
public void enableReceiveTimeout( int time )
{
if (debug)
z.reportln( "RXTXPort:enableReceiveTimeout() called");
if( time >= 0 )
{
timeout = time;
NativeEnableReceiveTimeoutThreshold( time , threshold,
InputBuffer );
}
else
{
throw new IllegalArgumentException
(
"Unexpected negative timeout value"
);
}
if (debug)
z.reportln( "RXTXPort:enableReceiveTimeout() returning");
}
/**
* @return boolean true if recieve timeout is enabled
*/
public boolean isReceiveTimeoutEnabled()
{
if (debug)
z.reportln( "RXTXPort:isReceiveTimeoutEnabled() called and returning " + NativeisReceiveTimeoutEnabled() );
return( NativeisReceiveTimeoutEnabled() );
}
/**
* @return int the timeout
*/
public int getReceiveTimeout()
{
if (debug)
z.reportln( "RXTXPort:getReceiveTimeout() called and returning " + NativegetReceiveTimeout() );
return(NativegetReceiveTimeout( ));
}
/** Receive threshold control */
private int threshold = 0;
/**
* @param thresh threshold
*/
public void enableReceiveThreshold( int thresh )
{
if (debug)
z.reportln( "RXTXPort:enableReceiveThreshold( " + thresh + " ) called");
if(thresh >=0)
{
threshold=thresh;
NativeEnableReceiveTimeoutThreshold(timeout, threshold,
InputBuffer);
}
else /* invalid thresh */
{
throw new IllegalArgumentException
(
"Unexpected negative threshold value"
);
}
if (debug)
z.reportln( "RXTXPort:enableReceiveThreshold( " + thresh + " ) returned");
}
/**
*/
public void disableReceiveThreshold()
{
if (debug)
z.reportln( "RXTXPort:disableReceiveThreshold() called and returning");
enableReceiveThreshold(0);
}
/**
* @return int the recieve threshold
*/
public int getReceiveThreshold()
{
if (debug)
z.reportln( "RXTXPort:getReceiveThreshold() called and returning " + threshold);
return threshold;
}
/**
* @return boolean true if receive threshold is enabled
*/
public boolean isReceiveThresholdEnabled()
{
if (debug)
z.reportln( "RXTXPort:isReceiveThresholdEnable() called and returning" + (threshold > 0) );
return(threshold>0);
}
/** Input/output buffers */
/** FIXME I think this refers to
FOPEN(3)/SETBUF(3)/FREAD(3)/FCLOSE(3)
taj@www.linux.org.uk
These are native stubs...
*/
private int InputBuffer=0;
private int OutputBuffer=0;
/**
* @param size
*/
public void setInputBufferSize( int size )
{
if (debug)
z.reportln( "RXTXPort:setInputBufferSize( " +
size + ") called");
if( size < 0 )
throw new IllegalArgumentException
(
"Unexpected negative buffer size value"
);
else InputBuffer=size;
if (debug)
z.reportln( "RXTXPort:setInputBufferSize( " +
size + ") returning");
}
/**
*/
public int getInputBufferSize()
{
if (debug)
z.reportln( "RXTXPort:getInputBufferSize() called and returning " + InputBuffer );
return(InputBuffer);
}
/**
* @param size
*/
public void setOutputBufferSize( int size )
{
if (debug)
z.reportln( "RXTXPort:setOutputBufferSize( " +
size + ") called");
if( size < 0 )
throw new IllegalArgumentException
(
"Unexpected negative buffer size value"
);
else OutputBuffer=size;
if (debug)
z.reportln( "RXTXPort:setOutputBufferSize( " +
size + ") returned");
}
/**
* @return in the output buffer size
*/
public int getOutputBufferSize()
{
if (debug)
z.reportln( "RXTXPort:getOutputBufferSize() called and returning " + OutputBuffer );
return(OutputBuffer);
}
/* =================== cleaned messages to here */
/**
* Line status methods
*/
/**
* @return true if DTR is set
*/
public native boolean isDTR();
/**
* @param state
*/
public native void setDTR( boolean state );
/**
* @param state
*/
public native void setRTS( boolean state );
private native void setDSR( boolean state );
/**
* @return boolean true if CTS is set
*/
public native boolean isCTS();
/**
* @return boolean true if DSR is set
*/
public native boolean isDSR();
/**
* @return boolean true if CD is set
*/
public native boolean isCD();
/**
* @return boolean true if RI is set
*/
public native boolean isRI();
/**
* @return boolean true if RTS is set
*/
public native boolean isRTS();
/**
* Write to the port
* @param duration
*/
public native void sendBreak( int duration );
protected native void writeByte( int b, boolean i ) throws IOException;
protected native void writeArray( byte b[], int off, int len, boolean i )
throws IOException;
protected native boolean nativeDrain( boolean i ) throws IOException;
/** RXTXPort read methods */
protected native int nativeavailable() throws IOException;
protected native int readByte() throws IOException;
protected native int readArray( byte b[], int off, int len )
throws IOException;
protected native int readTerminatedArray( byte b[], int off, int len, byte t[] )
throws IOException;
/** Serial Port Event listener */
private SerialPortEventListener SPEventListener;
/** Thread to monitor data */
private MonitorThread monThread;
/** Process SerialPortEvents */
native void eventLoop();
/**
* @return boolean true if monitor thread is interrupted
*/
boolean monThreadisInterrupted=true;
private native void interruptEventLoop( );
public boolean checkMonitorThread()
{
if (debug)
z.reportln( "RXTXPort:checkMonitorThread()");
if(monThread != null)
{
if ( debug )
z.reportln(
"monThreadisInterrupted = " +
monThreadisInterrupted );
return monThreadisInterrupted;
}
if ( debug )
z.reportln( "monThread is null " );
return(true);
}
/**
* @param event
* @param state
* @return boolean true if the port is closing
*/
public boolean sendEvent( int event, boolean state )
{
if (debug_events)
z.report( "RXTXPort:sendEvent(");
/* Let the native side know its time to die */
if ( fd == 0 || SPEventListener == null || monThread == null)
{
return(true);
}
switch( event )
{
case SerialPortEvent.DATA_AVAILABLE:
if( debug_events )
z.reportln( "DATA_AVAILABLE " +
monThread.Data + ")" );
break;
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
if( debug_events )
z.reportln(
"OUTPUT_BUFFER_EMPTY " +
monThread.Output + ")" );
break;
case SerialPortEvent.CTS:
if( debug_events )
z.reportln( "CTS " +
monThread.CTS + ")" );
break;
case SerialPortEvent.DSR:
if( debug_events )
z.reportln( "DSR " +
monThread.Output + ")" );
break;
case SerialPortEvent.RI:
if( debug_events )
z.reportln( "RI " +
monThread.RI + ")" );
break;
case SerialPortEvent.CD:
if( debug_events )
z.reportln( "CD " +
monThread.CD + ")" );
break;
case SerialPortEvent.OE:
if( debug_events )
z.reportln( "OE " +
monThread.OE + ")" );
break;
case SerialPortEvent.PE:
if( debug_events )
z.reportln( "PE " +
monThread.PE + ")" );
break;
case SerialPortEvent.FE:
if( debug_events )
z.reportln( "FE " +
monThread.FE + ")" );
break;
case SerialPortEvent.BI:
if( debug_events )
z.reportln( "BI " +
monThread.BI + ")" );
break;
default:
if( debug_events )
z.reportln( "XXXXXXXXXXXXXX " +
event + ")" );
break;
}
if( debug_events && debug_verbose )
z.reportln( " checking flags " );
switch( event )
{
case SerialPortEvent.DATA_AVAILABLE:
if( monThread.Data ) break;
return(false);
case SerialPortEvent.OUTPUT_BUFFER_EMPTY:
if( monThread.Output ) break;
return(false);
case SerialPortEvent.CTS:
if( monThread.CTS ) break;
return(false);
case SerialPortEvent.DSR:
if( monThread.DSR ) break;
return(false);
case SerialPortEvent.RI:
if( monThread.RI ) break;
return(false);
case SerialPortEvent.CD:
if( monThread.CD ) break;
return(false);
case SerialPortEvent.OE:
if( monThread.OE ) break;
return(false);
case SerialPortEvent.PE:
if( monThread.PE ) break;
return(false);
case SerialPortEvent.FE:
if( monThread.FE ) break;
return(false);
case SerialPortEvent.BI:
if( monThread.BI ) break;
return(false);
default:
System.err.println( "unknown event: " + event);
return(false);
}
if( debug_events && debug_verbose )
z.reportln( " getting event" );
SerialPortEvent e = new SerialPortEvent(this, event, !state,
state );
if( debug_events && debug_verbose )
z.reportln( " sending event" );
if(monThreadisInterrupted)
{
if( debug_events )
z.reportln( " sendEvent return" );
return(true);
}
if( SPEventListener != null )
{
SPEventListener.serialEvent( e );
}
if( debug_events && debug_verbose )
z.reportln( " sendEvent return" );
if (fd == 0 || SPEventListener == null || monThread == null)
{
return(true);
}
else
{
return(false);
}
}
/**
* Add an event listener
* @param lsnr SerialPortEventListener
* @throws TooManyListenersException
*/
boolean MonitorThreadLock = true;
public void addEventListener(
SerialPortEventListener lsnr ) throws TooManyListenersException
{
/* Don't let and notification requests happen until the
Eventloop is ready
*/
if (debug)
z.reportln( "RXTXPort:addEventListener()");
if( SPEventListener != null )
{
throw new TooManyListenersException();
}
SPEventListener = lsnr;
if( !MonitorThreadAlive )
{
MonitorThreadLock = true;
monThread = new MonitorThread();
monThread.start();
waitForTheNativeCodeSilly();
MonitorThreadAlive=true;
}
if (debug)
z.reportln( "RXTXPort:Interrupt=false");
}
/**
* Remove the serial port event listener
*/
public void removeEventListener()
{
if (debug)
z.reportln( "RXTXPort:removeEventListener() called");
waitForTheNativeCodeSilly();
//if( monThread != null && monThread.isAlive() )
if( monThreadisInterrupted == true )
{
z.reportln( " RXTXPort:removeEventListener() already interrupted");
monThread = null;
SPEventListener = null;
return;
}
else if( monThread != null && monThread.isAlive() )
{
if (debug)
z.reportln( " RXTXPort:Interrupt=true");
monThreadisInterrupted=true;
/*
Notify all threads in this PID that something is up
They will call back to see if its their thread
using isInterrupted().
*/
if (debug)
z.reportln( " RXTXPort:calling interruptEventLoop");
interruptEventLoop( );
if (debug)
z.reportln( " RXTXPort:calling monThread.join()");
try {
// wait a reasonable moment for the death of the monitor thread
monThread.join(3000);
} catch (InterruptedException ex) {
// somebody called interrupt() on us (ie wants us to abort)
// we dont propagate InterruptedExceptions so lets re-set the flag
Thread.currentThread().interrupt();
return;
}
if ( debug && monThread.isAlive() )
{
z.reportln( " MonThread is still alive!");
}
}
monThread = null;
SPEventListener = null;
MonitorThreadLock = false;
MonitorThreadAlive=false;
monThreadisInterrupted=true;
z.reportln( "RXTXPort:removeEventListener() returning");
}
/**
* Give the native code a chance to start listening to the hardware
* or should we say give the native code control of the issue.
*
* This is important for applications that flicker the Monitor
* thread while keeping the port open.
* In worst case test cases this loops once or twice every time.
*/
protected void waitForTheNativeCodeSilly()
{
while( MonitorThreadLock )
{
try {
Thread.sleep(5);
} catch( Exception e ) {}
}
}
/**
* @param enable
*/
private native void nativeSetEventFlag( int fd, int event,
boolean flag );
public void notifyOnDataAvailable( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnDataAvailable( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.DATA_AVAILABLE,
enable );
monThread.Data = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnOutputEmpty( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnOutputEmpty( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.OUTPUT_BUFFER_EMPTY,
enable );
monThread.Output = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnCTS( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnCTS( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.CTS, enable );
monThread.CTS = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnDSR( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnDSR( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.DSR, enable );
monThread.DSR = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnRingIndicator( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnRingIndicator( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.RI, enable );
monThread.RI = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnCarrierDetect( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnCarrierDetect( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.CD, enable );
monThread.CD = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnOverrunError( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnOverrunError( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.OE, enable );
monThread.OE = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnParityError( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnParityError( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.PE, enable );
monThread.PE = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnFramingError( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnFramingError( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.FE, enable );
monThread.FE = enable;
MonitorThreadLock = false;
}
/**
* @param enable
*/
public void notifyOnBreakInterrupt( boolean enable )
{
if (debug)
z.reportln( "RXTXPort:notifyOnBreakInterrupt( " +
enable+" )");
waitForTheNativeCodeSilly();
MonitorThreadLock = true;
nativeSetEventFlag( fd, SerialPortEvent.BI, enable );
monThread.BI = enable;
MonitorThreadLock = false;
}
/** Close the port */
private native void nativeClose( String name );
/**
*/
boolean closeLock = false;
public void close()
{
synchronized (this) {
if (debug)
z.reportln( "RXTXPort:close( " + this.name + " )");
while( IOLocked > 0 )
{
if( debug )
z.reportln("IO is locked " + IOLocked);
try {
this.wait(500);
} catch( InterruptedException ie ) {
// somebody called interrupt() on us
// we obbey and return without without closing the socket
Thread.currentThread().interrupt();
return;
}
}
// we set the closeLock after the above check because we might
// have returned without proceeding
if( closeLock ) return;
closeLock = true;
}
if ( fd <= 0 )
{
z.reportln( "RXTXPort:close detected bad File Descriptor" );
return;
}
setDTR(false);
setDSR(false);
if (debug)
z.reportln( "RXTXPort:close( " + this.name + " ) setting monThreadisInterrupted");
if ( ! monThreadisInterrupted )
{
removeEventListener();
}
if (debug)
z.reportln( "RXTXPort:close( " + this.name + " ) calling nativeClose");
nativeClose( this.name );
if (debug)
z.reportln( "RXTXPort:close( " + this.name + " ) calling super.close");
super.close();
fd = 0;
closeLock = false;
if (debug)
z.reportln( "RXTXPort:close( " + this.name + " ) leaving");
}
/** Finalize the port */
protected void finalize()
{
if (debug)
z.reportln( "RXTXPort:finalize()");
if( fd > 0 )
{
if (debug)
z.reportln( "RXTXPort:calling close()");
close();
}
z.finalize();
}
/** Inner class for SerialOutputStream */
class SerialOutputStream extends OutputStream
{
/**
* @param b
* @throws IOException
*/
public void write( int b ) throws IOException
{
if (debug_write)
z.reportln( "RXTXPort:SerialOutputStream:write(int)");
if( speed == 0 ) return;
if ( monThreadisInterrupted == true )
{
return;
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
if ( fd == 0 )
{
throw new IOException();
}
writeByte( b, monThreadisInterrupted );
if (debug_write)
z.reportln( "Leaving RXTXPort:SerialOutputStream:write( int )");
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @throws IOException
*/
public void write( byte b[] ) throws IOException
{
if (debug_write)
{
z.reportln( "Entering RXTXPort:SerialOutputStream:write(" + b.length + ") "/* + new String(b)*/ );
}
if( speed == 0 ) return;
if ( monThreadisInterrupted == true )
{
return;
}
if ( fd == 0 ) throw new IOException();
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
waitForTheNativeCodeSilly();
writeArray( b, 0, b.length, monThreadisInterrupted );
if (debug_write)
z.reportln( "Leaving RXTXPort:SerialOutputStream:write(" +b.length +")");
} finally {
synchronized(IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @param off
* @param len
* @throws IOException
*/
public void write( byte b[], int off, int len )
throws IOException
{
if( speed == 0 ) return;
if( off + len > b.length )
{
throw new IndexOutOfBoundsException(
"Invalid offset/length passed to read"
);
}
byte send[] = new byte[len];
System.arraycopy( b, off, send, 0, len );
if (debug_write)
{
z.reportln( "Entering RXTXPort:SerialOutputStream:write(" + send.length + " " + off + " " + len + " " +") " /*+ new String(send) */ );
}
if ( fd == 0 ) throw new IOException();
if ( monThreadisInterrupted == true )
{
return;
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try
{
waitForTheNativeCodeSilly();
writeArray( send, 0, len, monThreadisInterrupted );
if( debug_write )
z.reportln( "Leaving RXTXPort:SerialOutputStream:write(" + send.length + " " + off + " " + len + " " +") " /*+ new String(send)*/ );
} finally {
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
*/
public void flush() throws IOException
{
if (debug)
z.reportln( "RXTXPort:SerialOutputStream:flush() enter");
if( speed == 0 ) return;
if ( fd == 0 ) throw new IOException();
if ( monThreadisInterrupted == true )
{
if (debug)
z.reportln( "RXTXPort:SerialOutputStream:flush() Leaving Interrupted");
return;
}
synchronized(IOLockedMutex) {
IOLocked++;
}
try
{
waitForTheNativeCodeSilly();
/*
this is probably good on all OS's but for now
just sendEvent from java on Sol
*/
if ( nativeDrain( monThreadisInterrupted ) )
sendEvent( SerialPortEvent.OUTPUT_BUFFER_EMPTY, true );
if (debug)
z.reportln( "RXTXPort:SerialOutputStream:flush() leave");
}
finally
{
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
}
/** Inner class for SerialInputStream */
class SerialInputStream extends InputStream
{
/**
* @return int the int read
* @throws IOException
* @see java.io.InputStream
*
*timeout threshold Behavior
*------------------------------------------------------------------------
*0 0 blocks until 1 byte is available timeout > 0,
* threshold = 0, blocks until timeout occurs, returns -1
* on timeout
*>0 >0 blocks until timeout, returns - 1 on timeout, magnitude
* of threshold doesn't play a role.
*0 >0 Blocks until 1 byte, magnitude of threshold doesn't
* play a role
*/
public synchronized int read() throws IOException
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() called");
if ( fd == 0 ) throw new IOException();
if ( monThreadisInterrupted )
{
z.reportln( "+++++++++ read() monThreadisInterrupted" );
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try {
if (debug_read_results)
z.reportln( "RXTXPort:SerialInputStream:read() L" );
waitForTheNativeCodeSilly();
if (debug_read_results)
z.reportln( "RXTXPort:SerialInputStream:read() N" );
int result = readByte();
if (debug_read_results)
//z.reportln( "RXTXPort:SerialInputStream:read() returns byte = " + result );
z.reportln( "RXTXPort:SerialInputStream:read() returns" );
return( result );
}
finally
{
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @return int number of bytes read
* @throws IOException
*
*timeout threshold Behavior
*------------------------------------------------------------------------
*0 0 blocks until 1 byte is available
*>0 0 blocks until timeout occurs, returns 0 on timeout
*>0 >0 blocks until timeout or reads threshold bytes,
returns 0 on timeout
*0 >0 blocks until reads threshold bytes
*/
public synchronized int read( byte b[] ) throws IOException
{
int result;
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + ") called");
if ( monThreadisInterrupted == true )
{
return(0);
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try
{
waitForTheNativeCodeSilly();
result = read( b, 0, b.length);
if (debug_read_results)
z.reportln( "RXTXPort:SerialInputStream:read() returned " + result + " bytes" );
return( result );
}
finally
{
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/*
read(byte b[], int, int)
Documentation is at http://java.sun.com/products/jdk/1.2/docs/api/java/io/InputStream.html#read(byte[], int, int)
*/
/**
* @param b[]
* @param off
* @param len
* @return int number of bytes read
* @throws IOException
*
*timeout threshold Behavior
*------------------------------------------------------------------------
*0 0 blocks until 1 byte is available
*>0 0 blocks until timeout occurs, returns 0 on timeout
*>0 >0 blocks until timeout or reads threshold bytes,
returns 0 on timeout
*0 >0 blocks until either threshold # of bytes or len bytes,
whichever was lower.
*/
public synchronized int read( byte b[], int off, int len )
throws IOException
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + " " + off + " " + len + ") called" /*+ new String(b) */ );
int result;
/*
* Some sanity checks
*/
if ( fd == 0 )
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() fd == 0");
z.reportln("+++++++ IOException()\n");
throw new IOException();
}
if( b==null )
{
z.reportln("+++++++ NullPointerException()\n");
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() b == 0");
throw new NullPointerException();
}
if( (off < 0) || (len < 0) || (off+len > b.length))
{
z.reportln("+++++++ IndexOutOfBoundsException()\n");
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() off < 0 ..");
throw new IndexOutOfBoundsException();
}
/*
* Return immediately if len==0
*/
if( len==0 )
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() off < 0 ..");
return 0;
}
/*
* See how many bytes we should read
*/
int Minimum = len;
if( threshold==0 )
{
/*
* If threshold is disabled, read should return as soon
* as data are available (up to the amount of available
* bytes in order to avoid blocking)
* Read may return earlier depending of the receive time
* out.
*/
int a = nativeavailable();
if( a == 0 )
Minimum = 1;
else
Minimum = Math.min( Minimum, a );
}
else
{
/*
* Threshold is enabled. Read should return when
* 'threshold' bytes have been received (or when the
* receive timeout expired)
*/
Minimum = Math.min(Minimum, threshold);
}
if ( monThreadisInterrupted == true )
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() Interrupted");
return(0);
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try
{
waitForTheNativeCodeSilly();
result = readArray( b, off, Minimum);
if (debug_read_results)
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + " " + off + " " + len + ") returned " + result + " bytes" /*+ new String(b) */);
return( result );
}
finally
{
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @param b[]
* @param off
* @param len
* @param t[]
* @return int number of bytes read
* @throws IOException
We are trying to catch the terminator in the native code
Right now it is assumed that t[] is an array of 2 bytes.
if the read encounters the two bytes, it will return and the
array will contain the terminator. Otherwise read behavior should
be the same as read( b[], off, len ). Timeouts have not been well
tested.
*/
public synchronized int read( byte b[], int off, int len, byte t[] )
throws IOException
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + " " + off + " " + len + ") called" /*+ new String(b) */ );
int result;
/*
* Some sanity checks
*/
if ( fd == 0 )
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() fd == 0");
z.reportln("+++++++ IOException()\n");
throw new IOException();
}
if( b==null )
{
z.reportln("+++++++ NullPointerException()\n");
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() b == 0");
throw new NullPointerException();
}
if( (off < 0) || (len < 0) || (off+len > b.length))
{
z.reportln("+++++++ IndexOutOfBoundsException()\n");
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() off < 0 ..");
throw new IndexOutOfBoundsException();
}
/*
* Return immediately if len==0
*/
if( len==0 )
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() off < 0 ..");
return 0;
}
/*
* See how many bytes we should read
*/
int Minimum = len;
if( threshold==0 )
{
/*
* If threshold is disabled, read should return as soon
* as data are available (up to the amount of available
* bytes in order to avoid blocking)
* Read may return earlier depending of the receive time
* out.
*/
int a = nativeavailable();
if( a == 0 )
Minimum = 1;
else
Minimum = Math.min( Minimum, a );
}
else
{
/*
* Threshold is enabled. Read should return when
* 'threshold' bytes have been received (or when the
* receive timeout expired)
*/
Minimum = Math.min(Minimum, threshold);
}
if ( monThreadisInterrupted == true )
{
if (debug_read)
z.reportln( "RXTXPort:SerialInputStream:read() Interrupted");
return(0);
}
synchronized (IOLockedMutex) {
IOLocked++;
}
try
{
waitForTheNativeCodeSilly();
result = readTerminatedArray( b, off, Minimum, t );
if (debug_read_results)
z.reportln( "RXTXPort:SerialInputStream:read(" + b.length + " " + off + " " + len + ") returned " + result + " bytes" /*+ new String(b) */);
return( result );
}
finally
{
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
/**
* @return int bytes available
* @throws IOException
*/
public synchronized int available() throws IOException
{
if ( monThreadisInterrupted == true )
{
return(0);
}
if ( debug_verbose )
z.reportln( "RXTXPort:available() called" );
synchronized (IOLockedMutex) {
IOLocked++;
}
try
{
int r = nativeavailable();
if ( debug_verbose )
z.reportln( "RXTXPort:available() returning " +
r );
return r;
}
finally
{
synchronized (IOLockedMutex) {
IOLocked--;
}
}
}
}
/**
*/
class MonitorThread extends Thread
{
/** Note: these have to be separate boolean flags because the
SerialPortEvent constants are NOT bit-flags, they are just
defined as integers from 1 to 10 -DPL */
private volatile boolean CTS=false;
private volatile boolean DSR=false;
private volatile boolean RI=false;
private volatile boolean CD=false;
private volatile boolean OE=false;
private volatile boolean PE=false;
private volatile boolean FE=false;
private volatile boolean BI=false;
private volatile boolean Data=false;
private volatile boolean Output=false;
MonitorThread()
{
if (debug)
z.reportln( "RXTXPort:MontitorThread:MonitorThread()");
}
/**
* run the thread and call the event loop.
*/
public void run()
{
if (debug)
z.reportln( "RXTXPort:MontitorThread:run()");
monThreadisInterrupted=false;
eventLoop();
if (debug)
z.reportln( "eventLoop() returned");
}
protected void finalize() throws Throwable
{
if (debug)
z.reportln( "RXTXPort:MonitorThread exiting");
}
}
/**
* A dummy method added so RXTX compiles on Kaffee
* @deprecated deprecated but used in Kaffe
*/
public void setRcvFifoTrigger(int trigger){};
/*------------------------ END OF CommAPI -----------------------------*/
private native static void nativeStaticSetSerialPortParams( String f,
int b, int d, int s, int p )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticSetDSR( String port,
boolean flag )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticSetDTR( String port,
boolean flag )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticSetRTS( String port,
boolean flag )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsDSR( String port )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsDTR( String port )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsRTS( String port )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsCTS( String port )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsCD( String port )
throws UnsupportedCommOperationException;
private native static boolean nativeStaticIsRI( String port )
throws UnsupportedCommOperationException;
private native static int nativeStaticGetBaudRate( String port )
throws UnsupportedCommOperationException;
private native static int nativeStaticGetDataBits( String port )
throws UnsupportedCommOperationException;
private native static int nativeStaticGetParity( String port )
throws UnsupportedCommOperationException;
private native static int nativeStaticGetStopBits( String port )
throws UnsupportedCommOperationException;
private native byte nativeGetParityErrorChar( )
throws UnsupportedCommOperationException;
private native boolean nativeSetParityErrorChar( byte b )
throws UnsupportedCommOperationException;
private native byte nativeGetEndOfInputChar( )
throws UnsupportedCommOperationException;
private native boolean nativeSetEndOfInputChar( byte b )
throws UnsupportedCommOperationException;
private native boolean nativeSetUartType(String type, boolean test)
throws UnsupportedCommOperationException;
native String nativeGetUartType()
throws UnsupportedCommOperationException;
private native boolean nativeSetBaudBase(int BaudBase)
throws UnsupportedCommOperationException;
private native int nativeGetBaudBase()
throws UnsupportedCommOperationException;
private native boolean nativeSetDivisor(int Divisor)
throws UnsupportedCommOperationException;
private native int nativeGetDivisor()
throws UnsupportedCommOperationException;
private native boolean nativeSetLowLatency()
throws UnsupportedCommOperationException;
private native boolean nativeGetLowLatency()
throws UnsupportedCommOperationException;
private native boolean nativeSetCallOutHangup(boolean NoHup)
throws UnsupportedCommOperationException;
private native boolean nativeGetCallOutHangup()
throws UnsupportedCommOperationException;
private native boolean nativeClearCommInput()
throws UnsupportedCommOperationException;
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* This is only accurate up to 38600 baud currently.
*
* @param port the name of the port thats been preopened
* @return BaudRate on success
* @throws UnsupportedCommOperationException;
* This will not behave as expected with custom speeds
*
*/
public static int staticGetBaudRate( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln(
"RXTXPort:staticGetBaudRate( " + port + " )");
return(nativeStaticGetBaudRate( port ));
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* @param port the name of the port thats been preopened
* @return DataBits on success
* @throws UnsupportedCommOperationException;
*
*/
public static int staticGetDataBits( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln(
"RXTXPort:staticGetDataBits( " + port + " )");
return(nativeStaticGetDataBits( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* @param port the name of the port thats been preopened
* @return Parity on success
* @throws UnsupportedCommOperationException;
*
*/
public static int staticGetParity( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln(
"RXTXPort:staticGetParity( " + port + " )");
return( nativeStaticGetParity( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* @param port the name of the port thats been preopened
* @return StopBits on success
* @throws UnsupportedCommOperationException;
*
*/
public static int staticGetStopBits( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln(
"RXTXPort:staticGetStopBits( " + port + " )");
return(nativeStaticGetStopBits( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* Set the SerialPort parameters
* 1.5 stop bits requires 5 databits
* @param f filename
* @param b baudrate
* @param d databits
* @param s stopbits
* @param p parity
*
* @throws UnsupportedCommOperationException
* @see gnu.io.UnsupportedCommOperationException
*/
public static void staticSetSerialPortParams( String f, int b, int d,
int s, int p )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln(
"RXTXPort:staticSetSerialPortParams( " +
f + " " + b + " " + d + " " + s + " " + p );
nativeStaticSetSerialPortParams( f, b, d, s, p );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* Open the port and set DSR. remove lockfile and do not close
* This is so some software can appear to set the DSR before 'opening'
* the port a second time later on.
*
* @return true on success
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticSetDSR( String port, boolean flag )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticSetDSR( " + port +
" " + flag );
return( nativeStaticSetDSR( port, flag ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* Open the port and set DTR. remove lockfile and do not close
* This is so some software can appear to set the DTR before 'opening'
* the port a second time later on.
*
* @return true on success
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticSetDTR( String port, boolean flag )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticSetDTR( " + port +
" " + flag );
return( nativeStaticSetDTR( port, flag ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* Open the port and set RTS. remove lockfile and do not close
* This is so some software can appear to set the RTS before 'opening'
* the port a second time later on.
*
* @return none
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticSetRTS( String port, boolean flag )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticSetRTS( " + port +
" " + flag );
return( nativeStaticSetRTS( port, flag ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* find the fd and return RTS without using a Java open() call
*
* @param port
* @return true if asserted
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticIsRTS( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticIsRTS( " + port + " )" );
return( nativeStaticIsRTS( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* find the fd and return CD without using a Java open() call
*
* @param port
* @return true if asserted
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticIsCD( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticIsCD( " + port + " )" );
return( nativeStaticIsCD( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* find the fd and return CTS without using a Java open() call
*
* @param port
* @return true if asserted
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticIsCTS( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticIsCTS( " + port + " )" );
return( nativeStaticIsCTS( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* find the fd and return DSR without using a Java open() call
*
* @param port
* @return true if asserted
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticIsDSR( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticIsDSR( " + port + " )" );
return( nativeStaticIsDSR( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* find the fd and return DTR without using a Java open() call
*
* @param port
* @return true if asserted
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticIsDTR( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticIsDTR( " + port + " )" );
return( nativeStaticIsDTR( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
*
* find the fd and return RI without using a Java open() call
*
* @param port
* @return true if asserted
* @throws UnsupportedCommOperationException;
*
*/
public static boolean staticIsRI( String port )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:staticIsRI( " + port + " )" );
return( nativeStaticIsRI( port ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
* @return int the Parity Error Character
* @throws UnsupportedCommOperationException;
*
* Anyone know how to do this in Unix?
*/
public byte getParityErrorChar( )
throws UnsupportedCommOperationException
{
byte ret;
if ( debug )
z.reportln( "getParityErrorChar()" );
ret = nativeGetParityErrorChar();
if ( debug )
z.reportln( "getParityErrorChar() returns " +
ret );
return( ret );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
* @param b Parity Error Character
* @return boolean true on success
* @throws UnsupportedCommOperationException;
*
* Anyone know how to do this in Unix?
*/
public boolean setParityErrorChar( byte b )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "setParityErrorChar(" + b + ")" );
return( nativeSetParityErrorChar( b ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
* @return int the End of Input Character
* @throws UnsupportedCommOperationException;
*
* Anyone know how to do this in Unix?
*/
public byte getEndOfInputChar( )
throws UnsupportedCommOperationException
{
byte ret;
if ( debug )
z.reportln( "getEndOfInputChar()" );
ret = nativeGetEndOfInputChar();
if ( debug )
z.reportln( "getEndOfInputChar() returns " +
ret );
return( ret );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
* @param b End Of Input Character
* @return boolean true on success
* @throws UnsupportedCommOperationException;
*/
public boolean setEndOfInputChar( byte b )
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "setEndOfInputChar(" + b + ")" );
return( nativeSetEndOfInputChar( b ) );
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
* @param type String representation of the UART type which mayb
* be "none", "8250", "16450", "16550", "16550A", "16650", "16550V2"
* or "16750".
* @param test boolean flag to determin if the UART should be tested.
* @return boolean true on success
* @throws UnsupportedCommOperationException;
*/
public boolean setUARTType(String type, boolean test)
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:setUARTType()");
return nativeSetUartType(type, test);
}
/**
* Extension to CommAPI
* This is an extension to CommAPI. It may not be supported on
* all operating systems.
* @return type String representation of the UART type which mayb
* be "none", "8250", "16450", "16550", "16550A", "16650", "16550V2"
* or "16750".
* @throws UnsupportedCommOperationException;
*/
public String getUARTType() throws UnsupportedCommOperationException
{
return nativeGetUartType();
}
/**
* Extension to CommAPI. Set Baud Base to 38600 on Linux and W32
* before using.
* @param BaudBase The clock frequency divided by 16. Default
* BaudBase is 115200.
* @return true on success
* @throws UnsupportedCommOperationException, IOException
*/
public boolean setBaudBase(int BaudBase)
throws UnsupportedCommOperationException,
IOException
{
if ( debug )
z.reportln( "RXTXPort:setBaudBase()");
return nativeSetBaudBase(BaudBase);
}
/**
* Extension to CommAPI
* @return BaudBase
* @throws UnsupportedCommOperationException, IOException
*/
public int getBaudBase() throws UnsupportedCommOperationException,
IOException
{
if ( debug )
z.reportln( "RXTXPort:getBaudBase()");
return nativeGetBaudBase();
}
/**
* Extension to CommAPI. Set Baud Base to 38600 on Linux and W32
* before using.
* @param Divisor
* @throws UnsupportedCommOperationException, IOException
*/
public boolean setDivisor(int Divisor)
throws UnsupportedCommOperationException, IOException
{
if ( debug )
z.reportln( "RXTXPort:setDivisor()");
return nativeSetDivisor(Divisor);
}
/**
* Extension to CommAPI
* @return Divisor;
* @throws UnsupportedCommOperationException, IOException
*/
public int getDivisor() throws UnsupportedCommOperationException,
IOException
{
if ( debug )
z.reportln( "RXTXPort:getDivisor()");
return nativeGetDivisor();
}
/**
* Extension to CommAPI
* returns boolean true on success
* @throws UnsupportedCommOperationException
*/
public boolean setLowLatency() throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:setLowLatency()");
return nativeSetLowLatency();
}
/**
* Extension to CommAPI
* returns boolean true on success
* @throws UnsupportedCommOperationException
*/
public boolean getLowLatency() throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:getLowLatency()");
return nativeGetLowLatency();
}
/**
* Extension to CommAPI
* returns boolean true on success
* @throws UnsupportedCommOperationException
*/
public boolean setCallOutHangup(boolean NoHup)
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:setCallOutHangup()");
return nativeSetCallOutHangup(NoHup);
}
/**
* Extension to CommAPI
* returns boolean true on success
* @throws UnsupportedCommOperationException
*/
public boolean getCallOutHangup()
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:getCallOutHangup()");
return nativeGetCallOutHangup();
}
/**
* Extension to CommAPI
* returns boolean true on success
* @throws UnsupportedCommOperationException
*/
public boolean clearCommInput()
throws UnsupportedCommOperationException
{
if ( debug )
z.reportln( "RXTXPort:clearCommInput()");
return nativeClearCommInput();
}
/*------------------------ END OF CommAPI Extensions -----------------------*/
}
./rxtx-2.2pre2/src/gnu/io/CommPortOwnershipListener.java 0000644 0001750 0001750 00000007131 10614033755 023253 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
package gnu.io;
import java.util.*;
/**
* @author Trent Jarvi
* @version %I%, %G%
* @since JDK1.0
*/
public interface CommPortOwnershipListener extends EventListener
{
public static final int PORT_OWNED =1;
public static final int PORT_UNOWNED =2;
public static final int PORT_OWNERSHIP_REQUESTED =3;
public abstract void ownershipChange( int type );
}
./rxtx-2.2pre2/src/gnu/CVS/ 0000755 0001750 0001750 00000000000 11142410104 015245 5 ustar twerner twerner ./rxtx-2.2pre2/src/gnu/CVS/Tag 0000644 0001750 0001750 00000000017 11126534472 015722 0 ustar twerner twerner Tcommapi-0-0-1
./rxtx-2.2pre2/src/gnu/CVS/Root 0000644 0001750 0001750 00000000075 11126534472 016136 0 ustar twerner twerner :pserver:jarvi@cvs.milestonesolutions.com:/usr/local/cvsroot
./rxtx-2.2pre2/src/gnu/CVS/Entries 0000644 0001750 0001750 00000000011 11126534475 016615 0 ustar twerner twerner D/io////
./rxtx-2.2pre2/src/gnu/CVS/Repository 0000644 0001750 0001750 00000000023 11126534472 017363 0 ustar twerner twerner rxtx-devel/src/gnu
./rxtx-2.2pre2/src/lfd/ 0000755 0001750 0001750 00000000000 11126534474 014611 5 ustar twerner twerner ./rxtx-2.2pre2/src/lfd/lockdaemon.c 0000644 0001750 0001750 00000053613 10614033757 017100 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 2002-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define FHS
#define LOCKFILEPREFIX "LCK.."
#define LOCK fhs_lock
#define UNLOCK fhs_unlock
#define LOCKDIR "/var/lock"
char hostname[256];
#define M200 "200 Command okay.\n"
#define M202 "202 Command not implemented\n"
#define M220 "220 %s Lock File Server (Version rxtx-1.5-9) ready\n", hostname
#define M221 "221 Thank you for using the Lock File service on %s\n", hostname
#define M450 "450 : File busy.\n"
#define M500 "500 '%s': command not understood\n", str
#define M550 "550 : Permission denied.\n"
int is_device_locked( const char * );
int check_group_uucp();
int check_lock_status( const char * );
int check_lock_pid( const char *, int );
#define UNEXPECTED_LOCK_FILE "RXTX Error: Unexpected lock file: %s\n Please report to the RXTX developers\n"
#define UUCP_ERROR "\n\n\nRXTX WARNING: This library requires the user running applications to be in\ngroup uucp. Please consult the INSTALL documentation. More information is\navaiable under the topic 'How can I use Lock Files with rxtx?'\n"
extern int errno;
/*----------------------------------------------------------
fhs_lock
accept: The name of the device to try to lock
termios struct
perform: Create a lock file if there is not one already.
return: 1 on failure 0 on success
exceptions: none
comments: This is for linux and freebsd only currently. I see SVR4 does
this differently and there are other proposed changes to the
Filesystem Hierachy Standard
more reading:
----------------------------------------------------------*/
int fhs_lock( const char *filename, int pid )
{
/*
* There is a zoo of lockdir possibilities
* Its possible to check for stale processes with most of them.
* for now we will just check for the lockfile on most
* Problem lockfiles will be dealt with. Some may not even be in use.
*
*/
int fd,j;
char lockinfo[12], message[80];
char file[80], *p;
j = strlen( filename );
p = ( char * ) filename + j;
/* FIXME need to handle subdirectories /dev/cua/...
SCO Unix use lowercase all the time
taj
*/
while( *( p - 1 ) != '/' && j-- != 1 )
{
#if defined ( __unixware__ )
*p = tolower( *p );
#endif /* __unixware__ */
p--;
}
sprintf( file, "%s/LCK..%s", LOCKDIR, p );
if ( check_lock_status( filename ) )
{
/* syslog( LOG_INFO, "fhs_lock() lockstatus fail\n" ); */
return 1;
}
fd = open( file, O_CREAT | O_WRONLY | O_EXCL, 0444 );
if( fd < 0 )
{
sprintf( message,
"RXTX fhs_lock() Error: creating lock file: %s: %s\n",
file, strerror(errno) );
syslog( LOG_INFO, message );
return 1;
}
sprintf( lockinfo, "%10d\n", pid );
sprintf( message, "fhs_lock: creating lockfile: %s\n", lockinfo );
//syslog( LOG_INFO, message );
write( fd, lockinfo, 11 );
close( fd );
return 0;
}
/*----------------------------------------------------------
uucp_lock
accept: char * filename. Device to be locked
perform: Try to get a uucp_lock
return: int 0 on success
exceptions: none
comments:
The File System Hierarchy Standard
http://www.pathname.com/fhs/
UUCP Lock Files
http://docs.freebsd.org/info/uucp/uucp.info.UUCP_Lock_Files.html
FSSTND
ftp://tsx-11.mit.edu/pub/linux/docs/linux-standards/fsstnd/
Proposed Changes to the File System Hierarchy Standard
ftp://scicom.alphacdc.com/pub/linux/devlock-0.X.tgz
"UNIX Network Programming", W. Richard Stevens,
Prentice-Hall, 1990, pages 96-101.
There is much to do here.
1) UUCP style locks (done)
/var/spool/uucp
2) SVR4 locks
/var/spool/locks
3) FSSTND locks (done)
/var/lock
4) handle stale locks (done except kermit locks)
5) handle minicom lockfile contents (FSSTND?)
" 16929 minicom root\n" (done)
6) there are other Lock conventions that use Major and Minor
numbers...
7) Stevens recommends LCK..
most are caught above. If they turn out to be problematic
rather than an exercise, we will handle them.
----------------------------------------------------------*/
int uucp_lock( const char *filename, int pid )
{
char lockfilename[80], lockinfo[12], message[80];
char name[80];
int fd;
struct stat buf;
sprintf( message, "uucp_lock( %s );\n", filename );
syslog( LOG_INFO, message );
if ( check_lock_status( filename ) )
{
syslog( LOG_INFO, "RXTX uucp check_lock_status true\n" );
return 1;
}
if ( stat( LOCKDIR, &buf ) != 0 )
{
syslog( LOG_INFO, "RXTX uucp_lock() could not find lock directory.\n" );
return 1;
}
if ( stat( filename, &buf ) != 0 )
{
syslog( LOG_INFO, "RXTX uucp_lock() could not find device.\n" );
sprintf( message, "uucp_lock: device was %s\n", name );
syslog( LOG_INFO, message );
sprintf( message, "Filename is : %s \n", filename );
syslog( LOG_INFO, message );
return 1;
}
sprintf( lockfilename, "%s/LK.%03d.%03d.%03d",
LOCKDIR,
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
sprintf( lockinfo, "%10d\n", pid );
if ( stat( lockfilename, &buf ) == 0 )
{
sprintf( message, "RXTX uucp_lock() %s is there\n",
lockfilename );
syslog( LOG_INFO, message );
syslog( LOG_INFO, message );
return 1;
}
fd = open( lockfilename, O_CREAT | O_WRONLY | O_EXCL, 0444 );
if( fd < 0 )
{
sprintf( message,
"RXTX uucp_lock() Error: creating lock file: %s\n",
lockfilename );
syslog( LOG_INFO, message );
return 1;
}
write( fd, lockinfo,11 );
close( fd );
/*
setgid( nobody );
setuid( nobody );
*/
return 0;
}
/*----------------------------------------------------------
check_lock_status
accept: the lock name in question
perform: Make sure everything is sane
return: 0 on success
exceptions: none
comments:
----------------------------------------------------------*/
int check_lock_status( const char *filename )
{
struct stat buf;
/* First, can we find the directory? */
if ( stat( LOCKDIR, &buf ) != 0 )
{
syslog( LOG_INFO, "check_lock_status: could not find lock directory.\n" );
return 1;
}
/* OK. Are we able to write to it? If not lets bail */
if ( check_group_uucp() )
{
syslog( LOG_INFO, "check_lock_status: No permission to create lock file.
please see: How can I use Lock Files with rxtx? in INSTALL\n" );
return 1;
}
/* is the device alread locked */
if ( is_device_locked( filename ) )
{
/* syslog( LOG_INFO, "check_lock_status: device is locked by another application\n" ); */
return 1;
}
return 0;
}
/*----------------------------------------------------------
fhs_unlock
accept: The name of the device to unlock
perform: delete the lock file
return: none
exceptions: none
comments: This is for linux only currently. I see SVR4 does this
differently and there are other proposed changes to the
Filesystem Hierachy Standard
----------------------------------------------------------*/
int fhs_unlock( const char *filename, int openpid )
{
char file[80],*p, msg[80];
struct stat buf;
int i;
i = strlen( filename );
p = ( char * ) filename + i;
sprintf( msg, "fhs_unlock %s\n", filename );
/* syslog( LOG_INFO, msg ); */
/* FIXME need to handle subdirectories /dev/cua/... */
while( *( p - 1 ) != '/' && i-- != 1 ) p--;
sprintf( file, "%s/LCK..%s", LOCKDIR, p );
#ifdef asdf
if ( ! check_lock_status( p ) )
{
sprintf( msg, "fhs_unlock %s check_lock_status\n", filename );
syslog( LOG_INFO, msg );
return 0;
}
#endif
if ( stat( filename, &buf ) != 0 )
{
/* hmm the file is not there? */
syslog( LOG_INFO, "uucp_unlock() no such device\n" );
return(0);
}
if( !check_lock_pid( file, openpid ) )
{
unlink(file);
//syslog( LOG_INFO,"fhs_unlock: Removing LockFile\n");
return( 0 );
}
else
{
syslog( LOG_INFO,"fhs_unlock: Unable to remove LockFile\n");
return( 1 );
}
}
/*----------------------------------------------------------
uucp_unlock
accept: char *filename the device that is locked
perform: remove the uucp lockfile if it exists
return: none
exceptions: none
comments: http://docs.freebsd.org/info/uucp/uucp.info.UUCP_Lock_Files.html
----------------------------------------------------------*/
void uucp_unlock( const char *filename, int openpid )
{
struct stat buf;
char file[80], message[80];
/* FIXME */
sprintf( message, "uucp_unlock( %s );\n", filename );
syslog( LOG_INFO, message );
if ( stat( filename, &buf ) != 0 )
{
/* hmm the file is not there? */
syslog( LOG_INFO, "uucp_unlock() no such device\n" );
return;
}
sprintf( file, LOCKDIR"/LK.%03d.%03d.%03d",
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
if ( stat( file, &buf ) != 0 )
{
/* hmm the file is not there? */
syslog( LOG_INFO, "uucp_unlock no such lockfile\n" );
return;
}
if( !check_lock_pid( file, openpid ) )
{
sprintf( message, "uucp_unlock: unlinking %s\n", file );
syslog( LOG_INFO, message );
unlink(file);
}
else
{
sprintf( message, "uucp_unlock: unlinking failed %s\n", file );
syslog( LOG_INFO, message );
}
}
/*----------------------------------------------------------
check_lock_pid
accept: the name of the lockfile
perform: make sure the lock file is ours.
return: 0 on success
exceptions: none
comments:
----------------------------------------------------------*/
int check_lock_pid( const char *file, int openpid )
{
int fd, lockpid;
char pid_buffer[12];
char message[80];
fd=open( file, O_RDONLY );
if ( fd < 0 )
{
return( 1 );
}
if ( read( fd, pid_buffer, 11 ) < 0 )
{
close( fd );
return( 1 );
}
close( fd );
pid_buffer[11] = '\0';
lockpid = atol( pid_buffer );
if ( lockpid != openpid )
{
if( kill( (pid_t) lockpid, 0 ) && errno==ESRCH )
{
return( 0 );
}
sprintf(message, "check_lock_pid: lock = %s pid = %i gpid=%i openpid=%i\n",
pid_buffer, (int) getpid(), (int) getppid(), openpid );
syslog( LOG_INFO, message );
return( 1 );
}
return( 0 );
}
/*----------------------------------------------------------
check_group_uucp
accept: none
perform: check if the user is root or in group uucp
return: 0 on success
exceptions: none
comments:
This checks if the effective user is in group uucp so we can
create lock files. If not we give them a warning and bail.
If its root we just skip the test.
if someone really wants to override this they can use the USER_LOCK_DIRECTORY --not recommended.
In a recent change RedHat 7.2 decided to use group lock.
In order to get around this we just check the group id
of the lock directory.
----------------------------------------------------------*/
int check_group_uucp()
{
#ifndef USER_LOCK_DIRECTORY
int group_count;
struct passwd *user = getpwuid( geteuid() );
struct stat buf;
char msg[80];
gid_t list[ NGROUPS_MAX ];
if( stat( LOCKDIR, &buf) )
{
sprintf( msg, "check_group_uucp: Can not find Lock Directory: %s\n", LOCKDIR );
syslog( LOG_INFO, msg );
return( 1 );
}
group_count = getgroups( NGROUPS_MAX, list );
list[ group_count ] = geteuid();
if( user->pw_gid )
{
while( group_count >= 0 && buf.st_gid != list[ group_count ] )
{
group_count--;
}
if( buf.st_gid == list[ group_count ] )
return 0;
sprintf( msg, "%i %i\n", buf.st_gid, list[ group_count ] );
syslog( LOG_INFO, msg );
syslog( LOG_INFO, UUCP_ERROR );
return 1;
}
return 0;
/*
if( strcmp( user->pw_name, "root" ) )
{
while( *g->gr_mem )
{
if( !strcmp( *g->gr_mem, user->pw_name ) )
{
break;
}
(void) *g->gr_mem++;
}
if( !*g->gr_mem )
{
syslog( LOG_INFO, UUCP_ERROR );
return 1;
}
}
*/
#endif /* USER_LOCK_DIRECTORY */
return 0;
}
/*----------------------------------------------------------
The following should be able to follow symbolic links. I think the stat
method used below will work on more systems. This was found while looking
for information.
* realpath() doesn't exist on all of the systems my code has to run
on (HP-UX 9.x, specifically)
----------------------------------------------------------
int different_from_LOCKDIR(const char* ld)
{
char real_ld[MAXPATHLEN];
char real_LOCKDIR[MAXPATHLEN];
if (strncmp(ld, LOCKDIR, strlen(ld)) == 0)
return 0;
if (realpath(ld, real_ld) == NULL)
return 1;
if (realpath(LOCKDIR, real_LOCKDIR) == NULL)
return 1;
if (strncmp(real_ld, real_LOCKDIR, strlen(real_ld)) == 0)
return 0;
else
return 1;
}
*/
/*----------------------------------------------------------
is_device_locked
accept: char * filename. The device in question including the path.
perform: see if one of the many possible lock files is aready there
if there is a stale lock, remove it.
return: 1 if the device is locked or somethings wrong.
0 if its possible to create our own lock file.
exceptions: none
comments: check if the device is already locked
----------------------------------------------------------*/
int is_device_locked( const char *port_filename )
{
const char *lockdirs[] = { "/etc/locks", "/usr/spool/kermit",
"/usr/spool/locks", "/usr/spool/uucp", "/usr/spool/uucp/",
"/usr/spool/uucp/LCK", "/var/lock", "/var/lock/modem",
"/var/spool/lock", "/var/spool/locks", "/var/spool/uucp",
LOCKDIR, NULL
};
const char *lockprefixes[] = { "LCK..", "lk..", "LK.", NULL };
char *p, file[80], pid_buffer[20], message[80];
int i = 0, j, k, fd , pid;
struct stat buf;
struct stat buf2;
j = strlen( port_filename );
p = ( char * ) port_filename+j;
while( *( p-1 ) != '/' && j-- !=1 ) p--;
while( lockdirs[i] )
{
/*
Look for lockfiles in all known places other than the
defined lock directory for this system
report any unexpected lockfiles.
Is the suspect lockdir there?
if it is there is it not the expected lock dir?
*/
if( !stat( lockdirs[i], &buf2 ) &&
strncmp( lockdirs[i], LOCKDIR, strlen( lockdirs[i] ) ) )
{
j = strlen( port_filename );
p = ( char * ) port_filename + j;
/*
SCO Unix use lowercase all the time
taj
*/
while( *( p - 1 ) != '/' && j-- != 1 )
{
#if defined ( __unixware__ )
*p = tolower( *p );
#endif /* __unixware__ */
p--;
}
k=0;
while ( lockprefixes[k] )
{
/* FHS style */
sprintf( file, "%s/%s%s", lockdirs[i],
lockprefixes[k], p );
if( stat( file, &buf ) == 0 )
{
sprintf( message, UNEXPECTED_LOCK_FILE,
file );
syslog( LOG_INFO, message );
return 1;
}
/* UUCP style */
stat(port_filename , &buf );
sprintf( file, "%s/%s%03d.%03d.%03d",
lockdirs[i],
lockprefixes[k],
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
if( stat( file, &buf ) == 0 )
{
sprintf( message, UNEXPECTED_LOCK_FILE,
file );
syslog( LOG_INFO, message );
return 1;
}
k++;
}
}
i++;
}
/*
OK. We think there are no unexpect lock files for this device
Lets see if there any stale lock files that need to be
removed.
*/
#ifdef FHS
/* FHS standard locks */
i = strlen( port_filename );
p = ( char * ) port_filename + i;
while( *(p-1) != '/' && i-- != 1)
{
#if defined ( __unixware__ )
*p = tolower( *p );
#endif /* __unixware__ */
p--;
}
sprintf( file, "%s/%s%s", LOCKDIR, LOCKFILEPREFIX, p );
#else
/* UUCP standard locks */
sprintf( file, "%s/LK.%03d.%03d.%03d",
LOCKDIR,
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
#endif /* FHS */
if( stat( file, &buf ) == 0 )
{
/* check if its a stale lock */
fd=open( file, O_RDONLY );
read( fd, pid_buffer, 11 );
/* FIXME null terminiate pid_buffer? need to check in Solaris */
close( fd );
sscanf( pid_buffer, "%d", &pid );
sprintf( message, "found lock for %s with pid %i\n", file, pid );
/* syslog( LOG_INFO, message ); */
if( kill( (pid_t) pid, 0 ) && errno==ESRCH )
{
sprintf( message,
"RXTX Warning: Removing stale lock file. %s\n",
file );
syslog( LOG_INFO, message );
if( unlink( file ) != 0 )
{
snprintf( message, 80, "RXTX Error: Unable to \
remove stale lock file: %s\n",
file
);
syslog( LOG_INFO, message );
return 0;
}
}
else
{
sprintf( message, "could not kill %i\n", pid );
/* syslog( LOG_INFO, message ); */
return 1;
}
}
return 0;
}
int init( void )
{
pid_t pid;
if( ( pid = fork() ) < 0 )
{
return(-1);
}
else if ( pid != 0 )
{
exit( 0 );
}
setsid();
chdir("/");
umask( 0 );
return( 0 );
}
int process_requests( )
{
for(;;)
{
char str[80];
char str2[80];
char *p;
int ret;
ret = read( 1, str, 80 );
if( ret < 80 && ret > 1 )
str[ret] = '\0';
else
str[79] = '\0';
if ( !strncasecmp( str, "quit", 4 ) )
{
sprintf( str, M221 );
write( 0, str, strlen( str ) );
return( 1 );
}
else if( !strncasecmp( str, "lock ", 4 ) )
{
char *q,*r;
p = str + 5;
q=p;
while( *q != ' ' && *q != '\0' )
q++;
if ( *q == '\0' )
{
write( 0, M450, strlen( M450 ) );
return(0);
}
*q = '\0';
q++;
r=q;
while( *r != '\n' && *r != '\0' )
r++;
if( *r == '\n' )
*r = '\0';
if ( LOCK( p, atoi( q ) ) )
{
write( 0, M450, strlen( M450 ) );
}
else
{
write( 0, M200, strlen( M200 ) );
}
}
else if( !strncasecmp( str, "unlock ", 6 ) )
{
char *q,*r;
p = str + 7;
q=p;
while( *q != ' ' && *q != '\0' )
q++;
if ( *q == '\0' )
{
write( 0, "q=0\n", strlen( "q=0\n" ) );
write( 0, M450, strlen( M450 ) );
return(0);
}
*q = '\0';
q++;
r=q;
while( *r != '\n' && *r != '\0' )
r++;
if( *r == '\n' )
*r = '\0';
if ( UNLOCK( (const char *) p, atoi( q ) ) )
{
write( 0, M450, strlen( M450 ) );
}
else
{
write( 0, M200, strlen( M200 ) );
}
}
else
{
str[ret-2]='\0';
sprintf( str2, M500 );
write( 0, str2, strlen(str2));
}
return( 0 );
}
}
int main( int argc, char **argv )
{
char str[128];
char portstr[7];
struct sockaddr *cliaddr;
struct sockaddr_in *sin;
socklen_t len;
openlog( argv[0], LOG_PID, 0 );
cliaddr= malloc( 128 );
len = 128;
sin = ( struct sockaddr_in * ) cliaddr;
cliaddr= malloc( 128 );
gethostname( hostname, 255 );
if ( !inet_ntop( AF_INET, &(sin->sin_addr), str, sizeof(str) ) )
str[0] = '\0';
if ( !ntohs( sin->sin_port ) )
{
snprintf( portstr, sizeof( portstr ), ".%d", ntohs( sin->sin_port) );
strcat( str, portstr);
}
sprintf( str, M220 );
//syslog( LOG_INFO, str );
write( 0, str, strlen(str) );
for(;;)
{
if (process_requests( ))
{
goto exit;
}
}
syslog( LOG_INFO, "Lock Daemon Shutting down" );
exit:
closelog();
exit(0);
}
./rxtx-2.2pre2/src/lfd/LockFileServer.rfc 0000644 0001750 0001750 00000012355 07416410454 020170 0 ustar twerner twerner LOCK FILE PROTOCOL (LFP)
Status of this Memo
This memo is a proposed specification for the Lock File Protocol (LPF).
Distribution of this memo is currently limited.
The following commands are currently in this edition of this specification.
LOCK (lock a resource), UNLOCK (unlock a resource), QUIT (disconnect)
1. INTRODUCTION
The objectives of LPF are 1) to make administration of machines with a
large number of users easier 2) to encourage a common mechanism for
applications to share resources 3) to provide a platform neutral
interface for applications.
This specification tries to outline the minimal required features for
a LPF.
2. OVERVIEW
Lock files can be located in as many as 10 different directories depending
on the OS. Writing applications that handle all of the lock directories
is redundant and error prone.
By enabling three commands much of the redundant work can be eliminated and
a common locking scheme can be used. The end result is a consistant easy
to use interface.
2.1. HISTORY
Lock files have been used for a long time. For more information on
lock files see:
The File System Hierarchy Standard
http://www.pathname.com/fhs/
UUCP Lock Files
http://docs.freebsd.org/info/uucp/uucp.info.UUCP_Lock_Files.html
FSSTND
ftp://tsx-11.mit.edu/pub/linux/docs/linux-standards/fsstnd/
Proposed Changes to the File System Hierarchy Standard
ftp://scicom.alphacdc.com/pub/linux/devlock-0.X.tgz
"UNIX Network Programming", W. Richard Stevens,
Prentice-Hall, 1990, pages 96-101.
2.2 TERMINOLOGY
lock file
lock directory
uucp lock
fhs lock
2.3 THE LFP MODEL
lock
directory<----->Server<-----Client<---->User
3. LOCKFILE FUNCTIONS
4. LFP FUNCTIONS
4.1 LFP COMMANDS
4.1.1 ACCEESS CONTROL COMMANDS
QUIT The session is ended.
4.1.2 LOCK FILE CONTROL COMMANDS
LOCK If the device that is trying to be locked and the pid of the
requesting application are passed, an attempt will be made to
lock the device.
UNLOCK If the pid of the application requesting to unlock a device
is passed an attempt will be made to unlock the device.
Lock File Protocol January 2001
4.2 LFP REPLIES
The following replies exist and try to follow the same format as FTP
reply commands (rfc 959)
200 Command okay.
202 Command not implemented
220 hostname Lock File Server (Version rxtx-1.5-9) ready
221 Thank you for using the Lock File service on hostname
450 : File busy
500 'command': command not understood
550 : Permission denied.
5. DECLARATIVE SPECIFICATIONS
5.1 Minimum IMPLEMENTATION
The following commands must be in a minimum implementation
QUIT, LOCK, UNLOCK.
5.2 CONNECTIONS
Currently on connections assisted by inetd are supported.
Though not official, LFP currently listens on port 50001.
Only connections from localhost should be allowed.
5.3 COMMANDS
5.3.1 LFP COMMANDS
The following are the LFP COMMANDS
QUIT
LOCK
UNLOCK
5.3.2 LFP COMMAND ARGUMENTS
::=
::= any decimal integer
5.4. SEQUENCING OF COMMANDS AND REPLIES
Connection Establisment
LOCK
UNLOCK
QUIT
6. STATE DIAGRAMS
[ from rfc 959 ]
Here we present state diagrams for a very simple minded LFP
implementation. Only the first digit of the reply codes is used.
There is one state diagram for each group of LFP commands or command
sequences.
The command groupings were determined by constructing a model for
each command then collecting together the commands with structurally
identical models.
For each command or command sequence there are three possible
outcomes: success (S), failure (F), and error (E). In the state
diagrams below we use the symbol B for "begin", and the symbol W for
"wait for reply".
Lock File Protocol January 2001
We present the diagram that represents the largest group of LFP
commands:
1,3 +---+
----------->| E |
| +---+
|
+---+ cmd +---+ 2 +---+
| B |---------->| W |---------->| S |
+---+ +---+ +---+
|
| 4,5 +---+
----------->| F |
+---+
This diagram models the commands:
QUIT, LOCK, UNLOCK.
7. TYPICAL LFP SCENARIO
$ telnet 127.0.0.1 50001
Trying 127.0.0.1...
Connected to 127.0.0.1.
Escape character is '^]'.
lock /dev/ttyS1 1234
200 Command okay.
unlock /dev/ttyS1 1234
200 Command okay.
quit
221 Thank you for using the Lock File Service on servertrent.korpivaara.org.
Connection closed by foreign host.
$
./rxtx-2.2pre2/src/lfd/lockdaemon.c.noinetd 0000644 0001750 0001750 00000056570 10614033757 020544 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 2002-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define LOCK fhs_lock
#define UNLOCK fhs_unlock
#define LOCKDIR "/var/lock"
char hostname[256];
#define M200 "200 Command okay.\n"
#define M202 "202 Command not implemented\n"
#define M220 "220 %s Lock File Server (Version rxtx-1.5-9) ready\n", hostname
#define M221 "221 Thank you for using the Lock File service on %s\n", hostname
#define M450 "450 : File busy.\n"
#define M500 "500 '%s': command not understood\n", str
#define M550 "550 : Permission denied.\n"
int is_device_locked( const char * );
int check_group_uucp();
int check_lock_status( const char * );
int check_lock_pid( const char *, int );
#define UNEXPECTED_LOCK_FILE "RXTX Error: Unexpected lock file: %s\n Please report to the RXTX developers\n"
#define UUCP_ERROR "\n\n\nRXTX WARNING: This library requires the user running applications to be in\ngroup uucp. Please consult the INSTALL documentation. More information is\navaiable under the topic 'How can I use Lock Files with rxtx?'\n"
extern int errno;
/*----------------------------------------------------------
fhs_lock
accept: The name of the device to try to lock
termios struct
perform: Create a lock file if there is not one already.
return: 1 on failure 0 on success
exceptions: none
comments: This is for linux and freebsd only currently. I see SVR4 does
this differently and there are other proposed changes to the
Filesystem Hierachy Standard
more reading:
----------------------------------------------------------*/
int fhs_lock( const char *filename, int pid )
{
/*
* There is a zoo of lockdir possibilities
* Its possible to check for stale processes with most of them.
* for now we will just check for the lockfile on most
* Problem lockfiles will be dealt with. Some may not even be in use.
*
*/
int fd,j;
char lockinfo[12], message[80];
char file[80], *p;
j = strlen( filename );
p = ( char * ) filename + j;
/* FIXME need to handle subdirectories /dev/cua/...
SCO Unix use lowercase all the time
taj
*/
while( *( p - 1 ) != '/' && j-- != 1 )
{
#if defined ( __unixware__ )
*p = tolower( *p );
#endif /* __unixware__ */
p--;
}
sprintf( file, "%s/LCK..%s", LOCKDIR, p );
if ( check_lock_status( filename ) )
{
syslog( LOG_INFO, "fhs_lock() lockstatus fail\n" );
return 1;
}
fd = open( file, O_CREAT | O_WRONLY | O_EXCL, 0444 );
if( fd < 0 )
{
sprintf( message,
"RXTX fhs_lock() Error: creating lock file: %s: %s\n",
file, strerror(errno) );
syslog( LOG_INFO, message );
return 1;
}
sprintf( lockinfo, "%10d\n", pid );
sprintf( message, "fhs_lock: creating lockfile: %s\n", lockinfo );
syslog( LOG_INFO, message );
write( fd, lockinfo, 11 );
close( fd );
return 0;
}
/*----------------------------------------------------------
uucp_lock
accept: char * filename. Device to be locked
perform: Try to get a uucp_lock
return: int 0 on success
exceptions: none
comments:
The File System Hierarchy Standard
http://www.pathname.com/fhs/
UUCP Lock Files
http://docs.freebsd.org/info/uucp/uucp.info.UUCP_Lock_Files.html
FSSTND
ftp://tsx-11.mit.edu/pub/linux/docs/linux-standards/fsstnd/
Proposed Changes to the File System Hierarchy Standard
ftp://scicom.alphacdc.com/pub/linux/devlock-0.X.tgz
"UNIX Network Programming", W. Richard Stevens,
Prentice-Hall, 1990, pages 96-101.
There is much to do here.
1) UUCP style locks (done)
/var/spool/uucp
2) SVR4 locks
/var/spool/locks
3) FSSTND locks (done)
/var/lock
4) handle stale locks (done except kermit locks)
5) handle minicom lockfile contents (FSSTND?)
" 16929 minicom root\n" (done)
6) there are other Lock conventions that use Major and Minor
numbers...
7) Stevens recommends LCK..
most are caught above. If they turn out to be problematic
rather than an exercise, we will handle them.
----------------------------------------------------------*/
int uucp_lock( const char *filename, int pid )
{
char lockfilename[80], lockinfo[12], message[80];
char name[80];
int fd;
struct stat buf;
sprintf( message, "uucp_lock( %s );\n", filename );
syslog( LOG_INFO, message );
if ( check_lock_status( filename ) )
{
syslog( LOG_INFO, "RXTX uucp check_lock_status true\n" );
return 1;
}
if ( stat( LOCKDIR, &buf ) != 0 )
{
syslog( LOG_INFO, "RXTX uucp_lock() could not find lock directory.\n" );
return 1;
}
if ( stat( filename, &buf ) != 0 )
{
syslog( LOG_INFO, "RXTX uucp_lock() could not find device.\n" );
sprintf( message, "uucp_lock: device was %s\n", name );
syslog( LOG_INFO, message );
sprintf( message, "Filename is : %s \n", filename );
syslog( LOG_INFO, message );
return 1;
}
sprintf( lockfilename, "%s/LK.%03d.%03d.%03d",
LOCKDIR,
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
sprintf( lockinfo, "%10d\n", pid );
if ( stat( lockfilename, &buf ) == 0 )
{
sprintf( message, "RXTX uucp_lock() %s is there\n",
lockfilename );
syslog( LOG_INFO, message );
syslog( LOG_INFO, message );
return 1;
}
fd = open( lockfilename, O_CREAT | O_WRONLY | O_EXCL, 0444 );
if( fd < 0 )
{
sprintf( message,
"RXTX uucp_lock() Error: creating lock file: %s\n",
lockfilename );
syslog( LOG_INFO, message );
return 1;
}
write( fd, lockinfo,11 );
close( fd );
/*
setgid( nobody );
setuid( nobody );
*/
return 0;
}
/*----------------------------------------------------------
check_lock_status
accept: the lock name in question
perform: Make sure everything is sane
return: 0 on success
exceptions: none
comments:
----------------------------------------------------------*/
int check_lock_status( const char *filename )
{
struct stat buf;
/* First, can we find the directory? */
if ( stat( LOCKDIR, &buf ) != 0 )
{
syslog( LOG_INFO, "check_lock_status: could not find lock directory.\n" );
return 1;
}
/* OK. Are we able to write to it? If not lets bail */
if ( check_group_uucp() )
{
syslog( LOG_INFO, "check_lock_status: No permission to create lock file.
please see: How can I use Lock Files with rxtx? in INSTALL\n" );
return 1;
}
/* is the device alread locked */
if ( is_device_locked( filename ) )
{
syslog( LOG_INFO, "check_lock_status: device is locked by another application\n" );
return 1;
}
return 0;
}
/*----------------------------------------------------------
fhs_unlock
accept: The name of the device to unlock
perform: delete the lock file
return: none
exceptions: none
comments: This is for linux only currently. I see SVR4 does this
differently and there are other proposed changes to the
Filesystem Hierachy Standard
----------------------------------------------------------*/
int fhs_unlock( const char *filename, int openpid )
{
char file[80],*p;
struct stat buf;
int i;
i = strlen( filename );
p = ( char * ) filename + i;
/* FIXME need to handle subdirectories /dev/cua/... */
while( *( p - 1 ) != '/' && i-- != 1 ) p--;
sprintf( file, "%s/LCK..%s", LOCKDIR, p );
if ( ! check_lock_status( p ) )
{
return 0;
}
if ( stat( filename, &buf ) != 0 )
{
/* hmm the file is not there? */
syslog( LOG_INFO, "uucp_unlock() no such device\n" );
return(0);
}
if( !check_lock_pid( file, openpid ) )
{
unlink(file);
syslog( LOG_INFO,"fhs_unlock: Removing LockFile\n");
return( 0 );
}
else
{
syslog( LOG_INFO,"fhs_unlock: Unable to remove LockFile\n");
return( 1 );
}
}
/*----------------------------------------------------------
uucp_unlock
accept: char *filename the device that is locked
perform: remove the uucp lockfile if it exists
return: none
exceptions: none
comments: http://docs.freebsd.org/info/uucp/uucp.info.UUCP_Lock_Files.html
----------------------------------------------------------*/
void uucp_unlock( const char *filename, int openpid )
{
struct stat buf;
char file[80], message[80];
/* FIXME */
sprintf( message, "uucp_unlock( %s );\n", filename );
syslog( LOG_INFO, message );
if ( stat( filename, &buf ) != 0 )
{
/* hmm the file is not there? */
syslog( LOG_INFO, "uucp_unlock() no such device\n" );
return;
}
sprintf( file, LOCKDIR"/LK.%03d.%03d.%03d",
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
if ( stat( file, &buf ) != 0 )
{
/* hmm the file is not there? */
syslog( LOG_INFO, "uucp_unlock no such lockfile\n" );
return;
}
if( !check_lock_pid( file, openpid ) )
{
sprintf( message, "uucp_unlock: unlinking %s\n", file );
syslog( LOG_INFO, message );
unlink(file);
}
else
{
sprintf( message, "uucp_unlock: unlinking failed %s\n", file );
syslog( LOG_INFO, message );
}
}
/*----------------------------------------------------------
check_lock_pid
accept: the name of the lockfile
perform: make sure the lock file is ours.
return: 0 on success
exceptions: none
comments:
----------------------------------------------------------*/
int check_lock_pid( const char *file, int openpid )
{
int fd, lockpid;
char pid_buffer[12];
char message[80];
fd=open( file, O_RDONLY );
if ( fd < 0 )
{
return( 1 );
}
if ( read( fd, pid_buffer, 11 ) < 0 )
{
close( fd );
return( 1 );
}
close( fd );
pid_buffer[11] = '\0';
lockpid = atol( pid_buffer );
if ( lockpid != openpid )
{
if( kill( (pid_t) lockpid, 0 ) && errno==ESRCH )
{
return( 0 );
}
sprintf(message, "check_lock_pid: lock = %s pid = %i gpid=%i openpid=%i\n",
pid_buffer, (int) getpid(), (int) getppid(), openpid );
syslog( LOG_INFO, message );
return( 1 );
}
return( 0 );
}
/*----------------------------------------------------------
check_group_uucp
accept: none
perform: check if the user is root or in group uucp
return: 0 on success
exceptions: none
comments:
This checks if the effective user is in group uucp so we can
create lock files. If not we give them a warning and bail.
If its root we just skip the test.
if someone really wants to override this they can use the USER_LOCK_DIRECTORY --not recommended.
In a recent change RedHat 7.2 decided to use group lock.
In order to get around this we just check the group id
of the lock directory.
----------------------------------------------------------*/
int check_group_uucp()
{
#ifndef USER_LOCK_DIRECTORY
int group_count;
struct passwd *user = getpwuid( geteuid() );
struct stat buf;
char msg[80];
gid_t list[ NGROUPS_MAX ];
if( stat( LOCKDIR, &buf) )
{
sprintf( msg, "check_group_uucp: Can not find Lock Directory: %s\n", LOCKDIR );
syslog( LOG_INFO, msg );
return( 1 );
}
group_count = getgroups( NGROUPS_MAX, list );
list[ group_count ] = geteuid();
if( user->pw_gid )
{
while( group_count >= 0 && buf.st_gid != list[ group_count ] )
{
group_count--;
}
if( buf.st_gid == list[ group_count ] )
return 0;
sprintf( msg, "%i %i\n", buf.st_gid, list[ group_count ] );
syslog( LOG_INFO, msg );
syslog( LOG_INFO, UUCP_ERROR );
return 1;
}
return 0;
/*
if( strcmp( user->pw_name, "root" ) )
{
while( *g->gr_mem )
{
if( !strcmp( *g->gr_mem, user->pw_name ) )
{
break;
}
(void) *g->gr_mem++;
}
if( !*g->gr_mem )
{
syslog( LOG_INFO, UUCP_ERROR );
return 1;
}
}
*/
#endif /* USER_LOCK_DIRECTORY */
return 0;
}
/*----------------------------------------------------------
The following should be able to follow symbolic links. I think the stat
method used below will work on more systems. This was found while looking
for information.
* realpath() doesn't exist on all of the systems my code has to run
on (HP-UX 9.x, specifically)
----------------------------------------------------------
int different_from_LOCKDIR(const char* ld)
{
char real_ld[MAXPATHLEN];
char real_LOCKDIR[MAXPATHLEN];
if (strncmp(ld, LOCKDIR, strlen(ld)) == 0)
return 0;
if (realpath(ld, real_ld) == NULL)
return 1;
if (realpath(LOCKDIR, real_LOCKDIR) == NULL)
return 1;
if (strncmp(real_ld, real_LOCKDIR, strlen(real_ld)) == 0)
return 0;
else
return 1;
}
*/
/*----------------------------------------------------------
is_device_locked
accept: char * filename. The device in question including the path.
perform: see if one of the many possible lock files is aready there
if there is a stale lock, remove it.
return: 1 if the device is locked or somethings wrong.
0 if its possible to create our own lock file.
exceptions: none
comments: check if the device is already locked
----------------------------------------------------------*/
int is_device_locked( const char *port_filename )
{
const char *lockdirs[] = { "/etc/locks", "/usr/spool/kermit",
"/usr/spool/locks", "/usr/spool/uucp", "/usr/spool/uucp/",
"/usr/spool/uucp/LCK", "/var/lock", "/var/lock/modem",
"/var/spool/lock", "/var/spool/locks", "/var/spool/uucp",
LOCKDIR, NULL
};
const char *lockprefixes[] = { "LCK..", "lk..", "LK.", NULL };
char *p, file[80], pid_buffer[20], message[80];
int i = 0, j, k, fd , pid;
struct stat buf;
struct stat buf2;
j = strlen( port_filename );
p = ( char * ) port_filename+j;
while( *( p-1 ) != '/' && j-- !=1 ) p--;
while( lockdirs[i] )
{
/*
Look for lockfiles in all known places other than the
defined lock directory for this system
report any unexpected lockfiles.
Is the suspect lockdir there?
if it is there is it not the expected lock dir?
*/
if( !stat( lockdirs[i], &buf2 ) &&
strncmp( lockdirs[i], LOCKDIR, strlen( lockdirs[i] ) ) )
{
j = strlen( port_filename );
p = ( char * ) port_filename + j;
/*
SCO Unix use lowercase all the time
taj
*/
while( *( p - 1 ) != '/' && j-- != 1 )
{
#if defined ( __unixware__ )
*p = tolower( *p );
#endif /* __unixware__ */
p--;
}
k=0;
while ( lockprefixes[k] )
{
/* FHS style */
sprintf( file, "%s/%s%s", lockdirs[i],
lockprefixes[k], p );
if( stat( file, &buf ) == 0 )
{
sprintf( message, UNEXPECTED_LOCK_FILE,
file );
syslog( LOG_INFO, message );
return 1;
}
/* UUCP style */
stat(port_filename , &buf );
sprintf( file, "%s/%s%03d.%03d.%03d",
lockdirs[i],
lockprefixes[k],
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
if( stat( file, &buf ) == 0 )
{
sprintf( message, UNEXPECTED_LOCK_FILE,
file );
syslog( LOG_INFO, message );
return 1;
}
k++;
}
}
i++;
}
/*
OK. We think there are no unexpect lock files for this device
Lets see if there any stale lock files that need to be
removed.
*/
#ifdef FHS
/* FHS standard locks */
i = strlen( port_filename );
p = ( char * ) port_filename + i;
while( *(p-1) != '/' && i-- != 1)
{
#if defined ( __unixware__ )
*p = tolower( *p );
#endif /* __unixware__ */
p--;
}
sprintf( file, "%s/%s%s", LOCKDIR, LOCKFILEPREFIX, p );
#else
/* UUCP standard locks */
if ( stat( port_filename, &buf ) != 0 )
{
syslog( LOG_INFO, "RXTX is_device_locked() could not find device.\n" );
sprintf( message, "Filename is : %s \n", port_filename );
syslog( LOG_INFO, message );
sprintf( message, "Filename is : %s \n", port_filename );
syslog( LOG_INFO, message );
return 1;
}
sprintf( file, "%s/LK.%03d.%03d.%03d",
LOCKDIR,
(int) major( buf.st_dev ),
(int) major( buf.st_rdev ),
(int) minor( buf.st_rdev )
);
#endif /* FHS */
if( stat( file, &buf ) == 0 )
{
/* check if its a stale lock */
fd=open( file, O_RDONLY );
read( fd, pid_buffer, 11 );
/* FIXME null terminiate pid_buffer? need to check in Solaris */
close( fd );
sscanf( pid_buffer, "%d", &pid );
if( kill( (pid_t) pid, 0 ) && errno==ESRCH )
{
sprintf( message,
"RXTX Warning: Removing stale lock file. %s\n",
file );
syslog( LOG_INFO, message );
if( unlink( file ) != 0 )
{
snprintf( message, 80, "RXTX Error: Unable to \
remove stale lock file: %s\n",
file
);
syslog( LOG_INFO, message );
return 1;
}
}
}
return 0;
}
int init( void )
{
pid_t pid;
if( ( pid = fork() ) < 0 )
{
return(-1);
}
else if ( pid != 0 )
{
exit( 0 );
}
setsid();
chdir("/");
umask( 0 );
return( 0 );
}
int process_requests( int cfd )
{
for(;;)
{
char str[80];
char str2[80];
char *p;
int ret;
ret = read( cfd, str, 80 );
if( ret < 80 && ret > 1 )
str[ret] = '\0';
else
str[79] = '\0';
if ( !strncasecmp( str, "quit", 4 ) )
{
write( cfd, "Exit\n", strlen( "Exit\n" ) );
//sprintf( str, M220 );
//write( cfd, str, strlen( str ) );
sprintf( str, "221 Thank you for using the Lock File service on %s.\n", hostname );
write( cfd, str, strlen( str ) );
return( 1 );
}
else if( !strncasecmp( str, "lock ", 4 ) )
{
char *q,*r;
p = str + 5;
q=p;
while( *q != ' ' && *q != '\0' )
q++;
if ( *q == '\0' )
{
write( cfd, M450, strlen( M450 ) );
return(0);
}
*q = '\0';
q++;
r=q;
while( *r != '\n' && *r != '\0' )
r++;
if( *r == '\n' )
*r = '\0';
if ( LOCK( p, atoi( q ) ) )
write( cfd, M450, strlen( M450 ) );
write( cfd, M200, strlen( M200 ) );
}
else if( !strncasecmp( str, "unlock ", 6 ) )
{
char *q,*r;
p = str + 7;
q=p;
while( *q != ' ' && *q != '\0' )
q++;
if ( *q == '\0' )
{
write( cfd, "q=0\n", strlen( "q=0\n" ) );
write( cfd, M450, strlen( M450 ) );
return(0);
}
*q = '\0';
q++;
r=q;
while( *r != '\n' && *r != '\0' )
r++;
if( *r == '\n' )
*r = '\0';
if ( UNLOCK( (const char *) p, atoi( q ) ) )
{
write( cfd, M450, strlen( M450 ) );
}
write( cfd, M200, strlen( M200 ) );
}
else
{
str[ret-2]='\0';
sprintf( str2, M500 );
write( cfd, str2, strlen(str2));
}
//sprintf( str2, "%i\n", strlen(str) );
//write( cfd, str2, strlen(str2) );
//sprintf( str2, "%i\n", ret );
//write( cfd, str2, strlen(str2) );
//write( cfd, str, strlen(str) );
}
}
int main( int argc, char **argv )
{
char *ptr;
char str[128];
char portstr[7];
int fd, cfd;
struct sockaddr *cliaddr;
socklen_t len, addrlen;
struct sockaddr_in *sin;
struct addrinfo a_info, *results, *backup;
const int on = -1;
/* become a daemon */
if( argc != 3 )
{
fprintf( stderr, "usage: %s host port\n", argv[0] );
exit(1);
}
init();
gethostname( hostname, 255 );
hostname[256]='\0';
openlog( "rxtx", LOG_PID, LOG_UUCP );
syslog( LOG_INFO, "Lock Daemon Initialized" );
bzero( &a_info, sizeof( struct addrinfo ) );
a_info.ai_flags = AI_PASSIVE;
a_info.ai_family = AF_UNSPEC;
a_info.ai_socktype = SOCK_STREAM;
if( getaddrinfo( argv[1], argv[2], &a_info, &results ))
{
syslog( LOG_INFO, "Lock Daemon failed" );
goto exit;
}
backup = results;
do
{
fd = socket( results->ai_family, results->ai_socktype,
results->ai_protocol );
if ( fd < 0 ) continue;
setsockopt( fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on) );
if ( bind( fd, results->ai_addr, results->ai_addrlen ) == 0 ) break;
if ( results == NULL )
{
printf( "results is null\n" );
goto exit;
}
close( fd );
} while ( ( results = results->ai_next) != NULL );
if( fd < 0 )
{
}
if ( ( ptr = getenv( "LISTENQ" ) ) != NULL )
addrlen = atoi(ptr);
if( listen( fd, 1024 ) < 0 )
{
perror( strerror(errno));
printf( "fd is %i is another daemon running?\n", fd );
goto exit;
}
if ( &len )
len = results->ai_addrlen;
freeaddrinfo( backup );
cliaddr= malloc( addrlen );
len = addrlen;
cfd = accept( fd, cliaddr, &len );
sin = ( struct sockaddr_in * ) cliaddr;
if ( !inet_ntop( AF_INET, &(sin->sin_addr), str, sizeof(str) ) )
str[0] = '\0';
if ( !ntohs( sin->sin_port ) )
{
snprintf( portstr, sizeof( portstr ), ".%d", ntohs( sin->sin_port) );
strcat( str, portstr);
}
fprintf( stderr, "connected from %s\n", str );
sprintf( str, M220 );
write( cfd, str, strlen( str ) );
for(;;)
{
if (process_requests( cfd ))
{
close( cfd );
goto exit;
}
}
syslog( LOG_INFO, "Lock Daemon Shutting down" );
exit:
closelog();
exit(0);
}
./rxtx-2.2pre2/src/lfd/INSTALL 0000644 0001750 0001750 00000011020 10614033757 015633 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 2002-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
1. BUILDING LFD
In the src/lfd directory edit lockdaemon.c and specify the following defines:
#define LOCK fhs_lock
#define UNLOCK fhs_unlock
#define LOCKDIR "/var/lock"
LOCK may be fhs_lock (linux) or uucp_lock (Solaris)
UNLOCK may be fhs_unlock (Linux) or fhs_unlock (Solaris)
LOCkDIR may be /var/lock (Linux) or /var/spool/lock (Solaris)
After setting up the defines type make to build lfd.
2. INSTALLING.
daemons are usually placed in the /usr/sbin directory.
in.lfd will need to be setup for inetd or xinetd support.
2.1 xinetd support on RedHat Linux:
edit /etc/services and add the following lines:
lockfiled 50001/tcp # lock file daemon
lockfiled 50001/ucp # lock file daemon
create a file /etc/xinetd.d/lfd with the folowing contents:
# default: on
# description: The lockfiled server serves lockfiles; it uses \
#
service lfd
{
flags = REUSE
socket_type = stream
wait = no
user = uucp
server = /usr/sbin/in.lfd
log_on_failure += USERID
disable = no
}
2.2 inetd support on Solaris:
edit /etc/services and add the following lines:
lfd 50001/tcp # lock file daemon
lfd 50001/ucp # lock file daemon
add the following line to /etc/inetd.conf
lockfiled stream tcp nowait uucp /usr/sbin/in.lfd lfd
./rxtx-2.2pre2/src/lfd/Makefile 0000644 0001750 0001750 00000000150 07416410454 016243 0 ustar twerner twerner CC=gcc
CFLAGS= -Wall -g
all:
$(CC) $(CFLAGS) lockdaemon.c -o lfd
chown root:uucp lfd
chmod 2755 lfd
./rxtx-2.2pre2/src/lfd/CVS/ 0000755 0001750 0001750 00000000000 11142410104 015221 5 ustar twerner twerner ./rxtx-2.2pre2/src/lfd/CVS/Tag 0000644 0001750 0001750 00000000017 11126534474 015700 0 ustar twerner twerner Tcommapi-0-0-1
./rxtx-2.2pre2/src/lfd/CVS/Root 0000644 0001750 0001750 00000000075 11126534474 016114 0 ustar twerner twerner :pserver:jarvi@cvs.milestonesolutions.com:/usr/local/cvsroot
./rxtx-2.2pre2/src/lfd/CVS/Entries 0000644 0001750 0001750 00000000502 11126534474 016575 0 ustar twerner twerner /INSTALL/1.1.2.2/Thu Apr 26 05:26:07 2007//Tcommapi-0-0-1
/LockFileServer.rfc/1.1.2.1/Mon Jan 7 21:20:44 2002//Tcommapi-0-0-1
/Makefile/1.1.2.1/Mon Jan 7 21:20:44 2002//Tcommapi-0-0-1
/lockdaemon.c/1.1.2.3/Thu Apr 26 05:26:07 2007//Tcommapi-0-0-1
/lockdaemon.c.noinetd/1.1.2.5/Thu Apr 26 05:26:07 2007//Tcommapi-0-0-1
D
./rxtx-2.2pre2/src/lfd/CVS/Repository 0000644 0001750 0001750 00000000023 11126534474 017341 0 ustar twerner twerner rxtx-devel/src/lfd
./rxtx-2.2pre2/src/.cvsignore 0000755 0001750 0001750 00000000110 06673735645 016055 0 ustar twerner twerner win32s.h
fixup.cc
new.c
init.cc
typedefs_md.h.diff
Serial.def
termios.c
./rxtx-2.2pre2/src/fixup.c 0000644 0001750 0001750 00000006414 10614033756 015346 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
asm(".section .idata$3\n" ".long 0,0,0,0, 0,0,0,0");
./rxtx-2.2pre2/src/init.c 0000644 0001750 0001750 00000001415 10362605474 015154 0 ustar twerner twerner
/* init.c is used for compiling dll's with lcc. More info in Makefile.lcc */
#ifdef _WIN32
#include
#include
/**
* Lcc requuires that there should be LibraryMain function and seeks
* by default for LibMain. This might be someway not usefull for jni
* interface it satisfies lcc linker.
*/
BOOL WINAPI __declspec(dllexport) LibMain(HINSTANCE hDLLInst, DWORD fdwReason, LPVOID lpvReserved) {
return TRUE;
}
/**
* This is the standart implementation of Java 2 OnLoad and OnUnload native
* library calls. This template defines them empty functions
*
* Now in SerialImp.c
*/
/*
JNIEXPORT jint JNICALL JNI_OnLoad(JavaVM *vm, void *reserved) { return JNI_VERSION_1_2; }
JNIEXPORT void JNICALL JNI_OnUnload(JavaVM *vm, void *reserved) {}
*/
#endif
./rxtx-2.2pre2/src/termios.c 0000644 0001750 0001750 00000230076 11142410104 015657 0 ustar twerner twerner #ifdef TRENT_IS_HERE
#define TRACE
#define DEBUG
#define DEBUG_MW
#ifdef DEBUG_MW
extern void mexWarMsgTxt( const char * );
extern void mexPrintf( const char *, ... );
#endif /* DEBUG_MW */
#endif /* TRENT_IS_HERE */
extern void report( char * );
extern void report_warning( char * );
extern void report_error( char * );
/*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1998-2002 by Wayne roberts wroberts1@home.com
| Copyright 1997-2009 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
#include
#include
#include
#include
#include "win32termios.h"
/*
* odd malloc.h error with lcc compiler
* winsock has FIONREAD with lcc
*/
#ifdef __LCC__
# include
#else
# include
#endif /* __LCC__ */
#define SIGIO 0
int my_errno;
extern int errno;
struct termios_list
{
char filename[80];
int my_errno;
int interrupt;
int event_flag;
int tx_happened;
unsigned long *hComm;
struct termios *ttyset;
struct serial_struct *sstruct;
/* for DTR DSR */
unsigned char MSR;
struct async_struct *astruct;
struct serial_icounter_struct *sis;
int open_flags;
OVERLAPPED rol;
OVERLAPPED wol;
OVERLAPPED sol;
int fd;
struct termios_list *next;
struct termios_list *prev;
};
struct termios_list *first_tl = NULL;
/*----------------------------------------------------------
serial_test
accept: filename to test
perform:
return: 1 on success 0 on failure
exceptions:
win32api: CreateFile CloseHandle
comments: if the file opens it should be ok.
----------------------------------------------------------*/
int serial_test( char * filename )
{
unsigned long *hcomm;
int ret;
hcomm = CreateFile( filename, GENERIC_READ |GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0, 0 );
if ( hcomm == INVALID_HANDLE_VALUE )
{
if (GetLastError() == ERROR_ACCESS_DENIED)
{
ret = 1;
}
else
{
ret = 0;
}
}
else
{
ret = 1;
}
CloseHandle( hcomm );
return(ret);
}
void termios_setflags( int fd, int termios_flags[] )
{
struct termios_list *index = find_port( fd );
int i, result;
int windows_flags[11] = { 0, EV_RXCHAR, EV_TXEMPTY, EV_CTS, EV_DSR,
EV_RING|0x2000, EV_RLSD, EV_ERR,
EV_ERR, EV_ERR, EV_BREAK
};
if( !index )
{
LEAVE( "termios_setflags" );
return;
}
index->event_flag = 0;
for(i=0;i<11;i++)
if( termios_flags[i] )
index->event_flag |= windows_flags[i];
result = SetCommMask( index->hComm, index->event_flag );
/*
This is rank. 0x2000 was used to detect the trailing edge of ring.
The leading edge is detedted by EV_RING.
The trailing edge is reliable. The leading edge is not.
Softie no longer allows the trailing edge to be detected in NTsp2
and beyond.
So... Try the reliable option above and if it fails, use the less
reliable means.
The screams for a giveio solution that bypasses the kernel.
*/
if( index->event_flag & 0x2000 && result == 0 )
{
index->event_flag &= ~0x2000;
SetCommMask( index->hComm, index->event_flag );
}
}
/*----------------------------------------------------------
get_fd()
accept: filename
perform: find the file descriptor associated with the filename
return: fd
exceptions:
win32api: None
comments: This is not currently called by anything
----------------------------------------------------------*/
int get_fd( char *filename )
{
struct termios_list *index = first_tl;
ENTER( "get_fd" );
if( !index )
{
return -1;
}
while( strcmp( index->filename, filename ) )
{
index = index->next;
if( !index->next )
return( -1 );
}
LEAVE( "get_fd" );
return( index->fd );
}
/*----------------------------------------------------------
get_filename()
accept: file descriptor
perform: find the filename associated with the file descriptor
return: the filename associated with the fd
exceptions: None
win32api: None
comments: This is not currently called by anything
----------------------------------------------------------*/
char *get_filename( int fd )
{
struct termios_list *index = first_tl;
ENTER( "get_filename" );
if( !index )
return( "bad" );
while( index->fd != fd )
{
if( index->next == NULL )
return( "bad" );
index = index->next;
}
LEAVE( "get_filename" );
return( index->filename );
}
/*----------------------------------------------------------
dump_termios_list()
accept: string to print out.
perform:
return:
exceptions:
win32api: None
comments: used only for debugging eg serial_close()
----------------------------------------------------------*/
void dump_termios_list( char *foo )
{
#ifdef DEBUG
struct termios_list *index = first_tl;
printf( "============== %s start ===============\n", foo );
if ( index )
{
printf( "%i filename | %s\n", index->fd, index->filename );
}
/*
if ( index->next )
{
printf( "%i filename | %s\n", index->fd, index->filename );
}
*/
printf( "============== %s end ===============\n", foo );
#endif
}
/*----------------------------------------------------------
set_errno()
accept:
perform:
return:
exceptions:
win32api: None
comments: FIXME
----------------------------------------------------------*/
void set_errno( int error )
{
my_errno = error;
}
/*----------------------------------------------------------
usleep()
accept:
perform:
return:
exceptions:
win32api: Sleep()
comments:
----------------------------------------------------------*/
void usleep( unsigned long usec )
{
Sleep( usec/1000 );
}
/*----------------------------------------------------------
CBR_toB()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int CBR_to_B( int Baud )
{
ENTER( "CBR_to_B" );
switch ( Baud )
{
case 0: return( B0 );
case 50: return( B50 );
case 75: return( B75 );
case CBR_110: return( B110 );
case 134: return( B134 );
case 150: return( B150 );
case 200: return( B200 );
case CBR_300: return( B300 );
case CBR_600: return( B600 );
case CBR_1200: return( B1200 );
case 1800: return( B1800 );
case CBR_2400: return( B2400 );
case CBR_4800: return( B4800 );
case CBR_9600: return( B9600 );
case CBR_14400: return( B14400 );
case CBR_19200: return( B19200 );
case CBR_28800: return( B28800 );
case CBR_38400: return( B38400 );
case CBR_57600: return( B57600 );
case CBR_115200: return( B115200 );
case CBR_128000: return( B128000 );
case CBR_230400: return( B230400 );
case CBR_256000: return( B256000 );
case CBR_460800: return( B460800 );
case CBR_500000: return( B500000 );
case CBR_576000: return( B576000 );
case CBR_921600: return( B921600 );
case CBR_1000000: return( B1000000 );
case CBR_1152000: return( B1152000 );
case CBR_1500000: return( B1500000 );
case CBR_2000000: return( B2000000 );
case CBR_2500000: return( B2500000 );
case CBR_3000000: return( B3000000 );
case CBR_3500000: return( B3500000 );
case CBR_4000000: return( B4000000 );
default:
/* assume custom baudrate */
return( Baud );
}
}
/*----------------------------------------------------------
B_to_CBR()
accept:
perform:
return:
exceptions:
win32api:
comments: None
----------------------------------------------------------*/
int B_to_CBR( int Baud )
{
int ret;
ENTER( "B_to_CBR" );
switch ( Baud )
{
case 0: ret = 0; break;
case B50: ret = 50; break;
case B75: ret = 75; break;
case B110: ret = CBR_110; break;
case B134: ret = 134; break;
case B150: ret = 150; break;
case B200: ret = 200; break;
case B300: ret = CBR_300; break;
case B600: ret = CBR_600; break;
case B1200: ret = CBR_1200; break;
case B1800: ret = 1800; break;
case B2400: ret = CBR_2400; break;
case B4800: ret = CBR_4800; break;
case B9600: ret = CBR_9600; break;
case B14400: ret = CBR_14400; break;
case B19200: ret = CBR_19200; break;
case B28800: ret = CBR_28800; break;
case B38400: ret = CBR_38400; break;
case B57600: ret = CBR_57600; break;
case B115200: ret = CBR_115200; break;
case B128000: ret = CBR_128000; break;
case B230400: ret = CBR_230400; break;
case B256000: ret = CBR_256000; break;
case B460800: ret = CBR_460800; break;
case B500000: ret = CBR_500000; break;
case B576000: ret = CBR_576000; break;
case B921600: ret = CBR_921600; break;
case B1000000: ret = CBR_1000000; break;
case B1152000: ret = CBR_1152000; break;
case B1500000: ret = CBR_1500000; break;
case B2000000: ret = CBR_2000000; break;
case B2500000: ret = CBR_2500000; break;
case B3000000: ret = CBR_3000000; break;
case B3500000: ret = CBR_3500000; break;
case B4000000: ret = CBR_4000000; break;
default:
/* assume custom baudrate */
return Baud;
}
LEAVE( "B_to_CBR" );
return ret;
}
/*----------------------------------------------------------
bytesize_to_termios()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int bytesize_to_termios( int ByteSize )
{
ENTER( "bytesize_to_termios" );
switch ( ByteSize )
{
case 5: return( CS5 );
case 6: return( CS6 );
case 7: return( CS7 );
case 8:
default: return( CS8 );
}
}
/*----------------------------------------------------------
termios_to_bytesize()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int termios_to_bytesize( int cflag )
{
ENTER( "termios_to_bytesize" );
switch ( cflag & CSIZE )
{
case CS5: return( 5 );
case CS6: return( 6 );
case CS7: return( 7 );
case CS8:
default: return( 8 );
}
}
/*----------------------------------------------------------
get_dos_port()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
const char *get_dos_port( char const *name )
{
ENTER( "get_dos_port" );
if ( !strcmp( name, "/dev/cua0" ) ) return( "COM1" );
if ( !strcmp( name, "/dev/cua1" ) ) return( "COM2" );
if ( !strcmp( name, "/dev/cua2" ) ) return( "COM3" );
if ( !strcmp( name, "/dev/cua3" ) ) return( "COM4" );
LEAVE( "get_dos_port" );
return( ( const char * ) name );
}
/*----------------------------------------------------------
ClearErrors()
accept:
perform: keep track of errors for the eventLoop() (SerialImp.c)
return: the return value of ClearCommError()
exceptions:
win32api: ClearCommError()
comments:
----------------------------------------------------------*/
int ClearErrors( struct termios_list *index, COMSTAT *Stat )
{
unsigned long ErrCode;
int ret;
ret = ClearCommError( index->hComm, &ErrCode, Stat );
if ( ret == 0 )
{
YACK();
return( ret );
}
#ifdef DEBUG_ERRORS
if ( ErrCode )
{
printf("%i frame %i %i overrun %i %i parity %u %i brk %i %i\n",
(int) ErrCode,
(int) ErrCode & CE_FRAME,
index->sis->frame,
(int) (ErrCode & CE_OVERRUN) | ( ErrCode & CE_RXOVER ),
index->sis->overrun,
(int) ErrCode & CE_RXPARITY,
index->sis->parity,
(int) ErrCode & CE_BREAK,
index->sis->brk
);
}
#endif /* DEBUG_ERRORS */
if( ErrCode & CE_FRAME )
{
index->sis->frame++;
ErrCode &= ~CE_FRAME;
}
#ifdef LIFE_IS_GOOD
FIXME OVERRUN is spewing
if( ErrCode & CE_OVERRUN )
{
index->sis->overrun++;
ErrCode &= ~CE_OVERRUN;
}
/* should this be here? */
else if( ErrCode & CE_RXOVER )
{
index->sis->overrun++;
ErrCode &= ~CE_OVERRUN;
}
#endif /* LIFE_IS_GOOD */
if( ErrCode & CE_RXPARITY )
{
index->sis->parity++;
ErrCode &= ~CE_RXPARITY;
}
if( ErrCode & CE_BREAK )
{
index->sis->brk++;
ErrCode &= ~CE_BREAK;
}
return( ret );
}
/*----------------------------------------------------------
FillDCB()
accept:
perform:
return:
exceptions:
win32api: GetCommState(), SetCommState(), SetCommTimeouts()
comments:
----------------------------------------------------------*/
BOOL FillDCB( DCB *dcb, unsigned long *hCommPort, COMMTIMEOUTS Timeout )
{
ENTER( "FillDCB" );
dcb->DCBlength = sizeof( dcb );
if ( !GetCommState( hCommPort, dcb ) )
{
report( "GetCommState\n" );
return( -1 );
}
dcb->BaudRate = CBR_9600 ;
dcb->ByteSize = 8;
dcb->Parity = NOPARITY;
dcb->StopBits = ONESTOPBIT;
dcb->fDtrControl = DTR_CONTROL_ENABLE;
dcb->fRtsControl = RTS_CONTROL_ENABLE;
dcb->fOutxCtsFlow = FALSE;
dcb->fOutxDsrFlow = FALSE;
dcb->fDsrSensitivity = FALSE;
dcb->fOutX = FALSE;
dcb->fInX = FALSE;
dcb->fTXContinueOnXoff = FALSE;
dcb->XonChar = 0x11;
dcb->XoffChar = 0x13;
dcb->XonLim = 0;
dcb->XoffLim = 0;
dcb->fParity = TRUE;
if ( EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_RING|( EV_RLSD & EV_RXFLAG ) )
dcb->EvtChar = '\n';
else dcb->EvtChar = '\0';
if ( !SetCommState( hCommPort, dcb ) )
{
report( "SetCommState\n" );
YACK();
return( -1 );
}
if ( !SetCommTimeouts( hCommPort, &Timeout ) )
{
YACK();
report( "SetCommTimeouts\n" );
return( -1 );
}
LEAVE( "FillDCB" );
return ( TRUE ) ;
}
/*----------------------------------------------------------
serial_close()
accept:
perform:
return:
exceptions:
win32api: SetCommMask(), CloseHandle()
comments:
----------------------------------------------------------*/
int serial_close( int fd )
{
struct termios_list *index;
/* char message[80]; */
ENTER( "serial_close" );
if( !first_tl || !first_tl->hComm )
{
report( "gotit!" );
return( 0 );
}
index = find_port( fd );
if ( !index )
{
LEAVE( "serial_close" );
return -1;
}
/* WaitForSingleObject( index->wol.hEvent, INFINITE ); */
/*
if ( index->hComm != INVALID_HANDLE_VALUE )
{
if ( !SetCommMask( index->hComm, EV_RXCHAR ) )
{
YACK();
report( "eventLoop hung\n" );
}
CloseHandle( index->hComm );
}
else
{
sprintf( message, "serial_ close(): Invalid Port Reference for %s\n",
index->filename );
report( message );
}
*/
if ( index->next && index->prev )
{
index->next->prev = index->prev;
index->prev->next = index->next;
}
else if ( index->prev )
{
index->prev->next = NULL;
}
else if ( index->next )
{
index->next->prev = NULL;
first_tl = index->next;
}
else
first_tl = NULL;
if ( index )
{
if ( index->rol.hEvent ) CloseHandle( index->rol.hEvent );
if ( index->wol.hEvent ) CloseHandle( index->wol.hEvent );
if ( index->sol.hEvent ) CloseHandle( index->sol.hEvent );
if ( index->hComm ) CloseHandle( index->hComm );
if ( index->ttyset ) free( index->ttyset );
if ( index->astruct ) free( index->astruct );
if ( index->sstruct ) free( index->sstruct );
if ( index->sis ) free( index->sis );
/* had problems with strdup
if ( index->filename ) free( index->filename );
*/
free( index );
}
LEAVE( "serial_close" );
return 0;
}
/*----------------------------------------------------------
cfmakeraw()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
void cfmakeraw( struct termios *s_termios )
{
ENTER( "cfmakeraw" );
s_termios->c_iflag &= ~( IGNBRK|BRKINT|PARMRK|ISTRIP
|INLCR|IGNCR|ICRNL|IXON );
s_termios->c_oflag &= ~OPOST;
s_termios->c_lflag &= ~( ECHO|ECHONL|ICANON|ISIG|IEXTEN );
s_termios->c_cflag &= ~( CSIZE|PARENB );
s_termios->c_cflag |= CS8;
LEAVE( "cfmakeraw" );
}
/*----------------------------------------------------------
init_termios()
accept:
perform:
return:
exceptions:
win32api:
comments:
----------------------------------------------------------*/
BOOL init_serial_struct( struct serial_struct *sstruct )
{
ENTER( "init_serial_struct" );
/*
use of custom_divisor and baud_base requires access to
kernel space. The kernel does try its best if you just
toss a baud rate at it though.
*/
sstruct->custom_divisor = 0;
sstruct->baud_base = 115200;
/* not currently used check values before using */
/* unsigned short */
sstruct->close_delay = 0;
sstruct->closing_wait = 0;
sstruct->iomem_reg_shift = 0;
/* int */
sstruct->type = 0;
sstruct->line = 0;
sstruct->irq = 0;
sstruct->flags = 0;
sstruct->xmit_fifo_size = 0;
sstruct->hub6 = 0;
/* unsigned int */
sstruct->port = 0;
sstruct->port_high = 0;
/* char */
sstruct->io_type = 0;
/* unsigned char * */
sstruct->iomem_base = NULL;
LEAVE( "init_serial_struct" );
return TRUE;
}
/*----------------------------------------------------------
init_termios()
accept:
perform:
return:
exceptions:
win32api:
comments:
----------------------------------------------------------*/
BOOL init_termios(struct termios *ttyset )
{
ENTER( "init_termios" );
if ( !ttyset )
return FALSE;
memset( ttyset, 0, sizeof( struct termios ) );
cfsetospeed( ttyset, B9600 );
cfmakeraw( ttyset );
ttyset->c_cc[VINTR] = 0x03; /* 0: C-c */
ttyset->c_cc[VQUIT] = 0x1c; /* 1: C-\ */
ttyset->c_cc[VERASE] = 0x7f; /* 2: */
ttyset->c_cc[VKILL] = 0x15; /* 3: C-u */
ttyset->c_cc[VEOF] = 0x04; /* 4: C-d */
ttyset->c_cc[VTIME] = 0; /* 5: read timeout */
ttyset->c_cc[VMIN] = 1; /* 6: read returns after this
many bytes */
ttyset->c_cc[VSUSP] = 0x1a; /* 10: C-z */
ttyset->c_cc[VEOL] = '\r'; /* 11: */
ttyset->c_cc[VREPRINT] = 0x12; /* 12: C-r */
/*
ttyset->c_cc[VDISCARD] = 0x; 13: IEXTEN only
*/
ttyset->c_cc[VWERASE] = 0x17; /* 14: C-w */
ttyset->c_cc[VLNEXT] = 0x16; /* 15: C-w */
ttyset->c_cc[VEOL2] = '\n'; /* 16: */
LEAVE( "init_termios" );
return TRUE;
/* default VTIME = 0, VMIN = 1: read blocks forever until one byte */
}
/*----------------------------------------------------------
port_opened()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int port_opened( const char *filename )
{
struct termios_list *index = first_tl;
ENTER( "port_opened" );
if ( ! index )
return 0;
if( !strcmp( index->filename, filename ) )
return index->fd;
while ( index->next )
{
index = index->next;
if( !strcmp( index->filename, filename ) )
return index->fd;
}
LEAVE( "port_opened" );
return 0;
}
/*----------------------------------------------------------
open_port()
accept:
perform:
return:
exceptions:
win32api: CreateFile(), SetupComm(), CreateEvent()
comments:
FILE_FLAG_OVERLAPPED allows one to break out the select()
so RXTXPort.close() does not hang.
The setDTR() and setDSR() are the functions that noticed
to be blocked in the java close. Basically ioctl(TIOCM[GS]ET)
are where it hangs.
FILE_FLAG_OVERLAPPED also means we need to create valid OVERLAPPED
structure in Serial_select.
----------------------------------------------------------*/
int open_port( struct termios_list *port )
{
ENTER( "open_port" );
port->hComm = CreateFile( port->filename,
GENERIC_READ | GENERIC_WRITE,
0,
0,
OPEN_EXISTING,
FILE_FLAG_OVERLAPPED,
0
);
if ( port->hComm == INVALID_HANDLE_VALUE )
{
YACK();
set_errno( EINVAL );
/*
printf( "serial_open failed %s\n", port->filename );
*/
return -1;
}
if( !SetupComm( port->hComm, 2048, 1024 ) )
{
YACK();
return -1;
}
memset( &port->rol, 0, sizeof( OVERLAPPED ) );
memset( &port->wol, 0, sizeof( OVERLAPPED ) );
memset( &port->sol, 0, sizeof( OVERLAPPED ) );
port->rol.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( !port->rol.hEvent )
{
YACK();
report( "Could not create read overlapped\n" );
goto fail;
}
port->sol.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( !port->sol.hEvent )
{
YACK();
report( "Could not create select overlapped\n" );
goto fail;
}
port->wol.hEvent = CreateEvent( NULL, TRUE, FALSE, NULL );
if ( !port->wol.hEvent )
{
YACK();
report( "Could not create write overlapped\n" );
goto fail;
}
LEAVE( "open_port" );
return( 0 );
fail:
return( -1 );
}
/*----------------------------------------------------------
termios_list()
accept: fd which is a fake # for the port assigned when the port
is opened
perform: walk through a double linked list to see if the given
fd is in any of the termios_list members.
return: the termios_list if it is found.
NULL if no matches are found.
exceptions: None
win32api: None
comments:
----------------------------------------------------------*/
struct termios_list *find_port( int fd )
{
char message[80];
struct termios_list *index = first_tl;
ENTER( "find_port" );
if ( fd <= 0 || !first_tl ) goto fail;
while( index->fd )
{
if ( index->fd == fd )
{
LEAVE( "find_port" );
return index;
}
if ( !index->next )
break;
index = index->next;
}
fail:
sprintf( message, "No info known about the port. %i\n", fd );
report( message );
set_errno( EBADF );
LEAVE( "find_port" );
return NULL;
}
/*----------------------------------------------------------
get_free_fd()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int get_free_fd()
{
int next, last;
struct termios_list *index = first_tl;
ENTER( "get_free_fd" );
if ( !index )
{
return( 1 );
}
if ( !index->fd )
{
report( "!index->fd\n" );
return( 1 );
}
if ( index->fd > 1)
{
first_tl = index;
return ( 1 );
}
last = index->fd;
while( index->next )
{
next = index->next->fd;
if ( next != last + 1 )
{
return( last + 1 );
}
index = index->next;
last = next;
}
LEAVE( "get_free_fd" );
return( index->fd + 1 );
}
/*----------------------------------------------------------
add_port()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
struct termios_list *add_port( const char *filename )
{
struct termios_list *index = first_tl;
struct termios_list *port;
ENTER( "add_port" );
port = malloc( sizeof( struct termios_list ) );
if( !port )
goto fail;
memset( port, 0, sizeof( struct termios_list ) );
port->ttyset = malloc( sizeof( struct termios ) );
if( ! port->ttyset )
goto fail;
memset( port->ttyset, 0, sizeof( struct termios ) );
port->sstruct = malloc( sizeof( struct serial_struct ) );
if( ! port->sstruct )
goto fail;
memset( port->sstruct, 0, sizeof( struct serial_struct ) );
port->sis = malloc( sizeof( struct serial_icounter_struct ) );
if( ! port->sis )
goto fail;
memset( port->sis, 0, sizeof( struct serial_icounter_struct ) );
/* FIXME the async_struct is being defined by mingw32 headers?
port->astruct = malloc( sizeof( struct async_struct ) );
if( ! port->astruct )
goto fail;
memset( port->astruct, 0, sizeof( struct async_struct ) );
*/
port->MSR = 0;
strcpy(port->filename, filename );
/* didnt free well? strdup( filename ); */
if( ! port->filename )
goto fail;
port->fd = get_free_fd();
if ( !first_tl )
{
port->prev = NULL;
port->next = NULL;
first_tl = port;
}
else
{
while ( ( index->fd < port->fd ) && index->next )
index = index->next;
if ( index->fd > port->fd )
{
/* inserting previously closed fd */
port->prev = index->prev;
port->next=index;
index->prev->next = port;
index->prev = port;
}
else
{
/* adding to end of list */
port->prev = index;
port->next = NULL;
index->next = port;
}
}
LEAVE( "add_port" );
return port;
fail:
report( "add_port: Out Of Memory\n");
if ( port->ttyset ) free( port->ttyset );
if ( port->astruct ) free( port->astruct );
if ( port->sstruct ) free( port->sstruct );
if ( port->sis ) free( port->sis );
/* had problems with strdup
if ( port->filename ) free( port->filename );
*/
if ( port ) free( port );
return port;
}
/*----------------------------------------------------------
check_port_capabilities()
accept:
perform:
return:
exceptions:
win32api: GetCommProperties(), GetCommState()
comments:
----------------------------------------------------------*/
int check_port_capabilities( struct termios_list *index )
{
COMMPROP cp;
DCB dcb;
char message[80];
ENTER( "check_port_capabilities" );
/* check for capabilities */
GetCommProperties( index->hComm, &cp );
if ( !( cp.dwProvCapabilities & PCF_DTRDSR ) )
{
sprintf( message,
"%s: no DTR & DSR support\n", index->filename );
report( message );
}
if ( !( cp.dwProvCapabilities & PCF_RLSD ) )
{
sprintf( message, "%s: no carrier detect (RLSD) support\n",
index->filename );
report( message );
}
if ( !( cp.dwProvCapabilities & PCF_RTSCTS ) )
{
sprintf( message,
"%s: no RTS & CTS support\n", index->filename );
report( message );
}
if ( !( cp.dwProvCapabilities & PCF_TOTALTIMEOUTS ) )
{
sprintf( message, "%s: no timeout support\n", index->filename );
report( message );
}
if ( !GetCommState( index->hComm, &dcb ) )
{
YACK();
report( "GetCommState\n" );
return -1;
}
LEAVE( "check_port_capabilities" );
return 0;
}
/*----------------------------------------------------------
serial_open()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int serial_open( const char *filename, int flags, ... )
{
struct termios_list *index;
char message[80];
ENTER( "serial_open" );
if ( port_opened( filename ) )
{
report( "Port is already opened\n" );
return( -1 );
}
index = add_port( filename );
if( !index )
{
report( "serial_open !index\n" );
return( -1 );
}
index->interrupt = 0;
index->tx_happened = 0;
if ( open_port( index ) )
{
sprintf( message, "serial_open(): Invalid Port Reference for %s\n",
filename );
report( message );
serial_close( index->fd );
return -1;
}
if( check_port_capabilities( index ) )
{
report( "check_port_capabilites!" );
serial_close( index->fd );
return -1;
}
init_termios( index->ttyset );
init_serial_struct( index->sstruct );
/* set default condition */
tcsetattr( index->fd, 0, index->ttyset );
/* if opened with non-blocking, then operating non-blocking */
if ( flags & O_NONBLOCK )
index->open_flags = O_NONBLOCK;
else
index->open_flags = 0;
if( !first_tl->hComm )
{
sprintf( message, "open(): Invalid Port Reference for %s\n",
index->filename );
report( message );
}
if ( first_tl->hComm == INVALID_HANDLE_VALUE )
report( "serial_open: test\n" );
LEAVE( "serial_open" );
return( index->fd );
}
/*----------------------------------------------------------
serial_write()
accept:
perform:
return:
exceptions:
win32api: WriteFile(), GetLastError(),
WaitForSingleObject(), GetOverlappedResult(),
FlushFileBuffers(), Sleep()
comments:
----------------------------------------------------------*/
int serial_write( int fd, char *Str, int length )
{
unsigned long nBytes;
struct termios_list *index;
/* COMSTAT Stat; */
int old_flag;
ENTER( "serial_write" );
if ( fd <= 0 )
{
return 0;
}
index = find_port( fd );
if ( !index )
{
LEAVE( "serial_write");
return -1;
}
old_flag = index->event_flag;
/*
index->event_flag &= ~EV_TXEMPTY;
SetCommMask( index->hComm, index->event_flag );
index->tx_happened = 1;
*/
index->wol.Offset = index->wol.OffsetHigh = 0;
ResetEvent( index->wol.hEvent );
if ( !WriteFile( index->hComm, Str, length, &nBytes, &index->wol ) )
{
WaitForSingleObject( index->wol.hEvent,100 );
if ( GetLastError() != ERROR_IO_PENDING )
{
/* ClearErrors( index, &Stat ); */
report( "serial_write error\n" );
/* report("Condition 1 Detected in write()\n"); */
YACK();
errno = EIO;
nBytes=-1;
goto end;
}
/* This is breaking on Win2K, WinXP for some reason */
else while( !GetOverlappedResult( index->hComm, &index->wol,
&nBytes, TRUE ) )
{
if ( GetLastError() != ERROR_IO_INCOMPLETE )
{
/* report("Condition 2 Detected in write()\n"); */
YACK();
errno = EIO;
nBytes = -1;
goto end;
/* ClearErrors( index, &Stat ); */
}
}
}
else
{
/* Write finished synchronously. That is ok!
* I have seen this with USB to Serial
* devices like TI's.
*/
}
end:
/* FlushFileBuffers( index->hComm ); */
index->event_flag |= EV_TXEMPTY;
/* ClearErrors( index, &Stat ); */
SetCommMask( index->hComm, index->event_flag );
/* ClearErrors( index, &Stat ); */
index->event_flag = old_flag;
index->tx_happened = 1;
LEAVE( "serial_write" );
return nBytes;
}
/*----------------------------------------------------------
serial_read()
accept:
perform:
return:
exceptions:
win32api: ReadFile(), GetLastError(), WaitForSingleObject()
GetOverLappedResult()
comments: If setting errno make sure not to use EWOULDBLOCK
In that case use EAGAIN. See SerialImp.c:testRead()
----------------------------------------------------------*/
int serial_read( int fd, void *vb, int size )
{
long start, now;
unsigned long nBytes = 0, total = 0, error;
/* unsigned long waiting = 0; */
int err, vmin;
struct termios_list *index;
char message[80];
COMSTAT stat;
clock_t c;
unsigned char *dest = vb;
start = GetTickCount();
ENTER( "serial_read" );
if ( fd <= 0 )
{
return 0;
}
index = find_port( fd );
if ( !index )
{
LEAVE( "serial_read" );
return -1;
}
/* FIXME: CREAD: without this, data cannot be read
FIXME: PARMRK: mark framing & parity errors
FIXME: IGNCR: ignore \r
FIXME: ICRNL: convert \r to \n
FIXME: INLCR: convert \n to \r
*/
if ( index->open_flags & O_NONBLOCK )
{
int ret;
vmin = 0;
/* pull mucho-cpu here? */
do {
#ifdef DEBUG_VERBOSE
report( "vmin=0\n" );
#endif /* DEBUG_VERBOSE */
ret = ClearErrors( index, &stat);
/* we should use -1 instead of 0 for disabled timeout */
now = GetTickCount();
if ( index->ttyset->c_cc[VTIME] &&
now-start >= (index->ttyset->c_cc[VTIME]*100)) {
/*
sprintf( message, "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total);
report( message );
*/
return total; /* read timeout */
}
} while( stat.cbInQue < size && size > 1 );
}
else
{
/* VTIME is in units of 0.1 seconds */
#ifdef DEBUG_VERBOSE
report( "vmin!=0\n" );
#endif /* DEBUG_VERBOSE */
vmin = index->ttyset->c_cc[VMIN];
c = clock() + index->ttyset->c_cc[VTIME] * CLOCKS_PER_SEC / 10;
do {
error = ClearErrors( index, &stat);
usleep(1000);
} while ( c > clock() );
}
total = 0;
while ( size > 0 )
{
nBytes = 0;
/* ret = ClearErrors( index, &stat); */
index->rol.Offset = index->rol.OffsetHigh = 0;
ResetEvent( index->rol.hEvent );
err = ReadFile( index->hComm, dest + total, size, &nBytes, &index->rol );
#ifdef DEBUG_VERBOSE
/* warning Roy Rogers! */
sprintf(message, " ========== ReadFile = %i %s\n",
( int ) nBytes, (char *) dest + total );
report( message );
#endif /* DEBUG_VERBOSE */
size -= nBytes;
total += nBytes;
if ( !err )
{
switch ( GetLastError() )
{
case ERROR_BROKEN_PIPE:
report( "ERROR_BROKEN_PIPE\n ");
nBytes = 0;
break;
case ERROR_MORE_DATA:
report( "ERROR_MORE_DATA\n" );
break;
case ERROR_IO_PENDING:
while( ! GetOverlappedResult(
index->hComm,
&index->rol,
&nBytes,
TRUE ) )
{
if( GetLastError() !=
ERROR_IO_INCOMPLETE )
{
ClearErrors(
index,
&stat);
return( total );
}
}
size -= nBytes;
total += nBytes;
if (size > 0) {
now = GetTickCount();
sprintf(message, "size > 0: spent=%ld have=%d\n", now-start, index->ttyset->c_cc[VTIME]*100);
report( message );
/* we should use -1 for disabled
timouts */
if ( index->ttyset->c_cc[VTIME] && now-start >= (index->ttyset->c_cc[VTIME]*100)) {
report( "TO " );
/* read timeout */
return total;
}
}
sprintf(message, "end nBytes=%ld] ", nBytes);
report( message );
report( "ERROR_IO_PENDING\n" );
break;
default:
YACK();
return -1;
}
}
else
{
ClearErrors( index, &stat);
return( total );
}
}
LEAVE( "serial_read" );
return total;
}
#ifdef asdf
int serial_read( int fd, void *vb, int size )
{
long start, now;
unsigned long nBytes = 0, total = 0, error;
/* unsigned long waiting = 0; */
int err, vmin;
struct termios_list *index;
char message[80];
COMSTAT Stat;
clock_t c;
unsigned char *dest = vb;
start = GetTickCount();
ENTER( "serial_read" );
if ( fd <= 0 )
{
printf("1\n");
return 0;
}
index = find_port( fd );
if ( !index )
{
LEAVE( "serial_read 7" );
errno = EIO;
printf("2\n");
return -1;
}
/* FIXME: CREAD: without this, data cannot be read
FIXME: PARMRK: mark framing & parity errors
FIXME: IGNCR: ignore \r
FIXME: ICRNL: convert \r to \n
FIXME: INLCR: convert \n to \r
*/
ClearErrors( index, &Stat );
if ( index->open_flags & O_NONBLOCK )
{
int ret;
vmin = 0;
/* pull mucho-cpu here? */
do {
#ifdef DEBUG_VERBOSE
report( "vmin=0\n" );
#endif /* DEBUG_VERBOSE */
ret = ClearErrors( index, &Stat);
/* we should use -1 instead of 0 for disabled timeout */
now = GetTickCount();
if ( index->ttyset->c_cc[VTIME] &&
now-start >= (index->ttyset->c_cc[VTIME]*100)) {
/*
sprintf( message, "now = %i start = %i time = %i total =%i\n", now, start, index->ttyset->c_cc[VTIME]*100, total);
report( message );
*/
errno = EAGAIN;
printf("3\n");
return -1; /* read timeout */
}
} while( Stat.cbInQue < size && size > 1 );
}
else
{
/* VTIME is in units of 0.1 seconds */
#ifdef DEBUG_VERBOSE
report( "vmin!=0\n" );
#endif /* DEBUG_VERBOSE */
vmin = index->ttyset->c_cc[VMIN];
c = clock() + index->ttyset->c_cc[VTIME] * CLOCKS_PER_SEC / 10;
do {
error = ClearErrors( index, &Stat);
usleep(1000);
} while ( c > clock() );
}
total = 0;
while ( size > 0 )
{
nBytes = 0;
/* ret = ClearErrors( index, &Stat); */
index->rol.Offset = index->rol.OffsetHigh = 0;
ResetEvent( index->rol.hEvent );
err = ReadFile( index->hComm, dest + total, size, &nBytes, &index->rol );
#ifdef DEBUG_VERBOSE
/* warning Roy Rogers! */
sprintf(message, " ========== ReadFile = %i %s\n",
( int ) nBytes, (char *) dest + total );
report( message );
#endif /* DEBUG_VERBOSE */
size -= nBytes;
total += nBytes;
if ( !err )
{
switch ( GetLastError() )
{
case ERROR_BROKEN_PIPE:
report( "ERROR_BROKEN_PIPE\n ");
nBytes = 0;
break;
case ERROR_MORE_DATA:
report( "ERROR_MORE_DATA\n" );
break;
case ERROR_IO_PENDING:
while( ! GetOverlappedResult(
index->hComm,
&index->rol,
&nBytes,
TRUE ) )
{
if( GetLastError() !=
ERROR_IO_INCOMPLETE )
{
ClearErrors(
index,
&Stat);
printf("4\n");
return( total );
}
}
size -= nBytes;
total += nBytes;
if (size > 0) {
now = GetTickCount();
sprintf(message, "size > 0: spent=%ld have=%d\n", now-start, index->ttyset->c_cc[VTIME]*100);
report( message );
/* we should use -1 for disabled
timouts */
if ( index->ttyset->c_cc[VTIME] && now-start >= (index->ttyset->c_cc[VTIME]*100)) {
report( "TO " );
/* read timeout */
printf("5\n");
return total;
}
}
sprintf(message, "end nBytes=%ld] ", nBytes);
report( message );
report( "ERROR_IO_PENDING\n" );
break;
default:
YACK();
errno = EIO;
printf("6\n");
return -1;
}
}
else
{
ClearErrors( index, &Stat);
printf("7\n");
return( total );
}
}
LEAVE( "serial_read" );
ClearErrors( index, &Stat);
return total;
}
#endif /* asdf */
/*----------------------------------------------------------
cfsetospeed()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int cfsetospeed( struct termios *s_termios, speed_t speed )
{
char message[80];
ENTER( "cfsetospeed" );
/* clear baudrate */
s_termios->c_cflag &= ~CBAUD;
if ( speed & ~CBAUD )
{
sprintf( message, "cfsetospeed: not speed: %#o\n", speed );
report( message );
/* continue assuming its a custom baudrate */
s_termios->c_cflag |= B38400; /* use 38400 during custom */
s_termios->c_cflag |= CBAUDEX; /* use CBAUDEX for custom */
}
else if( speed )
{
s_termios->c_cflag |= speed;
}
else
{
/* PC blows up with speed 0 handled in Java */
s_termios->c_cflag |= B9600;
}
s_termios->c_ispeed = s_termios->c_ospeed = speed;
LEAVE( "cfsetospeed" );
return 1;
}
/*----------------------------------------------------------
cfsetispeed()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int cfsetispeed( struct termios *s_termios, speed_t speed )
{
return cfsetospeed( s_termios, speed );
}
/*----------------------------------------------------------
cfsetspeed()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int cfsetspeed( struct termios *s_termios, speed_t speed )
{
return cfsetospeed( s_termios, speed );
}
/*----------------------------------------------------------
cfgetospeed()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
speed_t cfgetospeed( struct termios *s_termios )
{
ENTER( "cfgetospeed" );
return s_termios->c_ospeed;
}
/*----------------------------------------------------------
cfgetispeed()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
speed_t cfgetispeed( struct termios *s_termios )
{
ENTER( "cfgetospeed" );
return s_termios->c_ispeed;
}
/*----------------------------------------------------------
termios_to_DCB()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int termios_to_DCB( struct termios *s_termios, DCB *dcb )
{
ENTER( "termios_to_DCB" );
if ( !(s_termios->c_cflag & CBAUDEX) )
s_termios->c_ispeed = s_termios->c_ospeed = s_termios->c_cflag & CBAUD;
dcb->BaudRate = B_to_CBR( s_termios->c_ispeed );
dcb->ByteSize = termios_to_bytesize( s_termios->c_cflag );
if ( s_termios->c_cflag & PARENB )
{
if ( s_termios->c_cflag & PARODD
&& s_termios->c_cflag & CMSPAR )
{
dcb->Parity = MARKPARITY;
}
else if ( s_termios->c_cflag & PARODD )
{
dcb->Parity = ODDPARITY;
}
else if ( s_termios->c_cflag & CMSPAR )
{
dcb->Parity = SPACEPARITY;
}
else
{
dcb->Parity = EVENPARITY;
}
}
else
{
dcb->Parity = NOPARITY;
}
if ( s_termios->c_cflag & CSTOPB )
{
if (dcb->ByteSize == 5)
{
dcb->StopBits = ONE5STOPBITS;
} else dcb->StopBits = TWOSTOPBITS;
}
else
{
dcb->StopBits = ONESTOPBIT;
}
if ( s_termios->c_cflag & HARDWARE_FLOW_CONTROL )
{
dcb->fRtsControl = RTS_CONTROL_HANDSHAKE;
dcb->fOutxCtsFlow = TRUE;
}
else
{
dcb->fRtsControl = RTS_CONTROL_DISABLE;
dcb->fOutxCtsFlow = FALSE;
}
LEAVE( "termios_to_DCB" );
return 0;
}
/*----------------------------------------------------------
DCB_to_serial_struct()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
int DCB_to_serial_struct( DCB *dcb, struct serial_struct *sstruct )
{
return( 0 );
}
/*----------------------------------------------------------
DCB_to_termios()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
void DCB_to_termios( DCB *dcb, struct termios *s_termios )
{
ENTER( "DCB_to_termios" );
s_termios->c_ispeed = CBR_to_B( dcb->BaudRate );
s_termios->c_ospeed = s_termios->c_ispeed;
s_termios->c_cflag |= s_termios->c_ispeed & CBAUD;
LEAVE( "DCB_to_termios" );
}
/*----------------------------------------------------------
show_DCB()
accept:
perform:
return:
exceptions:
win32api: None
comments:
----------------------------------------------------------*/
void show_DCB( myDCB )
{
#ifdef DEBUG_HOSED
char message[80];
sprintf( message, "DCBlength: %ld\n", myDCB.DCBlength );
report( message );
sprintf( "BaudRate: %ld\n", myDCB.BaudRate );
report( message );
if ( myDCB.fBinary )
report( "fBinary\n" );
if ( myDCB.fParity )
{
report( "fParity: " );
if ( myDCB.fErrorChar )
{
sprintf( message, "fErrorChar: %#x\n", myDCB.ErrorChar );
report( message );
}
else
{
report( "fErrorChar == false\n" );
}
}
if ( myDCB.fOutxCtsFlow )
report( "fOutxCtsFlow\n" );
if ( myDCB.fOutxDsrFlow )
report( "fOutxDsrFlow\n" );
if ( myDCB.fDtrControl & DTR_CONTROL_HANDSHAKE );
report( "DTR_CONTROL_HANDSHAKE\n" );
if ( myDCB.fDtrControl & DTR_CONTROL_ENABLE );
report( "DTR_CONTROL_ENABLE\n" );
if ( myDCB.fDtrControl & DTR_CONTROL_DISABLE );
report( "DTR_CONTROL_DISABLE\n" );
if ( myDCB.fDsrSensitivity )
report( "fDsrSensitivity\n" );
if ( myDCB.fTXContinueOnXoff )
report( "fTXContinueOnXoff\n" );
if ( myDCB.fOutX )
report( "fOutX\n" );
if ( myDCB.fInX )
report( "fInX\n" );
if ( myDCB.fNull )
report( "fNull\n" );
if ( myDCB.fRtsControl & RTS_CONTROL_TOGGLE )
report( "RTS_CONTROL_TOGGLE\n" );
if ( myDCB.fRtsControl == 0 )
report( "RTS_CONTROL_HANDSHAKE ( fRtsControl==0 )\n" );
if ( myDCB.fRtsControl & RTS_CONTROL_HANDSHAKE )
report( "RTS_CONTROL_HANDSHAKE\n" );
if ( myDCB.fRtsControl & RTS_CONTROL_ENABLE )
report( "RTS_CONTROL_ENABLE\n" );
if ( myDCB.fRtsControl & RTS_CONTROL_DISABLE )
report( "RTS_CONTROL_DISABLE\n" );
if ( myDCB.fAbortOnError )
report( "fAbortOnError\n" );
sprintf( message, "XonLim: %d\n", myDCB.XonLim );
report( message );
sprintf( message, "XoffLim: %d\n", myDCB.XoffLim );
report( message );
sprintf( message, "ByteSize: %d\n", myDCB.ByteSize );
report( message );
switch ( myDCB.Parity )
{
case EVENPARITY:
report( "EVENPARITY" );
break;
case MARKPARITY:
report( "MARKPARITY" );
break;
case NOPARITY:
report( "NOPARITY" );
break;
case ODDPARITY:
report( "ODDPARITY" );
break;
default:
sprintf( message,
"unknown Parity (%#x ):", myDCB.Parity );
report( message );
break;
}
report( "\n" );
switch( myDCB.StopBits )
{
case ONESTOPBIT:
report( "ONESTOPBIT" );
break;
case ONE5STOPBITS:
report( "ONE5STOPBITS" );
break;
case TWOSTOPBITS:
report( "TWOSTOPBITS" );
break;
default:
report( "unknown StopBits (%#x ):", myDCB.StopBits );
break;
}
report( "\n" );
sprintf( message, "XonChar: %#x\n", myDCB.XonChar );
report( message );
sprintf( message, "XoffChar: %#x\n", myDCB.XoffChar );
report( message );
sprintf( message, "EofChar: %#x\n", myDCB.EofChar );
report( message );
sprintf( message, "EvtChar: %#x\n", myDCB.EvtChar );
report( message );
report( "\n" );
#endif /* DEBUG_HOSED */
}
/*----------------------------------------------------------
tcgetattr()
accept:
perform:
return:
exceptions:
win32api: GetCommState(), GetCommTimeouts()
comments:
----------------------------------------------------------*/
int tcgetattr( int fd, struct termios *s_termios )
{
DCB myDCB;
COMMTIMEOUTS timeouts;
struct termios_list *index;
char message[80];
ENTER( "tcgetattr" );
if ( fd <= 0 )
return 0;
index = find_port( fd );
if ( !index )
{
LEAVE( "tcgetattr" );
return -1;
}
if ( !GetCommState( index->hComm, &myDCB ) )
{
sprintf( message, "GetCommState failed\n" );
report( message );
return -1;
}
memcpy( s_termios, index->ttyset, sizeof( struct termios ) );
show_DCB( myDCB );
/***** input mode flags (c_iflag ) ****/
/* parity check enable */
if ( myDCB.fParity )
{
s_termios->c_iflag |= INPCK;
s_termios->c_iflag &= ~IGNPAR;
} else {
s_termios->c_iflag &= ~INPCK;
s_termios->c_iflag |= IGNPAR;
}
/* FIXME: IGNBRK: ignore break */
/* FIXME: BRKINT: interrupt on break */
if ( myDCB.fOutX )
{
s_termios->c_iflag |= IXON;
}
else
{
/* IXON: output start/stop control */
s_termios->c_iflag &= ~IXON;
}
if ( myDCB.fInX )
{
s_termios->c_iflag |= IXOFF;
}
else
{
/* IXOFF: input start/stop control */
s_termios->c_iflag &= ~IXOFF;
}
if ( myDCB.fTXContinueOnXoff )
{
s_termios->c_iflag |= IXANY;
}
else
{
/* IXANY: any char restarts output */
s_termios->c_iflag &= ~IXANY;
}
/* FIXME: IMAXBEL: if input buffer full, send bell */
/***** control mode flags (c_cflag ) *****/
/* FIXME: CLOCAL: DONT send SIGHUP on modem disconnect */
/* FIXME: HUPCL: generate modem disconnect when all has closed or
exited */
/* CSTOPB two stop bits ( otherwise one) */
if ( myDCB.StopBits == TWOSTOPBITS )
{
s_termios->c_cflag |= CSTOPB;
} else if ( myDCB.StopBits == ONE5STOPBITS )
{
s_termios->c_cflag |= CSTOPB;
s_termios->c_cflag |= CS5;
} else if ( myDCB.StopBits == ONESTOPBIT )
{
s_termios->c_cflag &= ~CSTOPB;
}
/* PARENB enable parity bit */
s_termios->c_cflag &= ~( PARENB | PARODD | CMSPAR );
myDCB.fParity = 1;
if( myDCB.fParity )
{
report( "tcgetattr getting parity\n" );
s_termios->c_cflag |= PARENB;
if ( myDCB.Parity == MARKPARITY )
{
s_termios->c_cflag |= ( PARODD | CMSPAR );
}
else if ( myDCB.Parity == SPACEPARITY )
{
s_termios->c_cflag |= CMSPAR;
}
else if ( myDCB.Parity == ODDPARITY )
{
report( "ODDPARITY\n" );
s_termios->c_cflag |= PARODD;
}
else if ( myDCB.Parity == EVENPARITY )
{
report( "EVENPARITY\n" );
s_termios->c_cflag &= ~PARODD;
}
else if ( myDCB.Parity == NOPARITY )
{
s_termios->c_cflag &= ~(PARODD | CMSPAR | PARENB);
}
} else
{
s_termios->c_cflag &= ~PARENB;
}
/* CSIZE */
s_termios->c_cflag |= bytesize_to_termios( myDCB.ByteSize );
/* HARDWARE_FLOW_CONTROL: hardware flow control */
if (( myDCB.fOutxCtsFlow == TRUE ) ||
( myDCB.fRtsControl == RTS_CONTROL_HANDSHAKE))
{
s_termios->c_cflag |= HARDWARE_FLOW_CONTROL;
}
else
{
s_termios->c_cflag &= ~HARDWARE_FLOW_CONTROL;
}
/* MDMBUF: carrier based flow control of output */
/* CIGNORE: tcsetattr will ignore control modes & baudrate */
/***** NOT SUPPORTED: local mode flags (c_lflag) *****/
/* ICANON: canonical (not raw) mode */
/* ECHO: echo back to terminal */
/* ECHOE: echo erase */
/* ECHOPRT: hardcopy echo erase */
/* ECHOK: show KILL char */
/* ECHOKE: BSD ECHOK */
/* ECHONL: ICANON only: echo newline even with no ECHO */
/* ECHOCTL: if ECHO, then control-A are printed as '^A' */
/* ISIG: recognize INTR, QUIT & SUSP */
/* IEXTEN: implmentation defined */
/* NOFLSH: dont clear i/o queues on INTR, QUIT or SUSP */
/* TOSTOP: background process generate SIGTTOU */
/* ALTWERASE: alt-w erase distance */
/* FLUSHO: user DISCARD char */
/* NOKERNINFO: disable STATUS char */
/* PENDIN: input line needsd reprinting, set by REPRINT char */
/***** END - NOT SUPPORTED *****/
/***** control characters (c_cc[NCCS] ) *****/
if ( !GetCommTimeouts( index->hComm, &timeouts ) )
{
YACK();
report( "GetCommTimeouts\n" );
return -1;
}
s_termios->c_cc[VTIME] = timeouts.ReadTotalTimeoutConstant/100;
/*
handled in SerialImp.c?
s_termios->c_cc[VMIN] = ?
*/
s_termios->c_cc[VSTART] = myDCB.XonChar;
s_termios->c_cc[VSTOP] = myDCB.XoffChar;
s_termios->c_cc[VEOF] = myDCB.EofChar;
#ifdef DEBUG_VERBOSE
sprintf( message,
"tcgetattr: VTIME:%d, VMIN:%d\n", s_termios->c_cc[VTIME],
s_termios->c_cc[VMIN] );
report( message );
#endif /* DEBUG_VERBOSE */
/***** line discipline ( c_line ) ( == c_cc[33] ) *****/
DCB_to_termios( &myDCB, s_termios ); /* baudrate */
LEAVE( "tcgetattr" );
return 0;
}
/*
`TCSANOW'
Make the change immediately.
`TCSADRAIN'
Make the change after waiting until all queued output has
been written. You should usually use this option when
changing parameters that affect output.
`TCSAFLUSH'
This is like `TCSADRAIN', but also discards any queued input.
`TCSASOFT'
This is a flag bit that you can add to any of the above
alternatives. Its meaning is to inhibit alteration of the
state of the terminal hardware. It is a BSD extension; it is
only supported on BSD systems and the GNU system.
Using `TCSASOFT' is exactly the same as setting the `CIGNORE'
bit in the `c_cflag' member of the structure TERMIOS-P points
to. *Note Control Modes::, for a description of `CIGNORE'.
*/
/*----------------------------------------------------------
tcsetattr()
accept:
perform:
return:
exceptions:
win32api: GetCommState(), GetCommTimeouts(), SetCommState(),
SetCommTimeouts()
comments:
----------------------------------------------------------*/
int tcsetattr( int fd, int when, struct termios *s_termios )
{
int vtime;
DCB dcb;
COMMTIMEOUTS timeouts;
struct termios_list *index;
ENTER( "tcsetattr" );
if ( fd <= 0 )
return 0;
index = find_port( fd );
if ( !index )
{
LEAVE( "tcsetattr" );
return -1;
}
fflush( stdout );
if ( s_termios->c_lflag & ICANON )
{
report( "tcsetattr: no canonical mode support\n" );
/* and all other c_lflags too */
return -1;
}
if ( !GetCommState( index->hComm, &dcb ) )
{
YACK();
report( "tcsetattr:GetCommState\n" );
return -1;
}
if ( !GetCommTimeouts( index->hComm, &timeouts ) )
{
YACK();
report( "tcsetattr:GetCommTimeouts\n" );
return -1;
}
/*** control flags, c_cflag **/
if ( !( s_termios->c_cflag & CIGNORE ) )
{
dcb.fParity=1;
/* CIGNORE: ignore control modes and baudrate */
/* baudrate */
if ( termios_to_DCB( s_termios, &dcb ) < 0 ) return -1;
}
else
{
}
/*** input flags, c_iflag **/
/* This is wrong. It disables Parity FIXME
if( ( s_termios->c_iflag & INPCK ) && !( s_termios->c_iflag & IGNPAR ) )
{
dcb.fParity = TRUE;
} else
{
dcb.fParity = FALSE;
}
*/
/* not in win95?
Some years later...
eww.. FIXME This is used for changing the Parity
error character
I think this code is hosed. See VEOF below
Trent
*/
if ( s_termios->c_iflag & ISTRIP ) dcb.fBinary = FALSE;
/* ISTRIP: strip to seven bits */
else dcb.fBinary = TRUE;
/* FIXME: IGNBRK: ignore break */
/* FIXME: BRKINT: interrupt on break */
if ( s_termios->c_iflag & IXON )
{
dcb.fOutX = TRUE;
}
else
{
dcb.fOutX = FALSE;
}
if ( s_termios->c_iflag & IXOFF )
{
dcb.fInX = TRUE;
}
else
{
dcb.fInX = FALSE;
}
dcb.fTXContinueOnXoff = ( s_termios->c_iflag & IXANY ) ? TRUE : FALSE;
/* FIXME: IMAXBEL: if input buffer full, send bell */
/* no DTR control in termios? */
dcb.fDtrControl = DTR_CONTROL_DISABLE;
/* no DSR control in termios? */
dcb.fOutxDsrFlow = FALSE;
/* DONT ignore rx bytes when DSR is OFF */
dcb.fDsrSensitivity = FALSE;
dcb.XonChar = s_termios->c_cc[VSTART];
dcb.XoffChar = s_termios->c_cc[VSTOP];
dcb.XonLim = 0; /* ? */
dcb.XoffLim = 0; /* ? */
dcb.EofChar = s_termios->c_cc[VEOF];
if( dcb.EofChar != '\0' )
{
dcb.fBinary = 0;
}
else
{
dcb.fBinary = 1;
}
if ( EV_BREAK|EV_CTS|EV_DSR|EV_ERR|EV_RING | ( EV_RLSD & EV_RXFLAG ) )
dcb.EvtChar = '\n';
else
dcb.EvtChar = '\0';
if ( !SetCommState( index->hComm, &dcb ) )
{
report( "SetCommState error\n" );
YACK();
return -1;
}
#ifdef DEBUG_VERBOSE
sprintf( message, "VTIME:%d, VMIN:%d\n", s_termios->c_cc[VTIME],
s_termios->c_cc[VMIN] );
report( message );
#endif /* DEBUG_VERBOSE */
vtime = s_termios->c_cc[VTIME] * 100;
timeouts.ReadTotalTimeoutConstant = vtime;
timeouts.ReadIntervalTimeout = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
timeouts.WriteTotalTimeoutConstant = vtime;
timeouts.WriteTotalTimeoutMultiplier = 0;
/* max between bytes */
if ( s_termios->c_cc[VMIN] > 0 && vtime > 0 )
{
/* read blocks forever on VMIN chars */
} else if ( s_termios->c_cc[VMIN] == 0 && vtime == 0 )
{
/* read returns immediately */
timeouts.ReadIntervalTimeout = MAXDWORD;
timeouts.ReadTotalTimeoutConstant = 0;
timeouts.ReadTotalTimeoutMultiplier = 0;
}
#ifdef DEBUG_VERBOSE
sprintf( message, "ReadIntervalTimeout=%ld\n",
timeouts.ReadIntervalTimeout );
report( message );
sprintf( message, "c_cc[VTIME] = %d, c_cc[VMIN] = %d\n",
s_termios->c_cc[VTIME], s_termios->c_cc[VMIN] );
report( message );
sprintf( message, "ReadTotalTimeoutConstant: %ld\n",
timeouts.ReadTotalTimeoutConstant );
report( message );
sprintf( message, "ReadIntervalTimeout : %ld\n",
timeouts.ReadIntervalTimeout );
report( message );
sprintf( message, "ReadTotalTimeoutMultiplier: %ld\n",
timeouts.ReadTotalTimeoutMultiplier );
report( message );
#endif /* DEBUG_VERBOSE */
if ( !SetCommTimeouts( index->hComm, &timeouts ) )
{
YACK();
report( "SetCommTimeouts\n" );
return -1;
}
memcpy( index->ttyset, s_termios, sizeof( struct termios ) );
LEAVE( "tcsetattr" );
return 0;
}
/*----------------------------------------------------------
tcsendbreak()
accept:
perform:
return:
exceptions:
win32api: None
comments:
break for duration*0.25 seconds or
0.25 seconds if duration = 0.
----------------------------------------------------------*/
int tcsendbreak( int fd, int duration )
{
struct termios_list *index;
COMSTAT Stat;
ENTER( "tcsendbreak" );
index = find_port( fd );
if ( !index )
{
LEAVE( "tcdrain" );
return -1;
}
if ( duration <= 0 ) duration = 1;
if( !SetCommBreak( index->hComm ) )
ClearErrors( index, &Stat );
/* 0.25 seconds == 250000 usec */
usleep( duration * 250000 );
if( !ClearCommBreak( index->hComm ) )
ClearErrors( index, &Stat );
LEAVE( "tcsendbreak" );
return 1;
}
/*----------------------------------------------------------
tcdrain()
accept: file descriptor
perform: wait for ouput to be written.
return: 0 on success, -1 otherwise
exceptions: None
win32api: FlushFileBuffers
comments:
----------------------------------------------------------*/
int tcdrain ( int fd )
{
struct termios_list *index;
char message[80];
int old_flag;
ENTER( "tcdrain" );
index = find_port( fd );
if ( !index )
{
LEAVE( "tcdrain" );
return -1;
}
old_flag = index->event_flag;
/*
index->event_flag &= ~EV_TXEMPTY;
SetCommMask( index->hComm, index->event_flag );
index->tx_happened = 1;
*/
if ( !FlushFileBuffers( index->hComm ) )
{
/* FIXME Need to figure out what the various errors are in
windows. YACK() should report them and we can
handle them as we find them
Something funky is happening on NT. GetLastError =
0.
*/
sprintf( message, "FlushFileBuffers() %i\n",
(int) GetLastError() );
report( message );
if( GetLastError() == 0 )
{
set_errno( 0 );
return(0);
}
set_errno( EAGAIN );
YACK();
LEAVE( "tcdrain" );
return -1;
}
/*
sprintf( message, "FlushFileBuffers() %i\n",
(int) GetLastError() );
report( message );
*/
LEAVE( "tcdrain success" );
index->event_flag |= EV_TXEMPTY;
SetCommMask( index->hComm, index->event_flag );
index->event_flag = old_flag;
/*
index->tx_happened = 1;
*/
return 0;
}
/*----------------------------------------------------------
tcflush()
accept: file descriptor, queue_selector
perform: discard data not transmitted or read
TCIFLUSH: flush data not read
TCOFLUSH: flush data not transmitted
TCIOFLUSH: flush both
return: 0 on success, -1 on error
exceptions: none
win32api: PurgeComm
comments:
----------------------------------------------------------*/
int tcflush( int fd, int queue_selector )
{
struct termios_list *index;
int old_flag;
index = find_port( fd );
if( !index)
{
LEAVE( "tclflush" );
return(-1);
}
old_flag = index->event_flag;
/*
index->event_flag &= ~EV_TXEMPTY;
SetCommMask( index->hComm, index->event_flag );
index->tx_happened = 1;
*/
ENTER( "tcflush" );
if ( !index )
{
LEAVE( "tcflush" );
return -1;
}
index->tx_happened = 1;
switch( queue_selector )
{
case TCIFLUSH:
if ( !PurgeComm( index->hComm, PURGE_RXABORT ) )
{
goto fail;
}
break;
case TCOFLUSH:
if ( !PurgeComm( index->hComm, PURGE_TXABORT ) )
{
goto fail;
}
break;
case TCIOFLUSH:
if ( !PurgeComm( index->hComm, PURGE_TXABORT ) )
{
goto fail;
}
if ( !PurgeComm( index->hComm, PURGE_RXABORT ) )
{
goto fail;
}
break;
default:
/*
set_errno( ENOTSUP );
*/
report( "tcflush: Unknown queue_selector\n" );
LEAVE( "tcflush" );
return -1;
}
index->event_flag |= EV_TXEMPTY;
SetCommMask( index->hComm, index->event_flag );
index->event_flag = old_flag;
index->tx_happened = 1;
LEAVE( "tcflush" );
return( 0 );
/* FIXME Need to figure out what the various errors are in
windows. YACK() should report them and we can
handle them as we find them
*/
fail:
LEAVE( "tcflush" );
set_errno( EAGAIN );
YACK();
return -1;
}
/*----------------------------------------------------------
tcflow()
accept:
perform:
return:
exceptions:
win32api: None
comments: FIXME
----------------------------------------------------------*/
int tcflow( int fd, int action )
{
ENTER( "tcflow" );
switch ( action )
{
/* Suspend transmission of output */
case TCOOFF: break;
/* Restart transmission of output */
case TCOON: break;
/* Transmit a STOP character */
case TCIOFF: break;
/* Transmit a START character */
case TCION: break;
default: return -1;
}
LEAVE( "tcflow" );
return 1;
}
/*----------------------------------------------------------
fstat()
accept:
perform:
return:
exceptions:
win32api:
comments: this is just to keep the eventLoop happy.
----------------------------------------------------------*/
int fstat( int fd, ... )
{
return( 0 );
}
/*----------------------------------------------------------
ioctl()
accept:
perform:
return:
exceptions:
win32api: GetCommError(), GetCommModemStatus, EscapeCommFunction()
comments: FIXME
the DCB struct is:
typedef struct _DCB
{
unsigned long DCBlength, BaudRate, fBinary:1, fParity:1;
unsigned long fOutxCtsFlow:1, fOutxDsrFlow:1, fDtrControl:2;
unsigned long fDsrSensitivity:1, fTXContinueOnXoff:1;
unsigned long fOutX:1, fInX:1, fErrorChar:1, fNull:1;
unsigned long fRtsControl:2, fAbortOnError:1, fDummy2:17;
WORD wReserved, XonLim, XoffLim;
BYTE ByteSize, Parity, StopBits;
char XonChar, XoffChar, ErrorChar, EofChar, EvtChar;
WORD wReserved1;
} DCB;
----------------------------------------------------------*/
int ioctl( int fd, int request, ... )
{
unsigned long dwStatus = 0;
va_list ap;
int *arg, ret, result, old_flag;
char message[80];
#ifdef TIOCGSERIAL
DCB *dcb;
struct serial_struct *sstruct;
#endif /* TIOCGSERIAL */
COMSTAT Stat;
struct termios_list *index;
struct async_struct *astruct;
struct serial_multiport_struct *mstruct;
#ifdef TIOCGICOUNT
struct serial_icounter_struct *sistruct;
#endif /* TIOCGICOUNT */
ENTER( "ioctl" );
if ( fd <= 0 )
return 0;
index = find_port( fd );
if ( !index )
{
LEAVE( "ioctl" );
return -1;
}
va_start( ap, request );
ret = ClearErrors( index, &Stat );
if (ret == 0)
{
set_errno( EBADFD );
YACK();
report( "ClearError Failed! ernno EBADFD" );
arg = va_arg( ap, int * );
va_end( ap );
return -1;
}
switch( request )
{
case TCSBRK:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
case TCSBRKP:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCGSOFTCAR:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCSSOFTCAR:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCMGET:
arg = va_arg( ap, int * );
/* DORITOS */
if ( !GetCommModemStatus( index->hComm, &dwStatus ) )
report_error( "GetCommMOdemStatus failed!\n" );
if ( dwStatus & MS_RLSD_ON ) *arg |= TIOCM_CAR;
else *arg &= ~TIOCM_CAR;
if ( dwStatus & MS_RING_ON ) *arg |= TIOCM_RNG;
else *arg &= ~TIOCM_RNG;
if ( dwStatus & MS_DSR_ON ) *arg |= TIOCM_DSR;
else *arg &= ~TIOCM_DSR;
if ( dwStatus & MS_CTS_ON ) *arg |= TIOCM_CTS;
else *arg &= ~TIOCM_CTS;
/* I'm not seeing a way to read the MSR directly
we store the state using TIOCM_*
Trent
*/
if ( index->MSR & TIOCM_DTR )
*arg |= TIOCM_DTR;
else *arg &= ~TIOCM_DTR;
if ( index->MSR & TIOCM_RTS )
*arg |= TIOCM_RTS;
else *arg &= ~TIOCM_RTS;
/*
TIOCM_LE
TIOCM_ST
TIOCM_SR
*/
va_end( ap );
return( 0 );
/* TIOCMIS, TIOCMBIC and TIOCMSET all do the same thing... */
case TIOCMBIS:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCMBIC:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCMSET:
arg = va_arg( ap, int * );
if (( *arg & TIOCM_DTR) == (index->MSR & TIOCM_DTR) )
{
report( "DTR is unchanged\n" );
}
sprintf(message, "DTR %i %i\n", *arg&TIOCM_DTR, index->MSR & TIOCM_DTR );
report( message );
if ( *arg & TIOCM_DTR )
{
index->MSR |= TIOCM_DTR;
}
else
{
index->MSR &= ~TIOCM_DTR;
}
if ( EscapeCommFunction( index->hComm,
( *arg & TIOCM_DTR ) ? SETDTR :
CLRDTR ) )
report( "EscapeCommFunction: True\n" );
else
report( "EscapeCommFunction: False\n" );
if ( (*arg & TIOCM_RTS) == ( index->MSR & TIOCM_RTS) )
{
report( "RTS is unchanged\n" );
}
sprintf( message, "RTS %i %i\n", *arg&TIOCM_RTS, index->MSR & TIOCM_RTS );
report( message );
if ( *arg & TIOCM_RTS )
{
index->MSR |= TIOCM_RTS;
result &= SETRTS;
}
else
{
index->MSR &= ~TIOCM_RTS;
result &= CLRRTS;
}
if( EscapeCommFunction( index->hComm,
( *arg & TIOCM_RTS ) ? SETRTS : CLRRTS ) )
report( "EscapeCommFunction: True\n" );
else
report( "EscapeCommFunction: False\n" );
break;
#ifdef TIOCGSERIAL
case TIOCGSERIAL:
report( "TIOCGSERIAL\n" );
dcb = malloc( sizeof( DCB ) );
if( !dcb )
{
va_end( ap );
return -1;
}
memset( dcb, 0, sizeof( DCB ) );
GetCommState( index->hComm, dcb );
sstruct = va_arg( ap, struct serial_struct * );
if ( DCB_to_serial_struct( dcb, sstruct ) < 0 )
{
va_end( ap );
return -1;
}
index->sstruct = sstruct;
report( "TIOCGSERIAL\n" );
free(dcb);
break;
#endif /* TIOCGSERIAL */
#ifdef TIOCSSERIAL
case TIOCSSERIAL:
report( "TIOCSSERIAL\n" );
dcb = malloc( sizeof( DCB ) );
if( !dcb )
{
va_end( ap );
return -1;
}
memset( dcb, 0, sizeof( DCB ) );
GetCommState( index->hComm, dcb );
index->sstruct = va_arg( ap, struct serial_struct * );
report( "TIOCSSERIAL\n" );
free(dcb);
break;
#endif /* TIOCSSERIAL */
case TIOCSERCONFIG:
case TIOCSERGETLSR:
arg = va_arg( ap, int * );
/*
do {
wait = WaitForSingleObject( index->sol.hEvent, 5000 );
} while ( wait == WAIT_TIMEOUT );
*/
ret = ClearErrors( index, &Stat );
if ( ret == 0 )
{
/* FIXME ? */
set_errno( EBADFD );
YACK();
report( "TIOCSERGETLSR EBADFD" );
va_end( ap );
return -1;
}
if ( (int ) Stat.cbOutQue == 0 )
{
/* output is empty */
if( index->tx_happened == 1 )
{
old_flag = index->event_flag;
index->event_flag &= ~EV_TXEMPTY;
SetCommMask( index->hComm,
index->event_flag );
index->event_flag = old_flag;
*arg = 1;
index->tx_happened = 0;
report( "ioctl: ouput empty\n" );
}
else
{
*arg = 0;
}
ret = 0;
}
else
{
/* still data out there */
*arg = 0;
ret = 0;
}
va_end( ap );
return(0);
break;
case TIOCSERGSTRUCT:
astruct = va_arg( ap, struct async_struct * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCSERGETMULTI:
mstruct = va_arg( ap, struct serial_multiport_struct * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCSERSETMULTI:
mstruct = va_arg( ap, struct serial_multiport_struct * );
va_end( ap );
return -ENOIOCTLCMD;
case TIOCMIWAIT:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
/*
On linux this fills a struct with all the line info
(data available, bytes sent, ...
*/
#ifdef TIOCGICOUNT
case TIOCGICOUNT:
sistruct= va_arg( ap, struct serial_icounter_struct * );
ret = ClearErrors( index, &Stat );
if ( ret == 0 )
{
/* FIXME ? */
report( "TIOCGICOUNT failed\n" );
set_errno( EBADFD );
va_end( ap );
return -1;
}
if( sistruct->frame != index->sis->frame )
{
sistruct->frame = index->sis->frame;
/*
printf( "---------------frame = %i\n", sistruct->frame++ );
*/
}
if( sistruct->overrun != index->sis->overrun )
{
/*
printf( "---------------overrun\n" );
*/
sistruct->overrun = index->sis->overrun;
/* ErrCode &= ~CE_OVERRUN; */
}
if( sistruct->parity != index->sis->parity )
{
/*
printf( "---------------parity\n" );
*/
sistruct->parity = index->sis->parity;
}
if( sistruct->brk != index->sis->brk )
{
/*
printf( "---------------brk\n" );
*/
sistruct->brk = index->sis->brk;
}
va_end( ap );
return 0;
/* abolete ioctls */
#endif /* TIOCGICOUNT */
case TIOCSERGWILD:
case TIOCSERSWILD:
report( "TIOCSER[GS]WILD absolete\n" );
va_end( ap );
return 0;
/* number of bytes available for reading */
case FIONREAD:
arg = va_arg( ap, int * );
ret = ClearErrors( index, &Stat );
if ( ret == 0 )
{
/* FIXME ? */
report( "FIONREAD failed\n" );
set_errno( EBADFD );
va_end( ap );
return -1;
}
*arg = ( int ) Stat.cbInQue;
#ifdef DEBUG_VERBOSE
sprintf( message, "FIONREAD: %i bytes available\n",
(int) Stat.cbInQue );
report( message );
if( *arg )
{
sprintf( message, "FIONREAD: %i\n", *arg );
report( message );
}
#endif /* DEBUG_VERBOSE */
ret = 0;
break;
/* pending bytes to be sent */
case TIOCOUTQ:
arg = va_arg( ap, int * );
va_end( ap );
return -ENOIOCTLCMD;
default:
sprintf( message,
"FIXME: ioctl: unknown request: %#x\n",
request );
report( message );
va_end( ap );
return -ENOIOCTLCMD;
}
va_end( ap );
LEAVE( "ioctl" );
return 0;
}
/*----------------------------------------------------------
fcntl()
accept:
perform:
return:
exceptions:
win32api: None
comments: FIXME
----------------------------------------------------------*/
int fcntl( int fd, int command, ... )
{
int arg, ret = 0;
va_list ap;
struct termios_list *index;
char message[80];
ENTER( "fcntl" );
if ( fd <= 0 )
return 0;
index = find_port( fd );
if ( !index )
{
LEAVE( "fcntl" );
return -1;
}
va_start( ap, command );
arg = va_arg( ap, int );
switch ( command )
{
case F_SETOWN: /* set ownership of fd */
break;
case F_SETFL: /* set operating flags */
#ifdef DEBUG
sprintf( message, "F_SETFL fd=%d flags=%d\n", fd, arg );
report( message );
#endif
index->open_flags = arg;
break;
case F_GETFL: /* get operating flags */
ret = index->open_flags;
break;
default:
sprintf( message, "unknown fcntl command %#x\n", command );
report( message );
break;
}
va_end( ap );
LEAVE( "fcntl" );
return ret;
}
/*----------------------------------------------------------
termios_interrupt_event_loop()
accept:
perform:
return: let Serial_select break out so the thread can die
exceptions:
win32api:
comments:
----------------------------------------------------------*/
void termios_interrupt_event_loop( int fd, int flag )
{
struct termios_list * index = find_port( fd );
if ( !index )
{
LEAVE( "termios_interrupt_event_loop" );
return;
}
/*
index->event_flag = 0;
TRENT SetCommMask( index->hComm, index->event_flag );
usleep(2000);
tcdrain( index->fd );
SetEvent( index->sol.hEvent );
*/
index->interrupt = flag;
return;
}
/*----------------------------------------------------------
Serial_select()
accept:
perform:
return: number of fd's changed on success or -1 on error.
exceptions:
win32api: SetCommMask(), GetCommEvent(), WaitSingleObject()
comments:
----------------------------------------------------------*/
#ifndef __LCC__
int serial_select( int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout )
{
unsigned long dwCommEvent, wait = WAIT_TIMEOUT;
int fd = n-1;
struct termios_list *index;
char message[80];
COMSTAT Stat;
int ret;
ENTER( "serial_select" );
if ( fd <= 0 )
{
/* Baby did a bad baad thing */
goto fail;
}
index = find_port( fd );
if ( !index || !index->event_flag )
{
/* still setting up the port? hold off for a Sec so
things can fire up
this does happen. loops ~twice on a 350 Mzh with
usleep(1000000)
*/
usleep(10000);
return(0);
}
ResetEvent( index->wol.hEvent );
ResetEvent( index->sol.hEvent );
ResetEvent( index->rol.hEvent );
ret = ClearErrors( index, &Stat );
if (ret == 0) goto fail;
while ( wait == WAIT_TIMEOUT && index->sol.hEvent )
{
if( index->interrupt == 1 )
{
goto fail;
}
SetCommMask( index->hComm, index->event_flag );
ClearErrors( index, &Stat );
if ( !WaitCommEvent( index->hComm, &dwCommEvent,
&index->sol ) )
{
/* WaitCommEvent failed probably overlapped though */
if ( GetLastError() != ERROR_IO_PENDING )
{
ClearErrors( index, &Stat );
goto fail;
}
/* thought so... */
}
/* could use the select timeout here but it should not
be needed
*/
ClearErrors( index, &Stat );
wait = WaitForSingleObject( index->sol.hEvent, 100 );
switch ( wait )
{
case WAIT_OBJECT_0:
goto end;
case WAIT_TIMEOUT:
goto timeout;
case WAIT_ABANDONED:
default:
goto fail;
}
}
end:
/* You may want to chop this out for lower latency */
usleep(1000);
LEAVE( "serial_select" );
return( 1 );
timeout:
LEAVE( "serial_select" );
return( 0 );
fail:
YACK();
sprintf( message, "< select called error %i\n", n );
report( message );
errno = EBADFD;
LEAVE( "serial_select" );
return( 1 );
}
#ifdef asdf
int serial_select( int n, fd_set *readfds, fd_set *writefds,
fd_set *exceptfds, struct timeval *timeout )
{
unsigned long nBytes, dwCommEvent, wait = WAIT_TIMEOUT;
int fd = n-1;
struct termios_list *index;
char message[80];
ENTER( "serial_select" );
if ( fd <= 0 )
{
usleep(1000);
return 1;
}
index = find_port( fd );
if ( !index )
{
LEAVE( "serial_select" );
return -1;
}
if( index->interrupt == 1 )
{
goto end;
}
while(!index->event_flag )
{
usleep(1000);
return -1;
}
while ( wait == WAIT_TIMEOUT && index->sol.hEvent )
{
if( index->interrupt == 1 )
{
goto end;
}
if( !index->sol.hEvent )
{
return 1;
}
if ( !WaitCommEvent( index->hComm, &dwCommEvent,
&index->sol ) )
{
/* WaitCommEvent failed */
if( index->interrupt == 1 )
{
goto end;
}
if ( GetLastError() != ERROR_IO_PENDING )
{
sprintf( message, "WaitCommEvent filename = %s\n", index->filename);
report( message );
return(1);
/*
goto fail;
*/
}
return(1);
}
if( index->interrupt == 1 )
{
goto end;
}
wait = WaitForSingleObject( index->sol.hEvent, 1000 );
switch ( wait )
{
case WAIT_OBJECT_0:
if( index->interrupt == 1 )
{
goto end;
}
if( !index->sol.hEvent ) return(1);
if (!GetOverlappedResult( index->hComm,
&index->sol, &nBytes, TRUE ))
{
goto end;
}
else if( index->tx_happened == 1 )
{
goto end;
}
else
goto end;
break;
case WAIT_TIMEOUT:
default:
return(1); /* WaitFor error */
}
}
end:
LEAVE( "serial_select" );
return( 1 );
#ifdef asdf
/* FIXME this needs to be cleaned up... */
fail:
sprintf( message, "< select called error %i\n", n );
YACK();
report( message );
set_errno( EBADFD );
LEAVE( "serial_select" );
return( 1 );
#endif /* asdf */
}
#endif /* asdf */
#endif /* __LCC__ */
/*----------------------------------------------------------
termiosSetParityError()
accept: fd The device opened
perform: Get the Parity Error Char
return: the Parity Error Char
exceptions: none
win32api: GetCommState()
comments: No idea how to do this in Unix (handle in read?)
----------------------------------------------------------*/
int termiosGetParityErrorChar( int fd )
{
struct termios_list *index;
DCB dcb;
ENTER( "termiosGetParityErrorChar" );
index = find_port( fd );
if( !index )
{
LEAVE( "termiosGetParityErrorChar" );
return(-1);
}
GetCommState( index->hComm, &dcb );
LEAVE( "termiosGetParityErrorChar" );
return( dcb.ErrorChar );
}
/*----------------------------------------------------------
termiosSetParityError()
accept: fd The device opened, value the new Parity Error Char
perform: Set the Parity Error Char
return: void
exceptions: none
win32api: GetCommState(), SetCommState()
comments: No idea how to do this in Unix (handle in read?)
----------------------------------------------------------*/
void termiosSetParityError( int fd, char value )
{
DCB dcb;
struct termios_list *index;
ENTER( "termiosGetParityErrorChar" );
index = find_port( fd );
if ( !index )
{
LEAVE( "termiosSetParityError" );
return;
}
GetCommState( index->hComm, &dcb );
dcb.ErrorChar = value;
SetCommState( index->hComm, &dcb );
LEAVE( "termiosGetParityErrorChar" );
}
/*----------------------- END OF LIBRARY -----------------*/
#ifdef PLAYING_AROUND
static inline int inportb( int index )
{
unsigned char value;
__asm__ volatile ( "inb %1,%0"
: "=a" (value)
: "d" ((unsigned short)index) );
return value;
}
static inline void outportb(unsigned char val, unsigned short int index)
{
__asm__ volatile (
"outb %0,%1\n"
:
: "a" (val), "d" (index)
);
}
#endif /* PLAYING_AROUND */
./rxtx-2.2pre2/src/I2CImp.h 0000644 0001750 0001750 00000012455 10614033755 015244 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
/* gnu.io.SerialPort constants */
#ifndef WIN32
#define DATABITS_5 5
#define DATABITS_6 6
#define DATABITS_7 7
#define DATABITS_8 8
#define PARITY_NONE 0
#define PARITY_ODD 1
#define PARITY_EVEN 2
#define PARITY_MARK 3
#define PARITY_SPACE 4
#endif
#define STOPBITS_1 1
#define STOPBITS_2 2
#define FLOWCONTROL_NONE 0
#define FLOWCONTROL_RTSCTS_IN 1
#define FLOWCONTROL_RTSCTS_OUT 2
#define FLOWCONTROL_XONXOFF_IN 4
#define FLOWCONTROL_XONXOFF_OUT 8
/* gnu.io.SerialPortEvent constants */
#define SPE_DATA_AVAILABLE 1
#define SPE_OUTPUT_BUFFER_EMPTY 2
#define SPE_CTS 3
#define SPE_DSR 4
#define SPE_RI 5
#define SPE_CD 6
#define SPE_OE 7
#define SPE_PE 8
#define SPE_FE 9
#define SPE_BI 10
/* java exception class names */
#define UNSUPPORTED_COMM_OPERATION "gnu/io/UnsupportedCommOperationException"
#define ARRAY_INDEX_OUT_OF_BOUNDS "java/lang/ArrayIndexOutOfBoundsException"
#define OUT_OF_MEMORY "java/lang/OutOfMemoryError"
#define IO_EXCEPTION "java/io/IOException"
/*
Flow Control defines inspired by reading how mgetty by Gert Doering does it
*/
#ifdef CRTSCTS
#define HARDWARE_FLOW_CONTROL CRTSCTS
#else
# ifdef CCTS_OFLOW
# define HARDWARE_FLOW_CONTROL CCTS_OFLOW|CRST_IFLOW
# else
# ifdef RTSFLOW
# define HARDWARE_FLOW_CONTROL RTSFLOW|CTSFLOW
# else
# ifdef CRTSFL
# define HARDWARE_FLOW_CONTROL CRTSFL
# else
# ifdef CTSCD
# define HARDWARE_FLOW_CONTROL CTSCD
# else
# define HARDWARE_FLOW_CONTROL 0
# endif
# endif
# endif
# endif
#endif
/* PROTOTYPES */
int translate_speed( JNIEnv *, jint );
int translate_data_bits( JNIEnv *, int *, jint );
int translate_stop_bits( JNIEnv *, int *, jint );
int translate_parity( JNIEnv *, int *, jint );
int read_byte_array( int, unsigned char *, int, int );
int get_java_var( JNIEnv *, jobject, char *, char * );
int get_java_fd( JNIEnv *, jobject );
void send_modem_events( JNIEnv *, jobject, jmethodID, int, int, int );
void throw_java_exception( JNIEnv *, char *, char *, char * );
./rxtx-2.2pre2/src/SerialImp.cpp 0000644 0001750 0001750 00000156372 10614033756 016451 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2007 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
#include "config.h"
#include "gnu_io_RXTXPort.h"
#include
#include
#include
//#include // !!!
//#include // !!!
#include // !!!
//#include
//#include // !!!
#include
#include
#include
#include
#ifndef WIN32
#include
#include
#include
#ifdef HAVE_TERMIOS_H
# include
#endif
#ifdef HAVE_SYS_SIGNAL_H
# include
#endif
#else
# include
#endif
#include
#include
#include
#ifdef HAVE_SYS_FCNTL_H
# include
#endif
#ifdef HAVE_SYS_FILE_H
# include
#endif
extern int errno;
#include "SerialImp.h"
/* #define DEBUG */
/* this is so diff will not generate noise when merging 1.4 and 1.5 changes
* It will eventually be removed.
* */
#define RXTXPort(foo) Java_gnu_io_RXTXPort_ ## foo
#define RXTXCommDriver(foo) Java_gnu_io_RXTXCommDriver_ ## foo
//#define MAX_PORT_NUM 65;
BSerialPort *PortArray[65]; // !!!
BSerialPort *port; // !!!
FILE *fp; // !!!
/*----------------------------------------------------------
RXTXPort.Initialize
accept: none
perform: Initialize the native library
return: none
exceptions: none
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(Initialize)(
JNIEnv *env,
jclass jclazz
)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.Initialize\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
#ifndef WIN32
#ifndef __BEOS__
#ifdef DEBUG
struct utsname name;
#endif
/* This bit of code checks to see if there is a signal handler installed
for SIGIO, and installs SIG_IGN if there is not. This is necessary
for the native threads jdk, but we don't want to do it with green
threads, because it slows things down. Go figure. */
/* POSIX signal handling functions */
#if !defined(__FreeBSD___)
struct sigaction handler;
sigaction( SIGIO, NULL, &handler );
if( !handler.sa_handler ) signal( SIGIO, SIG_IGN );
#endif /* !__FreeBSD__ */
#ifdef DEBUG
/* Lets let people who upgraded kernels know they may have problems */
if (uname (&name) == -1)
{
report("RXTX WARNING: cannot get system name\n");
return;
}
if(!strcmp(name.release,UTS_RELEASE))
{
fprintf(stderr, LINUX_KERNEL_VERSION_ERROR, UTS_RELEASE,
name.release);
getchar();
}
#endif /* DEBUG */
#endif /* __BEOS__ */
#endif /* WIN32 */
}
/*----------------------------------------------------------
RXTXPort.open
accept: The device to open. ie "/dev/ttyS0"
perform: open the device, set the termios struct to sane settings and
return the filedescriptor
return: fd
exceptions: IOException
comments: Very often people complain about not being able to get past
this function and it turns out to be permissions on the
device file or bios has the device disabled.
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(open)(
JNIEnv *env,
jobject jobj,
jstring jstr
)
{
int i = 1;
int fd = -1;
for (i = 1; i < 65; i++) // we start at 1 because fd = 0 is invalid to RXTXPort.java
{
if (!PortArray[i]) // Here, we are finding the first non-null index into PortArray.
{
fd = i; // fd is no longer a "file descriptor" but an index
// into an array of pointers to BSerialPort Objects.
break; // got a good one.
}
}
if (fd < 1) // if no good fd found, throw exception.
{
throw_java_exception( env, PORT_IN_USE_EXCEPTION, "open",
strerror( errno ) );
return -1;
}
// retrieve the serial port filename, strip off extra goo to leave just serial1, serial2, etc.
const char *filename = env->GetStringUTFChars(jstr, 0); // retrieve filename from JAVAland.
char devName[B_OS_NAME_LENGTH];
const char *newDevName = strstr(filename, "serial");
strncpy(&devName[0], &newDevName[0], (strlen(newDevName) + 1));
// Instantiate the BSerialPort associated with devName (serial1, serial2, etc).
PortArray[fd] = new BSerialPort();
// Actually open serial port here:
//do
//{
status_t results = PortArray[fd]->Open(&devName[0]);
//} while (errno==EINTR);
if (results < 1) // throw exception if can't open port.
{
throw_java_exception( env, PORT_IN_USE_EXCEPTION, "open",
strerror( errno ) );
return -1;
}
// Set initial port parameters
PortArray[fd]->SetFlowControl(0);
PortArray[fd]->SetBlocking(false);
if (PortArray[fd]->SetDataRate(B_9600_BPS) != B_OK)
{
throw_java_exception( env, PORT_IN_USE_EXCEPTION, "open",
strerror( errno ) );
return -1;
}
env->ReleaseStringUTFChars(jstr, NULL); // releasing filename for JAVAland.
// Open Debug Error log file
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "inside RXTXPort.Open fd for BSerialPort is %i.\n",fd);
fprintf(fp, "inside RXTXPort.Open devName for BSerialPort is %s.\n", devName);
fprintf(fp, "inside RXTXPort.Open results of open is %i.\n", (int)results);
fclose(fp);
// Close Log File
return (jint)fd; // returning the "fd" (the index into array of BSerialPort pointers).
}
/*----------------------------------------------------------
RXTXPort.nativeClose
accept: none
perform: get the fd from the java end and close it
return: none
exceptions: none
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(nativeClose)( JNIEnv *env,
jobject jobj )
{
int fd = get_java_var( env, jobj,"fd","I" );
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside nativeClose\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
delete PortArray[fd];
return;
}
/*----------------------------------------------------------
RXTXPort.nativeSetSerialPortParams
accept: speed, data bits, stop bits, parity
perform: set the serial port parameters
return: void
exceptions: UnsupportedCommOperationException
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(nativeSetSerialPortParams)(
JNIEnv *env, jobject jobj, jint speed, jint dataBits, jint stopBits,
jint parity )
{
int fd = get_java_var( env, jobj,"fd","I" );
data_rate cspeed = translate_speed( env, speed );
data_bits numofdatabits;
stop_bits numofstopbits;
parity_mode whichparitymode;
if( !cspeed ) return;
if( !translate_data_bits( env, &(numofdatabits), dataBits ) ) return;
if( !translate_stop_bits( env, &(numofstopbits), stopBits ) ) return;
if( !translate_parity( env, &(whichparitymode), parity ) ) return;
PortArray[fd]->SetDataBits(numofdatabits);
PortArray[fd]->SetStopBits(numofstopbits);
PortArray[fd]->SetParityMode(whichparitymode);
if (PortArray[fd]->SetDataRate(cspeed) != B_OK)
{
throw_java_exception( env, UNSUPPORTED_COMM_OPERATION,
"nativeSetSerialPortParams", strerror( errno ) );
}
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.nativeSetSerialPortParams\n");
fprintf(fp, "speed = %i\n", speed);
fprintf(fp, "fd = %i\n", fd);
fprintf(fp, "RXTXPort:nativeSetSerialPortParams right before return\n");
fclose(fp);
////////////////// Close Log File /////////////////////
return;
}
/*----------------------------------------------------------
translate_speed
accept: speed in bits-per-second
perform: convert bits-per-second to a speed_t constant
return: speed_t constant
exceptions: UnsupportedCommOperationException
comments: Only the lowest level code should know about
the magic constants.
----------------------------------------------------------*/
data_rate translate_speed( JNIEnv *env, jint speed )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside translate_speed\n");
fclose(fp);
////////////////// Close Log File ////////////////////
switch( speed ) {
case 0: return B_0_BPS;
case 50: return B_50_BPS;
case 75: return B_75_BPS;
case 110: return B_110_BPS;
case 134: return B_134_BPS;
case 150: return B_150_BPS;
case 200: return B_200_BPS;
case 300: return B_300_BPS;
case 600: return B_600_BPS;
case 1200: return B_1200_BPS;
case 1800: return B_1800_BPS;
case 2400: return B_2400_BPS;
case 4800: return B_4800_BPS;
case 9600: return B_9600_BPS;
case 19200: return B_19200_BPS;
case 38400: return B_38400_BPS;
case 57600: return B_57600_BPS;
case 115200: return B_115200_BPS;
case 230400: return B_230400_BPS;
case 31250: return B_31250_BPS; // this one was in BeOS's SerialPort.h, but I am
// skeptical that this setting will work...
}
throw_java_exception( env, UNSUPPORTED_COMM_OPERATION,
"translate_speed", "speed" );
return B_0_BPS;
}
/*----------------------------------------------------------
translate_data_bits
accept: gnu.io.SerialPort.DATABITS_* constant
perform: convert to BeOS eqivalent bits
return: 1 if successful
0 if an exception is thrown
exceptions: UnsupportedCommOperationException
----------------------------------------------------------*/
int translate_data_bits( JNIEnv *env, data_bits *dbits, jint dataBits )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside translate_data_bits\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
switch( dataBits )
{
case DATABITS_7:
(*dbits) = B_DATA_BITS_7;
return 1;
case DATABITS_8:
(*dbits) = B_DATA_BITS_8;
return 1;
}
throw_java_exception( env, UNSUPPORTED_COMM_OPERATION,
"translate_data_bits", "data bits" );
return 0;
}
/*----------------------------------------------------------
translate_stop_bits
accept: gnu.io.SerialPort.STOPBITS_* constant
perform: convert to BeOS eqivalent bits
return: 1 if successful
0 if an exception is thrown
exceptions: UnsupportedCommOperationException
comments: You now can't specify anything but 1 or 2 stop bits.
----------------------------------------------------------*/
int translate_stop_bits( JNIEnv *env, stop_bits *sbits, jint stopBits )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside translate_stop_bits\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
switch( stopBits )
{
case STOPBITS_1:
(*sbits) = B_STOP_BITS_1;
return 1;
case STOPBITS_2:
(*sbits) = B_STOP_BITS_2;
return 1;
}
throw_java_exception( env, UNSUPPORTED_COMM_OPERATION,
"translate_stop_bits", "stop bits" );
return 0;
}
/*----------------------------------------------------------
translate_parity
accept: gnu.io.SerialPort.PARITY_* constant
perform: convert parity parameters to BeOS specific ones.
return: 1 if successful
0 if an exception is thrown
exceptions: UnsupportedCommOperationException
comments: The CMSPAR bit not there???
----------------------------------------------------------*/
int translate_parity( JNIEnv *env, parity_mode *parmode, jint parity )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside translate_parity\n");
fclose(fp);
////////////////// Close Log File ////////////////////
switch( parity )
{
case PARITY_NONE:
(*parmode) = B_NO_PARITY;
return 1;
case PARITY_EVEN:
(*parmode) = B_EVEN_PARITY;
return 1;
case PARITY_ODD:
(*parmode) = B_ODD_PARITY;
return 1;
}
throw_java_exception( env, UNSUPPORTED_COMM_OPERATION,
"translate_parity", "parity" );
return 0;
}
/*----------------------------------------------------------
RXTXPort.writeByte
accept: byte to write (passed as int)
perform: write a single byte to the port
return: none
exceptions: IOException
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(writeByte)( JNIEnv *env,
jobject jobj, jint ji )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.writeByte\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
unsigned char byte = (unsigned char)ji;
int fd = get_java_var( env, jobj,"fd","I" );
//fprintf(fp, "RXTXPort.writeByte fd = %i\n", fd);
ssize_t result;
do
{
result = PortArray[fd]->Write(&byte, sizeof(unsigned char));
} while ((result < (ssize_t) 0) && (errno==EINTR));
//fclose(fp);
//return;
//do {
// result=write (14, &byte, sizeof(unsigned char));
//} while (result < 0 && errno==EINTR);
if(result >= (ssize_t)0)
return;
throw_java_exception( env, IO_EXCEPTION, "writeByte",
strerror( errno ) );
}
/*----------------------------------------------------------
RXTXPort.writeArray
accept: jbarray: bytes used for writing
offset: offset in array to start writing
count: Number of bytes to write
perform: write length bytes of jbarray
return: none
exceptions: IOException
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(writeArray)( JNIEnv *env,
jobject jobj, jbyteArray jbarray, jint offset, jint count )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.writeArray\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
int total=0,i;
size_t result = 0;
unsigned char *bytes = (unsigned char *)malloc( count );
jbyte *body = env->GetByteArrayElements(jbarray, 0);
for( i = 0; i < count; i++ ) bytes[ i ] = body[ i + offset ];
env->ReleaseByteArrayElements(jbarray, body, 0);
do {
//result=write (fd, bytes + total, count - total);
result = PortArray[fd]->Write(bytes + total, count - total);
if(result >0){
total += result;
}
} while ((totalClearOutput();
count++;
} while (errno==EINTR && count <5);
//if( result ) throw_java_exception( env, IO_EXCEPTION, "drain",
// strerror( errno ) );
}
/*----------------------------------------------------------
RXTXPort.sendBreak
accept: duration in milliseconds.
perform: send break for actual time. not less than 0.25 seconds.
exceptions: none
comments: not very precise
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(sendBreak)( JNIEnv *env,
jobject jobj, jint duration )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.sendBreak\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
tcsendbreak( fd, (int)( duration / 250 ) );
}
/*----------------------------------------------------------
RXTXPort.NativegetReceiveTimeout
accept: none
perform: get termios.c_cc[VTIME]
return: VTIME
comments: see NativeEnableReceiveTimeoutThreshold
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(NativegetReceiveTimeout)(
JNIEnv *env,
jobject jobj
)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.NativeReceiveTimeout\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
struct termios ttyset;
if( tcgetattr( fd, &ttyset ) < 0 ) goto fail;
return(ttyset.c_cc[ VTIME ] * 100);
fail:
throw_java_exception( env, IO_EXCEPTION, "getReceiveTimeout",
strerror( errno ) );
return -1;
}
/*----------------------------------------------------------
RXTXPort.NativeisReceiveTimeoutEnabled
accept: none
perform: determine if VTIME is none 0
return: JNI_TRUE if VTIME > 0 else JNI_FALSE
comments: see NativeEnableReceiveTimeoutThreshold
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(NativeisReceiveTimeoutEnabled)(
JNIEnv *env,
jobject jobj
)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.NativeisReceiveTimeoutEnabled\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
struct termios ttyset;
if( tcgetattr( fd, &ttyset ) < 0 ) goto fail;
return(ttyset.c_cc[ VTIME ] > 0 ? JNI_TRUE:JNI_FALSE);
fail:
throw_java_exception( env, IO_EXCEPTION, "isReceiveTimeoutEnabled",
strerror( errno ) );
return JNI_FALSE;
}
/*----------------------------------------------------------
RXTXPort.isDSR
accept: none
perform: check status of DSR
return: true if TIOCM_DSR is set
false if TIOCM_DSR is not set
exceptions: none
comments: DSR stands for Data Set Ready
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(isDSR)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.isDSR\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (PortArray[fd]->IsDSR())
{
return JNI_TRUE;
}
else
{
return JNI_FALSE;
}
}
/*----------------------------------------------------------
RXTXPort.isCD
accept: none
perform: check status of CD
return: true if TIOCM_CD is set
false if TIOCM_CD is not set
exceptions: none
comments: CD stands for Carrier Detect
The following comment has been made...
"well, it works, there might ofcourse be a bug, but making DCD
permanently on fixed it for me so I don't care"
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(isCD)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.isCD\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (PortArray[fd]->IsDCD())
{
return JNI_TRUE;
}
else
{
return JNI_FALSE;
}
}
/*----------------------------------------------------------
RXTXPort.isCTS
accept: none
perform: check status of CTS
return: true if TIOCM_CTS is set
false if TIOCM_CTS is not set
exceptions: none
comments: CTS stands for Clear To Send.
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(isCTS)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.isCTS\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (PortArray[fd]->IsCTS())
{
return JNI_TRUE;
}
else
{
return JNI_FALSE;
}
}
/*----------------------------------------------------------
RXTXPort.isRI
accept: none
perform: check status of RI
return: true if TIOCM_RI is set
false if TIOCM_RI is not set
exceptions: none
comments: RI stands for Ring Indicator
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(isRI)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.isRI\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (PortArray[fd]->IsRI())
{
return JNI_TRUE;
}
else
{
return JNI_FALSE;
}
}
#ifndef __BEOS__
/*----------------------------------------------------------
RXTXPort.isRTS
accept: none
perform: check status of RTS
return: true if TIOCM_RTS is set
false if TIOCM_RTS is not set
exceptions: none
comments: tcgetattr with c_cflag CRTS_IFLOW
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(isRTS)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.isRTS\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (PortArray[fd]->IsRTS())
{
return JNI_TRUE;
}
else
{
return JNI_FALSE;
}
}
#endif /* __BEOS__ */
/*----------------------------------------------------------
RXTXPort.setRTS
accept: state flag to set/unset.
perform: depends on the state flag
if true TIOCM_RTS is set
if false TIOCM_RTS is unset
return: none
exceptions: none
comments: tcsetattr with c_cflag CRTS_IFLOW
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(setRTS)( JNIEnv *env,
jobject jobj, jboolean state )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.setRTS\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (state == JNI_TRUE)
{
PortArray[fd]->SetRTS(true);
}
else
{
PortArray[fd]->SetRTS(false);
}
return;
}
#ifndef __BEOS__
/*----------------------------------------------------------
RXTXPort.setDSR
accept: state flag to set/unset.
perform: depends on the state flag
if true TIOCM_DSR is set
if false TIOCM_DSR is unset
return: none
exceptions: none
comments: tcsetattr with c_cflag CRTS_IFLOW
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(setDSR)( JNIEnv *env,
jobject jobj, jboolean state )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.setDSR\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (state == JNI_TRUE)
{
PortArray[fd]->SetDSR(true);
}
else
{
PortArray[fd]->SetDSR(false);
}
return;
}
/*----------------------------------------------------------
RXTXPort.isDTR
accept: none
perform: check status of DTR
return: true if TIOCM_DTR is set
false if TIOCM_DTR is not set
exceptions: none
comments: DTR stands for Data Terminal Ready
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXPort(isDTR)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.isDTR\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (PortArray[fd]->IsDTR())
{
return JNI_TRUE;
}
else
{
return JNI_FALSE;
}
}
#endif /* __BEOS__ */
/*----------------------------------------------------------
RXTXPort.setDTR
accept: new DTR state
perform: if state is true, TIOCM_DTR is set
if state is false, TIOCM_DTR is unset
return: none
exceptions: none
comments: DTR stands for Data Terminal Ready
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(setDTR)( JNIEnv *env,
jobject jobj, jboolean state )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.setDTR\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
if (state == JNI_TRUE)
{
PortArray[fd]->SetDTR(true);
}
else
{
PortArray[fd]->SetDTR(false);
}
return;
}
/*----------------------------------------------------------
read_byte_array
accept: int fd file descriptor to read from
unsigned char *buffer buffer to read data into
int length number of bytes to read
int timeout milliseconds to wait before returning
perform: read bytes from the port into a buffer
return: status of read
-1 fail (IOException)
0 timeout
>0 number of bytes read
comments: According to the Communications API spec, a receive threshold
of 1 is the same as having the threshold disabled.
The nuts and bolts are documented in
NativeEnableReceiveTimeoutThreshold()
----------------------------------------------------------*/
int read_byte_array( int fd, unsigned char *buffer, int length, int timeout )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside read_byte_array\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int ret, left, bytes = 0;
struct timeval sleep;
struct timeval *psleep=&sleep;
#ifndef __BEOS__
fd_set rfds;
FD_ZERO( &rfds );
FD_SET( fd, &rfds );
if( timeout != 0 )
{
sleep.tv_sec = timeout / 1000;
sleep.tv_usec = 1000 * ( timeout % 1000 );
}
#endif __BEOS__
left = length;
while( bytes < length )
{
#ifndef __BEOS__
/* FIXME: In Linux, select updates the timeout automatically, so
other OSes will need to update it manually if they want to have
the same behavior. For those OSes, timeouts will occur after no
data AT ALL is received for the timeout duration. No big deal. */
do {
if( timeout == 0 ) psleep = NULL;
ret=select( fd + 1, &rfds, NULL, NULL, psleep );
} while (ret < 0 && errno==EINTR);
if( ret == 0 ) break;
if( ret < 0 ) return -1;
#endif __BEOS__
ret = read( fd, buffer + bytes, left );
if( ret == 0 ) break;
if( ret < 0 ) return -1;
bytes += ret;
left -= ret;
}
return bytes;
}
/*----------------------------------------------------------
NativeEnableReceiveTimeoutThreshold
accept: int threshold, int vtime,int buffer
perform: Set c_cc->VMIN to threshold and c_cc=>VTIME to vtime
return: void
exceptions: IOException
comments: This is actually all handled in read with select in
canonical input mode.
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(NativeEnableReceiveTimeoutThreshold)(
JNIEnv *env, jobject jobj, jint vtime, jint threshold, jint buffer)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside NativeEnableReceiveTimeoutThreshold\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
struct termios ttyset;
if( tcgetattr( fd, &ttyset ) < 0 ) goto fail;
ttyset.c_cc[ VMIN ] = threshold;
ttyset.c_cc[ VTIME ] = vtime/100;
if( tcsetattr( fd, TCSANOW, &ttyset ) < 0 ) goto fail;
return;
fail:
throw_java_exception( env, IO_EXCEPTION, "TimeoutThreshold",
strerror( errno ) );
return;
}
/*----------------------------------------------------------
RXTXPort.readByte
accept: none
perform: Read a single byte from the port
return: The byte read
exceptions: IOException
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(readByte)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.readByte\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
//status_t SetTimeout(bigtime_t timeout)
//int bytes;
unsigned char buffer[ 1 ];
int fd = get_java_var( env, jobj,"fd","I" );
int timeout = get_java_var( env, jobj, "timeout", "I" );
if (PortArray[fd]->SetTimeout((bigtime_t) timeout) != B_OK)
{
throw_java_exception( env, IO_EXCEPTION, "readByte",
strerror( errno ) );
return -1;
}
if (PortArray[fd]->Read(&buffer[0], sizeof(unsigned char)) != 1)
{
throw_java_exception( env, IO_EXCEPTION, "readByte",
strerror( errno ) );
return -1;
}
return (jint)buffer[0];
/*
bytes = read_byte_array( fd, buffer, 1, timeout );
if( bytes < 0 ) {
throw_java_exception( env, IO_EXCEPTION, "readByte",
strerror( errno ) );
return -1;
}
return (bytes ? (jint)buffer[ 0 ] : -1);
*/
}
/*----------------------------------------------------------
RXTXPort.readArray
accept: offset (offset to start storing data in the jbarray) and
Length (bytes to read)
perform: read bytes from the port into a byte array
return: bytes read on success
0 on read timeout
exceptions: IOException
comments: throws ArrayIndexOutOfBoundsException if asked to
read more than SSIZE_MAX bytes
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(readArray)( JNIEnv *env,
jobject jobj, jbyteArray jbarray, jint offset, jint length )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.readArray\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int bytes;
jbyte *body;
unsigned char *buffer;
int fd = get_java_var( env, jobj, "fd", "I" );
int timeout = get_java_var( env, jobj, "timeout", "I" );
if( length > SSIZE_MAX || length < 0 ) {
throw_java_exception( env, ARRAY_INDEX_OUT_OF_BOUNDS,
"readArray", "Invalid length" );
return -1;
}
buffer = (unsigned char *)malloc( sizeof( unsigned char ) * length );
if( buffer == 0 ) {
throw_java_exception( env, OUT_OF_MEMORY, "readArray",
"Unable to allocate buffer" );
return -1;
}
bytes = read_byte_array( fd, buffer, length, timeout );
if( bytes < 0 ) {
free( buffer );
throw_java_exception( env, IO_EXCEPTION, "readArray",
strerror( errno ) );
return -1;
}
//body = (*env)->GetByteArrayElements( env, jbarray, 0 );
body = env->GetByteArrayElements( jbarray, 0 ); // !!!
memcpy(body + offset, buffer, bytes);
//(*env)->ReleaseByteArrayElements( env, jbarray, body, 0 );
env->ReleaseByteArrayElements( jbarray, body, 0 ); // !!!
free( buffer );
return (bytes ? bytes : -1);
}
/*----------------------------------------------------------
RXTXPort.nativeavailable
accept: none
perform: find out the number of bytes available for reading
return: available bytes
-1 on error
exceptions: none
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(nativeavailable)( JNIEnv *env,
jobject jobj )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.nativeavailable\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
//#ifndef __BEOS__
int fd = get_java_var( env, jobj,"fd","I" );
//int result;
ssize_t result = 0;
result = PortArray[fd]->WaitForInput(); // WaitForInput() not the best choice, but all I could find.
return (jint)result;
/*
if( ioctl( fd, FIONREAD, &result ) )
{
throw_java_exception( env, IO_EXCEPTION, "nativeavailable",
strerror( errno ) );
return -1;
}
else return (jint)result;
*/
//#endif
//return (-1);
}
/*----------------------------------------------------------
RXTXPort.setflowcontrol
accept: flowmode
FLOWCONTROL_NONE none
FLOWCONTROL_RTSCTS_IN hardware flow control
FLOWCONTROL_RTSCTS_OUT ""
FLOWCONTROL_XONXOFF_IN input software flow control
FLOWCONTROL_XONXOFF_OUT output software flow control
perform: set flow control to flowmode
return: none
exceptions: IOException
comments: there is no differentiation between input and output hardware
flow control
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(setflowcontrol)( JNIEnv *env,
jobject jobj, jint flowmode )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.setflowcontrol\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd = get_java_var( env, jobj,"fd","I" );
switch( flowmode )
{
case FLOWCONTROL_NONE:
PortArray[fd]->SetFlowControl(B_NOFLOW_CONTROL);
if (PortArray[fd]->FlowControl() != B_NOFLOW_CONTROL)
{
throw_java_exception( env, IO_EXCEPTION, "setHWFC",
strerror( errno ) );
return;
}
break;
case FLOWCONTROL_RTSCTS_IN:
PortArray[fd]->SetFlowControl(B_HARDWARE_CONTROL);
if (PortArray[fd]->FlowControl() != B_HARDWARE_CONTROL)
{
throw_java_exception( env, IO_EXCEPTION, "setHWFC",
strerror( errno ) );
return;
}
break;
case FLOWCONTROL_RTSCTS_OUT:
PortArray[fd]->SetFlowControl(B_HARDWARE_CONTROL);
if (PortArray[fd]->FlowControl() != B_HARDWARE_CONTROL)
{
throw_java_exception( env, IO_EXCEPTION, "setHWFC",
strerror( errno ) );
return;
}
break;
case FLOWCONTROL_XONXOFF_IN:
PortArray[fd]->SetFlowControl(B_SOFTWARE_CONTROL);
if (PortArray[fd]->FlowControl() != B_SOFTWARE_CONTROL)
{
throw_java_exception( env, IO_EXCEPTION, "setHWFC",
strerror( errno ) );
return;
}
break;
case FLOWCONTROL_XONXOFF_OUT:
PortArray[fd]->SetFlowControl(B_SOFTWARE_CONTROL);
if (PortArray[fd]->FlowControl() != B_SOFTWARE_CONTROL)
{
throw_java_exception( env, IO_EXCEPTION, "setHWFC",
strerror( errno ) );
return;
}
break;
}
return;
/*
if( tcgetattr( fd, &ttyset ) ) goto fail;
if ( flowmode & ( FLOWCONTROL_RTSCTS_IN | FLOWCONTROL_RTSCTS_OUT ) )
ttyset.c_cflag |= HARDWARE_FLOW_CONTROL;
else ttyset.c_cflag &= ~HARDWARE_FLOW_CONTROL;
ttyset.c_iflag &= ~IXANY;
if ( flowmode & FLOWCONTROL_XONXOFF_IN )
ttyset.c_iflag |= IXOFF;
else ttyset.c_iflag &= ~IXOFF;
if ( flowmode & FLOWCONTROL_XONXOFF_OUT )
ttyset.c_iflag |= IXON;
else ttyset.c_iflag &= ~IXON;
if( tcsetattr( fd, TCSANOW, &ttyset ) ) goto fail;
return;
fail:
throw_java_exception( env, IO_EXCEPTION, "setHWFC",
strerror( errno ) );
return;
*/
}
#ifdef __BEOS__
/*----------------------------------------------------------
RXTXPort.eventLoop
accept: none
perform: periodically check for SerialPortEvents
return: none
exceptions: none
comments:
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(eventLoop)( JNIEnv *env, jobject jobj )
{
printf("BeOS eventLoop not Implemented\n");
#else /* __BEOS__ */
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside RXTXPort.eventLoop\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int fd, ret, change;
fd_set rfds;
struct timeval tv_sleep;
unsigned int mflags, omflags;
jboolean interrupted = 0;
#if defined TIOCSERGETLSR
struct stat fstatbuf;
#endif /* TIOCSERGETLSR */
#if defined(TIOCGICOUNT)
struct serial_icounter_struct sis, osis;
/* JK00: flag if this can be used on this port */
int has_tiocgicount = 1;
#endif /* TIOCGICOUNT */
#if defined(TIOCSERGETLSR)
int has_tiocsergetlsr = 1;
#endif /* TIOCSERGETLSR */
fd = get_java_var(env, jobj, "fd", "I");
#if defined(TIOCGICOUNT)
/* Some multiport serial cards do not implement TIOCGICOUNT ... */
/* So use the 'dumb' mode to enable using them after all! JK00 */
if( ioctl( fd, TIOCGICOUNT, &osis ) < 0 ) {
report("Port does not support TIOCGICOUNT events\n" );
has_tiocgicount = 0;
}
#endif /* TIOCGICOUNT */
#if defined(TIOCSERGETLSR)
/* JK00: work around for multiport cards without TIOCSERGETLSR */
/* Cyclades is one of those :-( */
if( ioctl( fd, TIOCSERGETLSR, &change ) ) {
report("Port does not support TIOCSERGETLSR\n" );
has_tiocsergetlsr = 0;
}
#endif /* TIOCSERGETLSR */
if( ioctl( fd, TIOCMGET, &omflags) <0 ) {
report("Port does not support events\n" );
return;
}
FD_ZERO( &rfds );
while( !interrupted ) {
FD_SET( fd, &rfds );
tv_sleep.tv_sec = 0;
tv_sleep.tv_usec = 100000;
do {
ret=select( fd + 1, &rfds, NULL, NULL, &tv_sleep );
} while (ret < 0 && errno==EINTR);
if( ret < 0 ) break;
interrupted = is_interrupted(env, jobj);
if(interrupted) return;
#if defined TIOCSERGETLSR
/* JK00: work around for Multi IO cards without TIOCSERGETLSR */
if( has_tiocsergetlsr ) {
if (fstat(fd, &fstatbuf)) break;
if( ioctl( fd, TIOCSERGETLSR, &change ) ) break;
else if( change )
send_event( env, jobj, SPE_OUTPUT_BUFFER_EMPTY,
1 );
}
#endif /* TIOCSERGETLSR */
#if defined(TIOCGICOUNT)
/* wait for RNG, DSR, CD or CTS but not DataAvailable
* The drawback here is it never times out so if someone
* reads there will be no chance to try again.
* This may make sense if the program does not want to
* be notified of data available or errors.
* ret=ioctl(fd,TIOCMIWAIT);
*/
/* JK00: only use it if supported by this port */
if (has_tiocgicount) {
if( ioctl( fd, TIOCGICOUNT, &sis ) ) break;
while( sis.frame != osis.frame ) {
send_event( env, jobj, SPE_FE, 1);
osis.frame++;
}
while( sis.overrun != osis.overrun ) {
send_event( env, jobj, SPE_OE, 1);
osis.overrun++;
}
while( sis.parity != osis.parity ) {
send_event( env, jobj, SPE_PE, 1);
osis.parity++;
}
while( sis.brk != osis.brk ) {
send_event( env, jobj, SPE_BI, 1);
osis.brk++;
}
osis = sis;
}
#endif /* TIOCGICOUNT */
/* A Portable implementation */
if( ioctl( fd, TIOCMGET, &mflags ) ) break;
change = (mflags&TIOCM_CTS) - (omflags&TIOCM_CTS);
if( change ) send_event( env, jobj, SPE_CTS, change );
change = (mflags&TIOCM_DSR) - (omflags&TIOCM_DSR);
if( change ) send_event( env, jobj, SPE_DSR, change );
change = (mflags&TIOCM_RNG) - (omflags&TIOCM_RNG);
if( change ) send_event( env, jobj, SPE_RI, change );
change = (mflags&TIOCM_CD) - (omflags&TIOCM_CD);
if( change ) send_event( env, jobj, SPE_CD, change );
omflags = mflags;
ioctl( fd, FIONREAD, &change );
if( change ) {
if(!send_event( env, jobj, SPE_DATA_AVAILABLE, 1 ))
usleep(100000); /* select wont block */
}
}
return;
#endif /* __BEOS__ */
}
/*----------------------------------------------------------
isDeviceGood
accept: a port name
perform: see if the port is valid on this OS.
return: JNI_TRUE if it exhists otherwise JNI_FALSE
exceptions: none
comments:
----------------------------------------------------------*/
JNIEXPORT jboolean JNICALL RXTXCommDriver(isDeviceGood)(JNIEnv *env,
jobject jobj, jstring tty_name)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside isDeviceGood\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
jboolean result;
static struct stat mystat;
char teststring[256];
int fd, i;
const char *name = env->GetStringUTFChars(tty_name, 0); // !!!
printf("inside RXTXCommDriver:isDeviceGood() deviceName is %s. ",name);
//!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!
//Let's try to enumerate the ports
/*
int32 portcount = 0;
int32 n = 0;
port = new BSerialPort();
char devName[B_OS_NAME_LENGTH];
portcount = port->CountDevices();
for (n = portcount - 1; n >= 0; n--)
{
port->GetDeviceName(n, devName);
printf("inside RXTXCommDriver:isDeviceGood() deviceName is %s. ",devName);
}
*/
for(i=0;i<64;i++){
#if defined(_GNU_SOURCE)
snprintf(teststring, 256, "%s%s%i",DEVICEDIR,name, i);
#else
sprintf(teststring,"%s%s%i",DEVICEDIR,name, i);
#endif /* _GNU_SOURCE */
stat(teststring,&mystat);
if(S_ISCHR(mystat.st_mode)){
printf("inside RXTXCommDriver:isDeviceGood() trying to open %s. ",teststring);
fd=open(teststring,O_RDONLY|O_NONBLOCK);
printf("got %i\n",fd);
if (fd>0){
printf("inside RXTXCommDriver:isDeviceGood() %s is valid on this system.\n",teststring);
close(fd);
result=JNI_TRUE;
break;
}
}
result=JNI_FALSE;
}
#if defined(_GNU_SOURCE)
snprintf(teststring, 256, "%s%s",DEVICEDIR,name);
#else
sprintf(teststring,"%s%s",DEVICEDIR,name);
#endif /* _GNU_SOURCE */
stat(teststring,&mystat);
if(S_ISCHR(mystat.st_mode)){
fd=open(teststring,O_RDONLY|O_NONBLOCK);
if (fd>0){
close(fd);
result=JNI_TRUE;
}
}
printf("result is %i for %s\n",result, name);
env->ReleaseStringUTFChars(tty_name, name); // !!!
return(result);
}
/*----------------------------------------------------------
getDeviceDirectory
accept:
perform:
return: the directory containing the device files
exceptions:
comments: use this to avoid hard coded "/dev/"
values are in SerialImp.h
----------------------------------------------------------*/
/*
JNIEXPORT jstring JNICALL Java_gnu_io_RXTXCommDriver_getDeviceDirectory(JNIEnv*, jobject);
*/
JNIEXPORT jstring JNICALL RXTXCommDriver(getDeviceDirectory)(JNIEnv *env,
jobject jobj, int test)
{
return env->NewStringUTF(DEVICEDIR);
}
/*----------------------------------------------------------
setInputBufferSize
accept:
perform:
return: none
exceptions: none
comments: see fopen/fclose/fwrite/fread man pages.
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(setInputBufferSize)(JNIEnv *env,
jobject jobj, jint size )
{
report("setInputBufferSize is not implemented\n");
}
/*----------------------------------------------------------
getIputBufferSize
accept:
perform:
return: none
exceptions: none
comments: see fopen/fclose/fwrite/fread man pages.
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(getInputBufferSize)(JNIEnv *env,
jobject jobj)
{
report("getInputBufferSize is not implemented\n");
return(1);
}
/*----------------------------------------------------------
setOutputBufferSize
accept:
perform:
return: none
exceptions: none
comments: see fopen/fclose/fwrite/fread man pages.
----------------------------------------------------------*/
JNIEXPORT void JNICALL RXTXPort(setOutputBufferSize)(JNIEnv *env,
jobject jobj, jint size )
{
report("setOutputBufferSize is not implemented\n");
}
/*----------------------------------------------------------
getOutputBufferSize
accept:
perform:
return: none
exceptions: none
comments: see fopen/fclose/fwrite/fread man pages.
----------------------------------------------------------*/
JNIEXPORT jint JNICALL RXTXPort(getOutputBufferSize)(JNIEnv *env,
jobject jobj)
{
report("getOutputBufferSize is not implemented\n");
return(1);
}
/*----------------------------------------------------------
is_interrupted
accept:
perform: see if the port is being closed.
return: a positive value if the port is being closed.
exceptions: none
comments:
----------------------------------------------------------*/
jboolean is_interrupted(JNIEnv *env, jobject jobj)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is is_interrupted\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
jmethodID foo;
jclass jclazz;
int result;
//(*env)->ExceptionClear(env);
env->ExceptionClear(); // !!!
//jclazz = (*env)->GetObjectClass( env, jobj );
jclazz = env->GetObjectClass( jobj ); // !!!
if(jclazz == NULL) return JNI_TRUE;
//foo = (*env)->GetMethodID( env, jclazz, "checkMonitorThread", "()Z");
foo = env->GetMethodID( jclazz, "checkMonitorThread", "()Z"); // !!!
if(foo == NULL) return JNI_TRUE;
//result = (*env)->CallBooleanMethod( env, jobj, foo );
result = env->CallBooleanMethod( jobj, foo ); // !!!
#ifdef DEBUG
//if((*env)->ExceptionOccurred(env)) {
if(env->ExceptionOccurred()) { // !!!
report ("an error occured calling sendEvent()\n");
//(*env)->ExceptionDescribe(env);
env->ExceptionDescribe(); // !!!
//(*env)->ExceptionClear(env);
env->ExceptionClear(); // !!!
}
#endif /* DEBUG */
//(*env)->DeleteLocalRef( env, jclazz );
env->DeleteLocalRef( jclazz ); // !!!
return(result);
}
/*----------------------------------------------------------
send_event
accept: The event type and the event state
perform: if state is > 0 send a JNI_TRUE event otherwise send JNI_FALSE
return: a positive value if the port is being closed.
exceptions: none
comments:
----------------------------------------------------------*/
int send_event(JNIEnv *env, jobject jobj, jint type, int flag)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside send_event\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int result;
jmethodID foo;
//jclass jclazz = (*env)->GetObjectClass( env, jobj );
jclass jclazz = env->GetObjectClass( jobj ); // !!!
if(jclazz == NULL) return JNI_TRUE;
//foo = (*env)->GetMethodID( env, jclazz, "sendEvent", "(IZ)Z" );
foo = env->GetMethodID( jclazz, "sendEvent", "(IZ)Z" ); // !!!
//(*env)->ExceptionClear(env);
env->ExceptionClear(); // !!!
//result = (*env)->CallBooleanMethod( env, jobj, foo, type,
result = env->CallBooleanMethod( jobj, foo, type, // !!!
flag > 0 ? JNI_TRUE : JNI_FALSE );
#ifdef DEBUG
//if((*env)->ExceptionOccurred(env)) {
if(env->ExceptionOccurred()) { // !!!
report ("an error occured calling sendEvent()\n");
//(*env)->ExceptionDescribe(env);
env->ExceptionDescribe(); // !!!
//(*env)->ExceptionClear(env);
env->ExceptionClear(); // !!!
}
#endif /* DEBUG */
//(*env)->DeleteLocalRef( env, jclazz );
env->DeleteLocalRef( jclazz ); // !!!
return(result);
}
/*----------------------------------------------------------
get_java_var
accept: env (keyhole to java)
jobj (java RXTXPort object)
return: the fd field from the java object
exceptions: none
comments:
----------------------------------------------------------*/
int get_java_var( JNIEnv *env, jobject jobj, char *id, char *type )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside get_java_var\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int result = 0;
//jclass jclazz = (*env)->GetObjectClass( env, jobj );
jclass jclazz = env->GetObjectClass( jobj ); // !!!
//jfieldID jfd = (*env)->GetFieldID( env, jclazz, id, type );
jfieldID jfd = env->GetFieldID( jclazz, id, type ); // !!!
if( !jfd ) {
//(*env)->ExceptionDescribe( env );
env->ExceptionDescribe(); // !!!
//(*env)->ExceptionClear( env );
env->ExceptionClear(); // !!!
return result;
}
//result = (int)( (*env)->GetIntField( env, jobj, jfd ) );
result = (int)( env->GetIntField( jobj, jfd ) ); // !!!
/* ct7 & gel * Added DeleteLocalRef */
//(*env)->DeleteLocalRef( env, jclazz );
env->DeleteLocalRef( jclazz ); // !!!
#ifdef DEBUG
if(!strncmp("fd",id,2) && result == 0)
report("invalid file descriptor\n");
#endif
return result;
}
/*----------------------------------------------------------
throw_java_exception
accept: env (keyhole to java)
*exc (exception class name)
*foo (function name)
*msg (error message)
perform: Throw a new java exception
return: none
exceptions: haha!
comments:
----------------------------------------------------------*/
void throw_java_exception( JNIEnv *env, char *exc, char *foo, char *msg )
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside throw_java_exception\n\n"); // !!!
fprintf(fp, "%s in %s\n", msg, foo ); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
char buf[ 60 ];
//jclass clazz = (*env)->FindClass( env, exc );
jclass clazz = env->FindClass( exc ); // !!!
if( !clazz ) {
//(*env)->ExceptionDescribe( env );
env->ExceptionDescribe(); // !!!
//(*env)->ExceptionClear( env );
env->ExceptionClear(); // !!!
return;
}
#if defined(_GNU_SOURCE)
snprintf( buf, 60, "%s in %s", msg, foo );
#else
sprintf( buf,"%s in %s", msg, foo );
#endif /* _GNU_SOURCE */
//(*env)->ThrowNew( env, clazz, buf );
env->ThrowNew( clazz, buf ); // !!!
/* ct7 * Added DeleteLocalRef */
//(*env)->DeleteLocalRef( env, clazz );
env->DeleteLocalRef( clazz ); // !!!
}
/*----------------------------------------------------------
report
accept: string to send to stderr
perform: if DEBUG is defined send the string to stderr.
return: none
exceptions: none
comments:
----------------------------------------------------------*/
void report(char *msg)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside report\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
#ifdef DEBUG
fprintf(stderr, msg);
#endif
}
/*----------------------------------------------------------
dump_termios
accept: string to indicate where this was called.
termios struct
perform: print the termios struct to stderr.
return: none
exceptions: none
comments: used to debug the termios struct.
----------------------------------------------------------*/
void dump_termios(char *foo,struct termios *ttyset)
{
////////////////// Open Log File /////////////////////
fp = fopen("RXTXOut.log", "a");
fprintf(fp, "Brian is inside dump_termios\n"); // !!!
fclose(fp);
////////////////// Close Log File ////////////////////
int i;
//fprintf(stderr,"%s %o\n",foo,ttyset->c_iflag);
//fprintf(stderr,"%s %o\n",foo,ttyset->c_lflag);
//fprintf(stderr,"%s %o\n",foo,ttyset->c_oflag);
//fprintf(stderr,"%s %o\n",foo,ttyset->c_cflag);
for(i=0;ic_cc[i]);
}
fprintf(stderr,"\n");
}
./rxtx-2.2pre2/src/SerialImp.c 0000644 0001750 0001750 00000521114 11142410530 016061 0 ustar twerner twerner /*-------------------------------------------------------------------------
| RXTX License v 2.1 - LGPL v 2.1 + Linking Over Controlled Interface.
| RXTX is a native interface to serial ports in java.
| Copyright 1997-2009 by Trent Jarvi tjarvi@qbang.org and others who
| actually wrote it. See individual source files for more information.
|
| A copy of the LGPL v 2.1 may be found at
| http://www.gnu.org/licenses/lgpl.txt on March 4th 2007. A copy is
| here for your convenience.
|
| This library is free software; you can redistribute it and/or
| modify it under the terms of the GNU Lesser General Public
| License as published by the Free Software Foundation; either
| version 2.1 of the License, or (at your option) any later version.
|
| This library is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
| Lesser General Public License for more details.
|
| An executable that contains no derivative of any portion of RXTX, but
| is designed to work with RXTX by being dynamically linked with it,
| is considered a "work that uses the Library" subject to the terms and
| conditions of the GNU Lesser General Public License.
|
| The following has been added to the RXTX License to remove
| any confusion about linking to RXTX. We want to allow in part what
| section 5, paragraph 2 of the LGPL does not permit in the special
| case of linking over a controlled interface. The intent is to add a
| Java Specification Request or standards body defined interface in the
| future as another exception but one is not currently available.
|
| http://www.fsf.org/licenses/gpl-faq.html#LinkingOverControlledInterface
|
| As a special exception, the copyright holders of RXTX give you
| permission to link RXTX with independent modules that communicate with
| RXTX solely through the Sun Microsytems CommAPI interface version 2,
| regardless of the license terms of these independent modules, and to copy
| and distribute the resulting combined work under terms of your choice,
| provided that every copy of the combined work is accompanied by a complete
| copy of the source code of RXTX (the version of RXTX used to produce the
| combined work), being distributed under the terms of the GNU Lesser General
| Public License plus this exception. An independent module is a
| module which is not derived from or based on RXTX.
|
| Note that people who make modified versions of RXTX are not obligated
| to grant this special exception for their modified versions; it is
| their choice whether to do so. The GNU Lesser General Public License
| gives permission to release a modified version without this exception; this
| exception also makes it possible to release a modified version which
| carries forward this exception.
|
| You should have received a copy of the GNU Lesser General Public
| License along with this library; if not, write to the Free
| Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
| All trademarks belong to their respective owners.
--------------------------------------------------------------------------*/
#if defined(__MWERKS__) /* dima */
#include "RXTXPort.h" /* dima */
#else /* dima */
#ifndef WIN32
# include "config.h"
#endif
#include "gnu_io_RXTXPort.h"
#endif /* dima */
#ifdef __LCC__ /* windows lcc compiler for fd_set. probably wrong */
# include
#endif /* __LCC__ */
#include
#include
#include
#include
#include
#include
#include
#ifndef WIN32
#include
#include
#include
#include
#include
#else
# include "win32termios.h"
/* FIXME returns 0 in all cases on win32
#define S_ISCHR(m) (((m)&S_IFMT) == S_IFCHR)
*/
# if !defined(S_ISCHR)
# define S_ISCHR(m) (1)
# endif /* S_ISCHR(m) */
#endif /* WIN32 */
#ifdef HAVE_TERMIOS_H
# include
#endif /* HAVE_TERMIOS_H */
# include
#ifdef HAVE_SIGNAL_H
# include
#endif /* HAVE_SIGNAL_H */
#ifdef HAVE_SYS_SIGNAL_H
# include
#endif /* HAVE_SYS_SIGNAL_H */
#include
#ifdef HAVE_SYS_TIME_H
# include
#endif /* HAVE_SYS_TIME_H */
# include
#ifdef HAVE_SYS_FCNTL_H
# include
#endif /* HAVE_SYS_FCNTL_H */
#ifdef HAVE_SYS_FILE_H
# include
#endif /* HAVE_SYS_FILE_H */
#ifdef LFS /* File Lock Server */
# include
# include
# include
#endif /* FLS */
#if defined(__linux__)
# include /* fix for linux-2.3.4? kernels */
# include
# include
#endif /* __linux__ */
#if defined(__sun__)
# include
# include
#endif /* __sun__ */
#if defined(__hpux__)
# include
#endif /* __hpux__ */
/* FIXME -- new file */
#if defined(__APPLE__)
# include
# include