gary-rowe / hid4java

A cross-platform Java Native Access (JNA) wrapper for the libusb/hidapi library. Works out of the box on Windows/Mac/Linux.
MIT License
234 stars 72 forks source link

hidDataReceived callback never returns more than 64 bytes #159

Open fanaticanders opened 6 days ago

fanaticanders commented 6 days ago

Describe the problem

It seems like hidDataReceived never returns more than 64 bytes of data.

I'm working with a magnetic swipe reader that delivers 337 bytes of data and I only get 64 bytes.

I have downloaded the code and changed readAll to use a buffer of 400 bytes instead and then I get all the data.

You may find that this issue has arisen before, so here is a checklist of useful links to provide assistance and potentially avoid duplicate issues:

Please provide a clear and concise description of what the problem is below:

Platform

To Reproduce

Steps to reproduce the behavior:

Connect a a hidDevice with a interrupt report >64bytes In the hidDataReceived(final HidServicesEvent event) callback you will never get more than 64 bytes

Expected behavior Getting all the data when using hidDataReceived call back

fanaticanders commented 5 days ago

Example code:


import org.hid4java.*;
import org.hid4java.event.HidServicesEvent;

/**
 * Demonstrate the USB HID interface using a Satoshi Labs Trezor
 *
 * @since 0.0.1
 */
public class UsbHidEnumerationExample extends BaseExample {

  public static void main(String[] args) throws HidException {

    UsbHidEnumerationExample example = new UsbHidEnumerationExample();
    example.executeExample();

  }

  private void executeExample() throws HidException {

    printPlatform();

    // Configure to use custom specification
    HidServicesSpecification hidServicesSpecification = new HidServicesSpecification();
    // Use the v0.7.0 manual start feature to get immediate attach events
    hidServicesSpecification.setAutoStart(false);
    hidServicesSpecification.setAutoDataRead(true);

    // Get HID services using custom specification
    HidServices hidServices = HidManager.getHidServices(hidServicesSpecification);
    hidServices.addHidServicesListener(this);

    // Manually start the services to get attachment event
    System.out.println(ANSI_GREEN + "Manually starting HID services." + ANSI_RESET);
    hidServices.start();

    System.out.println(ANSI_GREEN + "Enumerating attached devices..." + ANSI_RESET);

    HidDevice device = hidServices.getHidDevice(0x801, 0x0002, null);

    waitAndShutdown(hidServices);

  }

  @Override
  public void hidDataReceived(HidServicesEvent event) {
    super.hidDataReceived(event);

    System.out.println(ANSI_GREEN + "Received HID data: " + event.getDataReceived().length + " bytes" + ANSI_RESET);
  }

}
fanaticanders commented 5 days ago

Sample logs from unmodified code:

Platform architecture: x86-64
Resource prefix: linux-x86-64
Libusb activation: true
Manually starting HID services.
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw2, vendorId=0x4f3, productId=0x20d0, serialNumber=, releaseNumber=0x1112, manufacturer=ELAN, product=Touchscreen, usagePage=0xd, usage=0x4, interfaceNumber=0]}
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw0, vendorId=0x6cb, productId=0x76af, serialNumber=, releaseNumber=0x0, manufacturer=, product=DLL075B:01 06CB:76AF, usagePage=0x1, usage=0x2, interfaceNumber=-1]}
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw3, vendorId=0x801, productId=0x2, serialNumber=, releaseNumber=0x100, manufacturer=Mag-Tek, product=USB Swipe Reader, usagePage=0xffffff00, usage=0x1, interfaceNumber=0]}
Enumerating attached devices...
Waiting 30s to demonstrate attach/detach handling. Watch for slow response after write if configured.
Data received:
< [40]: 00 00 00 0f 18 00 00 ...
Received HID data: 64 bytes
fanaticanders commented 5 days ago

Changing 64 to 400 in the following line: https://github.com/gary-rowe/hid4java/blob/672f0a7adaeac0ae9ead2cca32548ed0974886c6/src/main/java/org/hid4java/HidDevice.java#L482 Renders these logs:

Platform architecture: x86-64
Resource prefix: linux-x86-64
Libusb activation: true
Manually starting HID services.
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw3, vendorId=0x801, productId=0x2, serialNumber=, releaseNumber=0x100, manufacturer=Mag-Tek, product=USB Swipe Reader, usagePage=0xffffff00, usage=0x1, interfaceNumber=0]}
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw0, vendorId=0x6cb, productId=0x76af, serialNumber=, releaseNumber=0x0, manufacturer=, product=DLL075B:01 06CB:76AF, usagePage=0x1, usage=0x2, interfaceNumber=-1]}
Device attached: HidServicesEvent{hidDevice=HidDevice [path=/dev/hidraw2, vendorId=0x4f3, productId=0x20d0, serialNumber=, releaseNumber=0x1112, manufacturer=ELAN, product=Touchscreen, usagePage=0xd, usage=0x4, interfaceNumber=0]}
Enumerating attached devices...
Waiting 30s to demonstrate attach/detach handling. Watch for slow response after write if configured.
Data received:
< [190]: 00 00 00 0f 18 00 00 ...
Received HID data: 400 bytes