2016-09-20 5 views
1

私はUSB接続の科学機器をWindows(HIDデバイス)(x86とx86_64の両方)と通信するためにusb4java(低レベルAPI)を使用しようとしています。それには非常に古いC++アプリケーションがありますが、さまざまな理由から純粋なJavaに置き換えようとしています。usb4java:データ転送が正常に動作しません

デバイス記述子を取得してインターフェイスとエンドポイントを特定できますが、非同期転送は発生しません(Device Monitoring Studioでチェックされています)。コールバックは決して呼び出されません。 usb4javaによって例外がスローされることはなく、libusbのレベルでログにアクセスできるかどうかはわかりません(もし可能であれば)。私はハードウェアを扱う上での完全な初心者ですから、本当に基本的なものかもしれません。

エンドポイントが1つしかないので、C++コードがどのように双方向通信を管理しているかわかりません。すべての詳細は第三者のライブラリに埋め込まれているので、コード内の転送タイプについては明示的に言及していません。

libusbKドライバをインストールしましたが、ハイレベルの実装(javax-usb)を試しました。転送はまだ通過しません。

以下は、エンドポイント・ディスクリプタ・ダンプの出力と、コードの短縮バージョンです。任意の提案を事前に

import java.nio.*; 
import java.util.*; 
import org.usb4java.*; 


/** 
* This class is intended to test USB communication using usb4java 
* 
*/ 
public class Test { 

    private static final String vendorId = "VVV"; 
    private static final String productId = "PPP"; 

    private Context context; 
    private Device device; 
    private Handle handle; 

    static volatile boolean exit = false; 
    Object synchObj = new Object(); 
    boolean readCompleted = false; 

    private static final int BUFFER_SIZE = 8; 

    private final byte[] idQuery = new byte[]{ 0x1d, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0 }; 

    public Test(){ 

     initialize(); 

     if (device == null){ 
      System.out.println("No target devices found"); 
      System.exit(0); 
     } 

     boolean loop = true; 

     //claim interface 0 
     int result = LibUsb.claimInterface(handle, 0); 
     if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to claim interface", result); 

     //this code doesn't get executed because the transfer never completes correctly 
     final TransferCallback readCallback = new TransferCallback(){ 
      public void processTransfer(Transfer transfer){ 
       System.out.println(transfer.actualLength() + " bytes sent"); 

       //read the response here 

       synchronized (synchObj){ 
        readCompleted = true; 
        synchObj.notify(); 
       } 
      } 
     }; 

     //initial request writing the device identification query 
     write(handle, idQuery, readCallback); 

     //waiting for the write/response to complete 
     while (loop){   
      synchronized (synchObj){ 
       while (!readCompleted){ 
        try{ 
         synchObj.wait(); 
        } 
        catch (InterruptedException ex){ 
         ex.printStackTrace(); 
        } 
       } 
      } 
      readCompleted = false; 
      loop = false; 
      System.out.println("Completed reading"); 
     } 

     result = LibUsb.releaseInterface(handle, 0); 
     LibUsb.close(handle); 

    } 

    private void initialize(){ 
     try{ 
      context = new Context(); 
      int result = LibUsb.init(context); 
      if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to initialize libusb.", result);  

      DeviceList deviceList = new DeviceList(); 
      result = LibUsb.getDeviceList(context, deviceList); 
      if (result < 0) throw new LibUsbException("Unable to get device list.", result); 

      for (int i = 0; i < deviceList.getSize(); i++){ 
       Device dev = deviceList.get(i); 

       DeviceHandle h = new DeviceHandle(); 
       int res = LibUsb.open(dev, h); 
       if (res != LibUsb.SUCCESS) continue; 

       DeviceDescriptor descriptor = new DeviceDescriptor(); 
       result = LibUsb.getDeviceDescriptor(dev, descriptor); 
       if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to read device descriptor", result); 

       String dump = descriptor.dump(h);    
       if (dump.indexOf("PPP") > -1){ 
        device = dev; 
        handle = h; 
        System.out.println("Found target device"); 
        break; 
       } 
      } 

     } 
     catch (Exception ex){ 
      ex.printStackTrace(); 
     } 
    } 

    public static void write(DeviceHandle handle, byte[] data, TransferCallback callback){ 
     ByteBuffer buffer = BufferUtils.allocateByteBuffer(data.length); 
     buffer.put(data); 
     Transfer transfer = LibUsb.allocTransfer(); 
     LibUsb.fillInterruptTransfer(transfer, handle, (byte)0x81, buffer, callback, null, 1000); 
     System.out.println("Sending " + data.length + " bytes to device"); 
     int result = LibUsb.submitTransfer(transfer); 
     if (result != LibUsb.SUCCESS) throw new LibUsbException("Unable to submit transfer", result); 
    } 

    public static void main(String[] args){ 
     Test app = new Test(); 
    } 
} 

ありがとう:

Endpoint Descriptor: 
    bLength     7 
    bDescriptorType   5 
    bEndpointAddress  0x81 EP 1 IN 
    bmAttributes    3 
    Transfer Type    Interrupt 
    Synch Type    None 
    Usage Type    Data 
    wMaxPacketSize   8 
    bInterval    100 
    extralen     0 
    extra: 

は、ここでは、コードです。

答えて

0

初心者:あなたがひっそりとしていない場合は、既に提供されているソフトウェアを使用して暮らすことをお勧めします。あなたの読書を台無しにする可能性を秘めています。

これがうまくいかない理由: 興味深いのはbEndpointAddress 0x81 EP 1 INです。それは、ホストにデータを送信できるエンドポイントがあるということです。はい、ではなく、このエンドポイントに書き込むことができます。これは、デバイスに送信するデータがあり、提供したバッファ内のデータを単に上書きするまで待機します。

なぜこれが当てはまるのか:あなたはHIDを扱っています。単純にASCIIバッファーを戻すのではなく、HIDプロトコルに従って解釈する必要のある特別にフォーマットされたバイト配列を取得するので、そのことについてよく読んでください。

このデバイスにデータを送信する唯一の方法は、エンドポイント0x00の制御転送を使用することです。

最も簡単な方法は、usbスニッファでC++ソフトウェアを使用して、データのやりとりをやりとりすることです。

関連する問題