Try to leave the serial port in a reusable state if an exception occurs.

This commit is contained in:
akwizgran
2012-11-23 18:00:34 +00:00
parent 91cb3ce7a9
commit 61f4dce408
2 changed files with 30 additions and 5 deletions

View File

@@ -4,17 +4,22 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
/**
* A modem that can be used for multiple sequential incoming and outgoing
* calls. If the modem or its input or output streams throw an exception it
* cannot continue to be used.
*/
interface Modem {
/**
* Call this method once after creating the modem. If an exception is
* thrown, the modem cannot be used.
* Call this method once after creating the modem and before making any
* calls.
*/
void init() throws IOException;
/**
* Initiates an outgoing call and returns true if the call connects. If the
* call does not connect the modem is hung up.
* call does not connect the modem is hung up and can continue to be used.
*/
boolean dial(String number) throws IOException;

View File

@@ -72,6 +72,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
port.writeBytes("ATZ\r\n".getBytes("US-ASCII")); // Reset
port.writeBytes("ATE0\r\n".getBytes("US-ASCII")); // Echo off
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
}
try {
@@ -84,6 +85,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) {
if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while initialising modem");
tryToClose(port);
Thread.currentThread().interrupt();
throw new IOException("Interrupted while initialising modem");
}
@@ -99,6 +101,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try {
port.writeBytes(("ATDT" + number + "\r\n").getBytes("US-ASCII"));
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
}
try {
@@ -108,6 +111,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) {
if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while connecting outgoing call");
tryToClose(port);
Thread.currentThread().interrupt();
throw new IOException("Interrupted while connecting outgoing call");
}
@@ -129,6 +133,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try {
port.setDTR(false);
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
}
received.add(new byte[0]); // Empty buffer indicates EOF
@@ -155,8 +160,10 @@ class ModemImpl implements Modem, SerialPortEventListener {
}
private void handleText(byte[] b) throws IOException {
if(lineLen + b.length > MAX_LINE_LENGTH)
if(lineLen + b.length > MAX_LINE_LENGTH) {
tryToClose(port);
throw new IOException("Line too long");
}
for(int i = 0; i < b.length; i++) {
line[lineLen] = b[i];
if(b[i] == '\n') {
@@ -201,6 +208,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try {
port.writeBytes("ATA\r\n".getBytes("US-ASCII"));
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
}
try {
@@ -210,6 +218,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) {
if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while connecting incoming call");
tryToClose(port);
Thread.currentThread().interrupt();
throw new IOException("Interrupted while connecting incoming call");
}
@@ -217,7 +226,15 @@ class ModemImpl implements Modem, SerialPortEventListener {
else hangUp();
}
private static class ModemInputStream extends InputStream {
private void tryToClose(SerialPort port) {
try {
port.closePort();
} catch(SerialPortException e) {
if(LOG.isLoggable(WARNING)) LOG.warning(e.toString());
}
}
private class ModemInputStream extends InputStream {
private final BlockingQueue<byte[]> received;
@@ -262,6 +279,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) {
if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while reading");
tryToClose(port);
Thread.currentThread().interrupt();
throw new IOException(e.toString());
}
@@ -277,6 +295,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try {
port.writeByte((byte) b);
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
}
}
@@ -286,6 +305,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try {
port.writeBytes(b);
} catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString());
}
}