stella.io
Class RS485ReadWriteServer

java.lang.Object
  extended by util.PropertyContainer
      extended by util.PropertyResources
          extended by util.PropertyBundles
              extended by io.AbstractDriver
                  extended by io.AbstractSerialDriver
                      extended by stella.io.RS485ReadWriteServer
All Implemented Interfaces:
Driver, Cloneable, ExitCleaning, Initializable, LocalizedSupplying, PropertySupplying, ResourceSupplying
Direct Known Subclasses:
RS485Scan

public class RS485ReadWriteServer
extends AbstractSerialDriver
implements ExitCleaning

A class enabeling write access to the serial port. It is used to write commands to a serial port and to receive incoming replies.

Applications should only use the writeCommand(java.lang.String) method to write commands to the serial line and read in replies (the reply is returned as a string from the method call). This method locks on the serial port until the reply is received. Please use this method with the correct number of reply-bytes specified whenever possible. Calling this method with a too-small number of reply-bytes specified can cause premature read aborts (though they should not happen frequently). A generic methods, private, is provided that reads to the serial line, namely writeString(java.lang.String). This method does not lock on the serial port and should therefore be used with extreme care. The suggested approach is to not use them at all, but if it is really necessary, always synchronize on the #lock object prior to calling either of this methods.

The serial I/O-streams are buffered by the underlying implementation, but are nevertheless software-wise wrapped into buffered streams. The read-in of the command always sets the CommPort.enableReceiveThreshold of the comm extension package to the number of bytes awaited for the command. Additionally, if the driver does not support receive-thresholds, a software implementation of a receive threshold is implemented.

If the KEY_CLOSE key points to true, the serial port is closed on exit via a shutdown-hook.

In version 1.2 (20-01-03), a counter for failed reading was introduced. The KEY_FAILURES points to a maximum number of failures allowed within a KEY_FAILTIME to consider the server working probably. If this number is exceeded (within the stated time), the serial port is closed and opened again after the KEY_REINIT time.


Nested Class Summary
static class RS485ReadWriteServer.Checksum
          This innner class reports the checksum to the given command line argument.
static class RS485ReadWriteServer.Command
          Sends a single command to the server stated on the command line.
static class RS485ReadWriteServer.Info
          Tries to cat info on the specified port to system.out.
protected  class RS485ReadWriteServer.ReadWrite
          A cancelable thread that does the following things on run.
static class RS485ReadWriteServer.Scan
          Scans for valid serial devices and reports all found to system.out.
 
Nested classes/interfaces inherited from class io.AbstractSerialDriver
AbstractSerialDriver.Available
 
Nested classes/interfaces inherited from class util.PropertyResources
PropertyResources.URLResource
 
Field Summary
private  boolean checksumming
          True if checksumming is enabled.
private static RS485ReadWriteServer.ReadWrite commandthread
          The server's read/write thread for command issuing.
private  byte[] crbytes
          The byte array representation of the CR.
private static int DEFCHECKCHAR
          The default number of checksum bytes (2).
private static boolean DEFCHECKSUM
          The default value for checksummed communication (false).
private static boolean DEFCLOSE
          True if the serial port should be closed on java-VM exits.
private static String DEFCR
          The default carriage return character.
private static boolean DEFECHO
          True if the command issued is echoed on the result read.
private static String DEFINVALID
          The default invalid-command marker.
private static int DEFMAXBUFFER
          The default value for the read buffer size.
private static int DEFMAXBUSY
          The default number of retries of non-busy queries to the serial .
private static long DEFQUERYTIME
          The default query time.
private static long DEFRESPONDTIME
          The default respond time, 1 sec.
private static long DEFTIMEBUSY
          The default time-out between non-busy queries to the serial server.
static String KEY_CHECKCHAR
          The key whether to enable checksumming.
static String KEY_CHECKSUM
          The key whether to enable checksumming.
static String KEY_CLOSE
          The key for closing the serial line on exit with a shutdown hook.
static String KEY_CR
          The key to the terminal character(s) written after a string.
static String KEY_ECHO
          The key to echo-on.
static String KEY_FAILTIME
          The key to the time span until failures are considered invalid.
static String KEY_FAILURES
          The key for the maximum number of failures allowed.
static String KEY_INVALID
          The key linked to the starting sequence of invalid commands.
static String KEY_MAXBUFFER
          The key to the buffer size of the read buffer.
static String KEY_MAXBUSY
          The maximum retries for non-busy queries to the serial server.
static String KEY_QUERYTIME
          The key for the inputstream.available queries (ms).
static String KEY_REINIT
          The key to the time between closing and re-opening the serial port.
static String KEY_RESPONDTIME
          The key for the response-reading timeout (ms).
static String KEY_STARTUP
          The key to a comma-separated list of commands to send on open.
static String KEY_TIMEBUSY
          The time-out between non-busy queries to the serial server.
private  byte[] readbytes
          The byte array representation of the input.
 
Fields inherited from class io.AbstractSerialDriver
inport, KEY_BAUDRATE, KEY_CLOSETIMEOUT, KEY_DATABIT, KEY_FLOWCONTROL, KEY_INBUFFER, KEY_NOTIFYCOOLDOWN, KEY_OUTBUFFER, KEY_PARITYBIT, KEY_PORTNAME, KEY_RECEIVEFRAMING, KEY_RECEIVETHRESHOLD, KEY_RECEIVETIMEOUT, KEY_STOPBIT, KEY_TIMEOUT, outport, staticlock
 
Fields inherited from class io.AbstractDriver
KEY_DRIVERNAME
 
Fields inherited from class util.PropertyBundles
KEY_LOCALECOUNTRY, KEY_LOCALELANGUAGE, KEY_RESOURCEBUNDLES
 
Fields inherited from class util.PropertyResources
KEY_NOINITONCREATE, localurl, locate, POSTFIX_DIR, POSTFIX_EXT, POSTFIX_FILE, POSTFIX_LIST, POSTFIX_URL, urlset
 
Fields inherited from class util.PropertyContainer
KEY_LISTSEPARATOR, KEY_MAPKEYVALUECHAR, KEY_MAPSEPARATOR
 
Fields inherited from interface util.ResourceSupplying
KEY_URLRESOURCES, KEY_URLUSECONFIG, KEY_URLUSECURRENT, KEY_URLUSEHOME
 
Fields inherited from interface util.PropertySupplying
CONFIG, KEY_CLASS
 
Constructor Summary
RS485ReadWriteServer(Map prop)
          Constructs a new RS485 server.
 
Method Summary
 void cancelCommand()
          Cancels the command-read thread.
 String deferCommand(String cmd)
          Writes a command to the serial port and reads in the resonse.
protected  String endCommand()
          For subclasses only: Read the result of a previous command on clean the line.
 String ensureCommand(String cmd, int retries)
          For very faulty serial lines, this method should ensure that a command is sent.
 void exit()
          The finalizer of the RS485 server.
protected static byte[] getCheckSum(byte[] send, int len)
          Calculates a checksum over a number of bytes.
 boolean getCheckSumming()
          Returns if checksumming is enabled.
private  String interpretString(String raw)
          Interprets a string read in from the serial line.
 boolean isReadAlive()
          Queries the server if it is busy writing a command.
 boolean isReading()
          Queries the server if it is busy writing a command.
 boolean open()
          Opens the serial port and additionally sets the baud rate, the data bit, stop bit, and parity bit.
 String readString()
          If we have bytes on input, read them, otherwise return null.
 void setCheckSumming(boolean newcheck)
          Sets the checksumming option.
protected  void startCommand(String cmd)
          For subclasses only: Start the command thread and return.
 String writeCommand(String cmd)
          Writes a command to the serial port and reads in the resonse.
 String writeString(String mess)
          Writes the argumental string to the output stream.
 
Methods inherited from class io.AbstractSerialDriver
close, createPortEventListener, createPortEventListener, deregisterSoleEventListener, disableEvent, enableEvent, getDriverName, isOpen, registerSoleEventListener, resetOriginalParameters
 
Methods inherited from class io.AbstractDriver
createDriver, equals, hashCode
 
Methods inherited from class util.PropertyBundles
clone, getLocalized, getLocalized, getLocalizedString, getLocalizedString, loadResource
 
Methods inherited from class util.PropertyResources
createFrom, createFrom, createFrom, getApplet, getAsResources, getLocalClassLoader, getPropertiesToKey, getPropertiesToKey, getResource, getResourceAsStream, getResourceFromKey, getResources, init, keyCreate, keyCreate, reload, setApplet
 
Methods inherited from class util.PropertyContainer
augment, augment, augment, defaultBoolean, defaultChar, defaultDouble, defaultFloat, defaultInt, defaultLong, defaultObject, defaultObject, defaultProperties, defaultProperty, getAsBoolean, getAsChar, getAsDouble, getAsEnums, getAsFloat, getAsInt, getAsList, getAsLong, getAsMap, getAsMap, getAsObject, getAsObject, getProperties, getProperty, has, isNew, parseObject, reload, removeProperty, rescanned, setObject, setProperties, setProperty, stringProperties, toString
 
Methods inherited from class java.lang.Object
finalize, getClass, notify, notifyAll, wait, wait, wait
 
Methods inherited from interface util.ResourceSupplying
getResource, getResourceAsStream, getResources
 
Methods inherited from interface util.PropertySupplying
defaultBoolean, defaultChar, defaultDouble, defaultFloat, defaultInt, defaultLong, defaultObject, defaultObject, defaultProperties, defaultProperty, getAsBoolean, getAsChar, getAsDouble, getAsFloat, getAsInt, getAsList, getAsLong, getAsMap, getAsObject, getAsObject, getProperties, getProperty, has, parseObject, removeProperty, setObject, setProperty, stringProperties
 
Methods inherited from interface util.Initializable
init
 

Field Detail

KEY_MAXBUFFER

public static final String KEY_MAXBUFFER
The key to the buffer size of the read buffer.

See Also:
Constant Field Values

KEY_CR

public static final String KEY_CR
The key to the terminal character(s) written after a string.

See Also:
Constant Field Values

KEY_CHECKSUM

public static final String KEY_CHECKSUM
The key whether to enable checksumming.

See Also:
Constant Field Values

KEY_CHECKCHAR

public static final String KEY_CHECKCHAR
The key whether to enable checksumming.

See Also:
Constant Field Values

KEY_INVALID

public static final String KEY_INVALID
The key linked to the starting sequence of invalid commands.

See Also:
Constant Field Values

KEY_STARTUP

public static final String KEY_STARTUP
The key to a comma-separated list of commands to send on open.

See Also:
Constant Field Values

KEY_QUERYTIME

public static final String KEY_QUERYTIME
The key for the inputstream.available queries (ms).

See Also:
Constant Field Values

KEY_RESPONDTIME

public static final String KEY_RESPONDTIME
The key for the response-reading timeout (ms).

See Also:
Constant Field Values

KEY_CLOSE

public static final String KEY_CLOSE
The key for closing the serial line on exit with a shutdown hook.

See Also:
Constant Field Values

KEY_FAILURES

public static final String KEY_FAILURES
The key for the maximum number of failures allowed.

See Also:
Constant Field Values

KEY_FAILTIME

public static final String KEY_FAILTIME
The key to the time span until failures are considered invalid.

See Also:
Constant Field Values

KEY_REINIT

public static final String KEY_REINIT
The key to the time between closing and re-opening the serial port.

See Also:
Constant Field Values

KEY_ECHO

public static final String KEY_ECHO
The key to echo-on. Echo means repetition of the command on result.

See Also:
Constant Field Values

KEY_MAXBUSY

public static final String KEY_MAXBUSY
The maximum retries for non-busy queries to the serial server.

See Also:
Constant Field Values

KEY_TIMEBUSY

public static final String KEY_TIMEBUSY
The time-out between non-busy queries to the serial server.

See Also:
Constant Field Values

DEFMAXBUFFER

private static final int DEFMAXBUFFER
The default value for the read buffer size.

See Also:
Constant Field Values

DEFCR

private static final String DEFCR
The default carriage return character.

See Also:
Constant Field Values

DEFCHECKSUM

private static final boolean DEFCHECKSUM
The default value for checksummed communication (false).

See Also:
Constant Field Values

DEFCHECKCHAR

private static final int DEFCHECKCHAR
The default number of checksum bytes (2).

See Also:
Constant Field Values

DEFINVALID

private static final String DEFINVALID
The default invalid-command marker. (?)

See Also:
Constant Field Values

DEFQUERYTIME

private static final long DEFQUERYTIME
The default query time.

See Also:
Constant Field Values

DEFRESPONDTIME

private static final long DEFRESPONDTIME
The default respond time, 1 sec.

See Also:
Constant Field Values

DEFCLOSE

private static final boolean DEFCLOSE
True if the serial port should be closed on java-VM exits.

See Also:
Constant Field Values

DEFECHO

private static final boolean DEFECHO
True if the command issued is echoed on the result read.

See Also:
Constant Field Values

DEFMAXBUSY

private static final int DEFMAXBUSY
The default number of retries of non-busy queries to the serial .

See Also:
Constant Field Values

DEFTIMEBUSY

private static final long DEFTIMEBUSY
The default time-out between non-busy queries to the serial server.

See Also:
Constant Field Values

checksumming

private boolean checksumming
True if checksumming is enabled.


readbytes

private byte[] readbytes
The byte array representation of the input.


crbytes

private byte[] crbytes
The byte array representation of the CR.


commandthread

private static RS485ReadWriteServer.ReadWrite commandthread
The server's read/write thread for command issuing.

Constructor Detail

RS485ReadWriteServer

public RS485ReadWriteServer(Map prop)
Constructs a new RS485 server. The serial line is not opened until the PropertyResources.init() method is called, as specified in the Driver interface.

Method Detail

open

public boolean open()
             throws IOException
Opens the serial port and additionally sets the baud rate, the data bit, stop bit, and parity bit. The original settings are stored and can be reset with the #resetClose method. If successful input and output streams available at the port are opened.

Specified by:
open in interface Driver
Overrides:
open in class AbstractSerialDriver
Returns:
True if initialization was successful.
Throws:
IOException

exit

public void exit()
The finalizer of the RS485 server. It checks if the port is open and closes it by calling AbstractSerialDriver.close().

Specified by:
exit in interface ExitCleaning

setCheckSumming

public void setCheckSumming(boolean newcheck)
Sets the checksumming option.


getCheckSumming

public boolean getCheckSumming()
Returns if checksumming is enabled.


writeCommand

public String writeCommand(String cmd)
                    throws IOException
Writes a command to the serial port and reads in the resonse. Reading and writing locks on the serial port via a individual thread, RS485ReadWriteServer.ReadWrite. This thread is also responsible for avoiding deadlocking. If the timer runs out or the writing of the command fails for any reason null is returned and should be treated accordingly in the calling method. This method cannot be used on serial devices that do not return a reply on commands sent.

Specified by:
writeCommand in class AbstractSerialDriver
Parameters:
cmd - The command to write
count - The number of bytes to read as a command reply. Zero for unspecified numbers.
Throws:
IOException

deferCommand

public String deferCommand(String cmd)
                    throws IOException
Writes a command to the serial port and reads in the resonse. Only if writing to the port was successful and the received answer does not start with a String (normally a single '?') qualified by KEY_INVALID the string read in is returned. The difference to the writeCommand(java.lang.String) is that this method defers command sending if the server is currently writing. This is the more gentle way of writing a command. As from version 1.1, the defer command waits at max. KEY_MAXBUSY times KEY_TIMEBUSY if the serial server is busy.

Throws:
IOException

ensureCommand

public String ensureCommand(String cmd,
                            int retries)
                     throws IOException
For very faulty serial lines, this method should ensure that a command is sent. It defers commands with deferCommand(java.lang.String) until this method returns non-null. If deferring commands fails for the stated maximum number of retries, a warning is issued to syslog.

Parameters:
retries - If zero, try forever.
Throws:
IOException

startCommand

protected void startCommand(String cmd)
For subclasses only: Start the command thread and return. The caller must ensure proper reading of the result to clean the line.


endCommand

protected String endCommand()
For subclasses only: Read the result of a previous command on clean the line.


cancelCommand

public void cancelCommand()
Cancels the command-read thread. If a command is currently on, the cancel flag of the command-reading thread is set and any result is discarded.


isReading

public boolean isReading()
Queries the server if it is busy writing a command. This method checks if it has a valid reference to a RS485ReadWriteServer.ReadWrite thread stored in it's private commandthread field. If this reference is valid and return true, true is returned.


isReadAlive

public boolean isReadAlive()
Queries the server if it is busy writing a command. This method checks if it has a valid reference to a RS485ReadWriteServer.ReadWrite thread stored in it's private commandthread field. If this reference is valid and return true, true is returned.


writeString

public String writeString(String mess)
                   throws IOException
Writes the argumental string to the output stream. The serial port must be opened prior to calling this method, otherwise writing will fail. If checksumming is enabled the checksum is calculated from the command string and added to the transferred byte array imediately before the terminal KEY_CR character(s).

Note that this method calls flush on the output stream after writing the String as a series of bytes to the port.

This method does not synchronize on the serial port! External synchronization by locking on the #lock object is necessary, if this method is used outside of the writeCommand(java.lang.String) method.

Specified by:
writeString in class AbstractSerialDriver
Returns:
The entire string writtn to the port, including chksum and CR
Throws:
IOException

readString

public String readString()
                  throws IOException
If we have bytes on input, read them, otherwise return null.

Specified by:
readString in class AbstractSerialDriver
Throws:
IOException

interpretString

private String interpretString(String raw)
                        throws IOException
Interprets a string read in from the serial line. If checksumming is enabled, the checksum is verified and, on failure, a Checksum exception is thrown.

Returns:
A string stripped from CR and the checksum bytes.
Throws:
IOException

getCheckSum

protected static final byte[] getCheckSum(byte[] send,
                                          int len)
Calculates a checksum over a number of bytes. Returns the checksum as a len-element byte array. The checksum is calculated by adding all bytes, taking the modulo to 256. The returning two-hex nibble is returned as two bytes bye converting the nibble values to their ascii representation, e.g. 0x31 for 1.