Skip to content
Snippets Groups Projects
Commit cfb90597 authored by akwizgran's avatar akwizgran
Browse files

Wrapped jSSC's SerialPort and SerialPortList classes for testability.

parent b090a12b
No related branches found
No related tags found
No related merge requests found
......@@ -21,6 +21,6 @@ class ModemFactoryImpl implements ModemFactory {
public Modem createModem(Modem.Callback callback, String portName) {
return new ModemImpl(executor, reliabilityFactory, clock, callback,
portName);
new SerialPortImpl(portName));
}
}
......@@ -12,10 +12,8 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.logging.Logger;
import jssc.SerialPort;
import jssc.SerialPortEvent;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
import net.sf.briar.api.clock.Clock;
import net.sf.briar.api.reliability.ReliabilityLayer;
import net.sf.briar.api.reliability.ReliabilityLayerFactory;
......@@ -47,12 +45,12 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
private boolean initialised = false, connected = false; // Locking: this
ModemImpl(Executor executor, ReliabilityLayerFactory reliabilityFactory,
Clock clock, Callback callback, String portName) {
Clock clock, Callback callback, SerialPort port) {
this.executor = executor;
this.reliabilityFactory = reliabilityFactory;
this.clock = clock;
this.callback = callback;
port = new SerialPort(portName);
this.port = port;
stateChange = new Semaphore(1);
line = new byte[MAX_LINE_LENGTH];
}
......@@ -67,12 +65,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
}
try {
// Open the serial port
try {
if(!port.openPort())
throw new IOException("Failed to open serial port");
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
port.openPort();
// Find a suitable baud rate and initialise the modem
try {
boolean foundBaudRate = false;
......@@ -90,9 +83,9 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
port.addEventListener(this);
port.writeBytes("ATZ\r\n".getBytes("US-ASCII")); // Reset
port.writeBytes("ATE0\r\n".getBytes("US-ASCII")); // Echo off
} catch(SerialPortException e) {
} catch(IOException e) {
tryToClose(port);
throw new IOException(e.toString());
throw e;
}
// Wait for the event thread to receive "OK"
boolean success = false;
......@@ -122,7 +115,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
private void tryToClose(SerialPort port) {
try {
port.closePort();
} catch(SerialPortException e) {
} catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
......@@ -145,11 +138,7 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
}
try {
hangUpInner();
try {
port.closePort();
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
port.closePort();
} finally {
stateChange.release();
}
......@@ -179,9 +168,9 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
tryToClose(port);
Thread.currentThread().interrupt();
throw new IOException("Interrupted while hanging up");
} catch(SerialPortException e) {
} catch(IOException e) {
tryToClose(port);
throw new IOException(e.toString());
throw e;
}
}
......@@ -212,9 +201,9 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
try {
String dial = "ATDT" + number + "\r\n";
port.writeBytes(dial.getBytes("US-ASCII"));
} catch(SerialPortException e) {
} catch(IOException e) {
tryToClose(port);
throw new IOException(e.toString());
throw e;
}
// Wait for the event thread to receive "CONNECT"
try {
......@@ -275,9 +264,9 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
public void handleWrite(byte[] b) throws IOException {
try {
port.writeBytes(b);
} catch(SerialPortException e) {
} catch(IOException e) {
tryToClose(port);
throw new IOException(e.toString());
throw e;
}
}
......@@ -297,8 +286,6 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
}
} catch(IOException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch(SerialPortException e) {
if(LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
......@@ -391,9 +378,9 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
if(LOG.isLoggable(INFO)) LOG.info("Answering");
try {
port.writeBytes("ATA\r\n".getBytes("US-ASCII"));
} catch(SerialPortException e) {
} catch(IOException e) {
tryToClose(port);
throw new IOException(e.toString());
throw e;
}
// Wait for the event thread to receive "CONNECT"
boolean success = false;
......
......@@ -17,7 +17,6 @@ import java.util.concurrent.Executor;
import java.util.concurrent.Semaphore;
import java.util.logging.Logger;
import jssc.SerialPortList;
import net.sf.briar.api.ContactId;
import net.sf.briar.api.TransportProperties;
import net.sf.briar.api.crypto.PseudoRandom;
......@@ -41,6 +40,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
private final Executor pluginExecutor;
private final ModemFactory modemFactory;
private final SerialPortList serialPortList;
private final DuplexPluginCallback callback;
private final long pollingInterval;
private final Semaphore polling;
......@@ -49,10 +49,11 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
private volatile Modem modem = null;
ModemPlugin(@PluginExecutor Executor pluginExecutor,
ModemFactory modemFactory, DuplexPluginCallback callback,
long pollingInterval) {
ModemFactory modemFactory, SerialPortList serialPortList,
DuplexPluginCallback callback, long pollingInterval) {
this.pluginExecutor = pluginExecutor;
this.modemFactory = modemFactory;
this.serialPortList = serialPortList;
this.callback = callback;
this.pollingInterval = pollingInterval;
polling = new Semaphore(1);
......@@ -67,7 +68,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
}
public boolean start() {
for(String portName : SerialPortList.getPortNames()) {
for(String portName : serialPortList.getPortNames()) {
if(LOG.isLoggable(INFO))
LOG.info("Trying to initialise modem on " + portName);
modem = modemFactory.createModem(this, portName);
......@@ -97,7 +98,7 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
private boolean resetModem() {
if(!running) return false;
for(String portName : SerialPortList.getPortNames()) {
for(String portName : serialPortList.getPortNames()) {
modem = modemFactory.createModem(this, portName);
try {
modem.start();
......
......@@ -16,11 +16,13 @@ public class ModemPluginFactory implements DuplexPluginFactory {
private final Executor pluginExecutor;
private final ModemFactory modemFactory;
private final SerialPortList serialPortList;
public ModemPluginFactory(@PluginExecutor Executor pluginExecutor,
ReliabilityLayerFactory reliabilityFactory) {
this.pluginExecutor = pluginExecutor;
modemFactory = new ModemFactoryImpl(pluginExecutor, reliabilityFactory);
serialPortList = new SerialPortListImpl();
}
public TransportId getId() {
......@@ -31,7 +33,7 @@ public class ModemPluginFactory implements DuplexPluginFactory {
// This plugin is not enabled by default
String enabled = callback.getConfig().get("enabled");
if(StringUtils.isNullOrEmpty(enabled)) return null;
return new ModemPlugin(pluginExecutor, modemFactory, callback,
POLLING_INTERVAL);
return new ModemPlugin(pluginExecutor, modemFactory, serialPortList,
callback, POLLING_INTERVAL);
}
}
package net.sf.briar.plugins.modem;
import java.io.IOException;
import jssc.SerialPortEventListener;
interface SerialPort {
void openPort() throws IOException;
void closePort() throws IOException;
boolean setParams(int baudRate, int dataBits, int stopBits, int parityBits)
throws IOException;
void purgePort(int flags) throws IOException;
void addEventListener(SerialPortEventListener l) throws IOException;
byte[] readBytes() throws IOException;
void writeBytes(byte[] b) throws IOException;
}
package net.sf.briar.plugins.modem;
import java.io.IOException;
import jssc.SerialPortEventListener;
import jssc.SerialPortException;
class SerialPortImpl implements SerialPort {
private final jssc.SerialPort port;
SerialPortImpl(String portName) {
port = new jssc.SerialPort(portName);
}
public void openPort() throws IOException {
try {
if(!port.openPort()) throw new IOException("Failed to open port");
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
public void closePort() throws IOException {
try {
if(!port.closePort()) throw new IOException("Failed to close port");
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
public boolean setParams(int baudRate, int dataBits, int stopBits,
int parityBits) throws IOException {
try {
return port.setParams(baudRate, dataBits, stopBits, parityBits);
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
public void purgePort(int flags) throws IOException {
try {
if(!port.purgePort(flags))
throw new IOException("Failed to purge port");
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
public void addEventListener(SerialPortEventListener l) throws IOException {
try {
port.addEventListener(l);
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
public byte[] readBytes() throws IOException {
try {
return port.readBytes();
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
public void writeBytes(byte[] b) throws IOException {
try {
if(!port.writeBytes(b)) throw new IOException("Failed to write");
} catch(SerialPortException e) {
throw new IOException(e.toString());
}
}
}
package net.sf.briar.plugins.modem;
interface SerialPortList {
String[] getPortNames();
}
package net.sf.briar.plugins.modem;
class SerialPortListImpl implements SerialPortList {
public String[] getPortNames() {
return jssc.SerialPortList.getPortNames();
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment