2011-12-07 228 views

回答

0

我剛剛拿到了一個Si470x USB加密狗在Android上工作。我寫一個小包裝類圍繞着Android調用解決了HID部分:

private class HidDevice { 
    /** GET_REPORT request code */ 
    public static final int REQUEST_GET_REPORT = 0x01; 
    /** SET_REPORT request code */ 
    public static final int REQUEST_SET_REPORT = 0x09; 
    /** INPUT report type */ 
    public static final int REPORT_TYPE_INPUT = 0x0100; 
    /** OUTPUT report type */ 
    public static final int REPORT_TYPE_OUTPUT = 0x0200; 
    /** FEATURE report type */ 
    public static final int REPORT_TYPE_FEATURE = 0x0300; 

    private Context context; 
    private UsbManager manager; 
    private UsbDevice device; 
    private UsbInterface ifHid = null; 
    private UsbEndpoint epIn = null; 
    private UsbDeviceConnection connection; 

    public HidDevice(Context context, UsbDevice device) throws IOException { 
     this.context = context; 
     this.device = device; 

     for (int i = 0; (this.ifHid == null) && (i < device.getInterfaceCount()); i++) 
      if (device.getInterface(i).getInterfaceClass() == UsbConstants.USB_CLASS_HID) { 
       this.ifHid = device.getInterface(i); 
       for (int j = 0; j < ifHid.getEndpointCount(); j++) { 
        UsbEndpoint ep = ifHid.getEndpoint(j); 
        if ((ep.getDirection() == UsbConstants.USB_DIR_IN) && (ep.getType() == UsbConstants.USB_ENDPOINT_XFER_INT)) 
         epIn = ep; 
       } 
      } 
     if (this.ifHid == null) 
      throw new IllegalArgumentException("Device has no HID interface"); 
     else if (this.epIn == null) 
      throw new IllegalArgumentException("Device has no INTERRUPT IN endpoint (type USB_ENDPOINT_XFER_INT, direction USB_DIR_IN"); 

     this.manager = (UsbManager) context.getSystemService(Context.USB_SERVICE); 
     this.connection = manager.openDevice(device); 
     if (!connection.claimInterface(ifHid, true)) 
      throw new IOException("Failed to claim HID interface"); 
    } 

    public int getFeatureReport(int reportId, byte[] data, int length) { 
     if ((reportId & 0xFF) != reportId) 
      throw new IllegalArgumentException("reportId may only set the lowest 8 bits"); 
     return connection.controlTransfer(
       UsbConstants.USB_DIR_IN | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 
       REQUEST_GET_REPORT, 
       reportId | REPORT_TYPE_OUTPUT, 
       ifHid.getId(), data, length, 0); 
    } 

    public int read(byte[] data, int length) { 
     return connection.bulkTransfer(epIn, data, length, 0); 
    } 

    public int sendFeatureReport(int reportId, byte[] data, int length) { 
     if ((reportId & 0xFF) != reportId) 
      throw new IllegalArgumentException("reportId may only set the lowest 8 bits"); 
     return connection.controlTransfer(
       UsbConstants.USB_DIR_OUT | UsbConstants.USB_TYPE_CLASS | UsbConstants.USB_INTERFACE_SUBCLASS_BOOT, 
       REQUEST_SET_REPORT, 
       reportId | REPORT_TYPE_INPUT, 
       ifHid.getId(), data, length, 0); 
    } 
} 

請注意,不像HIDAPI,Android的發送或查詢功能的報告時,對報告數量的獨立參數。您不需要預先填充數據數組。但是,返回結果時,結果數組將具有報告編號作爲其第一個元素。

對於高層次的東西,看看Linux driverhid_open()對應於HidDevice的構造函數,其餘的應該很簡單。

請注意,在拼接來自byte[]數組的數據時,Java中缺少無符號整數類型可能會產生不必要的副作用。解決方法是使用(data[i] & 0xFF)而不是data[i]

音頻不通過此通道傳輸 - 加密狗爲此實現了一個單獨的音頻設備,這似乎是一個標準的Linux音頻設備。沒有經驗,但(對於我的項目,我只需要RDS數據)。