manuelbl / JavaDoesUSB

USB library for Java
MIT License
136 stars 10 forks source link

net.codecrete.usb.UsbTimeoutException: transfer IN on endpoint 2 failed #20

Open flagsoft opened 5 months ago

flagsoft commented 5 months ago

I was able to connect to a printer USB.

Problem: I can not receive any data.

8 bytes sent.
net.codecrete.usb.UsbTimeoutException: transfer IN on endpoint 2 failed

Any idea?

manuelbl commented 5 months ago

It is impossible to say what the cause is without seeing your code and having more information about the printer.

Are the 4 sent bytes data your printer understands and can act on? Did you specify a timeout for the receive, or is this a built-in time out?

I can provide more support of you provide the code and the output of enumerate (just the part describing your printer).

flagsoft commented 5 months ago

Experimenting with an old printer Canon CAPT USB Printer (GDI) I know that this printer accept 4 byte commands. I don't know if I sending it right? Or can should I do a brute force attack and see what happens? In gerneral how can we test devices which do not reply? (The printer works with correct drivers on an old Windows system via USB port.)

Source, monitor.java example modified.

package net.codecrete.usb.examples;

import net.codecrete.usb.Usb;
import net.codecrete.usb.UsbDevice;

import net.codecrete.usb.UsbDirection;

import net.codecrete.usb.UsbRequestType;

import java.io.IOException;

import java.util.HexFormat;
import java.lang.Thread;  

/**
 * Sample application monitoring USB devices as they are connected and disconnected.
 */
public class Monitor
{

    // -- Canon LBP-810
    private static final int VID = 0x04a9;  // Canon
    private static final int PID = 0x260a;  // LBP-810

    // -- Keyboard, VID: 0x1c4f, PID: 0x0002, manufacturer: SIGMACHIP, product: USB Keyboard, serial: null, ID: 4294992995
    //private static final int VID = 0x1c4f;
    //private static final int PID = 0x0002;

    private static final int INTERFACE_NO = 0;
    private static final int ENDPOINT_OUT = 1;
    private static final int ENDPOINT_IN = 2;

    public static void main(String[] args) throws IOException, InterruptedException
    {

        /*System.out.println("-- INFO. START list all devices");
        for (var device : Usb.getAllDevices()) {
            System.out.println(device);
        }
        System.out.println("-- INFO. END list all devices");*/

        // register callbacks for events
        Usb.setOnDeviceConnected(device    -> printDetails(device, "Connected"));
        Usb.setOnDeviceDisconnected(device -> printDetails(device, "Disconnected"));

        // display the already present USB devices
        for (var device : Usb.getDevices()) {
            printDetails(device, "Present");
        }

        // wait for ENTER to quit program
        System.out.println("-- INFO: Monitoring... Press ENTER to quit.");
        System.in.read();
    }

    private static void printDetails(UsbDevice device, String event)
    {
        System.out.printf("%-14s", event + ":");
        System.out.println(device.toString());
        //System.out.println( device.getProductId() );

        // VID: 0x04a9, PID: 0x260a, manufacturer: Canon, product: Canon CAPT USB Printer, serial: 5922JB45, ID: 4294973486
        if ( ( device.getVendorId() == 0x04a9 ) &&
             ( device.getProductId() == 0x260a )
        ) {
          System.out.println( "-- INFO: Canon CAPT USB Printer.");
        }

        if (event.toString() == "Connected") {

          var optionalDevice = Usb.findDevice(VID, PID);
          if (optionalDevice.isEmpty()) {
              System.out.printf("-- INFO: No USB device with VID=0x%04x and PID=0x%04x found.%n", VID, PID);
          } else {
              System.out.printf("-- INFO: USB device with VID=0x%04x and PID=0x%04x found.%n", VID, PID);

              var device2 = optionalDevice.get();

              System.out.printf("getManufacturer:%s\n", device2.getManufacturer());  // "Canon"
              System.out.printf("getProduct:%s\n", device2.getProduct());  // "Canon CAPT USB Printer"
              System.out.printf("getSerialNumber:%s\n", device2.getSerialNumber());  // "5922JB45"
              System.out.printf("getUsbVersion:%s\n", device2.getUsbVersion());  // "1.1.0"
              System.out.printf("getDeviceVersion:%s\n", device2.getDeviceVersion());  // "1.0.0"

              device2.open();

              device2.claimInterface(INTERFACE_NO);

              try {  

                int i;
                for (i = 0; i < 120; i++) {

                  // -- PAPER READY
                  // -- 0xa0, 0xa0, 0, 2);
                  // -- 0xa1, 0xa0, 0, 2);
                  // // d0 00 00 02 b0 09 b3 0d ,  7d 00 [fd|00] 00 00 00 00 00
                  // if 0xFD -> paper ready
                  byte[] data1 = HexFormat.ofDelimiter(":").parseHex("a0:a0:00:02:a1:a0:00:02");

                  /*
                  outb(0x7f,LPPORT);
                  outb(0xbf,LPPORT);
                  outb(0x4f,LPPORT);
                  outb(0x80,LPPORT);
                  */
                  //byte[] data1 = HexFormat.ofDelimiter(":").parseHex("7f:bf:4f:80");  //

                  // -- test CF, LF
                  //byte[] data1 = HexFormat.ofDelimiter(":").parseHex("0d:0a:0d:0a");  //
                  //byte[] data1 = HexFormat.ofDelimiter(":").parseHex("7f:bf:4f:80:0d:0a");  // 0d 0a

                  device2.transferOut(ENDPOINT_OUT, data1);
                  System.out.println(data1.length + " bytes sent.");

                  //Thread.sleep(1000);

                  /*byte[] data2 = HexFormat.ofDelimiter(":").parseHex("a1:a0:00:02");
                  device2.transferOut(ENDPOINT_OUT, data2);
                  System.out.println(data2.length + " bytes sent.");*/

                  //Thread.sleep(1000);

                  //device2.clearHalt(OUT, 1);

                  // --

                  // -- https://javadoc.io/doc/net.codecrete.usb/java-does-usb/latest/net.codecrete.usb/net/codecrete/usb/UsbDevice.html

                  /*byte[] data_cti = controlTransferIn(STANDARD, 255);
                  System.out.println(data_cti.length + " bytes received.");*/

                  // -- TODO: waits forever
                  byte[] data_r;
                  data_r = device2.transferIn(ENDPOINT_IN, 8000);
                  System.out.println(data_r.length + " bytes received.");
                  //System.out.println("Data:" + data_r.data);

                  /*if (cmdbuffer[1][10] == 0xfd) {
                    return 1;
                  }*/

                  // --
                  if (i == 0) {
                    System.out.println("Waiting for paper...");
                  }

                  // -- wait 
                  Thread.sleep(1000);
                  //Thread.sleep(10000);
                  //usleep(1000000);

                }
              } catch (Exception e) {
                System.out.println(e);
              }

              device2.close();

          }

        }

    }

}

Output:

% mvn compile exec:exec [INFO] Scanning for projects... [INFO] [INFO] -----------------< net.codecrete.usb.examples:monitor >----------------- [INFO] Building monitor 0.7.1 [INFO] from pom.xml [INFO] --------------------------------[ jar ]--------------------------------- [INFO] [INFO] --- resources:3.0.2:resources (default-resources) @ monitor --- [INFO] Using 'UTF-8' encoding to copy filtered resources. [INFO] Copying 1 resource [INFO] [INFO] --- compiler:3.8.0:compile (default-compile) @ monitor --- [INFO] Changes detected - recompiling the module! [INFO] Compiling 1 source file to ...../JavaDoesUSB/JavaDoesUSB-main/examples/monitor/target/classes [INFO] [INFO] --- exec:3.1.0:exec (default-cli) @ monitor --- Present: ... Present: VID: 0x04a9, PID: 0x260a, manufacturer: Canon, product: Canon CAPT USB Printer, serial: 5922JB45, ID: 4294968276 -- INFO: Canon CAPT USB Printer. Present: ... Present: ... Present: ... Present: ... -- INFO: Monitoring... Press ENTER to quit. Disconnected: VID: 0x04a9, PID: 0x260a, manufacturer: Canon, product: Canon CAPT USB Printer, serial: 5922JB45, ID: 4294968276 -- INFO: Canon CAPT USB Printer. Connected: VID: 0x04a9, PID: 0x260a, manufacturer: Canon, product: Canon CAPT USB Printer, serial: 5922JB45, ID: 4294970451 -- INFO: Canon CAPT USB Printer. -- INFO: USB device with VID=0x04a9 and PID=0x260a found. getManufacturer:Canon getProduct:Canon CAPT USB Printer getSerialNumber:5922JB45 getUsbVersion:1.1.0 getDeviceVersion:1.0.0 8 bytes sent. net.codecrete.usb.UsbTimeoutException: transfer IN on endpoint 2 failed

[INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 17.938 s [INFO] Finished at: 2024-02-02T10:01:18+01:00 [INFO] ------------------------------------------------------------------------ %

manuelbl commented 5 months ago

The reason a UsbTimeoutException exception is thrown is probably simply because the printer does not send any data.

If it is supposed to send any data after the bytes it has received depends the implemented protocol (application level above USB protocol layer).

Do you have any documentation that indicates that the printer is supposed to send something?