diff --git a/src/net/sf/briar/plugins/modem/Modem.java b/src/net/sf/briar/plugins/modem/Modem.java index d85a7bfacd4ba257d113aa250a9dcf26cb1ace8c..e758ef8b820dfcca3ce8bb6070f2c424ce8e3726 100644 --- a/src/net/sf/briar/plugins/modem/Modem.java +++ b/src/net/sf/briar/plugins/modem/Modem.java @@ -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; diff --git a/src/net/sf/briar/plugins/modem/ModemImpl.java b/src/net/sf/briar/plugins/modem/ModemImpl.java index be4515fa57adf1f24d0bb6d27bca7e333ce0a7c7..d66907ce0962e9c75723c24ba15fc92fe8629c22 100644 --- a/src/net/sf/briar/plugins/modem/ModemImpl.java +++ b/src/net/sf/briar/plugins/modem/ModemImpl.java @@ -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()); } }