Files
quality_app/old code/tray/src/qz/communication/PJHA_HidIO.java
Quality System Admin c96039542d updated control access
2025-10-16 02:36:32 +03:00

155 lines
4.7 KiB
Java
Executable File

package qz.communication;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;
import purejavahidapi.HidDevice;
import purejavahidapi.HidDeviceInfo;
import purejavahidapi.InputReportListener;
import purejavahidapi.PureJavaHidApi;
import qz.utils.SystemUtilities;
import qz.ws.SocketConnection;
import javax.usb.util.UsbUtil;
import java.io.IOException;
import java.util.Vector;
public class PJHA_HidIO implements DeviceIO {
private static final Logger log = LogManager.getLogger(PJHA_HidIO.class);
private HidDeviceInfo deviceInfo;
private HidDevice device;
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, SocketConnection websocket) throws DeviceException {
this(PJHA_HidUtilities.findDevice(dOpts), dOpts, websocket);
}
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");
}
this.deviceInfo = deviceInfo;
dataBuffer = new Vector<byte[]>() {
@Override
public synchronized boolean add(byte[] e) {
while(this.size() >= BUFFER_SIZE) {
this.remove(0);
}
return super.add(e);
}
};
}
public void open() throws DeviceException {
if (!isOpen()) {
try {
device = PureJavaHidApi.openDevice(deviceInfo);
device.setInputReportListener(new InputReportListener() {
@Override
public void onInputReport(HidDevice source, byte id, byte[] data, int len) {
byte[] dataCopy = new byte[len];
System.arraycopy(data, 0, dataCopy, 0, len);
dataBuffer.add(dataCopy);
}
});
}
catch(IOException ex) {
throw new DeviceException(ex);
}
}
}
public boolean isOpen() {
return device != null;
}
public void setStreaming(boolean active) {
streaming = active;
}
public boolean isStreaming() {
return streaming;
}
public String getVendorId() {
return UsbUtil.toHexString(deviceInfo.getVendorId());
}
public String getProductId() {
return UsbUtil.toHexString(deviceInfo.getProductId());
}
public byte[] readData(int responseSize, Byte unused) throws DeviceException {
byte[] response = new byte[responseSize];
if (dataBuffer.isEmpty()) {
return new byte[0]; //no data received yet
}
byte[] latestData = dataBuffer.remove(0);
if (SystemUtilities.isWindows()) {
//windows missing the leading byte
System.arraycopy(latestData, 0, response, 1, Math.min(responseSize - 1, latestData.length));
} else {
System.arraycopy(latestData, 0, response, 0, Math.min(responseSize - 1, latestData.length));
}
return response;
}
public void sendData(byte[] data, Byte reportId) throws DeviceException {
if (reportId == null) { reportId = (byte)0x00; }
int wrote = device.setOutputReport(reportId, data, data.length);
if (wrote == -1) {
throw new DeviceException("Failed to write to device");
}
}
public byte[] getFeatureReport(int responseSize, Byte unused) throws DeviceException {
byte[] response = new byte[responseSize];
int read = device.getFeatureReport(response, responseSize);
if (read == -1) {
throw new DeviceException("Failed to read from device");
}
return response;
}
public void sendFeatureReport(byte[] data, Byte reportId) throws DeviceException {
if (reportId == null) { reportId = (byte)0x00; }
int wrote = device.setFeatureReport(reportId, data, data.length);
if (wrote == -1) {
throw new DeviceException("Failed to write to device");
}
}
@Override
public void close() {
setStreaming(false);
// Remove orphaned reference
websocket.removeDevice(dOpts);
if (isOpen()) {
try {
device.setInputReportListener(null);
device.close();
}
catch(IllegalStateException e) {
log.warn("Device already closed");
}
}
device = null;
}
}