Skip to content

Commit

Permalink
Refactor closable listeners
Browse files Browse the repository at this point in the history
  • Loading branch information
tresf committed Nov 22, 2024
1 parent 1183887 commit 6f6f5cc
Show file tree
Hide file tree
Showing 17 changed files with 156 additions and 151 deletions.
5 changes: 2 additions & 3 deletions src/qz/communication/DeviceIO.java
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
package qz.communication;

public interface DeviceIO {
public interface DeviceIO extends DeviceListener {

String getVendorId();

Expand All @@ -11,8 +11,7 @@ public interface DeviceIO {

boolean isOpen();

void close() throws DeviceException;

void close();

void setStreaming(boolean streaming);

Expand Down
4 changes: 3 additions & 1 deletion src/qz/communication/DeviceListener.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
package qz.communication;

public interface DeviceListener {

/**
* Cleanup task for when a socket closes while a device is still streaming
*/
void close();

}
3 changes: 2 additions & 1 deletion src/qz/communication/FileIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@
import java.nio.file.WatchKey;
import java.util.ArrayList;

public class FileIO {
public class FileIO implements DeviceListener {
public static final String SANDBOX_DATA_SUFFIX = "sandbox";
public static final String GLOBAL_DATA_SUFFIX = "shared";
public static final int FILE_LISTENER_DEFAULT_LINES = 10;
Expand Down Expand Up @@ -153,6 +153,7 @@ public void sendError(String message) throws ClosedChannelException {
}


@Override
public void close() {
if (wk != null) {
wk.cancel();
Expand Down
18 changes: 13 additions & 5 deletions src/qz/communication/H4J_HidIO.java
Original file line number Diff line number Diff line change
@@ -1,21 +1,27 @@
package qz.communication;

import org.hid4java.HidDevice;
import qz.ws.SocketConnection;

import javax.usb.util.UsbUtil;

public class H4J_HidIO implements DeviceIO {
public class H4J_HidIO implements DeviceIO, DeviceListener {

private HidDevice device;

private boolean streaming;

private DeviceOptions dOpts;
private SocketConnection websocket;

public H4J_HidIO(DeviceOptions dOpts) throws DeviceException {
this(H4J_HidUtilities.findDevice(dOpts));

public H4J_HidIO(DeviceOptions dOpts, SocketConnection websocket) throws DeviceException {
this(H4J_HidUtilities.findDevice(dOpts), dOpts, websocket);
}

public H4J_HidIO(HidDevice device) throws DeviceException {
private H4J_HidIO(HidDevice device, DeviceOptions dOpts, SocketConnection websocket) throws DeviceException {
this.dOpts = dOpts;
this.websocket = websocket;
if (device == null) {
throw new DeviceException("HID device could not be found");
}
Expand All @@ -30,7 +36,7 @@ public void open() {
}

public boolean isOpen() {
return device.isOpen();
return !device.isClosed();
}

public void setStreaming(boolean active) {
Expand Down Expand Up @@ -92,6 +98,8 @@ public void sendFeatureReport(byte[] data, Byte reportId) throws DeviceException
}

public void close() {
// Remove orphaned listeners
websocket.removeDevice(dOpts);
if (isOpen()) {
device.close();
}
Expand Down
39 changes: 7 additions & 32 deletions src/qz/communication/H4J_HidListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import qz.ws.StreamEvent;

import javax.usb.util.UsbUtil;
import java.nio.channels.ClosedChannelException;

public class H4J_HidListener implements DeviceListener, HidServicesListener {

Expand All @@ -30,14 +29,8 @@ public H4J_HidListener(Session session) {

@Override
public void hidFailure(HidServicesEvent hidServicesEvent) {
try {
log.debug("Device failure: {}", hidServicesEvent.getHidDevice().getProduct());
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Device Failure"));
}
catch(ClosedChannelException cce) {
log.error("Stream is closed, could not send message");
this.close();
}
log.debug("Device failure: {}", hidServicesEvent.getHidDevice().getProduct());
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Device Failure"), this);
}

@Override
Expand All @@ -49,37 +42,19 @@ public void hidDataReceived(HidServicesEvent hidServicesEvent) {
hex.put(UsbUtil.toHexString(b));
}

try {
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Data Received", hex));
}
catch(ClosedChannelException cce) {
log.error("Stream is closed, could not send message");
this.close();
}
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Data Received", hex), this);
}

@Override
public void hidDeviceDetached(HidServicesEvent hidServicesEvent) {
try {
log.debug("Device detached: {}", hidServicesEvent.getHidDevice().getProduct());
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Device Detached"));
}
catch(ClosedChannelException cce) {
log.error("Stream is closed, could not send message");
this.close();
}
log.debug("Device detached: {}", hidServicesEvent.getHidDevice().getProduct());
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Device Detached"), this);
}

@Override
public void hidDeviceAttached(HidServicesEvent hidServicesEvent) {
try {
log.debug("Device attached: {}", hidServicesEvent.getHidDevice().getProduct());
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Device Attached"));
}
catch(ClosedChannelException cce) {
log.error("Stream is closed, could not send message");
this.close();
}
log.debug("Device attached: {}", hidServicesEvent.getHidDevice().getProduct());
PrintSocketClient.sendStream(session, createStreamAction(hidServicesEvent.getHidDevice(), "Device Attached"), this);
}

private StreamEvent createStreamAction(HidDevice device, String action) {
Expand Down
14 changes: 10 additions & 4 deletions src/qz/communication/PJHA_HidIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import purejavahidapi.InputReportListener;
import purejavahidapi.PureJavaHidApi;
import qz.utils.SystemUtilities;
import qz.ws.SocketConnection;

import javax.usb.util.UsbUtil;
import java.io.IOException;
Expand All @@ -22,13 +23,16 @@ public class PJHA_HidIO implements DeviceIO {
private static final int BUFFER_SIZE = 32;
private Vector<byte[]> dataBuffer;
private boolean streaming;
private DeviceOptions dOpts;
private SocketConnection websocket;


public PJHA_HidIO(DeviceOptions dOpts) throws DeviceException {
this(PJHA_HidUtilities.findDevice(dOpts));
public PJHA_HidIO(DeviceOptions dOpts, SocketConnection websocket) throws DeviceException {
this(PJHA_HidUtilities.findDevice(dOpts), dOpts, websocket);
}

public PJHA_HidIO(HidDeviceInfo deviceInfo) throws DeviceException {
private PJHA_HidIO(HidDeviceInfo deviceInfo, DeviceOptions dOpts, SocketConnection websocket) throws DeviceException {
this.dOpts = dOpts;
this.websocket = websocket;
if (deviceInfo == null) {
throw new DeviceException("HID device could not be found");
}
Expand Down Expand Up @@ -130,6 +134,8 @@ public void sendFeatureReport(byte[] data, Byte reportId) throws DeviceException
}

public void close() {
// Remove orphaned listeners
websocket.removeDevice(dOpts);
if (isOpen()) {
try {
device.setInputReportListener(null);
Expand Down
11 changes: 2 additions & 9 deletions src/qz/communication/PJHA_HidListener.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
import qz.ws.StreamEvent;

import javax.usb.util.UsbUtil;
import java.nio.channels.ClosedChannelException;

public class PJHA_HidListener implements DeviceListener, DeviceRemovalListener {

Expand Down Expand Up @@ -45,13 +44,7 @@ public void close() {

@Override
public void onDeviceRemoval(HidDevice device) {
try {
log.debug("Device detached: {}", device.getHidDeviceInfo().getProductString());
PrintSocketClient.sendStream(session, createStreamAction(device, "Device Detached"));
}
catch(ClosedChannelException cce) {
log.error("Stream is closed, could not send message");
this.close();
}
log.debug("Device detached: {}", device.getHidDeviceInfo().getProductString());
PrintSocketClient.sendStream(session, createStreamAction(device, "Device Detached"), this);
}
}
30 changes: 19 additions & 11 deletions src/qz/communication/SerialIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
import qz.common.ByteArrayBuilder;
import qz.utils.ByteUtilities;
import qz.utils.DeviceUtilities;
import qz.ws.SocketConnection;

import java.io.IOException;

/**
* @author Tres
*/
public class SerialIO {
public class SerialIO implements DeviceListener {

private static final Logger log = LogManager.getLogger(SerialIO.class);

Expand All @@ -28,14 +29,17 @@ public class SerialIO {

private ByteArrayBuilder data = new ByteArrayBuilder();

private SocketConnection websocket;


/**
* Controller for serial communications
*
* @param portName Port name to open, such as "COM1" or "/dev/tty0/"
*/
public SerialIO(String portName) {
public SerialIO(String portName, SocketConnection websocket) {
this.portName = portName;
this.websocket = websocket;
}

/**
Expand Down Expand Up @@ -257,26 +261,30 @@ public void sendData(JSONObject params, SerialOptions opts) throws JSONException
/**
* Closes the serial port, if open.
*
* @return Boolean indicating success.
* @throws SerialPortException If the port fails to close.
*/
public boolean close() throws SerialPortException {
public void close() {
// Remove orphaned listeners
websocket.removeSerialPort(portName);

if (!isOpen()) {
log.warn("Serial port [{}] is not open.", portName);
return false;
}

boolean closed = port.closePort();
if (closed) {
log.info("Serial port [{}] closed successfully.", portName);
} else {
try {
boolean closed = port.closePort();
if (closed) {
log.info("Serial port [{}] closed successfully.", portName);
} else {
// Handle ambiguity in JSSCs API
throw new SerialPortException(portName, "closePort", "Port not closed");
}
} catch(SerialPortException e) {
log.warn("Serial port [{}] was not closed properly.", portName);
}

port = null;
portName = null;

return closed;
}

private Integer min(Integer a, Integer b) {
Expand Down
26 changes: 21 additions & 5 deletions src/qz/communication/SocketIO.java
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
import org.apache.logging.log4j.Logger;
import qz.utils.DeviceUtilities;
import qz.utils.NetworkUtilities;
import qz.ws.SocketConnection;

import java.io.DataInputStream;
import java.io.DataOutputStream;
Expand All @@ -15,7 +16,7 @@
import java.nio.charset.Charset;
import java.util.ArrayList;

public class SocketIO {
public class SocketIO implements DeviceListener {

private static final Logger log = LogManager.getLogger(SocketIO.class);

Expand All @@ -27,10 +28,13 @@ public class SocketIO {
private DataOutputStream dataOut;
private DataInputStream dataIn;

public SocketIO(String host, int port, Charset encoding) {
private SocketConnection websocket;

public SocketIO(String host, int port, Charset encoding, SocketConnection websocket) {
this.host = host;
this.port = port;
this.encoding = encoding;
this.websocket = websocket;
}

public boolean open() throws IOException {
Expand Down Expand Up @@ -68,9 +72,21 @@ public String processSocketResponse() throws IOException {
return null;
}

public void close() throws IOException {
dataOut.close();
socket.close();
@Override
public void close() {
// Remove orphaned listeners
websocket.removeNetworkSocket(String.format("%s:%s", host, port));

try {
dataOut.close();
} catch(IOException e) {
log.warn("Could not close socket output stream", e);
}
try {
socket.close();
} catch(IOException e) {
log.warn("Could not close socket", e);
}
}

public String getHost() {
Expand Down
Loading

0 comments on commit 6f6f5cc

Please sign in to comment.