Example #1
0
static int wince_submit_control_or_bulk_transfer(struct usbi_transfer *itransfer)
{
	struct libusb_transfer *transfer = USBI_TRANSFER_TO_LIBUSB_TRANSFER(itransfer);
	struct libusb_context *ctx = DEVICE_CTX(transfer->dev_handle->dev);
	struct wince_transfer_priv *transfer_priv = (struct wince_transfer_priv*)usbi_transfer_get_os_priv(itransfer);
	struct wince_device_priv *priv = _device_priv(transfer->dev_handle->dev);
	BOOL direction_in, ret;
	struct winfd wfd;
	DWORD flags;
	HANDLE eventHandle;
	PUKW_CONTROL_HEADER setup = NULL;
	const BOOL control_transfer = transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL;

	transfer_priv->pollable_fd = INVALID_WINFD;
	if (control_transfer) {
		setup = (PUKW_CONTROL_HEADER) transfer->buffer;
		direction_in = setup->bmRequestType & LIBUSB_ENDPOINT_IN;
	} else {
		direction_in = transfer->endpoint & LIBUSB_ENDPOINT_IN;
	}
	flags = direction_in ? UKW_TF_IN_TRANSFER : UKW_TF_OUT_TRANSFER;
	flags |= UKW_TF_SHORT_TRANSFER_OK;

	eventHandle = CreateEvent(NULL, FALSE, FALSE, NULL);
	if (eventHandle == NULL) {
		usbi_err(ctx, "Failed to create event for async transfer");
		return LIBUSB_ERROR_NO_MEM;
	}

	wfd = usbi_create_fd(eventHandle, direction_in ? RW_READ : RW_WRITE, itransfer, &wince_cancel_transfer);
	if (wfd.fd < 0) {
		CloseHandle(eventHandle);
		return LIBUSB_ERROR_NO_MEM;
	}

	transfer_priv->pollable_fd = wfd;
	if (control_transfer) {
		// Split out control setup header and data buffer
		DWORD bufLen = transfer->length - sizeof(UKW_CONTROL_HEADER);
		PVOID buf = (PVOID) &transfer->buffer[sizeof(UKW_CONTROL_HEADER)];

		ret = UkwIssueControlTransfer(priv->dev, flags, setup, buf, bufLen, &transfer->actual_length, wfd.overlapped);
	} else {
		ret = UkwIssueBulkTransfer(priv->dev, flags, transfer->endpoint, transfer->buffer, 
			transfer->length, &transfer->actual_length, wfd.overlapped);
	}
	if (!ret) {
		int libusbErr = translate_driver_error(GetLastError());
		usbi_err(ctx, "UkwIssue%sTransfer failed: error %d",
			control_transfer ? "Control" : "Bulk", GetLastError());
		wince_clear_transfer_priv(itransfer);
		return libusbErr;
	}
	usbi_add_pollfd(ctx, transfer_priv->pollable_fd.fd, direction_in ? POLLIN : POLLOUT);
	itransfer->flags |= USBI_TRANSFER_UPDATED_FDS;

	return LIBUSB_SUCCESS;
}
static void startAAPBulkTransfer(char line[])
{
    char* linePtr = line + 1;

    // Parse the device index
    DWORD devIdx = 0;
    linePtr = parseNumber(linePtr, devIdx);
    if (!linePtr) {
        printf("Please provide a decimal device number following the command\n");
        return;
    }
    if (devIdx >= gDeviceListSize || devIdx < 0) {
        printf("Invalid device index '%d' provided\n", devIdx);
        return;
    }

    UKW_DEVICE device = gDeviceList[devIdx];

    // Find endpoints
    UCHAR epin, epout;
    if (!findAAPEndpoints(device, epin, epout))
        return;

    OVERLAPPED overlapped;
    memset(&overlapped, 0, sizeof(overlapped));
    overlapped.hEvent = CreateEvent(NULL, FALSE, FALSE, NULL);
    if (overlapped.hEvent == NULL) {
        printf("Failed to create event for asynchronous request.\n");
        return;
    }

    UCHAR buf[16383];
    DWORD bytesTransferred;

    switch (line[0]) {
    case 'r':
    {
        // Read a transfer
        if (!UkwIssueBulkTransfer(device, UKW_TF_IN_TRANSFER, epin, buf, 16383, &bytesTransferred, &overlapped)) {
            printf("Failed to read bulk transfer from endpoint %d on device %d: error %d", epin, devIdx, GetLastError());
        } else if (waitForOverlapped(overlapped)) {
            printf("Read %d bytes: [ ", bytesTransferred);
            for (DWORD i = 0; i < bytesTransferred; i++) {
                printf("%.02x ", buf[i]);
            }
            printf("]\n");
        } else {
            // Attempt to cancel it
            if (!UkwCancelTransfer(device, &overlapped, 0)) {
                printf("Attempt to cancel timed out transfer failed with %d\n", GetLastError());
                return;
            }
            printf("Cancelled transfer due to timeout\n");
            if (!waitForOverlapped(overlapped)) {
                printf("Timeout out waiting for cancel to complete\n");
            }
            printf("Transfer cancel completed with: Internal: %d InternalHigh: %d Offset: %d OffsetHigh %d\n",
                   overlapped.Internal, overlapped.InternalHigh,
                   overlapped.Offset, overlapped.OffsetHigh);
        }
        break;
    }
    case 'w':
    {
        // Write a AAP handshake bulk transfer
        UCHAR Handshake[10];
        Handshake[0] = 0xff;
        Handshake[1] = 0xff;
        Handshake[2] = 0x00;
        Handshake[3] = 0x00;
        Handshake[4] = 0x0a;
        Handshake[5] = 0x0a;
        Handshake[6] = 'H';
        Handshake[7] = 'O';
        Handshake[8] = 'S';
        Handshake[9] = 'T';

        memcpy(buf, Handshake, 10);
        if (!UkwIssueBulkTransfer(device, UKW_TF_IN_TRANSFER, epout, buf, 10, &bytesTransferred, &overlapped)) {
            printf("Failed to write bulk transfer from endpoint %d on device %d: error %d", epin, devIdx, GetLastError());
        } else if (waitForOverlapped(overlapped)) {
            printf("Wrote %d bytes\n", bytesTransferred);
        } else {
            // Attempt to cancel it
            if (!UkwCancelTransfer(device, &overlapped, 0)) {
                printf("Attempt to cancel timed out transfer failed with %d\n", GetLastError());
                return;
            }
            printf("Cancelled transfer due to timeout\n");
            if (!waitForOverlapped(overlapped)) {
                printf("Timeout out waiting for cancel to complete\n");
            }
            printf("Transfer cancel completed with: Internal: %d InternalHigh: %d Offset: %d OffsetHigh %d\n",
                   overlapped.Internal, overlapped.InternalHigh,
                   overlapped.Offset, overlapped.OffsetHigh);
        }
        break;
    }
    default:
    {
        printf("Don't know bulk transfer operation '%c', doing nothing\n", line[0]);
    }
    }
    CloseHandle(overlapped.hEvent);
}