ESCPOS-ThermalPrinter-Android icon indicating copy to clipboard operation
ESCPOS-ThermalPrinter-Android copied to clipboard

UsbDeviceHelper findPrinterInterface dont found my printer

Open bondcs opened this issue 2 years ago • 11 comments

Hi @DantSu, in the latest version this method is returning null when it doesn't find a code 7 printer interface, but my epson TM-20 code interface is 255 (I dont know why).

In version 3.1.2, usbDevice.getInterface(0) was returned when not found, i believe to have a better coverage it would be correct to keep in the old way.

new way

public static UsbInterface findPrinterInterface(UsbDevice usbDevice) {
        if (usbDevice == null) {
            return null;
        } else {
            int interfacesCount = usbDevice.getInterfaceCount();

            for(int i = 0; i < interfacesCount; ++i) {
                UsbInterface usbInterface = usbDevice.getInterface(i);
                if (usbInterface.getInterfaceClass() == 7) {
                    return usbInterface;
                }
            }

            return null;
        }
    }

old way

@Nullable
    static public UsbInterface findPrinterInterface(UsbDevice usbDevice) {
        if (usbDevice == null) {
            return null;
        }
        int interfacesCount = usbDevice.getInterfaceCount();
        for (int i = 0; i < interfacesCount; i++) {
            UsbInterface usbInterface = usbDevice.getInterface(i);
            if (usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_PRINTER) {
                return usbInterface;
            }
        }
        return usbDevice.getInterface(0);
    }

Thanks for good library

bondcs avatar Aug 25 '22 18:08 bondcs

https://github.com/DantSu/ESCPOS-ThermalPrinter-Android/blob/master/escposprinter/src/main/java/com/dantsu/escposprinter/connection/usb/UsbDeviceHelper.java

this still your old way. I haven't change this in the last version. usbInterface.getInterfaceClass() == UsbConstants.USB_CLASS_PRINTER

DantSu avatar Sep 15 '22 13:09 DantSu

Hello, In the old method, the first interface was returned when the printing interface was not found. Perhaps it is better not to restrict the interface of printer, since apparently there are equipment that do not return correctly. My TM-20 is retuning 255 (Vendor Spec) only

Editing**

This is device information from USB manager

UsbDevice[mName=/dev/bus/usb/007/002,mVendorId=1208,mProductId=514,mClass=0,mSubclass=0,mProtocol=0,mManufacturerName=EPSON,mProductName=TM-T20,mVersion=2.0,mSerialNumber=5256324d4962150000,mConfigurations=[
UsbConfiguration[mId=1,mName=null,mAttributes=224,mMaxPower=1,mInterfaces=[
  UsbInterface[mId=0,mAlternateSetting=0,mName=null,mClass=255,mSubclass=255,mProtocol=2,mEndpoints=[
    UsbEndpoint[mAddress=1,mAttributes=2,mMaxPacketSize=64,mInterval=0]
    UsbEndpoint[mAddress=130,mAttributes=2,mMaxPacketSize=64,mInterval=0]
]]]

WhatsApp Image 2022-09-15 at 11 11 28

bondcs avatar Sep 15 '22 13:09 bondcs

Ok I was thinking that come from usbInterface.getInterfaceClass() == 7.

That come from this PR : https://github.com/DantSu/ESCPOS-ThermalPrinter-Android/pull/294/commits/cc48b4097d4f5e0a8bcd3267ffcf277fdc8f6fee

@mcarland Can you explain why you did this change ? There is a specific reason ?

DantSu avatar Sep 15 '22 13:09 DantSu

That come from this PR : cc48b40

@mcarland Can you explain why you did this change ? There is a specific reason ?

Yes, returning the first interface of any USB_CLASS_PER_INTERFACE returns either my devices USB touch screen, or FTDI serial port, if the printer was not on. Trying to print to the returned non-printer was an issue.

If there are printers not classed as printers, like this Epson, maybe there should be a collection of VID/PIDs to match with in addition to the interface class check?

mcarland avatar Sep 15 '22 14:09 mcarland

pffff.... constructors make me crazy.... I don't know what's the good answer to this ....

DantSu avatar Sep 15 '22 14:09 DantSu

I'll make a PR that checks a list of non-compliant printers, see what you think.

mcarland avatar Sep 15 '22 14:09 mcarland

Where will you find information about this ?

DantSu avatar Sep 15 '22 14:09 DantSu

They would have to be added individually as found. I would hope most printers would be coded correctly.

Another option would be a flag passed to findPrinterInterface(UsbDevice usbDevice) that enabled the default return of the first interface.

Returning the first interface blindly if UsbConstants.USB_CLASS_PRINTER was not found, either locked up or NPE later (I don't recall which it's been a while), if there was any PER_INTERFACE or MISC devices but no printer.

Edit: Actually, I don't think the printer had to be off, if I remember correctly when the touch screen or FTDI were enumerated first, it would return one of them.

mcarland avatar Sep 15 '22 14:09 mcarland

I will look to this in the future. That will take me time to find a correct solution to this.

DantSu avatar Sep 15 '22 14:09 DantSu

My previous PR had another commit https://github.com/DantSu/ESCPOS-ThermalPrinter-Android/pull/294/commits/dc614d34cde49fa9b2f3bba43c59ad3f6f2ae3bc that checked for printer interfaces on USB_CLASS_MISC in addition to USB_CLASS_PER_INTERFACE. I just verified that this change was not causing the FTDI or touch screen to be returned by default. This was added because my printer is USB_CLASS_MISC, but both of the incorrectly returned devices are USB_CLASS_PER_INTERFACE.

mcarland avatar Sep 15 '22 16:09 mcarland

Hi, after some research, epson has both classes, Vendor class and printer class, it is possible to change class with driver or performing some steps on the printer. Vendor class is for operating systems not to recognize the printer automatically. I think I could accept both classes preferably for printer class, here the objective is the automatic connection.

In my application, if I don't find printer class, I look for an interface with vendor class.

bondcs avatar Sep 22 '22 13:09 bondcs