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.InputStream;
import java.io.OutputStream; 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 { interface Modem {
/** /**
* Call this method once after creating the modem. If an exception is * Call this method once after creating the modem and before making any
* thrown, the modem cannot be used. * calls.
*/ */
void init() throws IOException; void init() throws IOException;
/** /**
* Initiates an outgoing call and returns true if the call connects. If the * 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; 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("ATZ\r\n".getBytes("US-ASCII")); // Reset
port.writeBytes("ATE0\r\n".getBytes("US-ASCII")); // Echo off port.writeBytes("ATE0\r\n".getBytes("US-ASCII")); // Echo off
} catch(SerialPortException e) { } catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
try { try {
@@ -84,6 +85,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) { } catch(InterruptedException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while initialising modem"); LOG.warning("Interrupted while initialising modem");
tryToClose(port);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
throw new IOException("Interrupted while initialising modem"); throw new IOException("Interrupted while initialising modem");
} }
@@ -99,6 +101,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try { try {
port.writeBytes(("ATDT" + number + "\r\n").getBytes("US-ASCII")); port.writeBytes(("ATDT" + number + "\r\n").getBytes("US-ASCII"));
} catch(SerialPortException e) { } catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
try { try {
@@ -108,6 +111,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) { } catch(InterruptedException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while connecting outgoing call"); LOG.warning("Interrupted while connecting outgoing call");
tryToClose(port);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
throw new IOException("Interrupted while connecting outgoing call"); throw new IOException("Interrupted while connecting outgoing call");
} }
@@ -129,6 +133,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try { try {
port.setDTR(false); port.setDTR(false);
} catch(SerialPortException e) { } catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
received.add(new byte[0]); // Empty buffer indicates EOF 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 { 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"); throw new IOException("Line too long");
}
for(int i = 0; i < b.length; i++) { for(int i = 0; i < b.length; i++) {
line[lineLen] = b[i]; line[lineLen] = b[i];
if(b[i] == '\n') { if(b[i] == '\n') {
@@ -201,6 +208,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try { try {
port.writeBytes("ATA\r\n".getBytes("US-ASCII")); port.writeBytes("ATA\r\n".getBytes("US-ASCII"));
} catch(SerialPortException e) { } catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
try { try {
@@ -210,6 +218,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) { } catch(InterruptedException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while connecting incoming call"); LOG.warning("Interrupted while connecting incoming call");
tryToClose(port);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
throw new IOException("Interrupted while connecting incoming call"); throw new IOException("Interrupted while connecting incoming call");
} }
@@ -217,7 +226,15 @@ class ModemImpl implements Modem, SerialPortEventListener {
else hangUp(); 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; private final BlockingQueue<byte[]> received;
@@ -262,6 +279,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
} catch(InterruptedException e) { } catch(InterruptedException e) {
if(LOG.isLoggable(WARNING)) if(LOG.isLoggable(WARNING))
LOG.warning("Interrupted while reading"); LOG.warning("Interrupted while reading");
tryToClose(port);
Thread.currentThread().interrupt(); Thread.currentThread().interrupt();
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
@@ -277,6 +295,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try { try {
port.writeByte((byte) b); port.writeByte((byte) b);
} catch(SerialPortException e) { } catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
} }
@@ -286,6 +305,7 @@ class ModemImpl implements Modem, SerialPortEventListener {
try { try {
port.writeBytes(b); port.writeBytes(b);
} catch(SerialPortException e) { } catch(SerialPortException e) {
tryToClose(port);
throw new IOException(e.toString()); throw new IOException(e.toString());
} }
} }