利用javaxusb从浙江POS打印机接收状态

利用javaxusb从浙江POS打印机接收状态,java,usb,escpos,Java,Usb,Escpos,更新:不要浪费时间。即使包含的SDK也无法成功从此打印机获取任何状态,因此可能不支持它 原始问题: 我有一个漂亮的小程序,不幸的是除了一个非常糟糕的“SDK”之外没有其他文档,它包括一个jar和几个示例 为了绕过这些限制,我尝试直接用javaxusb发送ESC/POS代码,但我怀疑我对USB的理解不透彻会造成干扰。它打印得很开心,但我完全被困在试图从这个小野兽那里恢复身份 它只有一个输入和一个输出端点,分别位于0x81和0x03。下面的代码,以及我在那里找到的每一组与状态相关的消息字节,总是只返

更新:不要浪费时间。即使包含的SDK也无法成功从此打印机获取任何状态,因此可能不支持它

原始问题:

我有一个漂亮的小程序,不幸的是除了一个非常糟糕的“SDK”之外没有其他文档,它包括一个jar和几个示例

为了绕过这些限制,我尝试直接用javaxusb发送ESC/POS代码,但我怀疑我对USB的理解不透彻会造成干扰。它打印得很开心,但我完全被困在试图从这个小野兽那里恢复身份

它只有一个输入和一个输出端点,分别位于0x81和0x03。下面的代码,以及我在那里找到的每一组与状态相关的消息字节,总是只返回一串零,并抛出
javax.usb.UsbException:Pipe仍然很忙

您是否希望以下方法写入请求并返回状态?有没有更好的办法来获取状态码

public void checkStatus(UsbPipe readpipe, UsbPipe writepipe) {
    byte[] msg= { 0x1b, 0x76 }; // ESC-v = { status, per https://www.sparkfun.com/datasheets/Components/General/Driver%20board.pdf
    //byte[] msg= { 0x00, 0x04 }; // DLE EOT is the epson standard status req
    //byte[] msg= { 0x1d, '(', 'H' }; // Another status request from somewhere.
    //byte[] msg= { 0x1d, 'a' }; // Sets Automatic Status Back (ASB) mode.
    //byte[] msg= { 0x1c, '(', 'e' }; // Another way to set ASB -- https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id= {72

    try {
        // Prepare to read response
        readpipe.open();
        byte[] data = new byte[8];
        final UsbIrp rirp = readpipe.asyncSubmit(data);
        rirp.setComplete(false);

        // Send away.
        writepipe.open();
        final UsbIrp wirp = writepipe.asyncSubmit(msg);
        wirp.waitUntilComplete(500);
        writepipe.close();

        // Wait until we get something back
        rirp.waitUntilComplete(500);
        System.out.println("returned data: " + DatatypeConverter.printHexBinary(rirp.getData()));
        readpipe.close();
    } catch (UsbNotActiveException | UsbNotClaimedException | UsbDisconnectedException | UsbException e1) {
        e1.printStackTrace();
    }
}
如果您有一台类似的打印机,并且受到启发尝试运行它,下面是完整的程序

package posprint;

import javax.usb.*;
import javax.usb.event.*;
import javax.xml.bind.DatatypeConverter;

import java.util.List;

public class Main {
    UsbServices services;
    UsbHub roothub;
    UsbDevice dev;
    UsbInterface iface;
    UsbEndpoint endpointOut;
    UsbEndpoint endpointIn;
    UsbPipe mWritepipe;
    UsbPipe mReadpipe;

    public static void main(String[] args) throws Exception {
        Main mn = new Main(); 
        if(mn.dev == null) return;
        mn.checkStatus(mn.mReadpipe, mn.mWritepipe);
        mn.iface.release();
    }

    public Main() throws Exception {
        services = UsbHostManager.getUsbServices();
        short vid = (short) 0x0493;
        short pid = (short) 0x8760;
        roothub = services.getRootUsbHub();
        dev = findDevice(roothub, vid, pid);
        if( dev == null) {
            System.out.println("not found");
            return;
        }
        getPipes(dev);
    }

    UsbDevice findDevice(UsbHub hub, short vendorId, short productId)
    {
        for (UsbDevice device : (List<UsbDevice>) hub.getAttachedUsbDevices())
        {
            UsbDeviceDescriptor desc = device.getUsbDeviceDescriptor();
            if (desc.idVendor() == vendorId && desc.idProduct() == productId) return device;
            if (device.isUsbHub())
            {
                device = findDevice((UsbHub) device, vendorId, productId);
                if (device != null) return device;
            }
        }
        return null;
    }

    void getPipes(UsbDevice device) throws Exception {
        UsbConfiguration configuration = device.getActiveUsbConfiguration();
        List<UsbInterface> ifaces = configuration.getUsbInterfaces();
        for ( UsbInterface ifac : ifaces ) { 
            System.out.println(ifac.toString());
        }

        iface = configuration.getUsbInterface((byte) 0);
        iface.claim(new UsbInterfacePolicy() {            
            @Override public boolean forceClaim(UsbInterface usbInterface)          {
                return true;
            }
        });

        List<UsbEndpoint> eps = iface.getUsbEndpoints();
        for( UsbEndpoint ep : eps ) {
            UsbEndpointDescriptor desc = ep.getUsbEndpointDescriptor();
            System.out.println(ep.toString() + " has endpoint: " + desc.bEndpointAddress());
        }

        endpointOut = iface.getUsbEndpoint((byte) 0x03);
        mWritepipe = endpointOut.getUsbPipe();

        endpointIn = iface.getUsbEndpoint((byte) 0x81); // -127
        mReadpipe = endpointIn.getUsbPipe();
    }

    public void checkControlStatus() throws UsbNotActiveException, UsbNotClaimedException, UsbDisconnectedException, UsbException {
        int ret = 0;
        byte[] readbuf = new byte[2]; 
        try { 
            // Write status request
            UsbControlIrp devirp = mWritepipe.createUsbControlIrp(
                    (byte) (UsbConst.REQUESTTYPE_DIRECTION_IN
                            | UsbConst.REQUESTTYPE_TYPE_STANDARD
                            | UsbConst.REQUESTTYPE_RECIPIENT_DEVICE),
                    UsbConst.REQUEST_GET_STATUS, //UsbConst.REQUEST_GET_CONFIGURATION,
                    (short) 0,
                    (short) 0
                    );
            devirp.setData(readbuf);
            dev.syncSubmit(devirp);
            System.out.println(DatatypeConverter.printHexBinary(devirp.getData()));
        } catch (RuntimeException e) {
            System.out.println(e.getMessage());
            return;
        }
        System.out.println( "Control status: " + DatatypeConverter.printHexBinary(readbuf));
    }

    private class MyListener implements UsbPipeListener {
        public MyListener(String prefix) {this.prefix = prefix; }
        String prefix;
        // used with
        // mReadpipe.addUsbPipeListener(new MyListener("read"));  // For backup, because the async read isn't working.
        @Override public void errorEventOccurred(UsbPipeErrorEvent event) {
            System.out.println(prefix + " pipe error: " + event.toString());
        }
        @Override public void dataEventOccurred(UsbPipeDataEvent event) {
            System.out.println(prefix + " listener data: " + DatatypeConverter.printHexBinary(event.getData()));
        }                   
    }

    public void checkStatus(UsbPipe readpipe, UsbPipe writepipe) {
        byte[] msg= { 0x1b, 0x76 }; // ESC-v = { status, per https://www.sparkfun.com/datasheets/Components/General/Driver%20board.pdf
        //byte[] msg= { 0x00, 0x04 }; // DLE EOT is the epson standard status req
        //byte[] msg= { 0x1d, '(', 'H' }; // Another status request from somewhere.
        //byte[] msg= { 0x1d, 'a' }; // Sets Automatic Status Back (ASB) mode.
        //byte[] msg= { 0x1c, '(', 'e' }; // Another way to set ASB -- https://reference.epson-biz.com/modules/ref_escpos/index.php?content_id= {72

        try {
            // Prepare to read response
            readpipe.open();
            byte[] data = new byte[8];
            final UsbIrp rirp = readpipe.asyncSubmit(data);
            rirp.setComplete(false);

            // Send away.
            writepipe.open();
            final UsbIrp wirp = writepipe.asyncSubmit(msg);
            wirp.waitUntilComplete(500);
            writepipe.close();

            // Wait until we get something back
            rirp.waitUntilComplete(500);
            System.out.println("returned data: " + DatatypeConverter.printHexBinary(rirp.getData()));
            readpipe.close();
        } catch (UsbNotActiveException | UsbNotClaimedException | UsbDisconnectedException | UsbException e1) {
            e1.printStackTrace();
        }
    }
}
package-posprint;
导入javax.usb.*;
导入javax.usb.event.*;
导入javax.xml.bind.DatatypeConverter;
导入java.util.List;
公共班机{
UsbServices服务;
UsbHub根中心;
usbdevicedev;
UsbInterface iface;
UsbEndpoint端点输出;
UsbEndpoint端点;
UsbPipe-mWritepipe;
美国管道公司;
公共静态void main(字符串[]args)引发异常{
Main mn=新的Main();
if(mn.dev==null)返回;
mn.检查状态(mn.mReadpipe,mn.mWritepipe);
mn.iface.release();
}
public Main()引发异常{
services=UsbHostManager.getUsbServices();
短视频=(短)0x0493;
短pid=(短)0x8760;
roothub=services.getRootUsbHub();
dev=findDevice(roothub、vid、pid);
如果(dev==null){
System.out.println(“未找到”);
返回;
}
getPipes(开发);
}
UsbDevice findDevice(UsbHub中心、短供应商ID、短产品ID)
{
对于(UsbDevice设备:(列表)hub.getAttachedUsbDevices())
{
UsbDeviceDescriptor desc=device.getUsbDeviceDescriptor();
if(desc.idVendor()==vendorId&&desc.idProduct()==productId)返回设备;
if(device.isUsbHub())
{
设备=findDevice((UsbHub)设备,供应商ID,产品ID);
如果(设备!=null)返回设备;
}
}
返回null;
}
void getPipes(UsbDevice设备)引发异常{
UsbConfiguration configuration=device.getActiveUsbConfiguration();
List ifaces=configuration.getUsbInterfaces();
对于(USB接口ifac:ifaces){
System.out.println(ifac.toString());
}
iface=configuration.getUsbInterface((字节)0);
iface.claim(新的UsbInterfacePolicy(){
@重写公共布尔forceClaim(UsbInterface UsbInterface){
返回true;
}
});
List eps=iface.getUsbEndpoints();
适用于(UsbEndpoint ep:eps){
UsbEndpointDescriptor desc=ep.getUsbEndpointDescriptor();
System.out.println(ep.toString()+“具有端点:”+desc.bEndpointAddress());
}
endpointOut=iface.getUsbEndpoint((字节)0x03);
mWritepipe=endpointOut.getUsbPipe();
endpointIn=iface.getUsbEndpoint((字节)0x81);//-127
mReadpipe=endpointIn.getUsbPipe();
}
public void checkControlStatus()引发usbNotActivieException、UsbNotClaimedException、UsbDisconnectedException、usbeException{
int-ret=0;
字节[]readbuf=新字节[2];
试试{
//写入状态请求
UsbControlIrp设备=mWritepipe.createUsbControlIrp(
(字节)(UsbConst.REQUESTTYPE_DIRECTION_IN
|UsbConst.REQUESTTYPE\u类型\u标准
|UsbConst.REQUESTTYPE_接收方_设备),
UsbConst.REQUEST\u GET\u状态,//UsbConst.REQUEST\u GET\u配置,
(短)0,
(短)0
);
设备设置数据(readbuf);
开发同步提交(dev.syncSubmit);
System.out.println(DatatypeConverter.printHexBinary(devirp.getData());
}捕获(运行时异常e){
System.out.println(e.getMessage());
返回;
}
System.out.println(“控制状态:“+DatatypeConverter.printHexBinary(readbuf));
}
私有类MyListener实现了UsbPipeListener{
公共MyListener(字符串前缀){this.prefix=prefix;}
字符串前缀;
//用于
//mReadpipe.addUsbPipeListener(新建MyListener(“读取”);//用于备份,因为异步读取不起作用。
@重写已发生的公共void ErrorEvent(UsbPipeErrorEvent事件){
System.out.println(前缀+“管道错误:”+event.toString());
}
@重写已发生的公共void DataEvent(UsbPipeDataEvent事件){
System.out.println(前缀+“侦听器数据:”+DatatypeConverter.printHexBinary(event.getData());
}                   
}
公共无效检查状态(UsbPipe读取管道、UsbPipe写入管道){
字节[]msg={0x1b,0x76};//ESC-v={状态,每https://www.sparkfun.com/datasheets/Components/General/Driver%20board.pdf
//byte[]msg={0x00,0x04};//DLE EOT是爱普生标准状态请求
//字节[]msg={0x1d',(','H'};//来自某处的另一个状态请求。
//字节[]msg={0x1d,'a'};//将自动状态设置回(ASB)模式。
//字节[]msg={0x1c',(','e'};//设置ASB的另一种方法--https://reference.epson-biz.com/modules/ref