Example #1
0
static int
gp_libusb1_find_device_lib(GPPort *port, int idvendor, int idproduct)
{
	char *s;
	int d, busnr = 0, devnr = 0;
	GPPortPrivateLibrary *pl;

	C_PARAMS (port);

	pl = port->pl;

	s = strchr (port->settings.usb.port,':');
	if (s && (s[1] != '\0')) { /* usb:%d,%d */
		if (sscanf (s+1, "%d,%d", &busnr, &devnr) != 2) {
			devnr = 0;
			sscanf (s+1, "%d", &busnr);
		}
	}
	/*
	 * 0x0000 idvendor is not valid.
	 * 0x0000 idproduct is ok.
	 * Should the USB layer report that ? I don't know.
	 * Better to check here.
	 */
	if (!idvendor) {
		gp_port_set_error (port, _("The supplied vendor or product "
			"id (0x%x,0x%x) is not valid."), idvendor, idproduct);
		return GP_ERROR_BAD_PARAMETERS;
	}

	pl->nrofdevs = load_devicelist (port->pl);

	for (d = 0; d < pl->nrofdevs; d++) {
		struct libusb_config_descriptor *confdesc;
		int config = -1, interface = -1, altsetting = -1;

		if ((pl->descs[d].idVendor != idvendor) ||
		    (pl->descs[d].idProduct != idproduct))
			continue;

		if (busnr && (busnr != libusb_get_bus_number (pl->devs[d])))
			continue;
		if (devnr && (devnr != libusb_get_device_address (pl->devs[d])))
			continue;

		port->pl->d = pl->devs[d];

		GP_LOG_D ("Looking for USB device (vendor 0x%x, product 0x%x)... found.", idvendor, idproduct);

		/* Use the first config, interface and altsetting we find */
		gp_libusb1_find_first_altsetting(pl->devs[d], &config, &interface, &altsetting);

		if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (pl->devs[d], config, &confdesc)))
			continue;

		/* Set the defaults */
		if (confdesc->interface[interface].altsetting[altsetting].bInterfaceClass
		    == LIBUSB_CLASS_MASS_STORAGE) {
			GP_LOG_D ("USB device (vendor 0x%x, product 0x%x) is a mass"
				  " storage device, and might not function with gphoto2."
				  " Reference: %s", idvendor, idproduct, URL_USB_MASSSTORAGE);
		}
		port->settings.usb.config = confdesc->bConfigurationValue;
		port->settings.usb.interface = confdesc->interface[interface].altsetting[altsetting].bInterfaceNumber;
		port->settings.usb.altsetting = confdesc->interface[interface].altsetting[altsetting].bAlternateSetting;

		port->settings.usb.inep  = gp_libusb1_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_BULK);
		port->settings.usb.outep = gp_libusb1_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_OUT, LIBUSB_TRANSFER_TYPE_BULK);
		port->settings.usb.intep = gp_libusb1_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_INTERRUPT);

		port->settings.usb.maxpacketsize = libusb_get_max_packet_size (pl->devs[d], port->settings.usb.inep);
		GP_LOG_D ("Detected defaults: config %d, interface %d, altsetting %d, "
			  "inep %02x, outep %02x, intep %02x, class %02x, subclass %02x",
			port->settings.usb.config,
			port->settings.usb.interface,
			port->settings.usb.altsetting,
			port->settings.usb.inep,
			port->settings.usb.outep,
			port->settings.usb.intep,
			confdesc->interface[interface].altsetting[altsetting].bInterfaceClass,
			confdesc->interface[interface].altsetting[altsetting].bInterfaceSubClass
			);
		libusb_free_config_descriptor (confdesc);
		return GP_OK;
	}
#if 0
	gp_port_set_error (port, _("Could not find USB device "
		"(vendor 0x%x, product 0x%x). Make sure this device "
		"is connected to the computer."), idvendor, idproduct);
#endif
	return GP_ERROR_IO_USB_FIND;
}
Example #2
0
static int
gp_libusb1_find_path_lib(GPPort *port)
{
	char *s;
	int d, busnr = 0, devnr = 0;
	GPPortPrivateLibrary *pl;

	C_PARAMS (port);

	pl = port->pl;

	s = strchr (port->settings.usb.port,':');
	C_PARAMS (s && (s[1] != '\0'));
	C_PARAMS (sscanf (s+1, "%d,%d", &busnr, &devnr) == 2); /* usb:%d,%d */

	pl->nrofdevs = load_devicelist (port->pl);

	for (d = 0; d < pl->nrofdevs; d++) {
		struct libusb_config_descriptor *confdesc;
		int config = -1, interface = -1, altsetting = -1;

		if (busnr != libusb_get_bus_number (pl->devs[d]))
			continue;
		if (devnr != libusb_get_device_address (pl->devs[d]))
			continue;

		port->pl->d = pl->devs[d];

		GP_LOG_D ("Found path %s", port->settings.usb.port);

		/* Use the first config, interface and altsetting we find */
		gp_libusb1_find_first_altsetting(pl->devs[d], &config, &interface, &altsetting);

		if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (pl->devs[d], config, &confdesc)))
			continue;

		/* Set the defaults */
		port->settings.usb.config = confdesc->bConfigurationValue;
		port->settings.usb.interface = confdesc->interface[interface].altsetting[altsetting].bInterfaceNumber;
		port->settings.usb.altsetting = confdesc->interface[interface].altsetting[altsetting].bAlternateSetting;

		port->settings.usb.inep  = gp_libusb1_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_BULK);
		port->settings.usb.outep = gp_libusb1_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_OUT, LIBUSB_TRANSFER_TYPE_BULK);
		port->settings.usb.intep = gp_libusb1_find_ep(pl->devs[d], config, interface, altsetting, LIBUSB_ENDPOINT_IN, LIBUSB_TRANSFER_TYPE_INTERRUPT);

		port->settings.usb.maxpacketsize = libusb_get_max_packet_size (pl->devs[d], port->settings.usb.inep);
		GP_LOG_D ("Detected defaults: config %d, interface %d, altsetting %d, "
			"inep %02x, outep %02x, intep %02x, class %02x, subclass %02x",
			port->settings.usb.config,
			port->settings.usb.interface,
			port->settings.usb.altsetting,
			port->settings.usb.inep,
			port->settings.usb.outep,
			port->settings.usb.intep,
			confdesc->interface[interface].altsetting[altsetting].bInterfaceClass,
			confdesc->interface[interface].altsetting[altsetting].bInterfaceSubClass
			);
		libusb_free_config_descriptor (confdesc);
		return GP_OK;
	}
#if 0
	gp_port_set_error (port, _("Could not find USB device "
		"(vendor 0x%x, product 0x%x). Make sure this device "
		"is connected to the computer."), idvendor, idproduct);
#endif
	return GP_ERROR_IO_USB_FIND;
}
Example #3
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo	info;
	int		nrofdevices = 0;
	int		d, i, i1, i2, unknownint;

	/* generic matcher. This will catch passed XXX,YYY entries for instance. */
	info.type = GP_PORT_USB;
	strcpy (info.name, "");
	strcpy (info.path, "^usb:");
	CHECK (gp_port_info_list_append (list, info));

	libusb_init (NULL);
	gp_nrofdevs = load_devicelist (NULL);

	for (d = 0; d < gp_nrofdevs; d++) {
		/* Devices which are definitely not cameras. */
		if (	(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HUB)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HID)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER)	||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_COMM)	||
			(gp_descs[d].bDeviceClass == 0xe0)	/* wireless / bluetooth */
		)
			continue;
		/* excepts HUBs, usually the interfaces have the classes, not
		 * the device */
		unknownint = 0;
		for (i = 0; i < gp_descs[d].bNumConfigurations; i++) {
			struct libusb_config_descriptor *config;
			int ret;

			ret = libusb_get_config_descriptor (gp_devs[d], i, &config);
			if (ret) {
				unknownint++;
				continue;
			}
			for (i1 = 0; i1 < config->bNumInterfaces; i1++)
				for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) {
					const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM)	||
						(intf->bInterfaceClass == 0xe0)	/* wireless/bluetooth*/
					)
						continue;
					unknownint++;
				}
			libusb_free_config_descriptor (config);
		}
		/* when we find only hids, printer or comm ifaces  ... skip this */
		if (!unknownint)
			continue;
		/* Note: We do not skip USB storage. Some devices can support both,
		 * and the Ricoh erronously reports it.
		 */ 
		nrofdevices++;
	}

#if 0
	/* If we already added usb:, and have 0 or 1 devices we have nothing to do.
	 * This should be the standard use case.
	 */
	/* We never want to return just "usb:" ... also return "usb:XXX,YYY", and
	 * let upper layers filter out the usb: */
	if (nrofdevices <= 1) 
		return (GP_OK);
#endif

	/* Redo the same bus/device walk, but now add the ports with usb:x,y notation,
	 * so we can address all USB devices.
	 */
	for (d = 0; d < gp_nrofdevs; d++) {
		/* Devices which are definitely not cameras. */
		if (	(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HUB)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_HID)		||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_PRINTER)	||
			(gp_descs[d].bDeviceClass == LIBUSB_CLASS_COMM)
		)
			continue;
		/* excepts HUBs, usually the interfaces have the classes, not
		 * the device */
		unknownint = 0;
		for (i = 0; i < gp_descs[d].bNumConfigurations; i++) {
			struct libusb_config_descriptor *config;
			int ret;

			ret = libusb_get_config_descriptor (gp_devs[d], i, &config);
			if (ret) {
				gp_log (GP_LOG_ERROR, "libusb1", "libusb_get_config_descriptor(%d) returned %d", d, ret);
				unknownint++;
				continue;
			}
			for (i1 = 0; i1 < config->bNumInterfaces; i1++)
				for (i2 = 0; i2 < config->interface[i1].num_altsetting; i2++) {
					const struct libusb_interface_descriptor *intf = &config->interface[i1].altsetting[i2]; 
					if (	(intf->bInterfaceClass == LIBUSB_CLASS_HID)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_PRINTER)	||
						(intf->bInterfaceClass == LIBUSB_CLASS_COMM))
						continue;
					unknownint++;
				}
			libusb_free_config_descriptor (config);
		}
		/* when we find only hids, printer or comm ifaces  ... skip this */
		if (!unknownint)
			continue;
		/* Note: We do not skip USB storage. Some devices can support both,
		 * and the Ricoh erronously reports it.
		 */ 
		info.type = GP_PORT_USB;
		strcpy (info.name, "Universal Serial Bus");
		snprintf (info.path,sizeof(info.path), "usb:%03d,%03d",
			libusb_get_bus_number (gp_devs[d]),
			libusb_get_device_address (gp_devs[d])
		);
		CHECK (gp_port_info_list_append (list, info));
	}
	/* This will only be added if no other device was ever added.
	 * Users doing "usb:" usage will enter the regular expression matcher case. */
	if (nrofdevices == 0) {
		info.type = GP_PORT_USB;
		strcpy (info.name, "Universal Serial Bus");
		strcpy (info.path, "usb:");
		CHECK (gp_port_info_list_append (list, info));
	}
	libusb_exit (NULL);
	return (GP_OK);
}