1. 程式人生 > >Android5.0 OTG模組傳輸速度-bulkTransfer

Android5.0 OTG模組傳輸速度-bulkTransfer

這個函式還是比較簡單的,沒有太多層級:

1.UsbDeviceConnection.java (\frameworks\base\core\java\android\hardware\usb) 

    /**
     * Performs a bulk transaction on the given endpoint.
     * The direction of the transfer is determined by the direction of the endpoint.
     * <p>
     * This method transfers data starting from index 0 in the buffer.
     * To specify a different offset, use
     * {@link #bulkTransfer(UsbEndpoint, byte[], int, int, int)}.
     * </p>
     *
     * @param endpoint the endpoint for this transaction
     * @param buffer buffer for data to send or receive
     * @param length the length of the data to send or receive
     * @param timeout in milliseconds
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     */
    public int bulkTransfer(UsbEndpoint endpoint,
            byte[] buffer, int length, int timeout) {
        return bulkTransfer(endpoint, buffer, 0, length, timeout);
    }
    public int bulkTransfer(UsbEndpoint endpoint,
            byte[] buffer, int offset, int length, int timeout) {
        checkBounds(buffer, offset, length);
        return native_bulk_request(endpoint.getAddress(), buffer, offset, length, timeout);
    }
    private native int native_bulk_request(int endpoint, byte[] buffer,
            int offset, int length, int timeout);

2.android_hardware_UsbDeviceConnection.cpp (\frameworks\base\core\jni) 

   {"native_bulk_request",     "(I[BIII)I",
                                        (void *)android_hardware_UsbDeviceConnection_bulk_request},
android_hardware_UsbDeviceConnection_bulk_request(JNIEnv *env, jobject thiz,
        jint endpoint, jbyteArray buffer, jint start, jint length, jint timeout)
{
    struct usb_device* device = get_device_from_object(env, thiz);
    if (!device) {
        ALOGE("device is closed in native_control_request");
        return -1;
    }

    jbyte* bufferBytes = NULL;
    if (buffer) {
        bufferBytes = (jbyte*)env->GetPrimitiveArrayCritical(buffer, NULL);
    }

    jint result = usb_device_bulk_transfer(device, endpoint, bufferBytes + start, length, timeout);

    if (bufferBytes) {
        env->ReleasePrimitiveArrayCritical(buffer, bufferBytes, 0);
    }

    return result;
}
int usb_device_bulk_transfer(struct usb_device *device,
                            int endpoint,
                            void* buffer,
                            int length,
                            unsigned int timeout)
{
    struct usbdevfs_bulktransfer  ctrl;

    // need to limit request size to avoid EINVAL
    if (length > MAX_USBFS_BUFFER_SIZE)
        length = MAX_USBFS_BUFFER_SIZE;

    memset(&ctrl, 0, sizeof(ctrl));
    ctrl.ep = endpoint;
    ctrl.len = length;
    ctrl.data = buffer;
    ctrl.timeout = timeout;
    return ioctl(device->fd, USBDEVFS_BULK, &ctrl);
}

結合前面的部分來理解:

通過Log得到的裝置資訊如下:

deviceinfo=UsbDevice[mName=/dev/bus/usb/001/002,mVendorId=1256,mProductId=42240,mClass=0,mSubclass=0,mProtocol=0,mInterfaces=[Landroid.os.Parcelable;@41a16f58]


 ====intfs===== 

intf[0]=UsbInterface[mId=0,mClass=3,mSubclass=0,mProtocol=0,mEndpoints=[Landroid.os.Parcelable;@41a16fe8]


 device intf=UsbInterface[mId=0,mClass=3,mSubclass=0,mProtocol=0,mEndpoints=[Landroid.os.Parcelable;@41a16fe8]

endpoint[0]=UsbEndpoint[mAddress=130,mAttributes=3,mMaxPacketSize=64,mInterval=1]

endpoint[1]=UsbEndpoint[mAddress=1,mAttributes=3,mMaxPacketSize=64,mInterval=1]


 epOut=UsbEndpoint[mAddress=1,mAttributes=3,mMaxPacketSize=64,mInterval=1]


 epIn=UsbEndpoint[mAddress=130,mAttributes=3,mMaxPacketSize=64,mInterval=1]

結合UsbHostManager.usbDeviceAdded函式可知,這個Android的這個OTG裝置只有一個interface,這個interface只有連個端點,一個用於輸入,一個用於輸出.

bulkTransfer從epIn端點中讀取資料