Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 1fce24b2 authored by Mike Lockwood's avatar Mike Lockwood
Browse files

Add support for synchronous bulk USB transfers



Change-Id: Id5de49e4d728a702fa1583ecc24f83f36cc57d21
Signed-off-by: default avatarMike Lockwood <lockwood@android.com>
parent 05b536e6
Loading
Loading
Loading
Loading
+44 −23
Original line number Original line Diff line number Diff line
@@ -94377,6 +94377,25 @@
>
>
<implements name="android.os.Parcelable">
<implements name="android.os.Parcelable">
</implements>
</implements>
<method name="bulkTransfer"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="endpoint" type="android.hardware.UsbEndpoint">
</parameter>
<parameter name="buffer" type="byte[]">
</parameter>
<parameter name="length" type="int">
</parameter>
<parameter name="timeout" type="int">
</parameter>
</method>
<method name="claimInterface"
<method name="claimInterface"
 return="boolean"
 return="boolean"
 abstract="false"
 abstract="false"
@@ -94403,6 +94422,31 @@
 visibility="public"
 visibility="public"
>
>
</method>
</method>
<method name="controlTransfer"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="requestType" type="int">
</parameter>
<parameter name="request" type="int">
</parameter>
<parameter name="value" type="int">
</parameter>
<parameter name="index" type="int">
</parameter>
<parameter name="buffer" type="byte[]">
</parameter>
<parameter name="length" type="int">
</parameter>
<parameter name="timeout" type="int">
</parameter>
</method>
<method name="describeContents"
<method name="describeContents"
 return="int"
 return="int"
 abstract="false"
 abstract="false"
@@ -94587,29 +94631,6 @@
 visibility="public"
 visibility="public"
>
>
</method>
</method>
<method name="sendControlRequest"
 return="int"
 abstract="false"
 native="false"
 synchronized="false"
 static="false"
 final="false"
 deprecated="not deprecated"
 visibility="public"
>
<parameter name="requestType" type="int">
</parameter>
<parameter name="request" type="int">
</parameter>
<parameter name="value" type="int">
</parameter>
<parameter name="index" type="int">
</parameter>
<parameter name="buffer" type="byte[]">
</parameter>
<parameter name="length" type="int">
</parameter>
</method>
<method name="writeToParcel"
<method name="writeToParcel"
 return="void"
 return="void"
 abstract="false"
 abstract="false"
+26 −4
Original line number Original line Diff line number Diff line
@@ -193,6 +193,11 @@ public final class UsbDevice implements Parcelable {


    /**
    /**
     * Performs a control transaction on endpoint zero for this device.
     * Performs a control transaction on endpoint zero for this device.
     * The direction of the transfer is determined by the request type.
     * If requestType & {@link UsbConstants#USB_ENDPOINT_DIR_MASK} is
     * {@link UsbConstants#USB_DIR_OUT}, then the transfer is a write,
     * and if it is {@link UsbConstants#USB_DIR_IN}, then the transfer
     * is a read.
     *
     *
     * @param requestType request type for this transaction
     * @param requestType request type for this transaction
     * @param request request ID for this transaction
     * @param request request ID for this transaction
@@ -201,12 +206,28 @@ public final class UsbDevice implements Parcelable {
     * @param buffer buffer for data portion of transaction,
     * @param buffer buffer for data portion of transaction,
     * or null if no data needs to be sent or received
     * or null if no data needs to be sent or received
     * @param length the length of the 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,
     * @return length of data transferred (or zero) for success,
     * or negative value for failure
     * or negative value for failure
     */
     */
    public int sendControlRequest(int requestType, int request, int value,
    public int controlTransfer(int requestType, int request, int value,
            int index, byte[] buffer, int length) {
            int index, byte[] buffer, int length, int timeout) {
        return native_control_request(requestType, request, value, index, buffer, length);
        return native_control_request(requestType, request, value, index, buffer, length, timeout);
    }

    /**
     * Performs a bulk transaction on the given endpoint.
     * The direction of the transfer is determined by the direction of the endpoint
     *
     * @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 native_bulk_request(endpoint.getAddress(), buffer, length, timeout);
    }
    }


    /**
    /**
@@ -305,7 +326,8 @@ public final class UsbDevice implements Parcelable {
    private native boolean native_claim_interface(int interfaceID, boolean force);
    private native boolean native_claim_interface(int interfaceID, boolean force);
    private native boolean native_release_interface(int interfaceID);
    private native boolean native_release_interface(int interfaceID);
    private native int native_control_request(int requestType, int request, int value,
    private native int native_control_request(int requestType, int request, int value,
            int index, byte[] buffer, int length);
            int index, byte[] buffer, int length, int timeout);
    private native int native_bulk_request(int endpoint, byte[] buffer, int length, int timeout);
    private native UsbRequest native_request_wait();
    private native UsbRequest native_request_wait();
    private native String native_get_serial();
    private native String native_get_serial();


+33 −4
Original line number Original line Diff line number Diff line
@@ -123,7 +123,7 @@ android_hardware_UsbDevice_release_interface(JNIEnv *env, jobject thiz, int inte
static jint
static jint
android_hardware_UsbDevice_control_request(JNIEnv *env, jobject thiz,
android_hardware_UsbDevice_control_request(JNIEnv *env, jobject thiz,
        jint requestType, jint request, jint value, jint index,
        jint requestType, jint request, jint value, jint index,
        jbyteArray buffer, jint length)
        jbyteArray buffer, jint length, jint timeout)
{
{
    struct usb_device* device = get_device_from_object(env, thiz);
    struct usb_device* device = get_device_from_object(env, thiz);
    if (!device) {
    if (!device) {
@@ -140,8 +140,35 @@ android_hardware_UsbDevice_control_request(JNIEnv *env, jobject thiz,
        bufferBytes = env->GetByteArrayElements(buffer, 0);
        bufferBytes = env->GetByteArrayElements(buffer, 0);
    }
    }


    jint result = usb_device_send_control(device, requestType, request,
    jint result = usb_device_control_transfer(device, requestType, request,
            value,  index, length, bufferBytes);
            value, index, bufferBytes, length, timeout);

    if (bufferBytes)
        env->ReleaseByteArrayElements(buffer, bufferBytes, 0);

    return result;
}

static jint
android_hardware_UsbDevice_bulk_request(JNIEnv *env, jobject thiz,
        jint endpoint, jbyteArray buffer, jint length, jint timeout)
{
    struct usb_device* device = get_device_from_object(env, thiz);
    if (!device) {
        LOGE("device is closed in native_control_request");
        return -1;
    }

    jbyte* bufferBytes = NULL;
    if (buffer) {
        if (env->GetArrayLength(buffer) < length) {
            env->ThrowNew(env->FindClass("java/lang/ArrayIndexOutOfBoundsException"), NULL);
            return -1;
        }
        bufferBytes = env->GetByteArrayElements(buffer, 0);
    }

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


    if (bufferBytes)
    if (bufferBytes)
        env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
        env->ReleaseByteArrayElements(buffer, bufferBytes, 0);
@@ -206,8 +233,10 @@ static JNINativeMethod method_table[] = {
    {"native_get_fd",           "()I",  (void *)android_hardware_UsbDevice_get_fd},
    {"native_get_fd",           "()I",  (void *)android_hardware_UsbDevice_get_fd},
    {"native_claim_interface",  "(IZ)Z",(void *)android_hardware_UsbDevice_claim_interface},
    {"native_claim_interface",  "(IZ)Z",(void *)android_hardware_UsbDevice_claim_interface},
    {"native_release_interface","(I)Z", (void *)android_hardware_UsbDevice_release_interface},
    {"native_release_interface","(I)Z", (void *)android_hardware_UsbDevice_release_interface},
    {"native_control_request",  "(IIII[BI)I",
    {"native_control_request",  "(IIII[BII)I",
                                        (void *)android_hardware_UsbDevice_control_request},
                                        (void *)android_hardware_UsbDevice_control_request},
    {"native_bulk_request",     "(I[BII)I",
                                        (void *)android_hardware_UsbDevice_bulk_request},
    {"native_request_wait",             "()Landroid/hardware/UsbRequest;",
    {"native_request_wait",             "()Landroid/hardware/UsbRequest;",
                                        (void *)android_hardware_UsbDevice_request_wait},
                                        (void *)android_hardware_UsbDevice_request_wait},
    { "native_get_serial",      "()Ljava/lang/String;",
    { "native_get_serial",      "()Ljava/lang/String;",
+5 −5
Original line number Original line Diff line number Diff line
@@ -92,16 +92,16 @@ MtpDevice* MtpDevice::open(const char* deviceName, int fd) {
                // some music players need to see this before entering MTP mode.
                // some music players need to see this before entering MTP mode.
                char buffer[256];
                char buffer[256];
                memset(buffer, 0, sizeof(buffer));
                memset(buffer, 0, sizeof(buffer));
                int ret = usb_device_send_control(device,
                int ret = usb_device_control_transfer(device,
                        USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_STANDARD,
                        USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_STANDARD,
                        USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | 0xEE,
                        USB_REQ_GET_DESCRIPTOR, (USB_DT_STRING << 8) | 0xEE,
                        0, sizeof(buffer), buffer);
                        0, buffer, sizeof(buffer), 0);
                printf("usb_device_send_control returned %d errno: %d\n", ret, errno);
                printf("usb_device_control_transfer returned %d errno: %d\n", ret, errno);
                if (ret > 0) {
                if (ret > 0) {
                    printf("got MTP string %s\n", buffer);
                    printf("got MTP string %s\n", buffer);
                    ret = usb_device_send_control(device,
                    ret = usb_device_control_transfer(device,
                            USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, 1,
                            USB_DIR_IN|USB_RECIP_DEVICE|USB_TYPE_VENDOR, 1,
                            0, 4, sizeof(buffer), buffer);
                            0, 4, buffer, sizeof(buffer), 0);
                    printf("OS descriptor got %d\n", ret);
                    printf("OS descriptor got %d\n", ret);
                } else {
                } else {
                    printf("no MTP string\n");
                    printf("no MTP string\n");