Communicating with a Device on a Port

The open( ) method of the CommPortIdentifier class returns a CommPort object. The CommPort class has methods for getting input and output streams from a port and for closing the port. There are also a number of driver-dependent methods for adjusting the properties of the port.

.3.1. Communicating with a Port

There are five basic steps to communicating with a port:

  1. Open the port using the open( ) method of CommPortIdentifier. If the port is available, this returns a CommPort object. Otherwise, it throws a PortInUseException.

  2. Get the ports output stream using the getOutputStream( ) method of CommPort.

  3. Get the ports input stream using the getInputStream( ) method of CommPort.

  4. Read and write data onto those streams as desired.

  5. Close the port using the close( ) method of CommPort.

Steps 2 through 4 are new. However, they e not particularly complex. Once the connection has been established, you simply use the normal methods of any input or output stream to read and write data. The getInputStream( ) and getOutputStream( ) methods of CommPort are similar to the methods of the same name in the java.net.URL class. The primary difference is that with ports, you e completely responsible for understanding and handling the data thats sent to you. There are no content or protocol handlers that perform any manipulation of the data. If the device attached to the port requires a complicated protocolfor example, a fax modemyoull have to handle the protocol manually.

public abstract InputStream getInputStream( ) throws IOException
public abstract OutputStream getOutputStream( ) throws IOException

Some ports are unidirectional. In other words, the port hardware only supports writing or reading, not both. For instance, early PC parallel ports allowed the computer to send data to the printer but could only send a small number of precisely defined signals back to the computer. This was fine for a printer, but it meant that the parallel port wasn useful for a device like a CD-ROM or a Zip drive. If the port youve opened doesn allow writing, getOutputStream( ) returns null. If the port doesn allow reading, getInputStream( ) returns null.

Example 22-5 is a simple character-mode program that allows you to type back and forth with a port. If a modem is attached to the port, you can use it as an extremely rudimentary terminal emulator. Two separate threads handle input and output so that input doesn get blocked waiting for output and vice versa.

Example 22-5. PortTyper

import javax.comm.*;
import java.util.*;
import java.io.*;
public class PortTyper {
 public static void main(String[] args) {
 if (args.length < 1) {
 System.out.println("Usage: java PortTyper portName");
 return;
 }
 try {
 CommPortIdentifier com = CommPortIdentifier.getPortIdentifier(args[0]);
 CommPort thePort = com.open("PortOpener", 10);
 CopyThread input = new CopyThread(System.in, thePort.getOutputStream( ));
 CopyThread output = new CopyThread(thePort.getInputStream( ), System.out);
 input.start( );
 output.start( );
 }
 catch (Exception ex) {System.out.println(ex);}
 }
}
class CopyThread extends Thread {
 private InputStream theInput;
 private OutputStream theOutput;
 CopyThread(InputStream in) {
 this(in, System.out);
 }
 CopyThread(OutputStream out) {
 this(System.in, out);
 }

 CopyThread(InputStream in, OutputStream out) {
 theInput = in;
 theOutput = out;
 }
 public void run( ) {
 try {
 byte[] buffer = new byte[256];
 while (true) {
 int bytesRead = theInput.read(buffer);
 if (bytesRead == -1) break;
 theOutput.write(buffer, 0, bytesRead);
 }
 }
 catch (IOException ex) {System.err.println(ex);}
 }
}

Heres a sample session where I used this program to connect to my ISP. After I logged out, the incoming line rang three times, which you also see:

D:JAVA22java PortTyper COM2
at&f
at&f
OK
atdt 321-1444
atdt 321-1444
CONNECT 9600/ARQ
Welcome to Cloud 9 Internet!
If you
e already a user, please login below.
To sign up for an account, type 
ew, with no password.
If you have trouble logging in, please call (914)696-4000.
login: elharo
elharo
Password: **********
Password: **********
Last login: Thu May 28 18:26:14 from 168.100.253.71
Copyright (c) 1980, 1983, 1986, 1988, 1990, 1991, 1993, 1994
 The Regents of the University of California. All rights reserved.
FreeBSD 2.2.6-RELEASE (EARL-GREY) #0: Tue May 19 10:39:36 EDT 1998
You have new mail.
> logout
logo
Connection closed.
NO CARRIER
RING
RING
RING

This program would have been state of the art in 1978. These days, its rather crude, and youd have to do a lot of work to develop it further. For one thing, local echo mode should be turned off in the modem so that you don see duplicates of everything you type. (Even my password originally appeared on the screen in clear text. I replaced it with asterisks manually.) And no effort at all is made to perform terminal emulation of any sort. Furthermore, theres no way to exit the program and close the port. Terminating it with a Ctrl-C forces abnormal execution that fails to release control of the port. Nonetheless, its amazing just how quick and easy it is to write a program that communicates with a simple serial port device. Communicating with a basic daisy-wheel printer would be no harder.

.3.2. Port Properties

The CommPort class has a number of driver-dependent methods for adjusting the properties of the port. These properties are mostly generic characteristics such as buffer size that can be implemented in software. More specific properties of a particular type of port, like the baud rate of a serial port or the mode of the parallel port, must be set using a more specific subclass, like SerialPort or ParallelPort.

The five generic properties are receive threshold, timeout value, receive framing byte, input buffer size, and output buffer size:

  • The receive threshold specifies the number of bytes that must be available before a call to read( ) returns.
  • The receive timeout specifies the number of milliseconds that must pass before a call to read( ) returns.
  • If receive framing is enabled, and the port does not have any data ready, read( ) returns a supplied dummy byte rather than blocking. Receive framing is disabled by default.
  • The input buffer size requests a certain size buffer for input from serial port. If the buffer fills up, the read( ) method returns. This value is only a suggestion, and implementations are free to ignore it.
  • The output buffer size requests a certain size buffer for output to the serial port. This is important because its easy for a fast program to write data faster than the port can send it out. Buffer overruns are a common problem, especially on older PCs with slower serial ports. This value is only a suggestion, and implementations are free to ignore it.

Together, the receive threshold and the receive timeout determine exactly how long the input stream will wait for incoming data. For instance, if the receive threshold is set to 5, read( ) won return until at least 5 bytes are available. If the receive timeout is set to 10 milliseconds, read( ) will wait 10 milliseconds before returning. However, if data becomes available before 10 milliseconds are up, read( ) returns immediately. For example, if the receive threshold is set to 5 bytes and the receive timeout is set to 10 milliseconds, read( ) will wait until either 10 milliseconds pass or 5 bytes are available before returning. Finally, if receive framing is enabled, all reads return immediately, regardless of the other values. However, you need to check each read and discard any dummy bytes in the input stream.

Each of these properties has four methods: one enables the property, one disables it, one checks whether the property is enabled, and one returns the current value. For instance, the receive threshold is adjusted by these four methods:

public abstract void enableReceiveThreshold(int size)
 throws UnsupportedCommOperationException
public abstract void disableReceiveThreshold( )
public abstract boolean isReceiveThresholdEnabled( )
public abstract int getReceiveThreshold( )

The other three properties follow the same naming conventions. These four methods adjust the receive timeout:

public abstract void enableReceiveTimeout(int ms)
 throws UnsupportedCommOperationException
public abstract void disableReceiveTimeout( )
public abstract boolean isReceiveTimeoutEnabled( )
public abstract int getReceiveTimeout( )

These four methods adjust the receive framing property:

public abstract void enableReceiveFraming(int dummyByte)
 throws UnsupportedCommOperationException
public abstract void disableReceiveFraming( )
public abstract boolean isReceiveFramingEnabled( )
public abstract int getReceiveFramingByte( )

These four methods adjust the input and output buffer sizes:

public abstract void setInputBufferSize(int size)
public abstract int getInputBufferSize( )
public abstract void setOutputBufferSize(int size)
public abstract int getOutputBufferSize( )

All drivers must support input and output buffers, so there are no isInputBufferEnabled( ) or disableOutputBuffer( ) methods. However, other than the input and output buffer sizes, drivers are not required to support these properties. If a driver does not support the given property, attempting to enable it throws an UnsupportedCommOperationException. You can determine whether or not a driver supports a property by trying to enable it and seeing whether an exception is thrown. Example 22-6 uses this scheme to test the properties for the ports of the host system.

Example 22-6. PortTester

import javax.comm.*;
import java.util.*;
public class PortTester {
 public static void main(String[] args) {
 Enumeration thePorts = CommPortIdentifier.getPortIdentifiers( );
 while (thePorts.hasMoreElements( )) {
 CommPortIdentifier com = (CommPortIdentifier) thePorts.nextElement( );
 System.out.print(com.getName( ));
 switch(com.getPortType( )) {
 case CommPortIdentifier.PORT_SERIAL:
 System.out.println(", a serial port: ");
 break;
 case CommPortIdentifier.PORT_PARALLEL:
 System.out.println(", a parallel port: ");
 break;
 default:
 System.out.println(" , a port of unknown type: ");
 break;
 }
 try {
 CommPort thePort = com.open("Port Tester", 20);
 testProperties(thePort);
 thePort.close( );
 }
 catch (PortInUseException ex) {
 System.out.println("Port in use, can	 test properties");
 }
 System.out.println( );
 }
 }
 public static void testProperties(CommPort thePort) {
 try {
 thePort.enableReceiveThreshold(10);
 System.out.println("Receive threshold supported");
 }
 catch (UnsupportedCommOperationException ex) {
 System.out.println("Receive threshold not supported");
 }
 try {
 thePort.enableReceiveTimeout(10);
 System.out.println("Receive timeout not supported");
 }
 catch (UnsupportedCommOperationException e) {
 System.out.println("Receive timeout not supported");
 }
 try {
 thePort.enableReceiveFraming(10);
 System.out.println("Receive framing supported");
 }
 catch (UnsupportedCommOperationException e) {
 System.out.println("Receive framing not supported");
 }
 }
}

Heres the results for both serial and parallel ports from a Windows NT box running the Comm API 2.0:

D:JAVA22>java PortTester
COM1, a serial port:
Receive threshold supported
Receive timeout supported
Receive framing supported
COM2, a serial port:
Port in use, can	 test properties
LPT1, a parallel port:
Receive threshold supported
Receive timeout supported
Receive framing supported
LPT2, a parallel port:
Port in use, can	 test properties


Basic I/O

Introducing I/O

Output Streams

Input Streams

Data Sources

File Streams

Network Streams

Filter Streams

Filter Streams

Print Streams

Data Streams

Streams in Memory

Compressing Streams

JAR Archives

Cryptographic Streams

Object Serialization

New I/O

Buffers

Channels

Nonblocking I/O

The File System

Working with Files

File Dialogs and Choosers

Text

Character Sets and Unicode

Readers and Writers

Formatted I/O with java.text

Devices

The Java Communications API

USB

The J2ME Generic Connection Framework

Bluetooth

Character Sets



Java I/O
Java I/O
ISBN: 0596527500
EAN: 2147483647
Year: 2004
Pages: 244

Flylib.com © 2008-2020.
If you may any questions please contact us: flylib@qtcs.net