Пример #1
0
/*****************************************************************************
 *
 *					OpenUSBByName
 *
 ****************************************************************************/
status_t OpenUSBByName(unsigned int reader_index, /*@null@*/ char *device)
{
	unsigned int alias;
	struct libusb_device_handle *dev_handle;
	char infofile[FILENAME_MAX];
#ifndef __APPLE__
	unsigned int device_vendor, device_product;
#endif
	int interface_number = -1;
	int i;
	static int previous_reader_index = -1;
	libusb_device **devs, *dev;
	ssize_t cnt;
	list_t plist, *values, *ifdVendorID, *ifdProductID, *ifdFriendlyName;
	int rv;
	int claim_failed = FALSE;
	int return_value = STATUS_SUCCESS;

	DEBUG_COMM3("Reader index: %X, Device: %s", reader_index, device);

#ifndef __APPLE__
	/* device name specified */
	if (device)
	{
		char *dirname;

		/* format: usb:%04x/%04x, vendor, product */
		if (strncmp("usb:", device, 4) != 0)
		{
			DEBUG_CRITICAL2("device name does not start with \"usb:\": %s",
				device);
			return STATUS_UNSUCCESSFUL;
		}

		if (sscanf(device, "usb:%x/%x", &device_vendor, &device_product) != 2)
		{
			DEBUG_CRITICAL2("device name can't be parsed: %s", device);
			return STATUS_UNSUCCESSFUL;
		}

		/* format usb:%04x/%04x:libudev:%d:%s
		 * with %d set to
		 * 01 (or whatever the interface number is)
		 * and %s set to
		 * /dev/bus/usb/008/004
		 */
		if ((dirname = strstr(device, "libudev:")) != NULL)
		{
			/* convert the interface number */
			interface_number = atoi(dirname + 8 /* "libudev:" */);
			DEBUG_COMM2("interface_number: %d", interface_number);
		}
	}
#endif

	/* is the reader_index already used? */
	if (usbDevice[reader_index].dev_handle != NULL)
	{
		DEBUG_CRITICAL2("USB driver with index %X already in use",
			reader_index);
		return STATUS_UNSUCCESSFUL;
	}

	/* Info.plist full patch filename */
	(void)snprintf(infofile, sizeof(infofile), "%s/%s/Contents/Info.plist",
		PCSCLITE_HP_DROPDIR, BUNDLE);
	DEBUG_INFO2("Using: %s", infofile);

	rv = bundleParse(infofile, &plist);
	if (rv)
		return STATUS_UNSUCCESSFUL;

#define GET_KEY(key, values) \
	rv = LTPBundleFindValueWithKey(&plist, key, &values); \
	if (rv) \
	{ \
		DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \
		return_value = STATUS_UNSUCCESSFUL; \
		goto end1; \
	} \
	else \
		DEBUG_INFO2(key ": %s", (char *)list_get_at(values, 0));

	/* general driver info */
	GET_KEY("ifdManufacturerString", values)
	GET_KEY("ifdProductString", values)
	GET_KEY("Copyright", values)

	if (NULL == ctx)
	{
		rv = libusb_init(&ctx);
		if (rv != 0)
		{
			DEBUG_CRITICAL2("libusb_init failed: %d", rv);
			return_value = STATUS_UNSUCCESSFUL;
			goto end1;
		}
	}

	cnt = libusb_get_device_list(ctx, &devs);
	if (cnt < 0)
	{
		DEBUG_CRITICAL("libusb_get_device_list() failed\n");
		return_value = STATUS_UNSUCCESSFUL;
		goto end1;
	}

#define GET_KEYS(key, values) \
	rv = LTPBundleFindValueWithKey(&plist, key, values); \
	if (rv) \
	{ \
		DEBUG_CRITICAL2("Value/Key not defined for " key " in %s", infofile); \
		return_value = STATUS_UNSUCCESSFUL; \
		goto end2; \
	}

	GET_KEYS("ifdVendorID", &ifdVendorID)
	GET_KEYS("ifdProductID", &ifdProductID);
	GET_KEYS("ifdFriendlyName", &ifdFriendlyName)

	/* The 3 lists do not have the same size */
	if  ((list_size(ifdVendorID) != list_size(ifdProductID))
		|| (list_size(ifdVendorID) != list_size(ifdFriendlyName)))
	{
		DEBUG_CRITICAL2("Error parsing %s", infofile);
		return_value = STATUS_UNSUCCESSFUL;
		goto end1;
	}

	/* for any supported reader */
	for (alias=0; alias<list_size(ifdVendorID); alias++)
	{
		unsigned int vendorID, productID;
		char *friendlyName;

		vendorID = strtoul(list_get_at(ifdVendorID, alias), NULL, 0);
		productID = strtoul(list_get_at(ifdProductID, alias), NULL, 0);
		friendlyName = list_get_at(ifdFriendlyName, alias);

#ifndef __APPLE__
		/* the device was specified but is not the one we are trying to find */
		if (device
			&& (vendorID != device_vendor || productID != device_product))
			continue;
#else
		/* Leopard puts the friendlyname in the device argument */
		if (device && strcmp(device, friendlyName))
			continue;
#endif

		/* for every device */
		i = 0;
		while ((dev = devs[i++]) != NULL)
		{
			struct libusb_device_descriptor desc;
			struct libusb_config_descriptor *config_desc;
			uint8_t bus_number = libusb_get_bus_number(dev);
			uint8_t device_address = libusb_get_device_address(dev);

			int r = libusb_get_device_descriptor(dev, &desc);
			if (r < 0)
			{
				DEBUG_INFO3("failed to get device descriptor for %d/%d",
					bus_number, device_address);
				continue;
			}

			if (desc.idVendor == vendorID && desc.idProduct == productID)
			{
				int already_used;
				const struct libusb_interface *usb_interface = NULL;
				int interface;
				int num = 0;
				const unsigned char *device_descriptor;
#if defined(USE_COMPOSITE_AS_MULTISLOT) || defined(__APPLE__)
				int readerID = (vendorID << 16) + productID;
#endif

#ifdef USE_COMPOSITE_AS_MULTISLOT
				static int static_interface = 1;

				/* simulate a composite device as when libudev is used */
				if ((GEMALTOPROXDU == readerID)
					|| (GEMALTOPROXSU == readerID))
				{
						/*
						 * We can't talk to the two CCID interfaces
						 * at the same time (the reader enters a
						 * dead lock). So we simulate a multi slot
						 * reader. By default multi slot readers
						 * can't use the slots at the same time. See
						 * TAG_IFD_SLOT_THREAD_SAFE
						 *
						 * One side effect is that the two readers
						 * are seen by pcscd as one reader so the
						 * interface name is the same for the two.
						 *
	* So we have:
	* 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
	* 1: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 01
	* instead of
	* 0: Gemalto Prox-DU [Prox-DU Contact_09A00795] (09A00795) 00 00
	* 1: Gemalto Prox-DU [Prox-DU Contactless_09A00795] (09A00795) 01 00
						 */

					/* the CCID interfaces are 1 and 2 */
					interface_number = static_interface;
				}
#endif
				/* is it already opened? */
				already_used = FALSE;

				DEBUG_COMM3("Checking device: %d/%d",
					bus_number, device_address);
				for (r=0; r<CCID_DRIVER_MAX_READERS; r++)
				{
					if (usbDevice[r].dev_handle)
					{
						/* same bus, same address */
						if (usbDevice[r].bus_number == bus_number
							&& usbDevice[r].device_address == device_address)
							already_used = TRUE;
					}
				}

				/* this reader is already managed by us */
				if (already_used)
				{
					if ((previous_reader_index != -1)
						&& usbDevice[previous_reader_index].dev_handle
						&& (usbDevice[previous_reader_index].bus_number == bus_number)
						&& (usbDevice[previous_reader_index].device_address == device_address)
						&& usbDevice[previous_reader_index].ccid.bCurrentSlotIndex < usbDevice[previous_reader_index].ccid.bMaxSlotIndex)
					{
						/* we reuse the same device
						 * and the reader is multi-slot */
						usbDevice[reader_index] = usbDevice[previous_reader_index];
						/* the other slots do not have the same data rates */
						if ((GEMCOREPOSPRO == usbDevice[reader_index].ccid.readerID)
							|| (GEMCORESIMPRO == usbDevice[reader_index].ccid.readerID))
						{
							usbDevice[reader_index].ccid.arrayOfSupportedDataRates = SerialCustomDataRates;
							usbDevice[reader_index].ccid.dwMaxDataRate = 125000;
						}

						*usbDevice[reader_index].nb_opened_slots += 1;
						usbDevice[reader_index].ccid.bCurrentSlotIndex++;
						usbDevice[reader_index].ccid.dwSlotStatus =
							IFD_ICC_PRESENT;
						DEBUG_INFO2("Opening slot: %d",
							usbDevice[reader_index].ccid.bCurrentSlotIndex);
						goto end;
					}
					else
					{
						/* if an interface number is given by HAL we
						 * continue with this device. */
						if (-1 == interface_number)
						{
							DEBUG_INFO3("USB device %d/%d already in use."
								" Checking next one.",
								bus_number, device_address);
							continue;
						}
					}
				}

				DEBUG_COMM3("Trying to open USB bus/device: %d/%d",
					bus_number, device_address);

				r = libusb_open(dev, &dev_handle);
				if (r < 0)
				{
					DEBUG_CRITICAL4("Can't libusb_open(%d/%d): %d",
						bus_number, device_address, r);

					continue;
				}

again:
#ifdef __APPLE__
				/* Some early Gemalto Ezio CB+ readers have
				 * bDeviceClass, bDeviceSubClass and bDeviceProtocol set
				 * to 0xFF (proprietary) instead of 0x00.
				 *
				 * So on Mac OS X the reader configuration is not done
				 * by the OS/kernel and we do it ourself.
				 */
				if (GEMALTO_EZIO_CBP == readerID)
				{
					r = libusb_set_configuration(dev_handle, 1);
					if (r < 0)
					{
						(void)libusb_close(dev_handle);
						DEBUG_CRITICAL4("Can't set configuration on %d/%d: %d",
							bus_number, device_address, r);
						continue;
					}
				}
#endif

				r = libusb_get_active_config_descriptor(dev, &config_desc);
				if (r < 0)
				{
					(void)libusb_close(dev_handle);
					DEBUG_CRITICAL4("Can't get config descriptor on %d/%d: %d",
						bus_number, device_address, r);
					continue;
				}

				usb_interface = get_ccid_usb_interface(config_desc, &num);
				if (usb_interface == NULL)
				{
					(void)libusb_close(dev_handle);
					if (0 == num)
						DEBUG_CRITICAL3("Can't find a CCID interface on %d/%d",
							bus_number, device_address);
					interface_number = -1;
					continue;
				}

				device_descriptor = get_ccid_device_descriptor(usb_interface);
				if (NULL == device_descriptor)
				{
					(void)libusb_close(dev_handle);
					DEBUG_CRITICAL3("Unable to find the device descriptor for %d/%d",
						bus_number, device_address);
					return_value = STATUS_UNSUCCESSFUL;
					goto end2;
				}

				interface = usb_interface->altsetting->bInterfaceNumber;
				if (interface_number >= 0 && interface != interface_number)
				{
					/* an interface was specified and it is not the
					 * current one */
					DEBUG_INFO3("Found interface %d but expecting %d",
						interface_number, interface);
					DEBUG_INFO3("Wrong interface for USB device %d/%d."
						" Checking next one.", bus_number, device_address);

					/* check for another CCID interface on the same device */
					num++;

					goto again;
				}

				r = libusb_claim_interface(dev_handle, interface);
				if (r < 0)
				{
					(void)libusb_close(dev_handle);
					DEBUG_CRITICAL4("Can't claim interface %d/%d: %d",
						bus_number, device_address, r);
					claim_failed = TRUE;
					interface_number = -1;
					continue;
				}

				DEBUG_INFO4("Found Vendor/Product: %04X/%04X (%s)",
					desc.idVendor, desc.idProduct, friendlyName);
				DEBUG_INFO3("Using USB bus/device: %d/%d",
					bus_number, device_address);

				/* check for firmware bugs */
				if (ccid_check_firmware(&desc))
				{
					(void)libusb_close(dev_handle);
					return_value = STATUS_UNSUCCESSFUL;
					goto end2;
				}

#ifdef USE_COMPOSITE_AS_MULTISLOT
				/* use the next interface for the next "slot" */
				static_interface++;

				/* reset for a next reader */
				if (static_interface > 2)
					static_interface = 1;
#endif

				/* Get Endpoints values*/
				(void)get_end_points(config_desc, &usbDevice[reader_index], num);

				/* store device information */
				usbDevice[reader_index].dev_handle = dev_handle;
				usbDevice[reader_index].bus_number = bus_number;
				usbDevice[reader_index].device_address = device_address;
				usbDevice[reader_index].interface = interface;
				usbDevice[reader_index].real_nb_opened_slots = 1;
				usbDevice[reader_index].nb_opened_slots = &usbDevice[reader_index].real_nb_opened_slots;
				usbDevice[reader_index].polling_transfer = NULL;

				/* CCID common informations */
				usbDevice[reader_index].ccid.real_bSeq = 0;
				usbDevice[reader_index].ccid.pbSeq = &usbDevice[reader_index].ccid.real_bSeq;
				usbDevice[reader_index].ccid.readerID =
					(desc.idVendor << 16) + desc.idProduct;
				usbDevice[reader_index].ccid.dwFeatures = dw2i(device_descriptor, 40);
				usbDevice[reader_index].ccid.wLcdLayout =
					(device_descriptor[51] << 8) + device_descriptor[50];
				usbDevice[reader_index].ccid.bPINSupport = device_descriptor[52];
				usbDevice[reader_index].ccid.dwMaxCCIDMessageLength = dw2i(device_descriptor, 44);
				usbDevice[reader_index].ccid.dwMaxIFSD = dw2i(device_descriptor, 28);
				usbDevice[reader_index].ccid.dwDefaultClock = dw2i(device_descriptor, 10);
				usbDevice[reader_index].ccid.dwMaxDataRate = dw2i(device_descriptor, 23);
				usbDevice[reader_index].ccid.bMaxSlotIndex = device_descriptor[4];
				usbDevice[reader_index].ccid.bCurrentSlotIndex = 0;
				usbDevice[reader_index].ccid.readTimeout = DEFAULT_COM_READ_TIMEOUT;
				usbDevice[reader_index].ccid.arrayOfSupportedDataRates = get_data_rates(reader_index, config_desc, num);
				usbDevice[reader_index].ccid.bInterfaceProtocol = usb_interface->altsetting->bInterfaceProtocol;
				usbDevice[reader_index].ccid.bNumEndpoints = usb_interface->altsetting->bNumEndpoints;
				usbDevice[reader_index].ccid.dwSlotStatus = IFD_ICC_PRESENT;
				usbDevice[reader_index].ccid.bVoltageSupport = device_descriptor[5];
				usbDevice[reader_index].ccid.sIFD_serial_number = NULL;
				usbDevice[reader_index].ccid.gemalto_firmware_features = NULL;
				if (desc.iSerialNumber)
				{
					unsigned char serial[128];
					int ret;

					ret = libusb_get_string_descriptor_ascii(dev_handle,
							desc.iSerialNumber, serial,
							sizeof(serial));
					if (ret > 0)
						usbDevice[reader_index].ccid.sIFD_serial_number
							= strdup((char *)serial);
				}

				usbDevice[reader_index].ccid.sIFD_iManufacturer = NULL;
				if (desc.iManufacturer)
				{
					unsigned char iManufacturer[128];
					int ret;

					ret = libusb_get_string_descriptor_ascii(dev_handle,
							desc.iManufacturer, iManufacturer,
							sizeof(iManufacturer));
					if (ret > 0)
						usbDevice[reader_index].ccid.sIFD_iManufacturer
							= strdup((char *)iManufacturer);
				}

				usbDevice[reader_index].ccid.IFD_bcdDevice = desc.bcdDevice;
				goto end;
			}
		}
	}
end:
	if (usbDevice[reader_index].dev_handle == NULL)
	{
		/* does not work for libusb <= 1.0.8 */
		/* libusb_exit(ctx); */
		if (claim_failed)
			return STATUS_COMM_ERROR;
		return STATUS_NO_SUCH_DEVICE;
	}

	/* memorise the current reader_index so we can detect
	 * a new OpenUSBByName on a multi slot reader */
	previous_reader_index = reader_index;

end2:
	/* free the libusb allocated list & devices */
	libusb_free_device_list(devs, 1);

end1:
	/* free bundle list */
	bundleRelease(&plist);

	return return_value;
} /* OpenUSBByName */
Пример #2
0
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	libusb_device **devs;
	libusb_device *dev;
	libusb_device_handle *handle;
	ssize_t num_devs;
	int i = 0;

	struct hid_device_info *root = NULL; /* return object */
	struct hid_device_info *cur_dev = NULL;

	if(hid_init() < 0)
		return NULL;

	num_devs = libusb_get_device_list(usb_context, &devs);
	if (num_devs < 0)
		return NULL;
	while ((dev = devs[i++]) != NULL) {
		struct libusb_device_descriptor desc;
		struct libusb_config_descriptor *conf_desc = NULL;
		int j, k;
		int interface_num = 0;

		int res = libusb_get_device_descriptor(dev, &desc);
		unsigned short dev_vid = desc.idVendor;
		unsigned short dev_pid = desc.idProduct;

		res = libusb_get_active_config_descriptor(dev, &conf_desc);
		if (res < 0)
			libusb_get_config_descriptor(dev, 0, &conf_desc);
		if (conf_desc) {
			for (j = 0; j < conf_desc->bNumInterfaces; j++) {
				const struct libusb_interface *intf = &conf_desc->interface[j];
				for (k = 0; k < intf->num_altsetting; k++) {
					const struct libusb_interface_descriptor *intf_desc;
					intf_desc = &intf->altsetting[k];
					if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
						interface_num = intf_desc->bInterfaceNumber;

						/* Check the VID/PID against the arguments */
						if ((vendor_id == 0x0 || vendor_id == dev_vid) &&
						    (product_id == 0x0 || product_id == dev_pid)) {
							struct hid_device_info *tmp;

							/* VID/PID match. Create the record. */
							tmp = calloc(1, sizeof(struct hid_device_info));
							if (cur_dev) {
								cur_dev->next = tmp;
							}
							else {
								root = tmp;
							}
							cur_dev = tmp;

							/* Fill out the record */
							cur_dev->next = NULL;
							cur_dev->path = make_path(dev, interface_num);

							res = libusb_open(dev, &handle);

							if (res >= 0) {
								/* Serial Number */
								if (desc.iSerialNumber > 0)
									cur_dev->serial_number =
										get_usb_string(handle, desc.iSerialNumber);

								/* Manufacturer and Product strings */
								if (desc.iManufacturer > 0)
									cur_dev->manufacturer_string =
										get_usb_string(handle, desc.iManufacturer);
								if (desc.iProduct > 0)
									cur_dev->product_string =
										get_usb_string(handle, desc.iProduct);

#ifdef INVASIVE_GET_USAGE
{
							/*
							This section is removed because it is too
							invasive on the system. Getting a Usage Page
							and Usage requires parsing the HID Report
							descriptor. Getting a HID Report descriptor
							involves claiming the interface. Claiming the
							interface involves detaching the kernel driver.
							Detaching the kernel driver is hard on the system
							because it will unclaim interfaces (if another
							app has them claimed) and the re-attachment of
							the driver will sometimes change /dev entry names.
							It is for these reasons that this section is
							#if 0. For composite devices, use the interface
							field in the hid_device_info struct to distinguish
							between interfaces. */
								unsigned char data[256];
#ifdef DETACH_KERNEL_DRIVER
								int detached = 0;
								/* Usage Page and Usage */
								res = libusb_kernel_driver_active(handle, interface_num);
								if (res == 1) {
									res = libusb_detach_kernel_driver(handle, interface_num);
									if (res < 0)
										LOG("Couldn't detach kernel driver, even though a kernel driver was attached.");
									else
										detached = 1;
								}
#endif
								res = libusb_claim_interface(handle, interface_num);
								if (res >= 0) {
									/* Get the HID Report Descriptor. */
									res = libusb_control_transfer(handle, LIBUSB_ENDPOINT_IN|LIBUSB_RECIPIENT_INTERFACE, LIBUSB_REQUEST_GET_DESCRIPTOR, (LIBUSB_DT_REPORT << 8)|interface_num, 0, data, sizeof(data), 5000);
									if (res >= 0) {
										unsigned short page=0, usage=0;
										/* Parse the usage and usage page
										   out of the report descriptor. */
										get_usage(data, res,  &page, &usage);
										cur_dev->usage_page = page;
										cur_dev->usage = usage;
									}
									else
										LOG("libusb_control_transfer() for getting the HID report failed with %d\n", res);

									/* Release the interface */
									res = libusb_release_interface(handle, interface_num);
									if (res < 0)
										LOG("Can't release the interface.\n");
								}
								else
									LOG("Can't claim interface %d\n", res);
#ifdef DETACH_KERNEL_DRIVER
								/* Re-attach kernel driver if necessary. */
								if (detached) {
									res = libusb_attach_kernel_driver(handle, interface_num);
									if (res < 0)
										LOG("Couldn't re-attach kernel driver.\n");
								}
#endif
}
#endif /* INVASIVE_GET_USAGE */

								libusb_close(handle);
							}
							/* VID/PID */
							cur_dev->vendor_id = dev_vid;
							cur_dev->product_id = dev_pid;

							/* Release Number */
							cur_dev->release_number = desc.bcdDevice;

							/* Interface Number */
							cur_dev->interface_number = interface_num;
						}
					}
				} /* altsettings */
			} /* interfaces */
			libusb_free_config_descriptor(conf_desc);
		}
	}

	libusb_free_device_list(devs, 1);

	return root;
}
Пример #3
0
int freespace_openDevice(FreespaceDeviceId id) {
    struct FreespaceDevice* device = findDeviceById(id);
    struct libusb_config_descriptor *config;
    const struct libusb_interface_descriptor* intd;
    int controlInterfaceNumber;
    int i;
    int rc;

    if (device == NULL) {
        return FREESPACE_ERROR_NOT_FOUND;
    }

    rc = libusb_open(device->dev_, &device->handle_);
    if (rc != LIBUSB_SUCCESS) {
        return libusb_to_freespace_error(rc);
    }

    controlInterfaceNumber = device->api_->controlInterfaceNumber_;
    rc = libusb_kernel_driver_active(device->handle_, controlInterfaceNumber);
    if (rc == 1) {
    	// Kernel driver attached.  Disconnect it.
    	rc = libusb_detach_kernel_driver(device->handle_, controlInterfaceNumber);
    	if (rc == LIBUSB_SUCCESS) {
            device->kernelDriverDetached_ = 1;
    	}
    }

    rc = libusb_claim_interface(device->handle_, controlInterfaceNumber);
    if (rc != LIBUSB_SUCCESS) {
        return libusb_to_freespace_error(rc);
    }

    rc = libusb_get_active_config_descriptor(device->dev_, &config);
    if (rc != LIBUSB_SUCCESS) {
        return libusb_to_freespace_error(rc);
    }

    intd = config->interface[controlInterfaceNumber].altsetting;

    for (i = 0; i < intd[0].bNumEndpoints; ++i) {
        const struct libusb_endpoint_descriptor* endpoint = &intd[0].endpoint[i];

        if ((endpoint->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN) {
            device->readEndpointAddress_ = endpoint->bEndpointAddress;
            device->maxReadSize_ = endpoint->wMaxPacketSize;
        } else {
            device->writeEndpointAddress_ = endpoint->bEndpointAddress;
            device->maxWriteSize_ = endpoint->wMaxPacketSize;
        }
    }
    if (device->maxReadSize_ == 0 || device->maxWriteSize_ == 0) {
        // Weird.  The device didn't have a read and write endpoint.
        return FREESPACE_ERROR_UNEXPECTED;
    }

    device->state_ = FREESPACE_OPENED;

    // Start the receive queue working.
    rc = freespace_initiateReceiveTransfers(device);
    return rc;
}
Пример #4
0
static void smartreader_check_endpoint(libusb_device *usb_dev, libusb_device_handle *handle)
{
	struct libusb_device_descriptor usbdesc;
	struct libusb_config_descriptor *configDesc;
	int32_t ret;
	int32_t j, k, l;
	uint32_t m;
	uint8_t tmpEndpointAddress;
	int32_t nb_endpoint_ok;
	int32_t busid, devid;
	unsigned char iserialbuffer[128], iproductbuffer[128];
	char *productptr = (char *)iproductbuffer;
	static const char *const typename_str[6] = {"SR", "Infinity", "SRv2", "TripleP1", "TripleP2", "TripleP3"};

	nb_endpoint_ok = 0;

	ret = libusb_get_device_descriptor(usb_dev, &usbdesc);
	if(ret < 0)
	{
		printf("Smartreader : couldn't read device descriptor, assuming this is not a smartreader");
		return;
	}
	if(usbdesc.bNumConfigurations)
	{
		ret = libusb_get_active_config_descriptor(usb_dev, &configDesc);
		if(ret)
		{
			printf("Smartreader : couldn't read config descriptor , assuming this is not a smartreader");
			return;
		}
		for(m = 0; m < sizeof(reader_types) / sizeof(struct s_reader_types); ++m)
		{
			nb_endpoint_ok = 0;
			for(j = 0; j < (configDesc->bNumInterfaces); j++)
			{
				for(k = 0; k < configDesc->interface[j].num_altsetting; k++)
				{
					for(l = 0; l < configDesc->interface[j].altsetting[k].bNumEndpoints; l++)
					{
						tmpEndpointAddress = configDesc->interface[j].altsetting[k].endpoint[l].bEndpointAddress;
						if((tmpEndpointAddress == reader_types[m].in_ep || tmpEndpointAddress == reader_types[m].out_ep))
						{
							nb_endpoint_ok++;
						}
					}
				}
			}
			
			if(nb_endpoint_ok == 2)
			{
				busid = libusb_get_bus_number(usb_dev);
				devid = libusb_get_device_address(usb_dev);
				memset(iserialbuffer, 0, sizeof(iserialbuffer));
				memset(iproductbuffer, 0, sizeof(iproductbuffer));
				libusb_get_string_descriptor_ascii(handle, usbdesc.iSerialNumber, iserialbuffer, sizeof(iserialbuffer));
				libusb_get_string_descriptor_ascii(handle, usbdesc.iProduct, iproductbuffer, sizeof(iproductbuffer));
				if ((!((!strcasecmp(productptr, "Triple Reader+")) && (m == 2))) && (!((!strcasecmp(productptr, "Smartreader2 plus")) && (m == 3)))) {
				printf("bus %03d, device %03d : %04x:%04x %s (type=%s, in_ep=%02x, out_ep=%02x; insert in ncam.server 'device = %s%sSerial:%s')\n",
					   busid, devid,
					   usbdesc.idVendor, usbdesc.idProduct, strlen(productptr) > 0 ? productptr : "Smartreader",
					   typename_str[reader_types[m].rdrtypename], reader_types[m].in_ep, reader_types[m].out_ep,
					   reader_types[m].rdrtypename == 0 ? "" : typename_str[reader_types[m].rdrtypename] , reader_types[m].rdrtypename == 0 ? "" : ";", iserialbuffer
					  );}
			}
		}
	}
}
Пример #5
0
/*! \brief Open a communcation channel to the given USB port name. */
XsResultValue UsbInterface::open(const XsPortInfo &portInfo, uint32_t, uint32_t)
{
	d->m_endTime = 0;

#ifdef USE_WINUSB
	JLDEBUG(gJournal, "Open usb port " << portInfo.portName().toStdString());
#else
	JLDEBUG(gJournal, "Open usb port " << portInfo.usbBus() << ":" << portInfo.usbAddress());
#endif

	if (isOpen())
	{
		JLALERT(gJournal, "Port " << portInfo.portName().toStdString() << " already open");
		return (d->m_lastResult = XRV_ALREADYOPEN);
	}

#ifdef USE_WINUSB
	d->m_deviceHandle = CreateFileA(portInfo.portName().c_str(),
		GENERIC_WRITE | GENERIC_READ,
		FILE_SHARE_WRITE | FILE_SHARE_READ,
		NULL,
		OPEN_EXISTING,
		FILE_ATTRIBUTE_NORMAL | FILE_FLAG_OVERLAPPED,
		NULL);

	if (d->m_deviceHandle == INVALID_HANDLE_VALUE)
	{
		d->m_deviceHandle = NULL;
		return (d->m_lastResult = XRV_PORTNOTFOUND);
	}

	BOOL result = FALSE;
	UCHAR speed = 0;
	ULONG length = 0;
	USB_INTERFACE_DESCRIPTOR interfaceDescriptor = {0,0,0,0,0,0,0,0,0};
	WINUSB_PIPE_INFORMATION pipeInfo;

	result = WinUsb_Initialize(d->m_deviceHandle, &d->m_usbHandle[0]);
	if (result)
	{
		result = WinUsb_GetAssociatedInterface(d->m_usbHandle[0],0,&d->m_usbHandle[1]);
	}
	else
	{
#ifdef XSENS_DEBUG
		DWORD err = GetLastError();
		assert(result);
#endif
		return (d->m_lastResult = XRV_ERROR);
	}

	for (int k = 0; k<2;k++)
	{
		if(result)
		{
			assert(d->m_usbHandle[k] != 0);
			length = sizeof(UCHAR);
			result = WinUsb_QueryDeviceInformation(d->m_usbHandle[k],
				DEVICE_SPEED,
				&length,
				&speed);
		}

		if(result)
		{
			d->m_deviceSpeed = speed;
			result = WinUsb_QueryInterfaceSettings(d->m_usbHandle[k],
				0,
				&interfaceDescriptor);
		}
		if(result)
		{
			for(int i=0;i<interfaceDescriptor.bNumEndpoints;i++)
			{
				result = WinUsb_QueryPipe(d->m_usbHandle[k],
					0,
					(UCHAR) i,
					&pipeInfo);

				if(pipeInfo.PipeType == UsbdPipeTypeBulk &&
					USB_ENDPOINT_DIRECTION_IN(pipeInfo.PipeId))
				{
					d->m_bulkInPipe = pipeInfo.PipeId;
					d->m_bulkInPipePacketSize =
						pipeInfo.MaximumPacketSize;
				}
				else if(pipeInfo.PipeType == UsbdPipeTypeBulk &&
					USB_ENDPOINT_DIRECTION_OUT(pipeInfo.PipeId))
				{
					d->m_bulkOutPipe = pipeInfo.PipeId;
				}
				else if(pipeInfo.PipeType == UsbdPipeTypeInterrupt)
				{
					d->m_interruptPipe = pipeInfo.PipeId;
				}
				else
				{
					result = FALSE;
					break;
				}
			}
		}
	}

	setTimeout(0);	//lint !e534
	flushData();	//lint !e534

	sprintf(d->m_portname, "%s", portInfo.portName().c_str());

//	d->m_offset = 0;
	::ResetEvent(&d->m_quitEvent);	//lint !e534
	d->m_threadHandle = xsStartThread(usbReadThreadFunc, d, &d->m_threadId);
	if (d->m_threadHandle == XSENS_INVALID_THREAD)
	{
#ifdef XSENS_DEBUG
		assert(0);
#endif
		return (d->m_lastResult = XRV_ERROR);
	}

#else // !USE_WINUSB
	static UsbInterfacePrivate::UsbContext  contextManager; //m_contextManager;

	libusb_device **deviceList;
	ssize_t listLength = libusb_get_device_list(contextManager.m_usbContext /*d->m_contextManager.m_usbContext*/, &deviceList);
	if (listLength < 0)
		return d->m_lastResult = d->libusbErrorToXrv((int)listLength);

	// "USBxxx:yyy"
	uint8_t bus = XsPortInfo_usbBus(&portInfo);
	uint8_t address = XsPortInfo_usbAddress(&portInfo);

	XsResultValue xrv = XRV_OK;
	int result;
	libusb_device *device = NULL;
	for (int i = 0; i < listLength && device == NULL; ++i) {
		libusb_device *dev = deviceList[i];
		if (libusb_get_bus_number(dev) != bus || libusb_get_device_address(dev) != address)
			continue;

		libusb_device_descriptor desc;
		result = libusb_get_device_descriptor(dev, &desc);
		if (result != LIBUSB_SUCCESS)
			break;

		libusb_config_descriptor *configDesc;
		result = libusb_get_active_config_descriptor(dev, &configDesc);
		if (result != LIBUSB_SUCCESS)
			break;

		d->m_interface = -1;
		d->m_interfaceCount = configDesc->bNumInterfaces;
		// find the bulk transfer endpoints
		for (uint8_t ifCount = 0; ifCount < configDesc->bNumInterfaces && d->m_interface == -1; ++ifCount) {
			for (uint8_t altsettingCount = 0; altsettingCount < configDesc->interface[ifCount].num_altsetting; altsettingCount++) {
				const libusb_endpoint_descriptor *endpoints = configDesc->interface[ifCount].altsetting[altsettingCount].endpoint;
				int inEndpoint = -1, outEndpoint = -1;
				for (uint8_t i = 0; i < configDesc->interface[ifCount].altsetting[altsettingCount].bNumEndpoints; i++) {
					if ((endpoints[i].bmAttributes&LIBUSB_TRANSFER_TYPE_MASK) != LIBUSB_TRANSFER_TYPE_BULK)
						continue;

					switch (endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_DIR_MASK) {
					case LIBUSB_ENDPOINT_IN:
						inEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK;
						break;

					case LIBUSB_ENDPOINT_OUT:
						outEndpoint = endpoints[i].bEndpointAddress&LIBUSB_ENDPOINT_ADDRESS_MASK;
						break;
					}

				}

				if (outEndpoint == -1 || inEndpoint == -1)
					continue;

				d->m_interface = ifCount;
				d->m_dataOutEndPoint = outEndpoint;
				d->m_dataInEndPoint = inEndpoint;
			}
		}
		if (d->m_interface == -1) {
			xrv = XRV_INPUTCANNOTBEOPENED;
			break;
		}

		libusb_free_config_descriptor(configDesc);
		libusb_ref_device(dev);
		device = dev;
		result = LIBUSB_SUCCESS;
	}

	libusb_free_device_list(deviceList, 1);
	if (result != LIBUSB_SUCCESS) {
		libusb_unref_device(device);
		return d->m_lastResult = d->libusbErrorToXrv(result);
	}

	if (xrv != XRV_OK) {
		libusb_unref_device(device);
		return d->m_lastResult = xrv;
	}

	libusb_device_handle *handle;
	result = libusb_open(device, &handle);
	if (result != LIBUSB_SUCCESS) {
		libusb_unref_device(device);
		return d->m_lastResult = d->libusbErrorToXrv(result);
	}

	// be rude and claim all interfaces
	for (int i = 0; i < d->m_interfaceCount; i++) {
		result = libusb_kernel_driver_active(handle, i);
		if (result > 0)
			result = libusb_detach_kernel_driver(handle, i);
		if (result == LIBUSB_SUCCESS)
			result = libusb_claim_interface(handle, i);
		if (result != LIBUSB_SUCCESS) {
			for (int j = 0; j < i; j++) {
				while (result != LIBUSB_SUCCESS) {
					result = libusb_release_interface(handle, j);
					libusb_attach_kernel_driver(handle, j);
				}
			}

			libusb_close(handle);
			libusb_unref_device(device);
			return d->m_lastResult = d->libusbErrorToXrv(result);
		}
	}

	d->m_deviceHandle = handle;
	sprintf(d->m_portname, "%s", portInfo.portName().c_str());

	flushData();

#endif // !USE_WINUSB
	JLDEBUG(gJournal, "USB Port opened");
	return (d->m_lastResult = XRV_OK);
}
Пример #6
0
hid_device * HID_API_EXPORT hid_open_path(const char *path)
{
    hid_device *dev = NULL;

    dev = new_hid_device();

    libusb_device **devs;
    libusb_device *usb_dev;
    ssize_t num_devs;
    int res;
    int d = 0;
    int good_open = 0;

    setlocale(LC_ALL,"");

    if (!initialized)
        hid_init();

    num_devs = libusb_get_device_list(NULL, &devs);
    while ((usb_dev = devs[d++]) != NULL) {
        struct libusb_device_descriptor desc;
        struct libusb_config_descriptor *conf_desc = NULL;
        int i,j,k;
        libusb_get_device_descriptor(usb_dev, &desc);

        if (libusb_get_active_config_descriptor(usb_dev, &conf_desc) < 0)
            continue;
        for (j = 0; j < conf_desc->bNumInterfaces; j++) {
            const struct libusb_interface *intf = &conf_desc->interface[j];
            for (k = 0; k < intf->num_altsetting; k++) {
                const struct libusb_interface_descriptor *intf_desc;
                intf_desc = &intf->altsetting[k];
                if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
                    char *dev_path = make_path(usb_dev, intf_desc->bInterfaceNumber);
                    if (!strcmp(dev_path, path)) {
                        /* Matched Paths. Open this device */

                        // OPEN HERE //
                        res = libusb_open(usb_dev, &dev->device_handle);
                        if (res < 0) {
                            LOG("can't open device\n");
                            free(dev_path);
                            break;
                        }
                        good_open = 1;

                        /* Detach the kernel driver, but only if the
                           device is managed by the kernel */
                        if (libusb_kernel_driver_active(dev->device_handle, intf_desc->bInterfaceNumber) == 1) {
                            res = libusb_detach_kernel_driver(dev->device_handle, intf_desc->bInterfaceNumber);
                            if (res < 0) {
                                libusb_close(dev->device_handle);
                                LOG("Unable to detach Kernel Driver\n");
                                free(dev_path);
                                good_open = 0;
                                break;
                            }
                        }

                        res = libusb_claim_interface(dev->device_handle, intf_desc->bInterfaceNumber);
                        if (res < 0) {
                            LOG("can't claim interface %d: %d\n", intf_desc->bInterfaceNumber, res);
                            free(dev_path);
                            libusb_close(dev->device_handle);
                            good_open = 0;
                            break;
                        }

                        /* Store off the string descriptor indexes */
                        dev->manufacturer_index = desc.iManufacturer;
                        dev->product_index      = desc.iProduct;
                        dev->serial_index       = desc.iSerialNumber;

                        /* Store off the interface number */
                        dev->interface = intf_desc->bInterfaceNumber;

                        /* Find the INPUT and OUTPUT endpoints. An
                           OUTPUT endpoint is not required. */
                        for (i = 0; i < intf_desc->bNumEndpoints; i++) {
                            const struct libusb_endpoint_descriptor *ep
                                    = &intf_desc->endpoint[i];

                            /* Determine the type and direction of this
                               endpoint. */
                            int is_interrupt =
                                (ep->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK)
                                == LIBUSB_TRANSFER_TYPE_INTERRUPT;
                            int is_output =
                                (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
                                == LIBUSB_ENDPOINT_OUT;
                            int is_input =
                                (ep->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK)
                                == LIBUSB_ENDPOINT_IN;

                            /* Decide whether to use it for intput or output. */
                            if (dev->input_endpoint == 0 &&
                                    is_interrupt && is_input) {
                                /* Use this endpoint for INPUT */
                                dev->input_endpoint = ep->bEndpointAddress;
                                dev->input_ep_max_packet_size = ep->wMaxPacketSize;
                            }
                            if (dev->output_endpoint == 0 &&
                                    is_interrupt && is_output) {
                                /* Use this endpoint for OUTPUT */
                                dev->output_endpoint = ep->bEndpointAddress;
                            }
                        }

                        pthread_create(&dev->thread, NULL, read_thread, dev);

                        // Wait here for the read thread to be initialized.
                        pthread_barrier_wait(&dev->barrier);

                    }
                    free(dev_path);
                }
            }
        }
        libusb_free_config_descriptor(conf_desc);

    }

    libusb_free_device_list(devs, 1);

    // If we have a good handle, return it.
    if (good_open) {
        return dev;
    }
    else {
        // Unable to open any devices.
        free_hid_device(dev);
        return NULL;
    }
}
Пример #7
0
static int get_port(struct state *st, char *port, int *portnum,
			struct libusb_device **hub_dev) {
	struct libusb_device **devs;
	struct libusb_device *dev;
	int current;
	int ret = 0;
	int bus_offset = 0;
	int hub_number = 0;

	if (*port == 'd')
		bus_offset = 2;
	else if (*port == 'u')
		bus_offset = 1;
	else
		return -EINVAL;

	*portnum = strtoul(port+1, NULL, 0);
	if (*portnum < 1 || *portnum > 4)
		return -EINVAL;

	/* XXX These ports have their wires swapped */
	if (bus_offset == 2) {
		if (*portnum == 4)
			*portnum = 1;
		else if (*portnum == 1)
			*portnum = 4;
	}

	if (libusb_get_device_list(st->ctx, &devs) < 0){
		perror ("failed to access USB");
		return 0;
	}

	for (current=0; (dev = devs[current]) != NULL; current++) {
		struct libusb_device_descriptor device_desc;
		struct libusb_config_descriptor *config_desc;
		libusb_device_handle *uh;
		uint16_t dev_vid, dev_pid;

		ret = libusb_get_device_descriptor(dev, &device_desc);
		if (ret)
			goto err;

		ret = libusb_get_active_config_descriptor(dev, &config_desc);

		dev_vid = libusb_le16_to_cpu(device_desc.idVendor);
		dev_pid = libusb_le16_to_cpu(device_desc.idProduct);

		if (libusb_open(dev, &uh) != 0 )
			continue;

		if (dev_vid == 0x05e3 && dev_pid == 0x0614) {
			hub_number = get_hub_number(dev);
			if (hub_number == bus_offset) {
				libusb_ref_device(dev);
				*hub_dev = dev;
			}
		}

		libusb_free_config_descriptor(config_desc);
		libusb_close(uh);
	}
err:
	libusb_free_device_list(devs, 1);

	return ret;
}
Пример #8
0
XN_C_API XnStatus xnUSBOpenEndPoint(XN_USB_DEV_HANDLE pDevHandle, XnUInt16 nEndPointID, XnUSBEndPointType nEPType, XnUSBDirectionType nDirType, XN_USB_EP_HANDLE* pEPHandlePtr)
{
	// validate parameters
	XN_VALIDATE_USB_INIT();
	XN_VALIDATE_DEVICE_HANDLE(pDevHandle);
	XN_VALIDATE_OUTPUT_PTR(pEPHandlePtr);

	// get the device from the handle
	libusb_device* pDevice = libusb_get_device(pDevHandle->hDevice);
	
	// get the configuration descriptor
	libusb_config_descriptor* pConfig;
	int rc = libusb_get_active_config_descriptor(pDevice, &pConfig);
	if (rc != 0)
	{
		return (XN_STATUS_USB_CONFIG_QUERY_FAILED);
	}
	
	// make sure configuration contains the interface we need
	if (pConfig->bNumInterfaces <= pDevHandle->nInterface)
	{
		libusb_free_config_descriptor(pConfig);
		return (XN_STATUS_USB_INTERFACE_QUERY_FAILED);
	}
	
	// take that interface
	const libusb_interface* pInterface = &pConfig->interface[pDevHandle->nInterface];
	
	// make sure interface contains the alternate setting we work with
	if (pInterface->num_altsetting <= pDevHandle->nAltSetting)
	{
		libusb_free_config_descriptor(pConfig);
		return (XN_STATUS_USB_INTERFACE_QUERY_FAILED);
	}
	
	// take that setting
	const libusb_interface_descriptor* pInterfaceDesc = &pInterface->altsetting[pDevHandle->nAltSetting];
	
	// search for the requested endpoint
	const libusb_endpoint_descriptor* pEndpointDesc = NULL;
	
	for (uint8_t i = 0; i < pInterfaceDesc->bNumEndpoints; ++i)
	{
		if (pInterfaceDesc->endpoint[i].bEndpointAddress == nEndPointID)
		{
			pEndpointDesc = &pInterfaceDesc->endpoint[i];
			break;
		}
	}
	
	if (pEndpointDesc == NULL)
	{
		libusb_free_config_descriptor(pConfig);
		return (XN_STATUS_USB_ENDPOINT_NOT_FOUND);
	}
	
	libusb_transfer_type transfer_type = (libusb_transfer_type)(pEndpointDesc->bmAttributes & 0x3); // lower 2-bits

    // calculate max packet size
	// NOTE: we do not use libusb functions (libusb_get_max_packet_size/libusb_get_max_iso_packet_size) because
	// they hace a bug and does not consider alternative interface
    XnUInt32 nMaxPacketSize = 0;
	
	if (transfer_type == LIBUSB_TRANSFER_TYPE_ISOCHRONOUS)
	{
		XnUInt32 wMaxPacketSize = pEndpointDesc->wMaxPacketSize;
		// bits 11 and 12 mark the number of additional transactions, bits 0-10 mark the size
		XnUInt32 nAdditionalTransactions = wMaxPacketSize >> 11;
		XnUInt32 nPacketSize = wMaxPacketSize & 0x7FF;
		nMaxPacketSize = (nAdditionalTransactions + 1) * (nPacketSize);
	}
Пример #9
0
void UsbConnection::print_info() {
    int error_config;
    libusb_config_descriptor *config_desc;
    libusb_device_descriptor desc;
    if (!device) {
        ConnectionStatus status = usb_connect ();
        if (status == ready){
            return;
        }
    }
    libusb_get_device_descriptor(device, &desc);

    unsigned char data[255] = {};
    int response = libusb_get_string_descriptor_ascii (handler, desc.iProduct, data, sizeof(data));
    qDebug("Product Description: %s|\n", data);
    response = libusb_get_string_descriptor_ascii (handler, desc.iManufacturer, data, sizeof(data));
    qDebug("Manufacturer Description: %s|\n", data);
    libusb_get_string_descriptor_ascii (handler, desc.iSerialNumber, data, sizeof(data));
    qDebug("SerialNumber Description: %s|\n", data);

    qDebug("\nbegin descriptor\n");
    qDebug("\tbus_num: %d\n", libusb_get_bus_number(device));
    qDebug("\taddress: %d\n", libusb_get_device_address(device));
    qDebug("\tspeed: %d\n", libusb_get_device_speed(device));
    qDebug("\tClass: %d\n", desc.bDeviceClass);
    qDebug("\tSubClass: %d\n", desc.bDeviceSubClass);
    qDebug("\tDeviceProtocol: %d\n", desc.bDeviceProtocol);
    qDebug("\tidVendor: %d\n", desc.idVendor);
    qDebug("\tidProduct: %d\n", desc.idProduct);
    qDebug("\tiManufacturer: %d\n", desc.iManufacturer);
    qDebug("\tiProduct: %d\n", desc.iProduct);
    qDebug("\tiSerialNumber: %d\n", desc.iSerialNumber);
    qDebug("\tbMaxPacketSize0: %d\n", desc.bMaxPacketSize0);
    qDebug("\tbNumConfigurations: %d\n", desc.bNumConfigurations);
    qDebug("\tconfigDescriptor:\n");


    error_config = libusb_get_active_config_descriptor(device, &config_desc);
    if (error_config) {
        if (error_config == LIBUSB_ERROR_NOT_FOUND) {
            qDebug("Error config not founds\n");
        } else {
            qDebug("Error in config %s\n", libusb_error_name (error_config));
        }
    } else {
        qDebug("\tiConfiguration: %d\n", config_desc->iConfiguration);
        qDebug("\tbNumInterface: %d\n", config_desc->bNumInterfaces);
        qDebug("\tbmAttributes: %d\n", config_desc->bmAttributes);
        for (int i_interface = 0; i_interface < config_desc->bNumInterfaces; i_interface++) {
            for (int i_altinterface = 0;
                 i_altinterface < config_desc->interface[i_interface].num_altsetting;
                i_altinterface++) {
                libusb_interface_descriptor alt_settings = config_desc->interface[i_interface].altsetting[i_altinterface];
                qDebug("\tbInterfaceNumber[%d][%d]: %d\n", i_interface, i_altinterface,
                    alt_settings.bInterfaceNumber);
                qDebug("\tbInterfaceClass[%d][%d]: %d\n", i_interface, i_altinterface,
                    alt_settings.bInterfaceClass);
                qDebug("\bInterfaceSubClass[%d][%d]: %d\n", i_interface, i_altinterface,
                    alt_settings.bInterfaceSubClass);
                qDebug("\tbInterfaceProtocol[%d][%d]: %d\n", i_interface, i_altinterface,
                    alt_settings.bInterfaceProtocol);
                qDebug("\textra[%d][%d]: %s\n", i_interface, i_altinterface,
                    alt_settings.extra);
                for (int i_ep = 0; i_ep < alt_settings.bNumEndpoints; i_ep++) {
                    libusb_endpoint_descriptor ep_desc = alt_settings.endpoint[i_ep];
                    qDebug("\t\tbEndpointAddress[%d][%d][%d]: %d (in=%d / out=%d)\n",
                        i_interface, i_altinterface, i_ep,
                        ep_desc.bEndpointAddress, LIBUSB_ENDPOINT_IN, LIBUSB_ENDPOINT_OUT);
                    qDebug("\t\tbDescriptorType[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep,
                        ep_desc.bDescriptorType);
                    qDebug("\t\tbmAttributes[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep,
                           ep_desc.bmAttributes);
                    qDebug("\t\textra[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep,
                        ep_desc.extra_length);
                    qDebug("\t\tbSynchAddress[%d][%d][%d]: %d\n", i_interface, i_altinterface, i_ep,
                        ep_desc.bSynchAddress);
                }
            }
        }
        libusb_free_config_descriptor(config_desc);
    }
}
Пример #10
0
int cyusb_get_active_config_descriptor(cyusb_handle *h, struct libusb_config_descriptor **config)
{
	cyusb_device *tdev = libusb_get_device(h);
	return ( libusb_get_active_config_descriptor(tdev, config) );
}
Пример #11
0
GSM_Error GSM_USB_Probe(GSM_StateMachine *s, GSM_USB_Match_Function matcher)
{
	libusb_device **devs;
	libusb_device *dev;
	GSM_Device_USBData *d = &s->Device.Data.USB;
	ssize_t cnt;
	int rc;
	int i = 0;
	struct libusb_device_descriptor desc;
	struct libusb_config_descriptor *config;
	GSM_Error error;
	int vendor = -1, product = -1, bus = -1, deviceid = -1;
	char *serial = NULL;
	char buffer[300];
	gboolean do_match;

	/* Device selection */
	GSM_USB_ParseDevice(s, &vendor, &product, &bus, &deviceid, &serial);
	do_match = (vendor != -1 || product != -1 || bus != -1 || deviceid != -1 || serial != NULL);

	cnt = libusb_get_device_list(d->context, &devs);
	if (cnt < 0) {
		smprintf(s, "Failed to list USB devices (%d)!\n", (int)cnt);
		return GSM_USB_Error(s, cnt);
	}

	/* Check all devices */
	i = 0;
	while ((dev = devs[i++]) != NULL) {
		rc = libusb_get_device_descriptor(dev, &desc);
		if (rc < 0) {
			smprintf(s, "Failed to get device descriptor (%d)!\n", rc);
			GSM_USB_Error(s, rc);
			continue;
		}

		smprintf(s, "Checking %04x:%04x (bus %d, device %d)\n",
			desc.idVendor, desc.idProduct,
			libusb_get_bus_number(dev), libusb_get_device_address(dev));

		if (do_match) {
			if (vendor != -1 && vendor != desc.idVendor) {
				smprintf(s, "Vendor does not match requested 0x%04x, ignoring\n", vendor);
				continue;
			}
			if (product != -1 && product != desc.idProduct) {
				smprintf(s, "Product does not match requested 0x%04x, ignoring\n", product);
				continue;
			}
			if (bus != -1 && bus != libusb_get_bus_number(dev)) {
				smprintf(s, "Bus does not match requested %d, ignoring\n", bus);
				continue;
			}
			if (deviceid != -1 && deviceid != libusb_get_device_address(dev)) {
				smprintf(s, "Device address does not match requested %d, ignoring\n", deviceid);
				continue;
			}
			if (serial != NULL && desc.iSerialNumber) {
				rc = libusb_open(dev, &d->handle);
				if (rc != 0) {
					smprintf(s, "Failed to read serial!\n");
				} else {
					libusb_get_string_descriptor_ascii(d->handle, desc.iSerialNumber, buffer, sizeof(buffer) - 1);
					smprintf(s, "Device serial: %s\n", buffer);
					libusb_close(d->handle);
					if (strcasecmp(buffer, serial) != 0) {
						smprintf(s, "Device serial does not match requested %s, ignoring\n", serial);
						continue;
					}
				}
			}
		}

		if (matcher(s, dev, &desc)) {
			break;
		}
	}

	if (dev == NULL) {
		error = ERR_DEVICENOTEXIST;
		goto done;
	}

	smprintf(s, "Trying to open device, config=%d, c_iface=%d, c_alt=%d, d_iface=%d, d_alt=%d\n",
		d->configuration, d->control_iface, d->control_altsetting, d->data_iface, d->data_altsetting);

	rc = libusb_open(dev, &d->handle);
	if (rc != 0) {
		d->handle = NULL;
		error = GSM_USB_Error(s, rc);
		goto done;
	}

	/* Unhook kernel driver */
	rc = libusb_get_active_config_descriptor(dev, &config);
	if (rc != 0) {
		smprintf(s, "Failed to get current device configuration!\n");
		libusb_close(d->handle);
		d->handle = NULL;
		error = GSM_USB_Error(s, rc);
		goto done;
	}

	/* Do we have to change configuration? */
	if (config->bConfigurationValue != d->configuration) {
		smprintf(s, "Will change configuration, unhooking all interfaces!\n");
		for (i = 0; i < config->bNumInterfaces; i++) {
			if (libusb_kernel_driver_active(d->handle, i) == 1) {
				smprintf(s, "Detaching kernel driver from interface %d\n", i);
				rc = libusb_detach_kernel_driver(d->handle, i);
				if (rc != 0) {
					smprintf(s, "Failed to detach kernel driver!\n");
					libusb_free_config_descriptor(config);
					libusb_close(d->handle);
					d->handle = NULL;
					error = GSM_USB_Error(s, rc);
					goto done;
				}
			}
		}


		smprintf(s, "Configuring USB device...\n");
		rc = libusb_set_configuration(d->handle, d->configuration);
		if (rc != 0) {
			smprintf(s, "Failed to set device configuration %d (%d)!\n", d->configuration, rc);
			libusb_free_config_descriptor(config);
			libusb_close(d->handle);
			d->handle = NULL;
			error = GSM_USB_Error(s, rc);
			goto done;
		}
	} else {
		smprintf(s, "Configuration change not required, unhooking only required interfaces!\n");

		if (libusb_kernel_driver_active(d->handle, d->control_iface) == 1) {
			smprintf(s, "Detaching kernel driver from interface %d\n", d->control_iface);
			rc = libusb_detach_kernel_driver(d->handle, d->control_iface);
			if (rc != 0) {
				smprintf(s, "Failed to detach kernel driver!\n");
				libusb_free_config_descriptor(config);
				libusb_close(d->handle);
				d->handle = NULL;
				error = GSM_USB_Error(s, rc);
				goto done;
			}
		}

		if (libusb_kernel_driver_active(d->handle, d->data_iface) == 1) {
			smprintf(s, "Detaching kernel driver from interface %d\n", d->data_iface);
			rc = libusb_detach_kernel_driver(d->handle, d->data_iface);
			if (rc != 0) {
				smprintf(s, "Failed to detach kernel driver!\n");
				libusb_free_config_descriptor(config);
				libusb_close(d->handle);
				d->handle = NULL;
				error = GSM_USB_Error(s, rc);
				goto done;
			}
		}
	}
	libusb_free_config_descriptor(config);

	smprintf(s, "Claiming USB control interface...\n");
	rc = libusb_claim_interface(d->handle, d->control_iface);
	if (rc != 0) {
		smprintf(s, "Failed to set claim control interface %d (%d)!\n", d->control_iface, rc);
		libusb_close(d->handle);
		d->handle = NULL;
		error = GSM_USB_Error(s, rc);
		goto done;
	}

	smprintf(s, "Configuring USB control interface...\n");
	rc = libusb_set_interface_alt_setting(d->handle, d->control_iface, d->control_altsetting);
	if (rc != 0) {
		smprintf(s, "Failed to set control alt setting %d (%d)!\n", d->control_altsetting, rc);
		libusb_close(d->handle);
		d->handle = NULL;
		error = GSM_USB_Error(s, rc);
		goto done;
	}

	smprintf(s, "Claiming USB data interface...\n");
	rc = libusb_claim_interface(d->handle, d->data_iface);
	if (rc != 0) {
		smprintf(s, "Failed to set claim data interface %d (%d)!\n", d->data_iface, rc);
		libusb_close(d->handle);
		d->handle = NULL;
		error = GSM_USB_Error(s, rc);
		goto done;
	}

	smprintf(s, "Configuring USB data interface...\n");
	rc = libusb_set_interface_alt_setting(d->handle, d->data_iface, d->data_altsetting);
	if (rc != 0) {
		smprintf(s, "Failed to set data alt setting %d (%d)!\n", d->data_altsetting, rc);
		libusb_close(d->handle);
		d->handle = NULL;
		error = GSM_USB_Error(s, rc);
		goto done;
	}

	smprintf(s, "Connected!\n");
	error = ERR_NONE;

done:

	return error;
}
Пример #12
0
static int 
probe(std::unique_ptr<usb_handle> &h, ifc_match_func callback)
{
	usb_ifc_info info;
	libusb_device_descriptor ddesc;
	libusb_config_descriptor *pcfg;
	int i, j;

	if (libusb_open(h->dev, &h->handle) < 0)
		return (-1);

	if (libusb_get_device_descriptor(h->dev, &ddesc) < 0) {
		libusb_close(h->handle);
		return (-1);
	}
	memset(&info, 0, sizeof(info));

	info.dev_vendor = ddesc.idVendor;
	info.dev_product = ddesc.idProduct;
	info.dev_class = ddesc.bDeviceClass;
	info.dev_subclass = ddesc.bDeviceSubClass;
	info.dev_protocol = ddesc.bDeviceProtocol;
	info.writable = 1;

	snprintf(info.device_path, sizeof(info.device_path), "ugen%d.%d",
		 libusb_get_bus_number(h->dev), libusb_get_device_address(h->dev));

	if (ddesc.iSerialNumber != 0) {
		libusb_get_string_descriptor_ascii(h->handle, ddesc.iSerialNumber,
		    (unsigned char *)info.serial_number, sizeof(info.serial_number));
	}
	if (libusb_get_active_config_descriptor(h->dev, &pcfg)) {
		libusb_close(h->handle);
		return (-1);
	}

	for (i = 0; i < pcfg->bNumInterfaces; i++) {

		h->ep_in = 0;
		h->ep_out = 0;
		h->iface = i;

		for (j = 0; j < pcfg->interface[i].altsetting[0].bNumEndpoints; j++) {

			unsigned char temp = pcfg->interface[i].altsetting[0].
			endpoint[j].bEndpointAddress;
			unsigned char type = pcfg->interface[i].altsetting[0].
			endpoint[j].bmAttributes & 0x03;

			/* check for BULK endpoint */
			if ((type & 0x03) == 0x02) {
				/* check for IN endpoint */
				if (temp & 0x80)
					h->ep_in = temp;
				else
					h->ep_out = temp;
			}
		}

		info.ifc_class = pcfg->interface[i].altsetting[0].bInterfaceClass;
		info.ifc_subclass = pcfg->interface[i].altsetting[0].bInterfaceSubClass;
		info.ifc_protocol = pcfg->interface[i].altsetting[0].bInterfaceProtocol;
		info.has_bulk_in = (h->ep_in != 0);
		info.has_bulk_out = (h->ep_out != 0);

		if (libusb_claim_interface(h->handle, h->iface) < 0)
			continue;

		if (callback(&info) == 0) {
			libusb_free_config_descriptor(pcfg);
			return (0);
		}
		libusb_release_interface(h->handle, h->iface);
	}

	libusb_free_config_descriptor(pcfg);
	libusb_close(h->handle);
	return (-1);
}
static void scan_for_bt_endpoints(void) {
    int r;

    event_in_addr = 0;
    acl_in_addr = 0;
    acl_out_addr = 0;
    sco_out_addr = 0;
    sco_in_addr = 0;

    // get endpoints from interface descriptor
    struct libusb_config_descriptor *config_descriptor;
    r = libusb_get_active_config_descriptor(dev, &config_descriptor);

    int num_interfaces = config_descriptor->bNumInterfaces;
    log_info("active configuration has %u interfaces", num_interfaces);

    int i;
    for (i = 0; i < num_interfaces ; i++){
        const struct libusb_interface *interface = &config_descriptor->interface[i];
        const struct libusb_interface_descriptor * interface_descriptor = interface->altsetting;
        log_info("interface %u: %u endpoints", i, interface_descriptor->bNumEndpoints);

        const struct libusb_endpoint_descriptor *endpoint = interface_descriptor->endpoint;

        for (r=0;r<interface_descriptor->bNumEndpoints;r++,endpoint++){
            log_info("- endpoint %x, attributes %x", endpoint->bEndpointAddress, endpoint->bmAttributes);

            switch (endpoint->bmAttributes & 0x3){
                case LIBUSB_TRANSFER_TYPE_INTERRUPT:
                    if (event_in_addr) continue;
                    event_in_addr = endpoint->bEndpointAddress;
                    log_info("-> using 0x%2.2X for HCI Events", event_in_addr);
                    break;
                case LIBUSB_TRANSFER_TYPE_BULK:
                    if (endpoint->bEndpointAddress & 0x80) {
                        if (acl_in_addr) continue;
                        acl_in_addr = endpoint->bEndpointAddress;
                        log_info("-> using 0x%2.2X for ACL Data In", acl_in_addr);
                    } else {
                        if (acl_out_addr) continue;
                        acl_out_addr = endpoint->bEndpointAddress;
                        log_info("-> using 0x%2.2X for ACL Data Out", acl_out_addr);
                    }
                    break;
                case LIBUSB_TRANSFER_TYPE_ISOCHRONOUS:
                    if (endpoint->bEndpointAddress & 0x80) {
                        if (sco_in_addr) continue;
                        sco_in_addr = endpoint->bEndpointAddress;
                        log_info("-> using 0x%2.2X for SCO Data In", sco_in_addr);
                    } else {
                        if (sco_out_addr) continue;
                        sco_out_addr = endpoint->bEndpointAddress;
                        log_info("-> using 0x%2.2X for SCO Data Out", sco_out_addr);
                    }
                    break;
                default:
                    break;
            }
        }
    }
    libusb_free_config_descriptor(config_descriptor);
}
Пример #14
0
/*
 * Iterates over the usb devices on the usb busses and returns a handle to the
 * first device found that matches the predefined vendor and product id
 */
libusb_device_handle *open_device(libusb_context * ctx, int vendor_id, int product_id)
{
	// discover devices
	libusb_device **list;
	libusb_device *found = NULL;
	libusb_device_handle *device_handle = NULL;
	struct libusb_device_descriptor descriptor;

	size_t cnt = libusb_get_device_list(ctx, &list);
	size_t i = 0;
	int err = 0;
	if (cnt < 0) {
		fprintf(stderr, "Failed to get a list of devices\n");
		return NULL;
	}

	for (i = 0; i < cnt; i++) {
		libusb_device *device = list[i];
		err = libusb_get_device_descriptor(device, &descriptor);
		if (err) {
			fprintf(stderr, "libusb_get_device_descriptor: %s\n", usbutil_error_to_string(err));
			libusb_free_device_list(list, 1);
			return NULL;
		}
		if ((descriptor.idVendor == vendor_id) && (descriptor.idProduct == product_id)) {
			found = device;
			usbutil_dump_device_descriptor(stderr, &descriptor);
			break;
		}
	}

	if (!found) {
		fprintf(stderr, "Device not found\n");
		libusb_free_device_list(list, 1);
		return NULL;
	}

	if ((err = libusb_open(found, &device_handle))) {
		fprintf(stderr, "Failed OPEN the device: %s\n", usbutil_error_to_string(err));
		libusb_free_device_list(list, 1);
		return NULL;
	}
	fprintf(stderr, "libusb_open: %s\n", usbutil_error_to_string(err));

	libusb_free_device_list(list, 1);

	if ((err = claim_device(device_handle, 0)) != 0) {
		fprintf(stderr, "Failed to claim the usb interface: %s\n", usbutil_error_to_string(err));
		return NULL;
	}

	struct libusb_config_descriptor *config_descriptor;
	err = libusb_get_active_config_descriptor(found, &config_descriptor);
	if (err) {
		fprintf(stderr, "libusb_get_active_config_descriptor: %s\n", usbutil_error_to_string(err));
		return NULL;
	}
	fprintf(stderr, "Active configuration:%d\n", config_descriptor->bConfigurationValue);
	libusb_free_config_descriptor(config_descriptor);

	fprintf(stderr, "Available configurations (%d):\n", descriptor.bNumConfigurations);
	for (i = 0; i < descriptor.bNumConfigurations; i++) {
		err = libusb_get_config_descriptor(found, i, &config_descriptor);
		if (err) {
			fprintf(stderr, "libusb_get_config_descriptor: %s\n", usbutil_error_to_string(err));
			return NULL;
		}

		usbutil_dump_config_descriptor(stderr, config_descriptor);
		libusb_free_config_descriptor(config_descriptor);
	}

	return device_handle;
}
Пример #15
0
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	libusb_device **devs;
	libusb_device *dev;
	libusb_device_handle *handle;
	ssize_t num_devs;
	int i = 0;
	
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;
	
	setlocale(LC_ALL,"");
	
	if (!initialized) {
		libusb_init(NULL);
		initialized = 1;
	}
	
	num_devs = libusb_get_device_list(NULL, &devs);
	if (num_devs < 0)
		return NULL;
	while ((dev = devs[i++]) != NULL) {
		struct libusb_device_descriptor desc;
		struct libusb_config_descriptor *conf_desc = NULL;
		int skip = 1;
		int j, k;
		int interface_num = 0;

		int res = libusb_get_device_descriptor(dev, &desc);
		unsigned short dev_vid = desc.idVendor;
		unsigned short dev_pid = desc.idProduct;
		
		/* HID's are defined at the interface level. */
		if (desc.bDeviceClass != LIBUSB_CLASS_PER_INTERFACE)
			continue;

		res = libusb_get_active_config_descriptor(dev, &conf_desc);
		if (res < 0)
			libusb_get_config_descriptor(dev, 0, &conf_desc);
		if (conf_desc) {
			for (j = 0; j < conf_desc->bNumInterfaces; j++) {
				const struct libusb_interface *intf = &conf_desc->interface[j];
				for (k = 0; k < intf->num_altsetting; k++) {
					const struct libusb_interface_descriptor *intf_desc;
					intf_desc = &intf->altsetting[k];
					if (intf_desc->bInterfaceClass == LIBUSB_CLASS_HID) {
						interface_num = intf_desc->bInterfaceNumber;
						skip = 0;
					}
				}
			}
			libusb_free_config_descriptor(conf_desc);
		}

		if (skip)
			continue;
			
		/* Check the VID/PID against the arguments */
		if ((vendor_id == 0x0 && product_id == 0x0) ||
		    (vendor_id == dev_vid && product_id == dev_pid)) {
			struct hid_device_info *tmp;

		    	/* VID/PID match. Create the record. */
			tmp = calloc(1, sizeof(struct hid_device_info));
			if (cur_dev) {
				cur_dev->next = tmp;
			}
			else {
				root = tmp;
			}
			cur_dev = tmp;
			
			/* Fill out the record */
			cur_dev->next = NULL;
			cur_dev->path = make_path(dev, interface_num);
			
			res = libusb_open(dev, &handle);


			if (res >= 0) {
			
				/* Serial Number */
				if (desc.iSerialNumber > 0)
					cur_dev->serial_number =
						get_usb_string(handle, desc.iSerialNumber);

				/* Manufacturer and Product strings */
				if (desc.iManufacturer > 0)
					cur_dev->manufacturer_string =
						get_usb_string(handle, desc.iManufacturer);
				if (desc.iProduct > 0)
					cur_dev->product_string =
						get_usb_string(handle, desc.iProduct);
				
				libusb_close(handle);
			}
			/* VID/PID */
			cur_dev->vendor_id = dev_vid;
			cur_dev->product_id = dev_pid;
		}
	}

	libusb_free_device_list(devs, 1);

	return root;
}