mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-12 10:49:06 +01:00
Wrapped jSSC's SerialPort and SerialPortList classes for testability.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
23
briar-core/src/net/sf/briar/plugins/modem/SerialPort.java
Normal file
23
briar-core/src/net/sf/briar/plugins/modem/SerialPort.java
Normal file
@@ -0,0 +1,23 @@
|
||||
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;
|
||||
}
|
||||
@@ -0,0 +1,73 @@
|
||||
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());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,6 @@
|
||||
package net.sf.briar.plugins.modem;
|
||||
|
||||
interface SerialPortList {
|
||||
|
||||
String[] getPortNames();
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
package net.sf.briar.plugins.modem;
|
||||
|
||||
class SerialPortListImpl implements SerialPortList {
|
||||
|
||||
public String[] getPortNames() {
|
||||
return jssc.SerialPortList.getPortNames();
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user