Esempio n. 1
0
libusbp_error * libusbp_device_copy(const libusbp_device * source, libusbp_device ** dest)
{
    if (dest == NULL)
    {
        return error_create("Device output pointer is null.");
    }

    *dest = NULL;

    if (source == NULL)
    {
        return NULL;
    }

    libusbp_error * error = NULL;

    // Allocate memory for the device itself.
    libusbp_device * new_device = NULL;
    if (error == NULL)
    {
        error = device_allocate(&new_device);
    }

    // Copy the device instance ID.
    if (error == NULL)
    {
        assert(source->device_instance_id != NULL);
        size_t size = strlen(source->device_instance_id) + 1;
        char * new_id = malloc(size);
        if (new_id == NULL)
        {
            error = &error_no_memory;
        }
        else
        {
            memcpy(new_id, source->device_instance_id, size);
            new_device->device_instance_id = new_id;
        }
    }

    if (error == NULL)
    {
        new_device->vendor_id = source->vendor_id;
        new_device->product_id = source->product_id;
        new_device->revision = source->revision;
    }

    // Pass the device to the caller.
    if (error == NULL)
    {
        *dest = new_device;
        new_device = NULL;
    }

    libusbp_device_free(new_device);
    return error;
}
Esempio n. 2
0
libusbp_error * create_device(io_service_t service, libusbp_device ** device)
{
    assert(service != MACH_PORT_NULL);
    assert(device != NULL);

    libusbp_error * error = NULL;

    // Allocate the device.
    libusbp_device * new_device = NULL;
    if (error == NULL)
    {
        error = device_allocate(&new_device);
    }

    // Get the numeric IDs.
    if (error == NULL)
    {
        error = get_uint16(service, CFSTR(kUSBVendorID), &new_device->vendor_id);
    }
    if (error == NULL)
    {
        error = get_uint16(service, CFSTR(kUSBProductID), &new_device->product_id);
    }
    if (error == NULL)
    {
        error = get_uint16(service, CFSTR(kUSBDeviceReleaseNumber), &new_device->revision);
    }

    // Get the serial number.
    if (error == NULL)
    {
        error = get_string(service, CFSTR(kUSBSerialNumberString), &new_device->serial_number);
    }

    // Get the ID.
    if (error == NULL)
    {
        error = get_id(service, &new_device->id);
    }

    // Pass the device to the caller.
    if (error == NULL)
    {
        *device = new_device;
        new_device = NULL;
    }

    libusbp_device_free(new_device);
    return error;
}
Esempio n. 3
0
libusbp_error * libusbp_device_copy(const libusbp_device * source, libusbp_device ** dest)
{
    if (dest == NULL)
    {
        return error_create("Device output pointer is null.");
    }

    *dest = NULL;

    if (source == NULL)
    {
        return NULL;
    }

    libusbp_error * error = NULL;

    // Allocate the device.
    libusbp_device * new_device = NULL;
    if (error == NULL)
    {
        error = device_allocate(&new_device);
    }

    // Copy the simple fields, while leaving the pointers owned by the
    // device NULL so that libusbp_device_free is still OK to call.
    if (error == NULL)
    {
        memcpy(new_device, source, sizeof(libusbp_device));
        new_device->serial_number = NULL;
    }

    // Copy the serial number.
    if (error == NULL && source->serial_number != NULL)
    {
        error = string_copy(source->serial_number, &new_device->serial_number);
    }

    // Pass the device to the caller.
    if (error == NULL)
    {
        *dest = new_device;
        new_device = NULL;
    }

    libusbp_device_free(new_device);
    return error;
}
Esempio n. 4
0
libusbp_error * create_device(HDEVINFO list, PSP_DEVINFO_DATA info, libusbp_device ** device)
{
    assert(list != INVALID_HANDLE_VALUE);
    assert(info != NULL);
    assert(info->cbSize == sizeof(SP_DEVINFO_DATA));
    assert(device != NULL);

    *device = NULL;

    libusbp_error * error = NULL;

    // Allocate memory for the device itself.
    libusbp_device * new_device = NULL;
    if (error == NULL)
    {
        error = device_allocate(&new_device);
    }

    // Get the device instance ID.
    if (error == NULL)
    {
        error = create_id_string(list, info, &new_device->device_instance_id);
    }

    // Get the vendor ID, product ID, and revision from the hardware IDs.
    char * new_ids = NULL;
    if (error == NULL)
    {
        error = device_get_hardware_ids(list, info, &new_ids);
    }
    if (error == NULL)
    {
        error = device_take_info_from_hardware_ids(new_device, new_ids);
    }

    // Return the device to the caller.
    if (error == NULL)
    {
        *device = new_device;
        new_device = NULL;
    }

    libusbp_string_free(new_ids);
    libusbp_device_free(new_device);
    return error;
}
Esempio n. 5
0
static struct jaylink_device *probe_device(struct jaylink_context *ctx,
		struct libusb_device *usb_dev)
{
	int ret;
	struct libusb_device_descriptor desc;
	struct libusb_device_handle *usb_devh;
	struct jaylink_device *dev;
	char buf[USB_SERIAL_NUMBER_LENGTH + 1];
	uint8_t usb_address;
	uint32_t serial_number;
	bool valid_serial_number;
	bool found_device;
	size_t i;

	ret = libusb_get_device_descriptor(usb_dev, &desc);

	if (ret != LIBUSB_SUCCESS) {
		log_warn(ctx, "Failed to get device descriptor: %s.",
			libusb_error_name(ret));
		return NULL;
	}

	if (desc.idVendor != USB_VENDOR_ID)
		return NULL;

	found_device = false;

	for (i = 0; i < sizeof(pids) / sizeof(pids[0]); i++) {
		if (pids[i][0] == desc.idProduct) {
			found_device = true;
			usb_address = pids[i][1];
			break;
		}
	}

	if (!found_device)
		return NULL;

	log_dbg(ctx, "Found device (VID:PID = %04x:%04x, bus:address = "
		"%03u:%03u).", desc.idVendor, desc.idProduct,
		libusb_get_bus_number(usb_dev),
		libusb_get_device_address(usb_dev));

	/*
	 * Search for an already allocated device instance for this device and
	 * if found return a reference to it.
	 */
	dev = find_device(ctx, usb_dev);

	if (dev) {
		log_dbg(ctx, "Device: USB address = %u.", dev->usb_address);

		if (dev->valid_serial_number)
			log_dbg(ctx, "Device: Serial number = %u.",
				dev->serial_number);
		else
			log_dbg(ctx, "Device: Serial number = N/A.");

		log_dbg(ctx, "Using existing device instance.");
		return jaylink_ref_device(dev);
	}

	/* Open the device to be able to retrieve its serial number. */
	ret = libusb_open(usb_dev, &usb_devh);

	if (ret != LIBUSB_SUCCESS) {
		log_warn(ctx, "Failed to open device: %s.",
			libusb_error_name(ret));
		return NULL;
	}

	valid_serial_number = true;

	ret = libusb_get_string_descriptor_ascii(usb_devh, desc.iSerialNumber,
		(unsigned char *)buf, USB_SERIAL_NUMBER_LENGTH + 1);

	libusb_close(usb_devh);

	if (ret < 0) {
		log_warn(ctx, "Failed to retrieve serial number: %s.",
			libusb_error_name(ret));
		valid_serial_number = false;
	}

	if (valid_serial_number) {
		if (!parse_serial_number(buf, &serial_number)) {
			log_warn(ctx, "Failed to parse serial number.");
			return NULL;
		}
	}

	log_dbg(ctx, "Device: USB address = %u.", usb_address);

	if (valid_serial_number)
		log_dbg(ctx, "Device: Serial number = %u.", serial_number);
	else
		log_dbg(ctx, "Device: Serial number = N/A.");

	log_dbg(ctx, "Allocating new device instance.");

	dev = device_allocate(ctx);

	if (!dev) {
		log_warn(ctx, "Device instance malloc failed.");
		return NULL;
	}

	dev->interface = JAYLINK_HIF_USB;
	dev->usb_dev = libusb_ref_device(usb_dev);
	dev->usb_address = usb_address;
	dev->serial_number = serial_number;
	dev->valid_serial_number = valid_serial_number;

	return dev;
}