2016-09-20 5 views
1

Windows에서 USB 연결 과학 기기 (x86 및 x86_64)를 설정하려면 usb4java (저수준 API)를 사용하여 HID 장치로 설정하려고합니다. 잘 작동하는 아주 오래된 C++ 응용 프로그램이 있지만 여러 가지 이유로 순수 Java로 대체하려고합니다.usb4java : 작동하도록 데이터 전송을 얻을 수 없습니다.

장치 설명자를 가져 와서 인터페이스/끝점을 확인할 수 있지만 비동기 전송이 발생하지 않으며 (Device Monitoring Studio에서 확인 됨) 콜백이 호출되지 않습니다. usb4java에 의해 예외가 발생하지 않으며 libusb 수준의 로그에 액세스 할 수 있는지 여부도 알 수 없습니다 (가능한 경우). 나는 하드웨어를 다루는 데있어 완전한 초보자이기 때문에, 내가 누락 된 것은 정말 기본적인 것이 될 수도있다.

엔드 포인트가 하나 뿐이므로 C++ 코드가 양방향 통신을 관리하는 방법을 잘 모르겠습니다. 모든 세부 사항은 제 3 자 라이브러리에 묻어 있기 때문에 코드의 전송 유형에 대한 명시적인 언급은 없습니다.

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

첫 번째 질문 : 당신이 열중하고 개입하지 않으면 이미 제공된 소프트웨어를 사용하는 것이 좋습니다. Theres 산의 전방 그리고 이것이 과학적인 장치이기 때문에 이것은 당신의 독서를 엉망으로 만드는 잠재력을 가지고 있습니다.

이것이 작동하지 않는 이유 : 흥미로운 점은이 부분이 bEndpointAddress 0x81 EP 1 IN입니다. 이것이 우리에게 말하는 것은 호스트에 데이터를 보낼 수있는 엔드 포인트가 있다는 것입니다. 예, 이 아닌이 끝점에 쓰기가 가능합니다. 이렇게하면 장치에 보낼 데이터가있을 때까지 기다렸다가 제공 한 버퍼에서 데이터를 단순히 덮어 씁니다.

이유에 대해 : 당신은 HID를 다루고 있습니다. HID 프로토콜에 따라 해석되어야하는 특수하게 포맷 된 바이트 배열을 가져 오지 않기 때문에 ASCII 버퍼에 대한 정보를 더 잘 읽을 수 있습니다.

이 장치로 데이터를 보내는 유일한 방법은 끝점 0x00에서 제어 전송을 사용하는 것입니다.

가장 쉬운 방법은 usb 스니퍼로 C++ 소프트웨어를 사용하고 데이터를주고받을 수 있도록하는 것입니다.