mirror of
https://code.briarproject.org/briar/briar.git
synced 2026-02-14 03:39:05 +01:00
Code cleanup for modem plugin, better locking in ModemImpl.
This commit is contained in:
@@ -15,10 +15,9 @@ class Crc32 {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static long update(long c, byte[] b, int off, int len) {
|
private static long update(long c, byte[] b, int off, int len) {
|
||||||
for(int i = off; i < off + len; i++) {
|
for(int i = off; i < off + len; i++)
|
||||||
c = TABLE[(int) ((c ^ b[i]) & 0xff)] ^ (c >> 8);
|
c = TABLE[(int) ((c ^ b[i]) & 0xff)] ^ (c >> 8);
|
||||||
}
|
|
||||||
return c;
|
return c;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ abstract class Frame {
|
|||||||
|
|
||||||
protected final byte[] buf;
|
protected final byte[] buf;
|
||||||
|
|
||||||
Frame(byte[] buf) {
|
protected Frame(byte[] buf) {
|
||||||
this.buf = buf;
|
this.buf = buf;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -49,8 +49,8 @@ abstract class Frame {
|
|||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if(o instanceof Frame) {
|
if(o instanceof Frame) {
|
||||||
Frame f = (Frame) o;
|
Frame f = (Frame) o;
|
||||||
if(buf[0] != f.buf[0]) return false;
|
return buf[0] == f.buf[0] &&
|
||||||
return getSequenceNumber() == f.getSequenceNumber();
|
getSequenceNumber() == f.getSequenceNumber();
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,10 +28,10 @@ interface Modem {
|
|||||||
boolean dial(String number) throws IOException;
|
boolean dial(String number) throws IOException;
|
||||||
|
|
||||||
/** Returns a stream for reading from the currently connected call. */
|
/** Returns a stream for reading from the currently connected call. */
|
||||||
InputStream getInputStream();
|
InputStream getInputStream() throws IOException;
|
||||||
|
|
||||||
/** Returns a stream for writing to the currently connected call. */
|
/** Returns a stream for writing to the currently connected call. */
|
||||||
OutputStream getOutputStream();
|
OutputStream getOutputStream() throws IOException;
|
||||||
|
|
||||||
/** Hangs up the modem, ending the currently connected call. */
|
/** Hangs up the modem, ending the currently connected call. */
|
||||||
void hangUp() throws IOException;
|
void hangUp() throws IOException;
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ import java.io.IOException;
|
|||||||
import java.io.InputStream;
|
import java.io.InputStream;
|
||||||
import java.io.OutputStream;
|
import java.io.OutputStream;
|
||||||
import java.util.concurrent.Executor;
|
import java.util.concurrent.Executor;
|
||||||
import java.util.concurrent.Semaphore;
|
|
||||||
import java.util.concurrent.atomic.AtomicBoolean;
|
import java.util.concurrent.atomic.AtomicBoolean;
|
||||||
import java.util.logging.Logger;
|
import java.util.logging.Logger;
|
||||||
|
|
||||||
@@ -32,20 +31,20 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
private final Executor executor;
|
private final Executor executor;
|
||||||
private final Callback callback;
|
private final Callback callback;
|
||||||
private final SerialPort port;
|
private final SerialPort port;
|
||||||
private final AtomicBoolean initialised, connected;
|
private final AtomicBoolean initialised; // Locking: self
|
||||||
private final Semaphore offHook;
|
private final AtomicBoolean connected; // Locking: self
|
||||||
private final byte[] line;
|
private final byte[] line;
|
||||||
|
|
||||||
private int lineLen = 0;
|
private int lineLen = 0;
|
||||||
|
|
||||||
private volatile ReliabilityLayer reliabilityLayer = null;
|
private ReliabilityLayer reliabilityLayer = null; // Locking: this
|
||||||
|
private boolean offHook = false; // Locking: this;
|
||||||
|
|
||||||
ModemImpl(Executor executor, Callback callback, String portName) {
|
ModemImpl(Executor executor, Callback callback, String portName) {
|
||||||
this.executor = executor;
|
this.executor = executor;
|
||||||
this.callback = callback;
|
this.callback = callback;
|
||||||
port = new SerialPort(portName);
|
port = new SerialPort(portName);
|
||||||
initialised = new AtomicBoolean(false);
|
initialised = new AtomicBoolean(false);
|
||||||
offHook = new Semaphore(1);
|
|
||||||
connected = new AtomicBoolean(false);
|
connected = new AtomicBoolean(false);
|
||||||
line = new byte[MAX_LINE_LENGTH];
|
line = new byte[MAX_LINE_LENGTH];
|
||||||
}
|
}
|
||||||
@@ -79,19 +78,19 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
try {
|
try {
|
||||||
synchronized(initialised) {
|
synchronized(initialised) {
|
||||||
if(!initialised.get()) initialised.wait(OK_TIMEOUT);
|
if(!initialised.get()) initialised.wait(OK_TIMEOUT);
|
||||||
|
if(initialised.get()) return;
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
tryToClose(port);
|
tryToClose(port);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new IOException("Interrupted while initialising modem");
|
throw new IOException("Interrupted while initialising modem");
|
||||||
}
|
}
|
||||||
if(!initialised.get())
|
tryToClose(port);
|
||||||
throw new IOException("Modem did not respond");
|
throw new IOException("Modem did not respond");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void stop() throws IOException {
|
public void stop() throws IOException {
|
||||||
if(offHook.tryAcquire()) offHook.release();
|
hangUp();
|
||||||
else hangUp();
|
|
||||||
try {
|
try {
|
||||||
port.closePort();
|
port.closePort();
|
||||||
} catch(SerialPortException e) {
|
} catch(SerialPortException e) {
|
||||||
@@ -100,13 +99,16 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public boolean dial(String number) throws IOException {
|
public boolean dial(String number) throws IOException {
|
||||||
if(!offHook.tryAcquire()) {
|
synchronized(this) {
|
||||||
if(LOG.isLoggable(INFO))
|
if(offHook) {
|
||||||
LOG.info("Not dialling - call in progress");
|
if(LOG.isLoggable(INFO))
|
||||||
return false;
|
LOG.info("Not dialling - call in progress");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
reliabilityLayer = new ReliabilityLayer(this);
|
||||||
|
reliabilityLayer.start();
|
||||||
|
offHook = true;
|
||||||
}
|
}
|
||||||
reliabilityLayer = new ReliabilityLayer(this);
|
|
||||||
reliabilityLayer.start();
|
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Dialling");
|
if(LOG.isLoggable(INFO)) LOG.info("Dialling");
|
||||||
try {
|
try {
|
||||||
port.writeBytes(("ATDT" + number + "\r\n").getBytes("US-ASCII"));
|
port.writeBytes(("ATDT" + number + "\r\n").getBytes("US-ASCII"));
|
||||||
@@ -117,36 +119,46 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
try {
|
try {
|
||||||
synchronized(connected) {
|
synchronized(connected) {
|
||||||
if(!connected.get()) connected.wait(CONNECT_TIMEOUT);
|
if(!connected.get()) connected.wait(CONNECT_TIMEOUT);
|
||||||
|
if(connected.get()) return true;
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
tryToClose(port);
|
tryToClose(port);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new IOException("Interrupted while connecting outgoing call");
|
throw new IOException("Interrupted while connecting outgoing call");
|
||||||
}
|
}
|
||||||
if(connected.get()) return true;
|
|
||||||
hangUp();
|
hangUp();
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public InputStream getInputStream() {
|
public synchronized InputStream getInputStream() throws IOException {
|
||||||
return reliabilityLayer.getInputStream();
|
if(offHook) return reliabilityLayer.getInputStream();
|
||||||
|
throw new IOException("Not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputStream getOutputStream() {
|
public synchronized OutputStream getOutputStream() throws IOException {
|
||||||
return reliabilityLayer.getOutputStream();
|
if(offHook) return reliabilityLayer.getOutputStream();
|
||||||
|
throw new IOException("Not connected");
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hangUp() throws IOException {
|
public void hangUp() throws IOException {
|
||||||
|
synchronized(this) {
|
||||||
|
if(!offHook) {
|
||||||
|
if(LOG.isLoggable(INFO))
|
||||||
|
LOG.info("Not hanging up - already on the hook");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reliabilityLayer.stop();
|
||||||
|
reliabilityLayer = null;
|
||||||
|
offHook = false;
|
||||||
|
}
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Hanging up");
|
if(LOG.isLoggable(INFO)) LOG.info("Hanging up");
|
||||||
|
connected.set(false);
|
||||||
try {
|
try {
|
||||||
port.setDTR(false);
|
port.setDTR(false);
|
||||||
} catch(SerialPortException e) {
|
} catch(SerialPortException e) {
|
||||||
tryToClose(port);
|
tryToClose(port);
|
||||||
throw new IOException(e.toString());
|
throw new IOException(e.toString());
|
||||||
}
|
}
|
||||||
reliabilityLayer.stop();
|
|
||||||
connected.set(false);
|
|
||||||
offHook.release();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void handleWrite(byte[] b) throws IOException {
|
public void handleWrite(byte[] b) throws IOException {
|
||||||
@@ -193,8 +205,8 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
if(LOG.isLoggable(INFO)) LOG.info("Modem status: " + s);
|
if(LOG.isLoggable(INFO)) LOG.info("Modem status: " + s);
|
||||||
if(s.startsWith("CONNECT")) {
|
if(s.startsWith("CONNECT")) {
|
||||||
synchronized(connected) {
|
synchronized(connected) {
|
||||||
if(!connected.getAndSet(true))
|
connected.set(true);
|
||||||
connected.notifyAll();
|
connected.notifyAll();
|
||||||
}
|
}
|
||||||
// There might be data in the buffer as well as text
|
// There might be data in the buffer as well as text
|
||||||
int off = i + 1;
|
int off = i + 1;
|
||||||
@@ -211,8 +223,8 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
}
|
}
|
||||||
} else if(s.equals("OK")) {
|
} else if(s.equals("OK")) {
|
||||||
synchronized(initialised) {
|
synchronized(initialised) {
|
||||||
if(!initialised.getAndSet(true))
|
initialised.set(true);
|
||||||
initialised.notifyAll();
|
initialised.notifyAll();
|
||||||
}
|
}
|
||||||
} else if(s.equals("RING")) {
|
} else if(s.equals("RING")) {
|
||||||
executor.execute(new Runnable() {
|
executor.execute(new Runnable() {
|
||||||
@@ -233,13 +245,16 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void answer() throws IOException {
|
private void answer() throws IOException {
|
||||||
if(!offHook.tryAcquire()) {
|
synchronized(this) {
|
||||||
if(LOG.isLoggable(INFO))
|
if(offHook) {
|
||||||
LOG.info("Not answering - call in progress");
|
if(LOG.isLoggable(INFO))
|
||||||
return;
|
LOG.info("Not answering - call in progress");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
reliabilityLayer = new ReliabilityLayer(this);
|
||||||
|
reliabilityLayer.start();
|
||||||
|
offHook = true;
|
||||||
}
|
}
|
||||||
reliabilityLayer = new ReliabilityLayer(this);
|
|
||||||
reliabilityLayer.start();
|
|
||||||
if(LOG.isLoggable(INFO)) LOG.info("Answering");
|
if(LOG.isLoggable(INFO)) LOG.info("Answering");
|
||||||
try {
|
try {
|
||||||
port.writeBytes("ATA\r\n".getBytes("US-ASCII"));
|
port.writeBytes("ATA\r\n".getBytes("US-ASCII"));
|
||||||
@@ -247,16 +262,18 @@ class ModemImpl implements Modem, WriteHandler, SerialPortEventListener {
|
|||||||
tryToClose(port);
|
tryToClose(port);
|
||||||
throw new IOException(e.toString());
|
throw new IOException(e.toString());
|
||||||
}
|
}
|
||||||
|
boolean success = false;
|
||||||
try {
|
try {
|
||||||
synchronized(connected) {
|
synchronized(connected) {
|
||||||
if(!connected.get()) connected.wait(CONNECT_TIMEOUT);
|
if(!connected.get()) connected.wait(CONNECT_TIMEOUT);
|
||||||
|
success = connected.get();
|
||||||
}
|
}
|
||||||
} catch(InterruptedException e) {
|
} catch(InterruptedException e) {
|
||||||
tryToClose(port);
|
tryToClose(port);
|
||||||
Thread.currentThread().interrupt();
|
Thread.currentThread().interrupt();
|
||||||
throw new IOException("Interrupted while connecting incoming call");
|
throw new IOException("Interrupted while connecting incoming call");
|
||||||
}
|
}
|
||||||
if(connected.get()) callback.incomingCallConnected();
|
if(success) callback.incomingCallConnected();
|
||||||
else hangUp();
|
else hangUp();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -208,11 +208,11 @@ class ModemPlugin implements DuplexPlugin, Modem.Callback {
|
|||||||
|
|
||||||
private final CountDownLatch finished = new CountDownLatch(1);
|
private final CountDownLatch finished = new CountDownLatch(1);
|
||||||
|
|
||||||
public InputStream getInputStream() {
|
public InputStream getInputStream() throws IOException {
|
||||||
return modem.getInputStream();
|
return modem.getInputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
public OutputStream getOutputStream() {
|
public OutputStream getOutputStream() throws IOException {
|
||||||
return modem.getOutputStream();
|
return modem.getOutputStream();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user