Skip to content

Commit

Permalink
Merge pull request #3 from umjammer/0.14.3v
Browse files Browse the repository at this point in the history
0.14.3v
  • Loading branch information
umjammer committed Dec 26, 2023
2 parents 58a71e9 + 17fc4ab commit 51bdae5
Show file tree
Hide file tree
Showing 24 changed files with 3,920 additions and 752 deletions.
5 changes: 4 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -19,11 +19,14 @@

* ~~sigabrt~~ ... `-Djbr.catch.SIGABRT=true` (maybe only for jetbrain's jvm)
* ~~npe on close~~
* windows/linux
* windows/linux not tested yet
* dig into the difference between static and instance method reference

## LESSON

* `sigabrt` `__pthread_kill+0x8` ... suspect using java heap as native memory, like using `byte[]` for a parameter type that should be `Pointer`
* the context object for callback become wired after a while ... [suspect data is garbage collected](https://github.com/umjammer/hid4java/issues/1#issuecomment-1783940125)

---

## Original
Expand Down
26 changes: 21 additions & 5 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

<groupId>org.hid4java</groupId>
<artifactId>hid4java</artifactId>
<version>0.14.2v</version>
<version>0.14.3v</version>

<name>hid4java</name>
<description>A cross-platform Java Native Access (JNA) wrapper for the libusb/hidapi library</description>
Expand Down Expand Up @@ -42,6 +42,11 @@
</repository>
</distributionManagement>

<properties>
<jinput.groupId>com.github.umjammer.jinput</jinput.groupId> <!-- net.java.jinput / com.github.umjammer.jinput -->
<jinput.version>2.0.12v</jinput.version>
</properties>

<build>
<plugins>

Expand Down Expand Up @@ -87,7 +92,8 @@
<artifactId>maven-javadoc-plugin</artifactId>
<version>3.5.0</version>
<configuration>
<source>17</source>
<doclint>none</doclint>
<locale>EN</locale>
</configuration>
<executions>
<execution>
Expand Down Expand Up @@ -138,7 +144,7 @@
<dependency>
<groupId>org.junit</groupId>
<artifactId>junit-bom</artifactId>
<version>5.9.3</version>
<version>5.10.0</version>
<type>pom</type>
<scope>import</scope>
</dependency>
Expand All @@ -147,9 +153,19 @@

<dependencies>
<dependency>
<groupId>com.github.umjammer.jinput</groupId> <!-- net.java.jinput / com.github.umjammer.jinput -->
<groupId>${jinput.groupId}</groupId>
<artifactId>osx-plugin</artifactId>
<version>2.0.11v</version>
<version>${jinput.version}</version>
</dependency>
<dependency>
<groupId>${jinput.groupId}</groupId>
<artifactId>linux-plugin</artifactId>
<version>${jinput.version}</version>
</dependency>
<dependency>
<groupId>${jinput.groupId}</groupId>
<artifactId>windows-plugin</artifactId>
<version>${jinput.version}</version>
</dependency>

<dependency>
Expand Down
118 changes: 40 additions & 78 deletions src/main/java/org/hid4java/HidDevice.java
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,8 @@ public class HidDevice {
private Info info;
private NativeHidDevice nativeDevice;

private boolean isOpen;

/**
* Maximum expected HID Report descriptor size in bytes.
*
Expand All @@ -58,33 +60,33 @@ public static class Info {

public enum HidBusType {
/** Unknown bus type */
HID_API_BUS_UNKNOWN,
BUS_UNKNOWN,
/**
* USB bus
*
* @see "https://usb.org/hid"
*/
HID_API_BUS_USB,
BUS_USB,
/**
* Bluetooth or Bluetooth LE bus
*
* @see "https://www.bluetooth.com/specifications/specs/human-interface-device-profile-1-1-1/"
* @see "https://www.bluetooth.com/specifications/specs/hid-service-1-0/"
* @see "https://www.bluetooth.com/specifications/specs/hid-over-gatt-profile-1-0/"
*/
HID_API_BUS_BLUETOOTH,
BUS_BLUETOOTH,
/**
* I2C bus
*
* @see "https://docs.microsoft.com/previous-versions/windows/hardware/design/dn642101(v=vs.85)"
*/
HID_API_BUS_I2C,
BUS_I2C,
/**
* SPI bus
*
* @see "https://www.microsoft.com/download/details.aspx?id=103325"
*/
HID_API_BUS_SPI
BUS_SPI
}

/** Platform-specific device path */
Expand Down Expand Up @@ -139,7 +141,7 @@ public enum HidBusType {
* @param servicesSpecification The HID services specification providing configuration details
* @since 0.1.0
*/
public HidDevice(Info info, org.hid4java.HidDeviceManager deviceManager, HidServicesSpecification servicesSpecification) {
public HidDevice(Info info, org.hid4java.HidDeviceManager deviceManager, HidServicesSpecification servicesSpecification) throws IOException {

this.manager = deviceManager;

Expand All @@ -154,6 +156,9 @@ public HidDevice(Info info, org.hid4java.HidDeviceManager deviceManager, HidServ
// In Java 8 Short.toUnsignedInt() is available.
this.info.vendorId = this.info.vendorId & 0xffff;
this.info.productId = this.info.productId & 0xffff;

nativeDevice = manager.open(info);
logger.finer(getPath() + "(@" + hashCode() + "): " + nativeDevice);
}

/**
Expand Down Expand Up @@ -246,59 +251,40 @@ public int getInterfaceNumber() {
}

/**
* Open this device and obtain a device structure
* Starts device event system.
*
* @return True if the device was successfully opened
* @since 0.1.0
*/
public boolean open() throws IOException {
logger.finer(getPath() + "(@" + hashCode() + ")");
nativeDevice = manager.open(info);
logger.finer(getPath() + "(@" + hashCode() + "): " + nativeDevice);

return nativeDevice != null;
public void open() throws IOException {
nativeDevice.open();
isOpen = true;
}

/**
* @return True if the device structure is present
* @return True if the device event system started
* @since 0.1.0
* @deprecated Use isClosed() instead of !isOpen() to improve code clarity
*/
@Deprecated
public boolean isOpen() {
return !isClosed();
}

/**
* @return True if the device structure is not present (device closed)
* @since 0.8.0
*/
public boolean isClosed() {
return nativeDevice == null;
return isOpen;
}

/**
* Close this device freeing the HidDeviceManager resources
*
* @since 0.1.0
*/
public void close() {
logger.finest("isClosed: " + info.product + ", " + isClosed());
if (isClosed()) {
//new Exception("close:").printStackTrace();
return;
}

public void close() throws IOException {
logger.finer("close native: " + nativeDevice);
// Close the Hidapi reference
nativeDevice.close();
isOpen = false;
}

/**
* Sets input report listener.
*/
public void setInputReportListener(InputReportListener l) {
nativeDevice.setReportInputListener(l);
public void addInputReportListener(InputReportListener l) {
nativeDevice.addInputReportListener(l);
}

/**
Expand All @@ -316,11 +302,8 @@ public void setInputReportListener(InputReportListener l) {
* been removed from the first byte), or -1 on error.
* @since 0.1.0
*/
public int getFeatureReport(byte[] data, byte reportId) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}
return nativeDevice.getFeatureReport(data, reportId);
public int getFeatureReport(byte[] data, int reportId) throws IOException {
return nativeDevice.getFeatureReport(data, (byte) reportId);
}

/**
Expand All @@ -347,11 +330,8 @@ public int getFeatureReport(byte[] data, byte reportId) throws IOException {
* on error.
* @since 0.1.0
*/
public int sendFeatureReport(byte[] data, byte reportId) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}
return nativeDevice.sendFeatureReport(data, reportId);
public int sendFeatureReport(byte[] data, int reportId) throws IOException {
return nativeDevice.sendFeatureReport(data, (byte)reportId);
}

/**
Expand All @@ -362,11 +342,7 @@ public int sendFeatureReport(byte[] data, byte reportId) throws IOException {
* @since 0.1.0
*/
public String getIndexedString(int index) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}
// TODO for windows/linux
throw new UnsupportedOperationException("hid_get_indexed_string: not available on this platform");
throw new UnsupportedOperationException("getIndexedString: not available on this platform");
}

/**
Expand All @@ -380,11 +356,8 @@ public String getIndexedString(int index) throws IOException {
* @return The number of bytes written (including report ID), or -1 if an error occurs
* @since 0.1.0
*/
public int write(byte[] message, int packetLength, byte reportId) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}
return write(message, packetLength, reportId, false);
public int write(byte[] message, int packetLength, int reportId) throws IOException {
return write(message, packetLength, (byte) reportId, false);
}

/**
Expand All @@ -399,20 +372,15 @@ public int write(byte[] message, int packetLength, byte reportId) throws IOExcep
* @return The number of bytes written (including report ID), or -1 if an error occurs
* @since 0.8.0
*/
public int write(byte[] message, int packetLength, byte reportId, boolean applyPadding) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}

public int write(byte[] message, int packetLength, int reportId, boolean applyPadding) throws IOException {
if (applyPadding) {
message = Arrays.copyOf(message, packetLength + 1);
}

int result = nativeDevice.write(message, packetLength, reportId);
int result = nativeDevice.write(message, packetLength, (byte) reportId);
// Update HID manager
manager.afterDeviceWrite();
return result;

}

/**
Expand All @@ -433,19 +401,13 @@ public boolean isVidPidSerial(int vendorId, int productId, String serialNumber)
}

/** */
public int getReportDescriptor(byte[] report) {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}
public int getReportDescriptor(byte[] report) throws IOException {
return nativeDevice.getReportDescriptor(report);
}

/** */
public int getInputDescriptor(byte[] report, byte reportId) throws IOException {
if (isClosed()) {
throw new IllegalStateException("Device has not been opened");
}
return nativeDevice.getInputReport(report, reportId);
public int getInputDescriptor(byte[] report, int reportId) throws IOException {
return nativeDevice.getInputReport(report, (byte) reportId);
}

@Override
Expand All @@ -467,15 +429,15 @@ public int hashCode() {
@Override
public String toString() {
return "HidDevice [path=" + info.path
+ ", vendorId=0x" + Integer.toHexString(info.vendorId)
+ ", productId=0x" + Integer.toHexString(info.productId)
+ ", serialNumber=" + info.serialNumber
+ ", releaseNumber=0x" + Integer.toHexString(info.releaseNumber)
+ ", manufacturer=" + info.manufacturer
+ String.format(", usagePage=0x%04x", info.usagePage)
+ String.format(", usage=0x%04x", info.usage)
+ String.format(", vendorId=0x%04x", info.vendorId)
+ String.format(", productId=0x%04x", info.productId)
+ ", product=" + info.product
+ ", usagePage=0x" + Integer.toHexString(info.usagePage)
+ ", usage=0x" + Integer.toHexString(info.usage)
+ ", manufacturer=" + info.manufacturer
+ ", interfaceNumber=" + info.interfaceNumber
+ ", serialNumber=" + info.serialNumber
+ ", releaseNumber=0x" + Integer.toHexString(info.releaseNumber)
+ "]";
}

Expand Down
Loading

0 comments on commit 51bdae5

Please sign in to comment.