Beispiel #1
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct drv_context *drvc;
	struct sr_usb_dev_inst *usb;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	GSList *devices;
	char connection_id[64];
	size_t i;
	int r;

	(void)options;

	drvc = di->context;

	devices = NULL;

	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);

	for (i = 0; devlist[i]; i++) {
		libusb_get_device_descriptor(devlist[i], &des);

		if (des.idVendor != LOGICSTUDIO16_VID)
			continue;

		usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));

		usb = NULL;

		switch (des.idProduct) {
		case LOGICSTUDIO16_PID_HAVE_FIRMWARE:
			usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
				libusb_get_device_address(devlist[i]), NULL);

			sdi = create_device(usb, SR_ST_INACTIVE, 0);
			break;
		case LOGICSTUDIO16_PID_LACK_FIRMWARE:
			r = ezusb_upload_firmware(drvc->sr_ctx, devlist[i],
				USB_CONFIGURATION, FX2_FIRMWARE);
			if (r != SR_OK) {
				/*
				 * An error message has already been logged by
				 * ezusb_upload_firmware().
				 */
				continue;
			}

			/*
			 * Put unknown as the address so that we know we still
			 * need to get the proper address after the device
			 * renumerates.
			 */
			usb = sr_usb_dev_inst_new(libusb_get_bus_number(devlist[i]),
				UNKNOWN_ADDRESS, NULL);

			sdi = create_device(usb, SR_ST_INITIALIZING,
				g_get_monotonic_time());
			break;
		default:
			break;
		}

		/* Cannot handle this device? */
		if (!usb)
			continue;

		sdi->connection_id = g_strdup(connection_id);

		devices = g_slist_append(devices, sdi);
	}

	libusb_free_device_list(devlist, 1);

	return std_scan_complete(di, devices);
}
Beispiel #2
0
  int iusb_init (byte ep_in_addr, byte ep_out_addr) {
    logd ("ep_in_addr: %d  ep_out_addr: %d", ep_in_addr, ep_out_addr);

    iusb_ep_in  = -1;
    iusb_ep_out = -1;
    iusb_best_device = NULL;
    iusb_best_vendor = 0;

    int usb_err = libusb_init (NULL);
    if (usb_err < 0) {
      loge ("Error libusb_init usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));
      return (-1);
    }
    logd ("OK libusb_init usb_err: %d", usb_err);

    libusb_set_debug (NULL, LIBUSB_LOG_LEVEL_WARNING);    // DEBUG);//
    logd ("Done libusb_set_debug");

    libusb_device ** list;
    usb_err = libusb_get_device_list (NULL, & list);                // Get list of USB devices
    if (usb_err < 0) {
      loge ("Error libusb_get_device_list cnt: %d", usb_err, iusb_error_get (usb_err));
      return (-1);
    }
    ssize_t cnt = usb_err;
    logd ("Done libusb_get_device_list cnt: %d", cnt);
    int idx = 0;
    int iusb_best_vendor_priority = 0;

    libusb_device * device;
    for (idx = 0; idx < cnt; idx ++) {                                  // For all USB devices...
      device = list [idx];
      int vendor = iusb_vendor_get (device);
      //int product = product_get (device);
      logd ("iusb_vendor_get vendor: 0x%04x  device: %p", vendor, device);
      if (vendor) {
        int vendor_priority = iusb_vendor_priority_get (vendor);
        //if (iusb_best_vendor_priority <  vendor_priority) {  // For first
        if (iusb_best_vendor_priority <= vendor_priority) {  // For last
          iusb_best_vendor_priority = vendor_priority;
          iusb_best_vendor = vendor;
          iusb_best_device = device;
          strncpy (iusb_best_man, iusb_curr_man, sizeof (iusb_best_man));
          strncpy (iusb_best_pro, iusb_curr_pro, sizeof (iusb_best_pro));
        }
      }
    }
    if (iusb_best_vendor == 0 || iusb_best_device == NULL) {                                             // If no vendor...
      loge ("Error device not found iusb_best_vendor: 0x%04x  iusb_best_device: %p", iusb_best_vendor, iusb_best_device);
      libusb_free_device_list (list, 1);                                // Free device list now that we are finished with it
      return (-1);
    }
    logd ("Device found iusb_best_vendor: 0x%04x  iusb_best_device: 0x%04x  iusb_best_man: \"%s\"  iusb_best_pro: \"%s\"", iusb_best_vendor, iusb_best_device, iusb_best_man, iusb_best_pro);

    //usb_perms_set ();                                                   // Setup USB permissions, where needed


    if (file_get ("/sdcard/suc")) {    // Set Permission w/ SU:
      int ret = system ("su -c chmod -R 777 /dev/bus 1>/dev/null 2>/dev/null"); // !! Binaries like ssd that write to stdout cause C system() to crash !
      logd ("iusb_usb_init system() ret: %d", ret);
    }


    usb_err = libusb_open (iusb_best_device, & iusb_dev_hndl);
    logd ("libusb_open usb_err: %d (%s)  iusb_dev_hndl: %p  list: %p", usb_err, iusb_error_get (usb_err), iusb_dev_hndl, list);

    libusb_free_device_list (list, 1);                                  // Free device list now that we are finished with it

    if (usb_err != 0) {
      loge ("Error libusb_open usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));
      return (-1);
    }
    logd ("Done libusb_open iusb_dev_hndl: %p", iusb_dev_hndl);

/*
    usb_err = libusb_set_auto_detach_kernel_driver (iusb_dev_hndl, 1);
    if (usb_err)
      loge ("Done libusb_set_auto_detach_kernel_driver usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));
    else
      logd ("Done libusb_set_auto_detach_kernel_driver usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));
//*/
    usb_err = libusb_claim_interface (iusb_dev_hndl, 0);
    if (usb_err)
      loge ("Error libusb_claim_interface usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));
    else
      logd ("OK libusb_claim_interface usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));

    struct libusb_config_descriptor * config = NULL;
    usb_err = libusb_get_config_descriptor (iusb_best_device, 0, & config);
    if (usb_err != 0) {
      loge ("Error libusb_get_config_descriptor usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));
      //return (-1);
      iusb_ep_in  = ep_in_addr; //129;                                  // Set  input endpoint
      iusb_ep_out = ep_out_addr;//  2;                                  // Set output endpoint
      return (0);
    }

    int num_int = config->bNumInterfaces;                               // Get number of interfaces
    logd ("Done get_config_descriptor config: %p  num_int: %d", config, num_int);

    const struct libusb_interface            * inter;
    const struct libusb_interface_descriptor * interdesc;
    const struct libusb_endpoint_descriptor  * epdesc;

    for (idx = 0; idx < num_int; idx ++) {                              // For all interfaces...
      inter = & config->interface [idx];
      int num_altsetting = inter->num_altsetting;
      logd ("num_altsetting: %d", num_altsetting);
      int j = 0;
      for (j = 0; j < inter->num_altsetting; j ++) {                    // For all alternate settings...
        interdesc = & inter->altsetting [j];
        int num_int = interdesc->bInterfaceNumber;
        logd ("num_int: %d", num_int);
        int num_eps = interdesc->bNumEndpoints;
        logd ("num_eps: %d", num_eps);
        int k = 0;
        for (k = 0; k < num_eps; k ++) {                                // For all endpoints...
	        epdesc = & interdesc->endpoint [k];
          if (epdesc->bDescriptorType == LIBUSB_DT_ENDPOINT) {          // 5
            if ((epdesc->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) == LIBUSB_TRANSFER_TYPE_BULK) {
              int ep_add = epdesc->bEndpointAddress;
              if (ep_add & LIBUSB_ENDPOINT_DIR_MASK) {
                if (iusb_ep_in < 0) {
                  iusb_ep_in = ep_add;                                   // Set input endpoint
                  logd ("iusb_ep_in: 0x%02x", iusb_ep_in);
                }
              }
              else {
                if (iusb_ep_out < 0) {
                  iusb_ep_out = ep_add;                                  // Set output endpoint
                  logd ("iusb_ep_out: 0x%02x", iusb_ep_out);
                }
              }
              if (iusb_ep_in > 0 && iusb_ep_out > 0) {                    // If we have both endpoints now...
                libusb_free_config_descriptor (config);

                if ((ep_in_addr != -1 || ep_out_addr != -1) && (iusb_ep_in != ep_in_addr || iusb_ep_out != ep_out_addr)) {
                  loge ("MISMATCH Done endpoint search iusb_ep_in: 0x%02x  iusb_ep_out: 0x%02x", iusb_ep_in, iusb_ep_out);    // Favor libusb over passed in
                }
                else
                  logd ("Match Done endpoint search iusb_ep_in: 0x%02x  iusb_ep_out: 0x%02x", iusb_ep_in, iusb_ep_out);

                return (0);
              }
            }
          }
        }
      }
    }
                                                                        // Else if DON'T have both endpoints...
    loge ("Error in and/or out endpoints unknown iusb_ep_in: 0x%02x  iusb_ep_out: 0x%02x", iusb_ep_in, iusb_ep_out);
    libusb_free_config_descriptor (config);

    if (iusb_ep_in == -1)
      iusb_ep_in  = ep_in_addr; //129;                                  // Set  input endpoint
    if (iusb_ep_out == -1)
      iusb_ep_out = ep_out_addr;//  2;                                  // Set output endpoint

    if (iusb_ep_in == -1 || iusb_ep_out == -1)
      return (-1);

    loge ("!!!!! FIXED EP's !!!!!");
    return (0);
  }
Beispiel #3
0
bool ns_usb_control::reset_device(int bus,int device_id){
	#ifdef _WIN32 
	return false;
	#else
	
	#ifdef USE_NEW_USB
	libusb_device **devices;
	int r;
	ssize_t cnt;
	ns_acquire_lock_for_scope lock(usb_context.libusb_lock,__FILE__,__LINE__);

	libusb_context * context = (libusb_context *)usb_context.get_context();
	try{
	  cnt = libusb_get_device_list(context, &devices);
	  if (cnt < 0)
	    throw ns_ex("ns_usb_control::Could not enumerate devices!");
	  try{
	    libusb_device *d;
	    libusb_device *requested_device(0);
	    int i = 0;
	    
	    while ((d= devices[i++]) != NULL) {
	      struct libusb_device_descriptor desc;
	      unsigned long bus_number(libusb_get_bus_number(d));
	      unsigned long device_address(libusb_get_device_address(d));
	      if (bus_number == bus && device_address == device_id){
		requested_device = d;
	      }
	      else
		libusb_unref_device(d);//don't hold onto devices that aren't used
	    }
	    
	    
	    if(requested_device==0){
	      libusb_free_device_list(devices,0);
	      lock.release();
	      return 0;
	    }
	    struct libusb_device_handle *device_handle;
	    int err = libusb_open(requested_device,&device_handle);
	    if (err != 0)
	      throw ns_ex("ns_usb_control::Could not open device: ") << err;
	    
	    err = libusb_reset_device(device_handle);
	    if (err){
	      libusb_close(device_handle);
	      libusb_unref_device(requested_device);
	      throw ns_ex("ns_usb::reset_device::Could not reset device: ") << err;
	    }
	    libusb_close(device_handle);
	    libusb_unref_device(requested_device);
	  }
	  catch(...){
	    //don't leak device name lists
	    libusb_free_device_list(devices, 0);
	    throw;
	  }
	}
	catch(...){
	  //release the context so that it can be reset
	  usb_context.release_context();
	  throw;
	}
	
	libusb_free_device_list(devices, 0);
	lock.release();
	return true;
#else
	
	ns_acquire_lock_for_scope lock(usb_context.libusb_lock,__FILE__,__LINE__);
	usb_find_busses();
	usb_find_devices();

	struct usb_device *device(0);
	ssize_t i = 0;
	int err = 0;

	for (struct usb_bus * cur_bus = usb_busses; cur_bus; cur_bus= cur_bus->next){
		int cur_bus_number(atoi(cur_bus->dirname));
		for (struct usb_device *dev = cur_bus->devices; dev; dev = dev->next){
			int cur_device_id(dev->devnum);
			//char * filename(dev->filename);

			if (cur_bus_number == bus && device_id == cur_device_id){
				device = dev;
				break;
			}
		}
	}
     

	if(!device){
		lock.release();
		return 0;
	}
	struct usb_dev_handle *handle;
	handle = usb_open(device);
	try{
		if (err)
			throw ns_ex("ns_usb::reset_device::Could not acquire handle for device");

		err = usb_reset(handle);
		//err2 = usb_reset(handle);
		if (err)
			throw ns_ex("ns_usb::reset_device::Could not reset device");
		usb_close(handle);
	}
	catch(...){
		usb_close(handle);
		throw;
	}
	lock.release();
	return true;
#endif
#endif
}
Beispiel #4
0
static void
_open_usb_device (ArvUvDevice *uv_device)
{
	libusb_device **devices;
	unsigned i, j, k;
	ssize_t count;

	count = libusb_get_device_list (uv_device->priv->usb, &devices);
	if (count < 0) {
		arv_warning_device ("[[UvDevice::_open_usb_device] Failed to get USB device list: %s",
				    libusb_error_name (count));
		return;
	}

	for (i = 0; i < count && uv_device->priv->usb_device == NULL; i++) {
		libusb_device_handle *usb_device;
		struct libusb_device_descriptor desc;

		if (libusb_get_device_descriptor (devices[i], &desc) >= 0 &&
		    libusb_open (devices[i], &usb_device) == LIBUSB_SUCCESS) {
			unsigned char *manufacturer;
			unsigned char *product;
			unsigned char *serial_nbr;
			int index;

			manufacturer = g_malloc0 (256);
			product = g_malloc0 (256);
			serial_nbr = g_malloc0 (256);

			index = desc.iManufacturer;
			if (index > 0)
				libusb_get_string_descriptor_ascii (usb_device, index, manufacturer, 256);
			index = desc.iProduct;
			if (index > 0)
				libusb_get_string_descriptor_ascii (usb_device, index, product, 256);
			index = desc.iSerialNumber;
			if (index > 0)
				libusb_get_string_descriptor_ascii (usb_device, index, serial_nbr, 256);

			if (g_strcmp0 ((char * ) manufacturer, uv_device->priv->vendor) == 0 &&
			    g_strcmp0 ((char * ) product, uv_device->priv->product) == 0 &&
			    g_strcmp0 ((char * ) serial_nbr, uv_device->priv->serial_nbr) == 0) {
				struct libusb_config_descriptor *config;
				struct libusb_endpoint_descriptor endpoint;
				const struct libusb_interface *inter;
				const struct libusb_interface_descriptor *interdesc;

				uv_device->priv->usb_device = usb_device;

				libusb_get_config_descriptor (devices[i], 0, &config);
				for (j = 0; j < (int) config->bNumInterfaces; j++) {
					inter = &config->interface[j];
					for (k = 0; k < inter->num_altsetting; k++) {
						interdesc = &inter->altsetting[k];
						if (interdesc->bInterfaceClass == ARV_UV_INTERFACE_INTERFACE_CLASS &&
						    interdesc->bInterfaceSubClass == ARV_UV_INTERFACE_INTERFACE_SUBCLASS) {
							if (interdesc->bInterfaceProtocol == ARV_UV_INTERFACE_CONTROL_PROTOCOL) {
								endpoint = interdesc->endpoint[0];
								uv_device->priv->control_endpoint = endpoint.bEndpointAddress & 0x0f;
								uv_device->priv->control_interface = interdesc->bInterfaceNumber;
							}
							if (interdesc->bInterfaceProtocol == ARV_UV_INTERFACE_DATA_PROTOCOL) {
								endpoint = interdesc->endpoint[0];
								uv_device->priv->data_endpoint = endpoint.bEndpointAddress & 0x0f;
								uv_device->priv->data_interface = interdesc->bInterfaceNumber;
							}
						}
					}
				}
				libusb_free_config_descriptor (config);
			} else
				libusb_close (usb_device);

			g_free (manufacturer);
			g_free (product);
			g_free (serial_nbr);
		}
	}

	libusb_free_device_list (devices, 1);
}
Beispiel #5
0
static int
usb_find_hubs (int listing, int verbose, int busnum, int devnum, int hub)
{

	struct libusb_device **devs;
	struct libusb_device *dev;
	int i = 0;
	int r;
	number_of_hubs_with_feature = 0;

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

	while ( (dev = devs[i++]) != NULL) {
		struct libusb_device_descriptor desc;
		unsigned short dev_vid, dev_pid, dev_bcd;

		r = libusb_get_device_descriptor(dev, &desc);
		if (r < 0) {
			continue;
		}
		dev_vid = libusb_le16_to_cpu(desc.idVendor);
		dev_pid = libusb_le16_to_cpu(desc.idProduct);
		dev_bcd = libusb_le16_to_cpu(desc.bcdUSB);
		//wmlog_msg(1, "Bus %03d Device %03d: ID %04x:%04x", libusb_get_bus_number(dev), libusb_get_device_address(dev), dev_vid, dev_pid);

		libusb_device_handle *uh;
		int print = 0;
		int usb3 = (dev_bcd >= 0x0300);

		//printf("found dev %d\n", dev->descriptor.bDeviceClass);
		if (desc.bDeviceClass != LIBUSB_CLASS_HUB)
			continue;


		if (listing
			|| (verbose ))
			//		  && ((atoi (bus->dirname) == busnum && dev->devnum == devnum)
			//		      || hub == number_of_hubs_with_feature)))
			print = 1;

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

/*		if(libusb_detach_kernel_driver( uh, 0 ))
			perror("libusb_detach_kernel_driver");

		if(libusb_claim_interface( uh, 0 ))
			perror("libusb_claim_interface");*/

		if ( uh != NULL )
		{	    

			if (print)
				printf ("Hub #%d at \tBUS:DEV\t\t%03d:%03d\n\t\tUSB VEND:PROD: \t%04x:%04x\n",
				number_of_hubs_with_feature,
				libusb_get_bus_number( dev ), 
				libusb_get_device_address( dev ),
				dev_vid, dev_pid
				);

			char buf[ sizeof(struct usb_hub_descriptor) + 2*4 ];
			int len;
			int nport;
			struct usb_hub_descriptor *uhd = (struct usb_hub_descriptor *)buf;

			if ( (len = libusb_control_transfer ( uh,
				LIBUSB_ENDPOINT_IN | USB_RT_HUB,
				LIBUSB_REQUEST_GET_DESCRIPTOR,
				(usb3 ? LIBUSB_DT_SUPERSPEED_HUB : LIBUSB_DT_HUB)<<8, 0,
				buf, (int)sizeof ( buf ),
				CTRL_TIMEOUT ) )
//			if( libusb_get_descriptor( uh, LIBUSB_DT_HUB, 0, buf, sizeof(buf) )
			    >(int)sizeof (struct usb_hub_descriptor) )
			{
				if (!(!(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND)
					&& (uhd->wHubCharacteristics[0] & HUB_CHAR_LPSM) >= 2)){

						switch ((uhd->wHubCharacteristics[0] & HUB_CHAR_LPSM))
						{
						case 0:
							if (print)
								fprintf (stderr, " INFO: ganged switching.\n");
							break;
						case 1:
							if (print)
								fprintf (stderr, " INFO: individual power switching.\n");
							break;
						case 2:
						case 3:
							if (print)
								fprintf (stderr, " WARN: No power switching.\n");
							break;
						}

						if (print
							&& !(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND))
							fprintf (stderr, " WARN: Port indicators are NOT supported.\n");
				}
			}
			else
			{
				perror ("Can't get hub descriptor.");
				printf( "%d\n",len );
			}

			if( len > 0 )
			{
				nport = buf[2];
				hubs[number_of_hubs_with_feature].busnum = libusb_get_bus_number( dev );
				hubs[number_of_hubs_with_feature].devnum = libusb_get_device_address( dev );
				hubs[number_of_hubs_with_feature].dev = dev;
				hubs[number_of_hubs_with_feature].indicator_support =
					(uhd->wHubCharacteristics[0] & HUB_CHAR_PORTIND)? 1 : 0;
				hubs[number_of_hubs_with_feature].nport = nport;
				hubs[number_of_hubs_with_feature].usb3 = usb3;

				number_of_hubs_with_feature++;

				if (verbose)
					hub_port_status (uh, nport, usb3);
			}
/*
			libusb_release_interface( uh,0 );
			libusb_attach_kernel_driver( uh, 0); */

			libusb_close (uh);
		}
	}
	libusb_free_device_list( devs, 1 );


	return number_of_hubs_with_feature;
}
Beispiel #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;
	
	hid_init();

	num_devs = libusb_get_device_list(usb_context, &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;
	}
}
Beispiel #7
0
static GSList *scan(struct sr_dev_driver *di, GSList *options)
{
	struct sr_dev_inst *sdi;
	struct drv_context *drvc;
	struct dev_context *devc;
	const struct zp_model *prof;
	struct libusb_device_descriptor des;
	struct libusb_device_handle *hdl;
	libusb_device **devlist;
	GSList *devices;
	int ret, i, j;
	char serial_num[64], connection_id[64];

	(void)options;

	drvc = di->priv;

	devices = NULL;

	/* Find all ZEROPLUS analyzers and add them to device list. */
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist); /* TODO: Errors. */

	for (i = 0; devlist[i]; i++) {
		ret = libusb_get_device_descriptor(devlist[i], &des);
		if (ret != 0) {
			sr_err("Failed to get device descriptor: %s.",
			       libusb_error_name(ret));
			continue;
		}

		if ((ret = libusb_open(devlist[i], &hdl)) < 0)
			continue;

		if (des.iSerialNumber == 0) {
			serial_num[0] = '\0';
		} else if ((ret = libusb_get_string_descriptor_ascii(hdl,
				des.iSerialNumber, (unsigned char *) serial_num,
				sizeof(serial_num))) < 0) {
			sr_warn("Failed to get serial number string descriptor: %s.",
				libusb_error_name(ret));
			continue;
		}

		libusb_close(hdl);

		usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));

		prof = NULL;
		for (j = 0; j < zeroplus_models[j].vid; j++) {
			if (des.idVendor == zeroplus_models[j].vid &&
				des.idProduct == zeroplus_models[j].pid) {
				prof = &zeroplus_models[j];
			}
		}
		/* Skip if the device was not found. */
		if (!prof)
			continue;
		sr_info("Found ZEROPLUS %s.", prof->model_name);

		/* Register the device with libsigrok. */
		sdi = g_malloc0(sizeof(struct sr_dev_inst));
		sdi->status = SR_ST_INACTIVE;
		sdi->vendor = g_strdup(VENDOR_NAME);
		sdi->model = g_strdup(prof->model_name);
		sdi->driver = di;
		sdi->serial_num = g_strdup(serial_num);
		sdi->connection_id = g_strdup(connection_id);

		/* Allocate memory for our private driver context. */
		devc = g_malloc0(sizeof(struct dev_context));
		sdi->priv = devc;
		devc->prof = prof;
		devc->num_channels = prof->channels;
#ifdef ZP_EXPERIMENTAL
		devc->max_sample_depth = 128 * 1024;
		devc->max_samplerate = 200;
#else
		devc->max_sample_depth = prof->sample_depth * 1024;
		devc->max_samplerate = prof->max_sampling_freq;
#endif
		devc->max_samplerate *= SR_MHZ(1);
		devc->memory_size = MEMORY_SIZE_8K;
		// memset(devc->trigger_buffer, 0, NUM_TRIGGER_STAGES);

		/* Fill in channellist according to this device's profile. */
		for (j = 0; j < devc->num_channels; j++)
			sr_channel_new(sdi, j, SR_CHANNEL_LOGIC, TRUE,
					channel_names[j]);

		devices = g_slist_append(devices, sdi);
		drvc->instances = g_slist_append(drvc->instances, sdi);
		sdi->inst_type = SR_INST_USB;
		sdi->conn = sr_usb_dev_inst_new(
			libusb_get_bus_number(devlist[i]),
			libusb_get_device_address(devlist[i]), NULL);
	}
	libusb_free_device_list(devlist, 1);

	return devices;
}
Beispiel #8
0
/*****************************************************************************
 *
 *					OpenUSBByName
 *
 ****************************************************************************/
status_t OpenUSBByName(unsigned int reader_index, /*@[email protected]*/ 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 */
Beispiel #9
0
int
gp_port_library_list (GPPortInfoList *list)
{
	GPPortInfo	info;
	int		nrofdevices = 0;
	int		d, i, i1, i2, unknownint;
	libusb_context	*ctx;
	libusb_device	**devs = NULL;
	int		nrofdevs = 0;
	struct libusb_device_descriptor	*descs;

	C_LIBUSB (libusb_init (&ctx), GP_ERROR_IO);

	/* TODO: make sure libusb_exit gets called in all error paths inside this function */

	/* generic matcher. This will catch passed XXX,YYY entries for instance. */
	C_GP (gp_port_info_new (&info));
	gp_port_info_set_type (info, GP_PORT_USB);
	gp_port_info_set_name (info, "");
	gp_port_info_set_path (info, "^usb:");
	C_GP (gp_port_info_list_append (list, info));

	nrofdevs = libusb_get_device_list (ctx, &devs);
	C_MEM (descs = calloc (nrofdevs, sizeof(descs[0])));
	for (i=0;i<nrofdevs;i++)
		LOG_ON_LIBUSB_E (libusb_get_device_descriptor(devs[i], &descs[i]));

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

			if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (devs[d], i, &config))) {
				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 < nrofdevs; d++) {
		char path[200];

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

			if (LOG_ON_LIBUSB_E (libusb_get_config_descriptor (devs[d], i, &config))) {
				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.
		 */ 
		C_GP (gp_port_info_new (&info));
		gp_port_info_set_type (info, GP_PORT_USB);
		gp_port_info_set_name (info, "Universal Serial Bus");
		snprintf (path,sizeof(path), "usb:%03d,%03d",
			libusb_get_bus_number (devs[d]),
			libusb_get_device_address (devs[d])
		);
		gp_port_info_set_path (info, path);
		C_GP (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) {
		C_GP (gp_port_info_new (&info));
		gp_port_info_set_type (info, GP_PORT_USB);
		gp_port_info_set_name (info, "Universal Serial Bus");
		gp_port_info_set_path (info, "usb:");
		C_GP (gp_port_info_list_append (list, info));
	}
	libusb_free_device_list (devs, 1);
	libusb_exit (ctx); /* should free all stuff above */
	free (descs);
	return (GP_OK);
}
Beispiel #10
0
static int scanDevices() {
    struct libusb_device** devs;
    ssize_t count;
    ssize_t i;
    int rc;
    int needToRescan;

    // Check if the devices need to be rescanned.
    rc = freespace_hotplug_perform(&needToRescan);
    if (rc != FREESPACE_SUCCESS || !needToRescan) {
        return rc;
    }

    count = libusb_get_device_list(freespace_libusb_context, &devs);
    if (count < 0) {
        return libusb_to_freespace_error(count);
    }

    ts++;
    for (i = 0; i < count; i++) {
        struct libusb_device_descriptor desc;
        struct libusb_device* dev = devs[i];
        struct FreespaceDeviceAPI const * api;

        rc = libusb_get_device_descriptor(dev, &desc);
        if (rc < 0) {
            // Can't get the device descriptor, so try the next one.
            continue;
        }

        // Find if this device is in the known list.
        api = lookupDevice(&desc);
        if (api != NULL) {
            uint8_t deviceAddress = libusb_get_device_address(dev);
            struct FreespaceDevice* device;
            device = findDeviceById(deviceAddress);
            if (device == NULL) {
                device = (struct FreespaceDevice*) malloc(sizeof(struct FreespaceDevice));
                if (device == NULL) {
                    // Out of memory.
                    libusb_free_device_list(devs, 1);
                    return FREESPACE_ERROR_OUT_OF_MEMORY;
                }
                memset(device, 0, sizeof(struct FreespaceDevice));

                libusb_ref_device(dev);
                device->dev_ = dev;
                device->idProduct_ = desc.idProduct;
                device->idVendor_ = desc.idVendor;
                device->api_ = api;
                device->id_ = libusb_get_device_address(dev);
                device->state_ = FREESPACE_CONNECTED;
                device->ts_ = ts;
                addFreespaceDevice(device);
                if (hotplugCallback) {
                    hotplugCallback(FREESPACE_HOTPLUG_INSERTION, device->id_, hotplugCookie);
                }
            }
            device->ts_ = ts;
        }
    }

    for (i = 0; i < FREESPACE_MAXIMUM_DEVICE_COUNT; i++) {
        struct FreespaceDevice* d = devices[i];
        if (d != NULL && d->ts_ != ts) {
            if (hotplugCallback) {
                hotplugCallback(FREESPACE_HOTPLUG_REMOVAL, d->id_, hotplugCookie);
            }
            if (d->state_ == FREESPACE_OPENED) {
                d->state_ = FREESPACE_DISCONNECTED;
            } else {
                removeFreespaceDevice(d);
            }
        }
    }

    libusb_free_device_list(devs, 1);
    return FREESPACE_SUCCESS;
}
//*****************************************************************************
//
//! Initializes the sample API.
//!
//! This function prepares the sample API for use by the application.
//!
//! \return None.
//
//*****************************************************************************
int
main(int argc, char *argv[])
{
    int rc;
    unsigned int iDev, iCfg, iIf, iAlt, iEndp;
    ssize_t nDevs;

    libusb_device        **pDevices;
    libusb_device        *pDev;

    struct libusb_config_descriptor *pdCfg;
    struct libusb_device_descriptor dDev;

    rc = libusb_init(&pCtx);
    ASSERT(rc == 0);

    // libusb_set_debug(pCtx, 5);


    nDevs = libusb_get_device_list(pCtx, &pDevices);
    TRACE(0, "nDevs = %d\n", (int)nDevs);
    ASSERT(nDevs >= 0);

    pDev = NULL;
    for (iDev = 0; iDev < nDevs; iDev++)
    {
        TRACE(0, "Considering device %d\n", iDev);
        //
        // Get the device descriptor so we know how many configurations there are
        //
        rc = libusb_get_device_descriptor(pDevices[iDev], &dDev);
        ASSERT(rc == 0);
        if ((dDev.idVendor == LMICDI_VID) &&
            (dDev.idProduct == LMICDI_PID))
        {
            pDev = pDevices[iDev];
            TRACE(1, "Found device with matching VID and PID.  pDev = %p\n", pDev);
            break;
        }
    }
    ASSERT(pDev != NULL);

    rc = libusb_open(pDev, &phDev);
    if (rc != 0)
    {
        TRACE(ALWAYS, "Failed to open device.  rc = %d\n", rc);
    }

    //
    // NOTE: If/When we get here dDev should still be valid
    //

    // For each configuration... 
    //   for each interface...
    //     for each alternate config for the interface...
    //        for each endpoint...
    //
    for (iCfg = 0; iCfg < dDev.bNumConfigurations; iCfg++)
    {
        TRACE(1, D0 "iCfg = %d\n", iCfg);

        rc = libusb_get_config_descriptor(pDev, iCfg, &pdCfg);
        ASSERT(rc == 0);

        //
        // It seems as though we need to detach the kernel before we can read
        // strings for ourselves.
        //
#if 0
        for (iIf = 0; iIf < pdCfg->bNumInterfaces; iIf++)
        {
            rc = libusb_kernel_driver_active(phDev, iIf);
            TRACE(1, D1 "kernel_driver_active(if%d) = %d\n",
                  iIf, rc);
            if (rc)
            {
                TRACE(1, D1 "Attempting to detach...");
                rc = libusb_detach_kernel_driver(phDev, iIf);
                if (rc)
                {
                    TRACE(1, " failed (%d)\n", rc);
                }
                else
                {
                    bKernel[iIf] = 1;

                    TRACE(1, " OK\n");
                }
            }
        }
#endif
        //
        // if the MFGr string is coming back as 0 then the device is wedged.
        //
        if (dDev.iManufacturer == 0) exit(EXIT_FAILURE);

        //
        // TODO: Figure out why some string indexes are coming back as 0
        //
        // _dump_cfg_strings(phDev, pdCfg, D0);
        // _dump_dev_strings(phDev, &dDev, D0);

        for (iIf = 0; iIf < pdCfg->bNumInterfaces; iIf++)
        {
            const struct libusb_interface *pIf = &pdCfg->interface[iIf];
            TRACE(1, D1 "iIf = %d\n", iIf);

            for (iAlt = 0; iAlt < pIf->num_altsetting; iAlt++)
            {
                const struct libusb_interface_descriptor *pdIf = 
                    &pIf->altsetting[iAlt];

                TRACE(1, D2 "iAlt = %d\n", iAlt);
                _dump_if_strings(phDev, pdIf, D2);

                //
                // The "correct" thing to do would be to identify the 
                // interface based on its name and string index but, at 
                // the moment, the iInterface is coming back as 0. 
                // Instead, we'll grab the interface that uses the
                // VENDOR_SPECIFIC class 
                //
                if (pdIf->bInterfaceClass != LIBUSB_CLASS_VENDOR_SPEC)
                {
                    continue;
                }
                
                // 
                // The interface we're interested in should have two endpoints
                //
                if (pdIf->bNumEndpoints != 2)
                {
                    continue;
                }

                rc = libusb_claim_interface(phDev, iIf);
                ASSERT(rc == 0);
                
                for (iEndp = 0; iEndp < pdIf->bNumEndpoints; iEndp++)
                {
                    const struct libusb_endpoint_descriptor *pdEndp = 
                        &pdIf->endpoint[iEndp];

                    TRACE(1, D3 "iEndp = %d\n", iEndp);
                   if ((pdEndp->bmAttributes & 0x3) != 
                            LIBUSB_TRANSFER_TYPE_BULK)
                    {
                        continue;
                    }

                    if ((pdEndp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == 
                            LIBUSB_ENDPOINT_IN)
                    {
                        TRACE(1, D3 "Found ENDPOINT_IN\n");
                        pdEndpIn = pdEndp;
                        continue;
                    }

                    if ((pdEndp->bEndpointAddress & LIBUSB_ENDPOINT_DIR_MASK) == 
                            LIBUSB_ENDPOINT_OUT)
                    {
                        TRACE(1, D3 "Found ENDPOINT_OUT\n");
                        pdEndpOut = pdEndp;
                        continue;
                    }

                    //
                    // We should never get here.  An endpoint has to be either 
                    // in or out
                    //
                    TRACE(ALWAYS, "%s[%d]: Unexpected error\n", __FILE__, __LINE__);
                    ASSERT(0);
                }
                goto found;
            }    
        }
    }

found:
    libusb_free_device_list(pDevices, 1);

    //
    // EXPERIMENT:  Can we kick of an async receive and then do a 
    // synchronous transmit? ANSWER:  YES!
    //
    pTrans = libusb_alloc_transfer(0);
    ASSERT(pTrans != NULL);
    
    //
    // Set up a pending receive...
    //
    pTrans->dev_handle = phDev;
    pTrans->flags = 0;              // no auto-freeing of transfers
    pTrans->endpoint = pdEndpIn->bEndpointAddress;
    pTrans->type = LIBUSB_TRANSFER_TYPE_BULK;
    pTrans->timeout = 0;           // no timeout
    pTrans->buffer = pResp;
    pTrans->length = sizeof(pResp);
    pTrans->callback = usb_callback;
    pTrans->num_iso_packets = 0;
    pTrans->user_data = &gdbUsbCtx;

    //
    // And wait for a RX operation to complete...
    //
    rc = libusb_submit_transfer(pTrans);
    if (rc != 0)
    {
        TRACE(ALWAYS, "%s: ERROR: submit_transfer rc = %d\n", __FUNCTION__, rc);
    }

    SocketIO(PORT, phDev);

    TRACE(1, "%s: libusb_release_interface\n", __FUNCTION__);
    libusb_release_interface(phDev, iIf);

    TRACE(1, "%s: libusb_close(phDev)\n", __FUNCTION__);
    libusb_close(phDev);

    TRACE(1, "%s: libusb_exit\n", __FUNCTION__);
    libusb_exit(pCtx);

    return(EXIT_SUCCESS);
}
Beispiel #12
0
//==============================================================================
USB_Enumerator::~USB_Enumerator()
{	libusb_free_device_list(list_, true); }
Beispiel #13
0
int main(int argc, const char * argv[])
{
    libusb_device ** devs;
    int r = libusb_init(NULL);
    if(r < 0) {
        fprintf(stderr, "libusb_init() returned error %d\n", r);
        return r;
    }
    
    ssize_t cnt = libusb_get_device_list(NULL, &devs);
    if(cnt < 0) {
        fprintf(stderr, "libusb_get_device_list() returned error %d\n", r);
        return cnt;
    }
    
    // for(libusb_device ** dev = devs; *dev != NULL; dev++)
    //     print_dev(*dev);
    libusb_device * lpcdev = find_lpc(devs);
    if(lpcdev)
    {
        printf("Found device:\n");
        print_dev(lpcdev);
        
        libusb_device_handle * lpchand;
        r = libusb_open(lpcdev, &lpchand);
        if(r < 0) {
            fprintf(stderr, "libusb_open() returned error %d\n", r);
            exit(r);
        }
        
        r = libusb_set_configuration(lpchand, 1);
        if(r < 0) {
            fprintf(stderr, "libusb_set_configuration() returned error %d\n", r);
            libusb_close(lpchand);
            exit(r);
        }
        
        int interface = 1;
        
        r = libusb_claim_interface(lpchand, interface);
        if(r < 0) {
            fprintf(stderr, "libusb_claim_interface() returned error %d\n", r);
            libusb_close(lpchand);
            exit(r);
        }
        
        // uint8_t endpoint = 0x82;
        uint8_t endpoint = 0x02;
        uint8_t data[256];
        char * chdata = (char *)data;
        int length, actualLength;
        
        // data[0] = 100;
        strcpy(chdata, "USB MESSAGE     ");
        length = 16;
        r = libusb_bulk_transfer(lpchand, endpoint, data, length, &actualLength, 1000);
        if(r < 0) {
            fprintf(stderr, "libusb_bulk_transfer() returned error %d\n", r);
            libusb_release_interface(lpchand, interface);
            libusb_close(lpchand);
            exit(r);
        }
        fprintf(stderr, "libusb_bulk_transfer() returned %d\n", r);
        printf("Bytes transferred: %d\n", actualLength);
        
        r = libusb_release_interface(lpchand, interface);
        if(r < 0) {
            fprintf(stderr, "libusb_release_interface() returned error %d\n", r);
            libusb_close(lpchand);
            exit(r);
        }
        
        libusb_close(lpchand);
    }
    else
    {
        printf("Device not found\n");
    }
    
    libusb_free_device_list(devs, 1);
    libusb_exit(NULL);
    
    return EXIT_SUCCESS;
}
Beispiel #14
0
static int open_device(struct sr_dev_inst *sdi)
{
	struct drv_context *drvc;
	struct sr_usb_dev_inst *usb;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	char connection_id[64];
	bool is_opened;
	size_t i;
	int r;

	if (sdi->status == SR_ST_ACTIVE)
		return SR_ERR;

	drvc = sdi->driver->context;
	usb = sdi->conn;

	is_opened = FALSE;

	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);

	for (i = 0; devlist[i]; i++) {
		libusb_get_device_descriptor(devlist[i], &des);

		if (des.idVendor != LOGICSTUDIO16_VID ||
			des.idProduct != LOGICSTUDIO16_PID_HAVE_FIRMWARE)
			continue;

		usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));

		/*
		 * Check if this device is the same one that we associated
		 * with this sdi in scan() and bail if it isn't.
		 */
		if (strcmp(sdi->connection_id, connection_id))
			continue;

		r = libusb_open(devlist[i], &usb->devhdl);

		if (r) {
			sr_err("Failed to open device: %s.",
				libusb_error_name(r));
			break;
		}

		/* Fix up address after firmware upload. */
		if (usb->address == UNKNOWN_ADDRESS)
			usb->address = libusb_get_device_address(devlist[i]);

		is_opened = TRUE;

		break;
	}

	libusb_free_device_list(devlist, 1);

	if (!is_opened)
		return SR_ERR;

	if ((r = libusb_claim_interface(usb->devhdl, USB_INTERFACE))) {
		sr_err("Failed to claim interface: %s.",
			libusb_error_name(r));
		return SR_ERR;
	}

	sdi->status = SR_ST_ACTIVE;

	return SR_OK;
}
// Find the device, and set up to read it periodically, then send 
// the data out stdout so another process can pick it up and do
// something reasonable with it.
// 
int main(int argc, char **argv)
{
    char *usage = {"usage: %s -u -n\n"};
    int libusbDebug = 0; //This will turn on the DEBUG for libusb
    int noisy = 0;       //This will print the packets as they come in
    libusb_device **devs;
    int r, err, c;
    ssize_t cnt;
    
    while ((c = getopt (argc, argv, "unh")) != -1)
        switch (c){
            case 'u':
                libusbDebug = 1;
                break;
            case 'n':
                noisy = 1;
                break;
            case 'h':
                fprintf(stderr, usage, argv[0]);
            case '?':
                exit(1);
            default:
                exit(1);
       }
    fprintf(stderr,"%s Starting ... ",argv[0]);
    fprintf(stderr,"libusbDebug = %d, noisy = %d\n", libusbDebug, noisy);
    // The Pi linker can give you fits.  If you get a linker error on
    // the next line, set LD_LIBRARY_PATH to /usr/local/lib 
    fprintf(stderr,"This is not an error!! Checking linker, %s\n", libusb_strerror(0));

    if (signal(SIGINT, sig_handler) == SIG_ERR)
        fprintf(stderr,"Couldn't set up signal handler\n"); 
    err = libusb_init(NULL);
    if (err < 0){
        fprintf(stderr,"Couldn't init usblib, %s\n", libusb_strerror(err));
        exit(1);
    }
    // This is where you can get debug output from libusb.
    // just set it to LIBUSB_LOG_LEVEL_DEBUG
    if (libusbDebug)
        libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_DEBUG);
    else
        libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_INFO);

    
    cnt = libusb_get_device_list(NULL, &devs);
    if (cnt < 0){
        fprintf(stderr,"Couldn't get device list, %s\n", libusb_strerror(err));
        exit(1);
    }
    // go get the device; the device handle is saved in weatherStation struct.
    if (!findDevice(devs)){
        fprintf(stderr,"Couldn't find the device\n");
        exit(1);
    }
    // Now I've found the weather station and can start to try stuff
    // So, I'll get the device descriptor
    struct libusb_device_descriptor deviceDesc;
    err = libusb_get_device_descriptor(weatherStation.device, &deviceDesc);
    if (err){
        fprintf(stderr,"Couldn't get device descriptor, %s\n", libusb_strerror(err));
        exit(1);
    }
    fprintf(stderr,"got the device descriptor back\n");
    
    // Open the device and save the handle in the weatherStation struct
    err = libusb_open(weatherStation.device, &weatherStation.handle);
    if (err){
        fprintf(stderr,"Open failed, %s\n", libusb_strerror(err));
        closeUpAndLeave();    }
    fprintf(stderr,"I was able to open it\n");
    // Now that it's opened, I can free the list of all devices
    libusb_free_device_list(devs, 1); // Documentation says to get rid of the list
                                      // Once I have the device I need
    fprintf(stderr,"Released the device list\n");
    err = libusb_set_auto_detach_kernel_driver(weatherStation.handle, 1);
    if(err){
        fprintf(stderr,"Some problem with detach %s\n", libusb_strerror(err));
        closeUpAndLeave();
    }
    int activeConfig;
    err =libusb_get_configuration(weatherStation.handle, &activeConfig);
    if (err){
        fprintf(stderr,"Can't get current active configuration, %s\n", libusb_strerror(err));;
        closeUpAndLeave();
    }
    fprintf(stderr,"Currently active configuration is %d\n", activeConfig);
    if(activeConfig != 1){
        err = libusb_set_configuration  (weatherStation.handle, 1);
        if (err){
            fprintf(stderr,"Cannot set configuration, %s\n", libusb_strerror(err));;
        closeUpAndLeave();
        }
        fprintf(stderr,"Just did the set configuration\n");
    }
    
    err = libusb_claim_interface(weatherStation.handle, 0); //claim interface 0 (the first) of device (mine had just 1)
    if(err) {
        fprintf(stderr,"Cannot claim interface, %s\n", libusb_strerror(err));
        closeUpAndLeave();
    }
    fprintf(stderr,"Claimed Interface\n");
    // I don't want to just hang up and read the reports as fast as I can, so
    // I'll space them out a bit.  It's weather, and it doesn't change very fast.
    sleep(1);
    fprintf(stderr,"Setting the device 'idle' before starting reads\n");
    err = libusb_control_transfer(weatherStation.handle, 
        0x21, 0x0a, 0, 0, 0, 0, 1000);
    sleep(1);
    int tickcounter= 0;
    fprintf(stderr,"Starting reads\n");
    while(1){
        sleep(1);
        if(tickcounter++ % 10 == 0){
            getit(1, noisy);
        }
        if(tickcounter % 30 == 0){
            getit(2, noisy);
        }
        if (tickcounter % 15 == 0){
            showit();
        }
    }
}
Beispiel #16
0
int
main(int argc, char *argv[])
{
   libusb_device **devs; //pointer  to pointer of device, used to retrieve a list of devices
   libusb_context *ctx = NULL; //a libusb session
   libusb_device_handle *dev_handle;

   int r;
   size_t cnt;
   int actual;
   pthread_t tid;

   r = libusb_init(&ctx);
   if (r < 0)
   {
      printf("Initialise Error %d\n", r);
      return 1;
   }

   printf("libusb initialised\n");

   libusb_set_debug(ctx, 3); // set verbosity level to 3, as suggested in documentation

   cnt = libusb_get_device_list(ctx, &devs);
   if (cnt < 0)
   {
      printf("Error getting device list %d\n", (int)cnt);
      return 1;
   }
 
   printf("Found %d USB devices\n", (int)cnt);

   print_devs(devs);

   libusb_free_device_list(devs, 1);

   /*
   * Initialise ANT
   */
   ANT_init(ctx);

   printf("*** ANT Initialised\n");

   dev_handle = libusb_open_device_with_vid_pid(ctx, 0x17a4, 0x0002);
   if (dev_handle == NULL)
   {
      printf("Cannot open device\n");
      return 1;
   }

   printf("Device Opened\n");

   if (libusb_kernel_driver_active(dev_handle, 0) == 1)
   {
      printf("Kernel Driver Active!\n");
      if (libusb_detach_kernel_driver(dev_handle, 0) == 0)
      {
         printf("Kernel Driver Detached!\n");
      }
   }
      
   r = libusb_claim_interface(dev_handle, 0); // claim interface 0 (the first) of device
   if (r < 0)
   {
      printf("Cannot claim interface!\n");
      return 1;
   }
   printf("Interface claimed!\n");


   UCHAR in_buff[ 512 ];
   int i;

   create_c2pm3_libusb_input_handler(dev_handle,
                                     &C2PM3_message_callback,
                                     in_buff);

   
   c2pm3_send_command(CSAFE_CMD_GET_CADENCE, NULL, 0);
   while(TRUE)
   {
      sleep(2);
   }

   printf("HUH!!!\n");

   


   libusb_close(dev_handle);
   libusb_exit(ctx);

   return (0);

#if 0
   char str[ 512 ];
   BOOL running = FALSE;
   int size;
   

   /*
   * Get to running state
   */
   while(!running)
   {
      size = sprintf(str, "CM\r\n");
      res = write(USB, str, size);
      if (res != size)
      {
         printf("Failed to send [CM]\n");
      }
      else
      {
         usleep(1000000);
         res = read(USB, str, 512);
         if (res < 0)
         {
            printf("Failed to read response to [CM]\n");
         }
         else
         {
            printf("Response to [CM] == %s\n", str);
            if (strncmp(str, "RUN", 3) == 0)
            {
               running = TRUE;
            }
            else
            {
               for(i = 0; i < strlen(str); i++)
               {
                  printf("[0x%02x][%c]\n", str[ i ], str[ i ]);
               }
            }
         }
      }
   }

   int pulse;
   int cadence;
   int speed;
   int distance;
   int desired_power;
   int energy;
   char time_string[ 20 ];
   int achieved_power;

   USHORT cum_pow = 0;

   struct timespec tp;
   ULONG last_time;
   ULONG time;
   ULONG elapsed;

   last_time = get_ms();   

   while(TRUE)
   {
      size = sprintf(str, "ST\r\n");
      res = write(USB, str, size);
      if (res != size)
      {
         printf("Failed to send [ST]\n");
      }
      else
      {
         usleep(250000);
         res = read(USB, str, 512);
         if (res < 0)
         {
            printf("Failed to read response to [ST]\n");
         }
         else
         {
            printf(str);
            char *pch;
            pch = strtok(str, "\t");
            int field = 0;
            while(pch != NULL)
            {
               switch(field)
               {
               case FIELD_PULSE:
                  pulse = atoi(pch);
                  break;
               case FIELD_CADENCE:
                  cadence = atoi(pch);
                  break;
               case FIELD_SPEED:
                  speed = atoi(pch);
                  break;
               case FIELD_DISTANCE:
                  distance = atoi(pch);
                  break;
               case FIELD_DESIRED_POWER:
                  desired_power = atoi(pch);
                  break;
               case FIELD_ENERGY:
                  energy = atoi(pch);
                  break;
               case FIELD_TIME:
                  strcpy(time_string, pch);
                  break;
               case FIELD_ACHIEVED_POWER:
                  achieved_power = atoi(pch);
                  break;
               }
           
               pch = strtok(NULL, "\t");
               field++;
            }

            time = get_ms();
            elapsed = time - last_time;
            last_time = time;

            cum_pow += (achieved_power * elapsed) / 1000;

            speed_sensor_set_speed(speed * 100);
            power_sensor_set_params(cum_pow, cadence);
         }
      }
   }
     

   close(USB);

#endif   
}
Beispiel #17
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;
	
	hid_init();

	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;
		
		/* 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;

						/* 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);

#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. */
								int detached = 0;
								unsigned char data[256];
							
								/* 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;
								}
								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);

								/* 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 /*******************/

								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;
}
Beispiel #18
0
static int lusb_probe(backend_probe_target probe_target,
                      struct bladerf_devinfo_list *info_list)
{
    int status, i, n;
    ssize_t count;
    libusb_device **list;
    struct bladerf_devinfo info;
    bool printed_access_warning = false;

    libusb_context *context;

    /* Initialize libusb for device tree walking */
    status = libusb_init(&context);
    if (status) {
        log_error("Could not initialize libusb: %s\n",
                  libusb_error_name(status));
        goto lusb_probe_done;
    }

    count = libusb_get_device_list(context, &list);
    /* Iterate through all the USB devices */
    for (i = 0, n = 0; i < count && status == 0; i++) {
        if (device_is_probe_target(probe_target, list[i])) {

            /* Open the USB device and get some information */
            status = get_devinfo(list[i], &info);
            if (status) {
                /* We may not be able to open the device if another
                 * driver (e.g., CyUSB3) is associated with it. Therefore,
                 * just log to the debug level and carry on. */
                log_debug("Could not open device: %s\n",
                          libusb_error_name(status) );

                if (status == LIBUSB_ERROR_ACCESS && !printed_access_warning) {
                    printed_access_warning = true;
                    log_warning("Found a bladeRF via VID/PID, but could not "
                                "open it due to insufficient permissions.\n");
                }

                /* Don't stop probing because one device was "problematic" */
                status = 0;
            } else {
                info.instance = n++;
                status = bladerf_devinfo_list_add(info_list, &info);
                if( status ) {
                    log_error("Could not add device to list: %s\n",
                              bladerf_strerror(status) );
                } else {
                    log_verbose("Added instance %d to device list\n",
                                info.instance);
                }
            }
        }
    }

    libusb_free_device_list(list, 1);
    libusb_exit(context);

lusb_probe_done:
    return status;
}
Beispiel #19
0
	/// \brief Search for compatible devices.
	/// \return A string with the result of the search.
	QString Device::search() {
		if(this->error)
			return tr("Can't search for Hantek oscilloscopes: %1").arg(Helper::libUsbErrorString(this->error));
		
		QString message;
		QString deviceAddress;
		int errorCode = LIBUSB_SUCCESS;
		
#if LIBUSB_VERSION == 0
		errorCode = usb_find_busses();
		if(errorCode >= 0)
			errorCode = usb_find_devices();
		if(errorCode < 0)
			return tr("Failed to get device list: %1").arg(Helper::libUsbErrorString(errorCode));
		
		struct usb_device *device = NULL;
		
		// Iterate through all usb devices
		for(struct usb_bus *bus = usb_busses; bus; bus = bus->next) {
			for(device = bus->devices; device; device = device->next) {
				// Check VID and PID
				if(device->descriptor.idVendor == HANTEK_VENDOR_ID) {
					this->model = (Model) this->modelIds.indexOf(device->descriptor.idProduct);
					if(this->model >= 0)
						break; // Found a compatible device, ignore others
				}
			}
			if(this->model >= 0) {
				deviceAddress = QString("%1:%2").arg(bus->dirname).arg(device->filename);
				break; // Found a compatible device, ignore other busses
			}
		}
		
		if(this->model >= 0) {
			// Open device
			deviceAddress = QString("%1:%2").arg(device->bus->location, 3, 10, QLatin1Char('0')).arg(device->devnum, 3, 10, QLatin1Char('0'));
			this->handle = usb_open(device);
			if(this->handle) {
				struct usb_config_descriptor *configDescriptor = device->config;
				struct usb_interface *interface;
				struct usb_interface_descriptor *interfaceDescriptor;
				for(int interfaceIndex = 0; interfaceIndex < configDescriptor->bNumInterfaces; ++interfaceIndex) {
					interface = &configDescriptor->interface[interfaceIndex];
					if(interface->num_altsetting < 1)
						continue;
					
					interfaceDescriptor = &interface->altsetting[0];
					if(interfaceDescriptor->bInterfaceClass == USB_CLASS_VENDOR_SPEC && interfaceDescriptor->bInterfaceSubClass == 0 && interfaceDescriptor->bInterfaceProtocol == 0 && interfaceDescriptor->bNumEndpoints == 2) {
						// That's the interface we need, claim it
						errorCode = usb_claim_interface(this->handle, interfaceDescriptor->bInterfaceNumber);
						if(errorCode < 0) {
							usb_close(this->handle);
							this->handle = 0;
							message = tr("Failed to claim interface %1 of device %2: %3").arg(QString::number(interfaceDescriptor->bInterfaceNumber), deviceAddress, Helper::libUsbErrorString(errorCode));
						}
						else {	
							this->interface = interfaceDescriptor->bInterfaceNumber;
							
							// Check the maximum endpoint packet size
							usb_endpoint_descriptor *endpointDescriptor;
							this->outPacketLength = 0;
							this->inPacketLength = 0;
							for (int endpoint = 0; endpoint < interfaceDescriptor->bNumEndpoints; ++endpoint) {
								endpointDescriptor = &interfaceDescriptor->endpoint[endpoint];
								switch(endpointDescriptor->bEndpointAddress) {
									case HANTEK_EP_OUT:
										this->outPacketLength = endpointDescriptor->wMaxPacketSize;
										break;
									case HANTEK_EP_IN:
										this->inPacketLength = endpointDescriptor->wMaxPacketSize;
										break;
								}
							}
							message = tr("Device found: Hantek %1 (%2)").arg(this->modelStrings[this->model], deviceAddress);
							emit connected();
						}
					}
				}
			}
			else
				message = tr("Couldn't open device %1").arg(deviceAddress);
		}
		else
			message = tr("No Hantek oscilloscope found");
#else
		libusb_device **deviceList;
		libusb_device *device;
		
		if(this->handle)
			libusb_close(this->handle);
		
		ssize_t deviceCount = libusb_get_device_list(this->context, &deviceList);
		if(deviceCount < 0)
			return tr("Failed to get device list: %1").arg(Helper::libUsbErrorString(errorCode));
		
		// Iterate through all usb devices
		this->model = MODEL_UNKNOWN;
		for(ssize_t deviceIterator = 0; deviceIterator < deviceCount; ++deviceIterator) {
			device = deviceList[deviceIterator];
			// Get device descriptor
			if(libusb_get_device_descriptor(device, &(this->descriptor)) < 0)
				continue;
	
			// Check VID and PID
			if(this->descriptor.idVendor == HANTEK_VENDOR_ID) {
				this->model = (Model) this->modelIds.indexOf(this->descriptor.idProduct);
				if(this->model >= 0)
					break; // Found a compatible device, ignore others
			}
		}
		
		if(this->model >= 0) {
			// Open device
			deviceAddress = QString("%1:%2").arg(libusb_get_bus_number(device), 3, 10, QLatin1Char('0')).arg(libusb_get_device_address(device), 3, 10, QLatin1Char('0'));
			errorCode = libusb_open(device, &(this->handle));
			if(errorCode == LIBUSB_SUCCESS) {
				libusb_config_descriptor *configDescriptor;
				const libusb_interface *interface;
				const libusb_interface_descriptor *interfaceDescriptor;
				
				// Search for the needed interface
				libusb_get_config_descriptor(device, 0, &configDescriptor);
				for(int interfaceIndex = 0; interfaceIndex < (int) configDescriptor->bNumInterfaces; ++interfaceIndex) {
					interface = &configDescriptor->interface[interfaceIndex];
					if(interface->num_altsetting < 1)
						continue;
					
					interfaceDescriptor = &interface->altsetting[0];
					if(interfaceDescriptor->bInterfaceClass == LIBUSB_CLASS_VENDOR_SPEC && interfaceDescriptor->bInterfaceSubClass == 0 && interfaceDescriptor->bInterfaceProtocol == 0 && interfaceDescriptor->bNumEndpoints == 2) {
						// That's the interface we need, claim it
						errorCode = libusb_claim_interface(this->handle, interfaceDescriptor->bInterfaceNumber);
						if(errorCode < 0) {
							libusb_close(this->handle);
							this->handle = 0;
							message = tr("Failed to claim interface %1 of device %2: %3").arg(QString::number(interfaceDescriptor->bInterfaceNumber), deviceAddress, Helper::libUsbErrorString(errorCode));
						}
						else {
							this->interface = interfaceDescriptor->bInterfaceNumber;
							
							// Check the maximum endpoint packet size
							const libusb_endpoint_descriptor *endpointDescriptor;
							this->outPacketLength = 0;
							this->inPacketLength = 0;
							for (int endpoint = 0; endpoint < interfaceDescriptor->bNumEndpoints; ++endpoint) {
								endpointDescriptor = &(interfaceDescriptor->endpoint[endpoint]);
								switch(endpointDescriptor->bEndpointAddress) {
									case HANTEK_EP_OUT:
										this->outPacketLength = endpointDescriptor->wMaxPacketSize;
										break;
									case HANTEK_EP_IN:
										this->inPacketLength = endpointDescriptor->wMaxPacketSize;
										break;
								}
							}
							message = tr("Device found: Hantek %1 (%2)").arg(this->modelStrings[this->model], deviceAddress);
							emit connected();
						}
					}
				}
				
				libusb_free_config_descriptor(configDescriptor);
			}
			else {
				this->handle = 0;
				message = tr("Couldn't open device %1: %2").arg(deviceAddress, Helper::libUsbErrorString(errorCode));
			}
		}
		else
			message = tr("No Hantek oscilloscope found");
		
		libusb_free_device_list(deviceList, true);
#endif
		
		return message;
	}
Beispiel #20
0
static int find_and_open_device(libusb_context *context,
                                const struct bladerf_devinfo *info_in,
                                struct bladerf_lusb **dev_out,
                                struct bladerf_devinfo *info_out)
{
    int status = BLADERF_ERR_NODEV;
    int i, n;
    ssize_t count;
    struct libusb_device **list;
    struct bladerf_devinfo curr_info;
    bool printed_access_warning = false;

    *dev_out = NULL;

    count = libusb_get_device_list(context, &list);
    if (count < 0) {
        if (count < INT_MIN) {
            /* Ensure we don't have a situation where we accidentally return 0
             * due to a narrowing conversion */
            return BLADERF_ERR_UNEXPECTED;
        } else {
            return error_conv((int) count);
        }
    }

    for (i = 0, n = 0; (i < count) && (*dev_out == NULL); i++) {
        if (device_is_bladerf(list[i])) {
            log_verbose("Found a bladeRF (idx=%d)\n", i);

            /* Open the USB device and get some information */
            status = get_devinfo(list[i], &curr_info);
            if (status < 0) {

                /* Give the user a helpful hint in case the have forgotten
                 * to update their udev rules */
                if (status == LIBUSB_ERROR_ACCESS && !printed_access_warning) {
                    printed_access_warning = true;
                    log_warning("Found a bladeRF via VID/PID, but could not "
                                "open it due to insufficient permissions.\n");
                } else {
                    log_debug("Could not open bladeRF device: %s\n",
                               libusb_error_name(status) );
                }

                status = BLADERF_ERR_NODEV;
                continue; /* Continue trying the next devices */
            } else {
                curr_info.instance = n++;
            }

            /* Check to see if this matches the info struct */
            if (bladerf_devinfo_matches(&curr_info, info_in)) {
                status = open_device(&curr_info, context, list[i], dev_out);
                if (status < 0) {
                    status = BLADERF_ERR_NODEV;
                    continue; /* Continue trying the next matching device */
                } else {
                    memcpy(info_out, &curr_info, sizeof(info_out[0]));
                }
            } else {
                status = BLADERF_ERR_NODEV;

                log_verbose("Devinfo doesn't match - skipping"
                        "(instance=%d, serial=%d, bus/addr=%d\n",
                        bladerf_instance_matches(&curr_info, info_in),
                        bladerf_serial_matches(&curr_info, info_in),
                        bladerf_bus_addr_matches(&curr_info, info_in));
            }
        }
    }

    if (status == 0) {
        /* Returning 0 indicates this function is providing a device */
        assert(*dev_out != NULL);
    }

    libusb_free_device_list(list, 1);
    return status;
}
Beispiel #21
0
SR_PRIV int hantek_6xxx_open(struct sr_dev_inst *sdi)
{
	struct dev_context *devc;
	struct drv_context *drvc = sdi->driver->context;
	struct sr_usb_dev_inst *usb;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	int err, i;
	char connection_id[64];

	devc = sdi->priv;
	usb = sdi->conn;

	if (sdi->status == SR_ST_ACTIVE)
		/* Already in use. */
		return SR_ERR;

	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		libusb_get_device_descriptor(devlist[i], &des);

		if (des.idVendor != devc->profile->fw_vid
		    || des.idProduct != devc->profile->fw_pid)
			continue;

		if ((sdi->status == SR_ST_INITIALIZING) ||
				(sdi->status == SR_ST_INACTIVE)) {
			/*
			 * Check device by its physical USB bus/port address.
			 */
			usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
			if (strcmp(sdi->connection_id, connection_id))
				/* This is not the one. */
				continue;
		}

		if (!(err = libusb_open(devlist[i], &usb->devhdl))) {
			if (usb->address == 0xff) {
				/*
				 * First time we touch this device after firmware upload,
				 * so we don't know the address yet.
				 */
				usb->address = libusb_get_device_address(devlist[i]);
			}

			sdi->status = SR_ST_ACTIVE;
			sr_info("Opened device on %d.%d (logical) / "
					"%s (physical) interface %d.",
				usb->bus, usb->address,
				sdi->connection_id, USB_INTERFACE);
		} else {
			sr_err("Failed to open device: %s.",
			       libusb_error_name(err));
		}

		/* If we made it here, we handled the device (somehow). */
		break;
	}

	libusb_free_device_list(devlist, 1);

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR;

	return SR_OK;
}
Beispiel #22
0
static int lusb_open_bootloader(void **driver, uint8_t bus, uint8_t addr)
{
    int status;
    struct libusb_device **dev_list = NULL;
    ssize_t dev_list_size, i;
    struct bladerf_lusb *lusb;

    *driver = NULL;

    lusb = calloc(1, sizeof(lusb[0]));
    if (lusb == NULL) {
        return BLADERF_ERR_MEM;
    }

    status = libusb_init(&lusb->context);
    if (status != 0) {
        log_debug("Failed to initialize libusb context: %s\n",
                  libusb_error_name(status));
        goto error;
    }

    dev_list_size = libusb_get_device_list(lusb->context, &dev_list);
    if (dev_list_size < 0) {
        log_debug("Failed to get device list: %s\n", libusb_error_name(status));
        status = (int) dev_list_size;
        goto error;
    }

    for (i = 0; i < dev_list_size; i++) {
        if (device_is_fx3_bootloader(dev_list[i]) &&
            bus_matches(bus, dev_list[i]) &&
            addr_matches(addr, dev_list[i])) {


            status = libusb_open(dev_list[i], &lusb->handle);
            if (status != 0) {
                log_debug("Failed to open device: %s\n",
                          libusb_error_name(status));
                goto error;
            } else {
                status = libusb_claim_interface(lusb->handle, 0);
                if (status < 0) {
                    log_debug("Failed to claim interface: %s\n",
                              libusb_error_name(status));

                    goto error;
                } else {
                    log_verbose("Opened bootloader at %u:%u\n",
                                libusb_get_bus_number(dev_list[i]),
                                libusb_get_device_address(dev_list[i]));
                    *driver = lusb;
                }
                break;
            }
        }
    }

error:
    if (dev_list != NULL) {
        libusb_free_device_list(dev_list, 1);
    }

    if (status != 0) {
        status = error_conv(status);
        lusb_close_bootloader(lusb);
    } else if (*driver == NULL) {
        status = BLADERF_ERR_NODEV;
        lusb_close_bootloader(lusb);
    }

    return status;
}
Beispiel #23
0
int main(int argc, char * const argv[])
{
	struct sdp_dev *p_id;
	struct mach_id *mach;
	libusb_device **devs;
	libusb_device *dev;
	int r;
	int err;
	ssize_t cnt;
	libusb_device_handle *h = NULL;
	int config = 0;
	int verify = 0;
	struct sdp_work *curr;
	struct sdp_work *cmd_head = NULL;
	char const *conf;
	char const *base_path = get_base_path(argv[0]);
	char const *conf_path = "/etc/imx-loader.d/";

	err = parse_opts(argc, argv, &conf_path, &verify, &cmd_head);
	if (err < 0)
		return -1;

	// Get list of machines...
	conf = conf_file_name("imx_usb.conf", base_path, conf_path);
	if (conf == NULL)
		return -1;

	struct mach_id *list = parse_imx_conf(conf);
	if (!list)
		return -1;

	r = libusb_init(NULL);
	if (r < 0)
		goto out;

	cnt = libusb_get_device_list(NULL, &devs);
	if (cnt < 0)
		goto out;

//	print_devs(devs);
	dev = find_imx_dev(devs, &mach, list);
	if (dev) {
		err = libusb_open(dev, &h);
		if (err)
			printf("%s:Could not open device vid=0x%x pid=0x%x err=%d\n", __func__, mach->vid, mach->pid, err);
	}
	libusb_free_device_list(devs, 1);

	if (!h)
		goto out;

	// Get machine specific configuration file..
	conf = conf_file_name(mach->file_name, base_path, conf_path);
	if (conf == NULL)
		goto out;

	p_id = parse_conf(conf);
	if (!p_id)
		goto out;

	if (p_id->mode == MODE_HID)
		p_id->transfer = &transfer_hid;
	if (p_id->mode == MODE_BULK)
		p_id->transfer = &transfer_bulk;

	// USB private pointer is libusb device handle...
	p_id->priv = h;

	libusb_get_configuration(h, &config);
	printf("%04x:%04x(%s) bConfigurationValue =%x\n",
			mach->vid, mach->pid, p_id->name, config);

	if (libusb_kernel_driver_active(h, 0))
		 libusb_detach_kernel_driver(h, 0);

	err = libusb_claim_interface(h, 0);
	if (err) {
		printf("Claim failed\n");
		goto out;
	}
	printf("Interface 0 claimed\n");
	err = do_status(p_id);
	if (err) {
		printf("status failed\n");
		goto out;
	}

	// By default, use work from config file...
	curr = p_id->work;

	if (cmd_head != NULL)
		curr = cmd_head;

	if (curr == NULL) {
		printf("no job found\n"); 
		goto out;
	}

	while (curr) {
		if (curr->mem)
			perform_mem_work(p_id, curr->mem);
//		printf("jump_mode %x\n", curr->jump_mode);
		if (curr->filename[0]) {
			err = DoIRomDownload(p_id, curr, verify);
		}
		if (err) {
			err = do_status(p_id);
			break;
		}
		if (!curr->next && (!curr->plug || curr != cmd_head))
			break;
		err = do_status(p_id);
		printf("jump_mode %x plug=%i err=%i\n", curr->jump_mode, curr->plug, err);
		if (err) {
			int retry;
			/* Rediscovers device */
			libusb_release_interface(h, 0);
			libusb_close(h);
			libusb_exit(NULL);
			for (retry = 0; retry < 10; retry++) {
				printf("sleeping\n");
				sleep(3);
				printf("done sleeping\n");
				h = open_vid_pid(mach, p_id);
				if (h)
					break;
			}
			if (!h)
				goto out;
		}
		if (curr == cmd_head && curr->plug) {
			curr->plug = 0;
			continue;
		}
		curr = curr->next;
	}

exit:
	libusb_release_interface(h, 0);
out:
	if (h)
		libusb_close(h);
	libusb_exit(NULL);
	return 0;
}
Beispiel #24
0
/*-----------------------------------------------------------------------------
 * Name      :  usb_create_from_uri
 * Purpose   :  Create USB port from URI string
 * Inputs    :  p   : port structure
 *              uri : URI string
 * Outputs   :  <>
 * Return    :  APS_OK or error code
 * -----------------------------------------------------------------------------*/
int usb_create_from_uri(aps_port_t *p,struct aps_uri *su)
{
	libusb_device * dev;
	libusb_device_handle * h;
	int r;
	ssize_t cnt;
	int i;
	const char *vidstr;
	const char *pidstr;
	int vid, pid;

	p->set.usb.busnum = 0;
	p->set.usb.devaddr = 0;

	vidstr = uri_get_opt(su,"vid");
	pidstr = uri_get_opt(su,"pid");

#ifdef DEBUG
	fprintf(stderr, "DEBUG: in %s()\n", __func__);
#endif
	if (devcnt == 0)
	{
		return APS_USB_DEVICE_NOT_FOUND;
	}

	if (vidstr == 0 || pidstr == 0)
	{
		return APS_INVALID_URI;
	}

	if (sscanf(vidstr,"%i",&vid)!=1) {
		return APS_INVALID_URI;
	}
	if (sscanf(pidstr,"%i",&pid)!=1) {
		return APS_INVALID_URI;
	}

	i = 0;
	while ((dev = devs[i]) != NULL)
	{
		struct libusb_device_descriptor desc;

		r = libusb_get_device_descriptor(dev, &desc);
		if (r < 0)
		{
			fprintf(stderr, "ERROR: failed to get device descriptor");
			libusb_free_device_list(devs, 1);
			libusb_exit(NULL);
			return APS_USB_DEVICE_NOT_FOUND;
		}

		//if (desc.idVendor == APS_VENDOR_ID || desc.idVendor == APS_VENDOR_ID0)
		if (desc.idVendor == vid && desc.idProduct == pid)
		{
#ifdef DEBUG
			fprintf(stderr, "DEBUG: ok, aps printer found...\n");
#endif
			break;
		}
		i ++;
	}

	if (dev == 0)
	{
#ifdef DEBUG
		fprintf(stderr, "DEBUG: aps printer not found, exiting\n");
#endif
		libusb_free_device_list(devs, 1);
		libusb_exit(NULL);
		devs = 0;
		devcnt = 0;
		return APS_USB_DEVICE_NOT_FOUND;
	}
#ifdef DEBUG
	fprintf(stderr, "DEBUG: printer at bus: %i\n", libusb_get_bus_number(dev));
	fprintf(stderr, "DEBUG: printer at address: %i\n", libusb_get_device_address(dev));
#endif
	/* shopov(04072011) - added */
	p->set.usb.busnum = libusb_get_bus_number(dev);
	p->set.usb.devaddr = libusb_get_device_address(dev);
	return APS_OK;
	/* shopov(04072011) - end added */
#if 0	

	if (libusb_open(dev, &h))
	{
		fprintf(stderr, "DEBUG: aps printer not found, exiting\n");
		libusb_free_device_list(devs, 1);
		libusb_exit(NULL);
		devs = 0;
		devcnt = 0;
		return APS_USB_DEVICE_NOT_FOUND;
	}
	r = libusb_kernel_driver_active(h, 0);
	if (r != 0 && r != 1)
	{
close_and_return:		
		libusb_close(h);
		fprintf(stderr, "DEBUG: aps printer not found, exiting\n");
		libusb_free_device_list(devs, 1);
		libusb_exit(NULL);
		devs = 0;
		devcnt = 0;
		return APS_IO_ERROR;
	}
	p->set.usb.was_kernel_driver_attached = r;
	if (r)
	{
		r = libusb_detach_kernel_driver(h, 0);
		if (r != 0)
			goto close_and_return;
	}
	r = libusb_claim_interface(h, 0);
	if (r != 0)
		goto close_and_return;

	p->set.usb.pdev = dev;
	p->set.usb.hdev = h;

	return APS_OK;
#endif


#if 0
	struct stat st;
	const char *device;
	const char *usbfs;
	const char *path;
	const char *vidstr;
	const char *pidstr;

	/*get device name*/
	device = uri_get_device(su);

	printf("Device:%s\n",device);

	if (stat(device,&st)<0) {
		return APS_IO_ERROR;
	}

	printf("stats ok!:\n");

	if (S_ISCHR(st.st_mode)) {
		printf("S_ISCHR =============ok!:\n");
		/*build connection path from device name*/
		return usb_create(p,device);
	}
	else if (S_ISDIR(st.st_mode)) {
		printf("S_ISDIR ok!:\n");
		usbfs = device;
	}
	else {
		printf("Ke dall !  ok!:\n");
		return APS_INVALID_URI;
	}

	/*get path, vendor ID and product ID parameters*/
	path = uri_get_opt(su,"path");
	vidstr = uri_get_opt(su,"vid");
	pidstr = uri_get_opt(su,"pid");

	if (path!=NULL) {
		/*create USB port from connection path*/
		/*just copy path into port structure*/

		/*set usbfs parameter*/
		if (strlen(usbfs)>sizeof(p->set.usb.usbfs)-1) {
			return APS_NAME_TOO_LONG;
		}
		else {
			strcpy(p->set.usb.usbfs,usbfs);
		}

		/*copy connection path*/
		if (strlen(path)>sizeof(p->set.usb.path)-1) {
			return APS_NAME_TOO_LONG;
		}
		else {
			strcpy(p->set.usb.path,path);
		}
	}
	else if (vidstr!=NULL && pidstr!=NULL) {
		/*create USB port from (vendor ID,product ID) pair*/
		/*build connection path*/

		int vid;
		int pid;

		if (sscanf(vidstr,"%i",&vid)!=1) {
			return APS_INVALID_URI;
		}
		if (sscanf(pidstr,"%i",&pid)!=1) {
			return APS_INVALID_URI;
		}

		return usb_create_from_id(p,usbfs,vid,pid);
	}
	else {
		return APS_INVALID_URI;
	}

	return APS_OK;
#endif
	return APS_OK;
}
Beispiel #25
0
SR_PRIV int fx2lafw_dev_open(struct sr_dev_inst *sdi, struct sr_dev_driver *di)
{
	libusb_device **devlist;
	struct sr_usb_dev_inst *usb;
	struct libusb_device_descriptor des;
	struct dev_context *devc;
	struct drv_context *drvc;
	struct version_info vi;
	int ret, i, device_count;
	uint8_t revid;
	char connection_id[64];

	drvc = di->context;
	devc = sdi->priv;
	usb = sdi->conn;

	if (sdi->status == SR_ST_ACTIVE)
		/* Device is already in use. */
		return SR_ERR;

	device_count = libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	if (device_count < 0) {
		sr_err("Failed to get device list: %s.",
		       libusb_error_name(device_count));
		return SR_ERR;
	}

	for (i = 0; i < device_count; i++) {
		libusb_get_device_descriptor(devlist[i], &des);

		if (des.idVendor != devc->profile->vid
		    || des.idProduct != devc->profile->pid)
			continue;

		if ((sdi->status == SR_ST_INITIALIZING) ||
				(sdi->status == SR_ST_INACTIVE)) {
			/*
			 * Check device by its physical USB bus/port address.
			 */
			usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
			if (strcmp(sdi->connection_id, connection_id))
				/* This is not the one. */
				continue;
		}

		if (!(ret = libusb_open(devlist[i], &usb->devhdl))) {
			if (usb->address == 0xff)
				/*
				 * First time we touch this device after FW
				 * upload, so we don't know the address yet.
				 */
				usb->address = libusb_get_device_address(devlist[i]);
		} else {
			sr_err("Failed to open device: %s.",
			       libusb_error_name(ret));
			break;
		}

		if (libusb_has_capability(LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)) {
			if (libusb_kernel_driver_active(usb->devhdl, USB_INTERFACE) == 1) {
				if ((ret = libusb_detach_kernel_driver(usb->devhdl, USB_INTERFACE)) < 0) {
					sr_err("Failed to detach kernel driver: %s.",
						libusb_error_name(ret));
					return SR_ERR;
				}
			}
		}

		ret = command_get_fw_version(usb->devhdl, &vi);
		if (ret != SR_OK) {
			sr_err("Failed to get firmware version.");
			break;
		}

		ret = command_get_revid_version(sdi, &revid);
		if (ret != SR_OK) {
			sr_err("Failed to get REVID.");
			break;
		}

		/*
		 * Changes in major version mean incompatible/API changes, so
		 * bail out if we encounter an incompatible version.
		 * Different minor versions are OK, they should be compatible.
		 */
		if (vi.major != FX2LAFW_REQUIRED_VERSION_MAJOR) {
			sr_err("Expected firmware version %d.x, "
			       "got %d.%d.", FX2LAFW_REQUIRED_VERSION_MAJOR,
			       vi.major, vi.minor);
			break;
		}

		sdi->status = SR_ST_ACTIVE;
		sr_info("Opened device on %d.%d (logical) / %s (physical), "
			"interface %d, firmware %d.%d.",
			usb->bus, usb->address, connection_id,
			USB_INTERFACE, vi.major, vi.minor);

		sr_info("Detected REVID=%d, it's a Cypress CY7C68013%s.",
			revid, (revid != 1) ? " (FX2)" : "A (FX2LP)");

		break;
	}
	libusb_free_device_list(devlist, 1);

	if (sdi->status != SR_ST_ACTIVE)
		return SR_ERR;

	return SR_OK;
}
Beispiel #26
0
/*-----------------------------------------------------------------------------
 * Name      :  usb_list_ports
 * Purpose   :  List available USB ports
 * Inputs    :  p   : array of port structures
 *              max : maximum number of ports in list
 * Outputs   :  <>
 * Return    :  Number of ports or error code
 * -----------------------------------------------------------------------------*/
int usb_list_ports(aps_port_t **p,int max)
{
	const char *usbfs = USBFS;
	int n;
	int i;
	int total;
	libusb_device * dev;


	if (libusb_ctx == 0)
	{
		init_libusb();
	}

	/*list connected devices*/
	n = devcnt;

	if (n <= 0) {
		return 0;
	}

	/*build ports from APS devices*/
	total = 0;

	i = 0;
	while (total < max && (dev = devs[i]) != NULL)
	{
		struct libusb_device_descriptor desc;
		int r;

		r = libusb_get_device_descriptor(dev, &desc);
		if (r < 0)
		{
			fprintf(stderr, "ERROR: failed to get device descriptor");
			libusb_free_device_list(devs, 1);
			libusb_exit(NULL);
			devs = 0;
			devcnt = 0;
			libusb_ctx = 0;
			return APS_USB_DEVICE_NOT_FOUND;
		}

		if (desc.idVendor == APS_VENDOR_ID || desc.idVendor == APS_VENDOR_ID0)
		{
#ifdef DEBUG
			fprintf(stderr, "DEBUG: ok, aps printer found...\n");
#endif
			*p = calloc(1, sizeof(aps_class_t));
			usb_custom(*p);
			(*p)->set.usb.pdev = dev;
			p ++;
			total ++;
		}
		i ++;
	}

#if 0
	for (i=0; i<n && total<max; i++) {
		libusb_device *dev = devs + i;

		if (dev->vendor_id==APS_VENDOR_ID || dev->vendor_id==APS_VENDOR_ID0) {
			*p = aps_create_usb_port_from_address(usbfs,dev->busnum,dev->devnum);

			if (*p!=NULL) {
				p++;
				total++;
			}
		}
	}
#endif

	return total;
}
Beispiel #27
0
int test_init(struct test_state *state)
{
	int i, ret;
	ssize_t cnt;
	libusb_device **list;

	state->found = NULL;
	state->ctx = NULL;
	state->handle = NULL;
	state->attached = 0;

	ret = libusb_init(&state->ctx);
	if (ret) {
		printf("cannot init libusb: %s\n", libusb_error_name(ret));
		return 1;
	}

	cnt = libusb_get_device_list(state->ctx, &list);
	if (cnt <= 0) {
		printf("no devices found\n");
		goto error1;
	}

	for (i = 0; i < cnt; ++i) {
		libusb_device *dev = list[i];
		struct libusb_device_descriptor desc;
		ret = libusb_get_device_descriptor(dev, &desc);
		if (ret) {
			printf("unable to get device descriptor: %s\n",
			       libusb_error_name(ret));
			goto error2;
		}
		if (desc.idVendor == VENDOR && desc.idProduct == PRODUCT) {
			state->found = dev;
			break;
		}
	}

	if (!state->found) {
		printf("no devices found\n");
		goto error2;
	}

	ret = libusb_open(state->found, &state->handle);
	if (ret) {
		printf("cannot open device: %s\n", libusb_error_name(ret));
		goto error2;
	}

	if (libusb_claim_interface(state->handle, 0)) {
		ret = libusb_detach_kernel_driver(state->handle, 0);
		if (ret) {
			printf("unable to detach kernel driver: %s\n",
			       libusb_error_name(ret));
			goto error3;
		}
		state->attached = 1;
		ret = libusb_claim_interface(state->handle, 0);
		if (ret) {
			printf("cannot claim interface: %s\n",
			       libusb_error_name(ret));
			goto error4;
		}
	}

	return 0;

error4:
	if (state->attached == 1)
		libusb_attach_kernel_driver(state->handle, 0);

error3:
	libusb_close(state->handle);

error2:
	libusb_free_device_list(list, 1);

error1:
	libusb_exit(state->ctx);
	return 1;
}
Beispiel #28
0
/*-----------------------------------------------------------------------------
 * Name      :  usb_open
 * Purpose   :  Open USB port
 * Inputs    :  p : port structure
 * Outputs   :  <>
 * Return    :  APS_OK or error code
 * -----------------------------------------------------------------------------*/
int usb_open(aps_port_t *p)
{
	libusb_device * dev;
	libusb_device_handle * h;
	int r;
	ssize_t cnt;
	int i;
	const char *vidstr;
	const char *pidstr;
#ifdef DEBUG
	fprintf(stderr, "DEBUG: in %s()\n", __func__);
#endif
	if (devcnt == 0)
	{
		return APS_USB_DEVICE_NOT_FOUND;
	}

	i = 0;
	while ((dev = devs[i]) != NULL)
	{
		struct libusb_device_descriptor desc;

		r = libusb_get_device_descriptor(dev, &desc);
		if (r < 0)
		{
			fprintf(stderr, "ERROR: failed to get device descriptor");
			libusb_free_device_list(devs, 1);
			libusb_exit(NULL);
			return APS_USB_DEVICE_NOT_FOUND;
		}

		/* shopov(04072011) - modified */
		//if (desc.idVendor == APS_VENDOR_ID || desc.idVendor == APS_VENDOR_ID0)
		if (libusb_get_bus_number(dev) == p->set.usb.busnum
				&& p->set.usb.devaddr == libusb_get_device_address(dev))
		{
#ifdef DEBUG
			fprintf(stderr, "DEBUG: ok, printer found...\n");
#endif
			break;
		}
		/* shopov(04072011) - end modified */
		i ++;
	}

	if (dev == 0)
	{
#ifdef DEBUG
		fprintf(stderr, "DEBUG: aps printer not found, exiting\n");
#endif
		libusb_free_device_list(devs, 1);
		libusb_exit(NULL);
		devs = 0;
		devcnt = 0;
		return APS_USB_DEVICE_NOT_FOUND;
	}
#ifdef DEBUG
	fprintf(stderr, "DEBUG: printer at bus: %i\n", libusb_get_bus_number(dev));
	fprintf(stderr, "DEBUG: printer at address: %i\n", libusb_get_device_address(dev));
#endif
	if (libusb_open(dev, &h))
	{
#ifdef DEBUG
		fprintf(stderr, "DEBUG: aps printer not found, exiting\n");
#endif
		libusb_free_device_list(devs, 1);
		libusb_exit(NULL);
		devs = 0;
		devcnt = 0;
		return APS_USB_DEVICE_NOT_FOUND;
	}
	r = libusb_kernel_driver_active(h, 0);
	if (r != 0 && r != 1)
	{
close_and_return:		
		libusb_close(h);
#ifdef DEBUG
		fprintf(stderr, "DEBUG: aps printer not found, exiting\n");
#endif
		libusb_free_device_list(devs, 1);
		libusb_exit(NULL);
		devs = 0;
		devcnt = 0;
		return APS_IO_ERROR;
	}
	p->set.usb.was_kernel_driver_attached = r;
	if (r)
	{
		r = libusb_detach_kernel_driver(h, 0);
		if (r != 0)
			goto close_and_return;
	}
	r = libusb_claim_interface(h, 0);
	if (r != 0)
		goto close_and_return;

	p->set.usb.pdev = dev;
	p->set.usb.hdev = h;

	return APS_OK;
}
Beispiel #29
0
/* Helper to open a libusb device that matches vid, pid, product string and/or serial string.
 * Set any field to 0 as a wildcard. If the device is found true is returned, with ctx containing
 * the already opened handle. ctx->interface must be set to the desired interface (channel) number
 * prior to calling this function. */
static bool open_matching_device(struct mpsse_ctx *ctx, const uint16_t *vid, const uint16_t *pid,
	const char *product, const char *serial, const char *location)
{
	libusb_device **list;
	struct libusb_device_descriptor desc;
	struct libusb_config_descriptor *config0;
	int err;
	bool found = false;
	ssize_t cnt = libusb_get_device_list(ctx->usb_ctx, &list);
	if (cnt < 0)
		LOG_ERROR("libusb_get_device_list() failed with %s", libusb_error_name(cnt));

	for (ssize_t i = 0; i < cnt; i++) {
		libusb_device *device = list[i];

		err = libusb_get_device_descriptor(device, &desc);
		if (err != LIBUSB_SUCCESS) {
			LOG_ERROR("libusb_get_device_descriptor() failed with %s", libusb_error_name(err));
			continue;
		}

		if (vid && *vid != desc.idVendor)
			continue;
		if (pid && *pid != desc.idProduct)
			continue;

		err = libusb_open(device, &ctx->usb_dev);
		if (err != LIBUSB_SUCCESS) {
			LOG_ERROR("libusb_open() failed with %s",
				  libusb_error_name(err));
			continue;
		}

		if (location && !device_location_equal(device, location)) {
			libusb_close(ctx->usb_dev);
			continue;
		}

		if (product && !string_descriptor_equal(ctx->usb_dev, desc.iProduct, product)) {
			libusb_close(ctx->usb_dev);
			continue;
		}

		if (serial && !string_descriptor_equal(ctx->usb_dev, desc.iSerialNumber, serial)) {
			libusb_close(ctx->usb_dev);
			continue;
		}

		found = true;
		break;
	}

	libusb_free_device_list(list, 1);

	if (!found) {
		LOG_ERROR("no device found");
		return false;
	}

	err = libusb_get_config_descriptor(libusb_get_device(ctx->usb_dev), 0, &config0);
	if (err != LIBUSB_SUCCESS) {
		LOG_ERROR("libusb_get_config_descriptor() failed with %s", libusb_error_name(err));
		libusb_close(ctx->usb_dev);
		return false;
	}

	/* Make sure the first configuration is selected */
	int cfg;
	err = libusb_get_configuration(ctx->usb_dev, &cfg);
	if (err != LIBUSB_SUCCESS) {
		LOG_ERROR("libusb_get_configuration() failed with %s", libusb_error_name(err));
		goto error;
	}

	if (desc.bNumConfigurations > 0 && cfg != config0->bConfigurationValue) {
		err = libusb_set_configuration(ctx->usb_dev, config0->bConfigurationValue);
		if (err != LIBUSB_SUCCESS) {
			LOG_ERROR("libusb_set_configuration() failed with %s", libusb_error_name(err));
			goto error;
		}
	}

	/* Try to detach ftdi_sio kernel module */
	err = libusb_detach_kernel_driver(ctx->usb_dev, ctx->interface);
	if (err != LIBUSB_SUCCESS && err != LIBUSB_ERROR_NOT_FOUND
			&& err != LIBUSB_ERROR_NOT_SUPPORTED) {
		LOG_ERROR("libusb_detach_kernel_driver() failed with %s", libusb_error_name(err));
		goto error;
	}

	err = libusb_claim_interface(ctx->usb_dev, ctx->interface);
	if (err != LIBUSB_SUCCESS) {
		LOG_ERROR("libusb_claim_interface() failed with %s", libusb_error_name(err));
		goto error;
	}

	/* Reset FTDI device */
	err = libusb_control_transfer(ctx->usb_dev, FTDI_DEVICE_OUT_REQTYPE,
			SIO_RESET_REQUEST, SIO_RESET_SIO,
			ctx->index, NULL, 0, ctx->usb_write_timeout);
	if (err < 0) {
		LOG_ERROR("failed to reset FTDI device: %s", libusb_error_name(err));
		goto error;
	}

	switch (desc.bcdDevice) {
	case 0x500:
		ctx->type = TYPE_FT2232C;
		break;
	case 0x700:
		ctx->type = TYPE_FT2232H;
		break;
	case 0x800:
		ctx->type = TYPE_FT4232H;
		break;
	case 0x900:
		ctx->type = TYPE_FT232H;
		break;
	default:
		LOG_ERROR("unsupported FTDI chip type: 0x%04x", desc.bcdDevice);
		goto error;
	}

	/* Determine maximum packet size and endpoint addresses */
	if (!(desc.bNumConfigurations > 0 && ctx->interface < config0->bNumInterfaces
			&& config0->interface[ctx->interface].num_altsetting > 0))
		goto desc_error;

	const struct libusb_interface_descriptor *descriptor;
	descriptor = &config0->interface[ctx->interface].altsetting[0];
	if (descriptor->bNumEndpoints != 2)
		goto desc_error;

	ctx->in_ep = 0;
	ctx->out_ep = 0;
	for (int i = 0; i < descriptor->bNumEndpoints; i++) {
		if (descriptor->endpoint[i].bEndpointAddress & 0x80) {
			ctx->in_ep = descriptor->endpoint[i].bEndpointAddress;
			ctx->max_packet_size =
					descriptor->endpoint[i].wMaxPacketSize;
		} else {
			ctx->out_ep = descriptor->endpoint[i].bEndpointAddress;
		}
	}

	if (ctx->in_ep == 0 || ctx->out_ep == 0)
		goto desc_error;

	libusb_free_config_descriptor(config0);
	return true;

desc_error:
	LOG_ERROR("unrecognized USB device descriptor");
error:
	libusb_free_config_descriptor(config0);
	libusb_close(ctx->usb_dev);
	return false;
}
Beispiel #30
0
static GSList *scan(GSList *options)
{
	struct drv_context *drvc;
	struct dev_context *devc;
	struct sr_dev_inst *sdi;
	struct sr_usb_dev_inst *usb;
	struct sr_config *src;
	const struct dso_profile *prof;
	GSList *l, *devices, *conn_devices;
	struct libusb_device_descriptor des;
	libusb_device **devlist;
	int devcnt, ret, i, j;
	const char *conn;

	drvc = di->priv;

	devcnt = 0;
	devices = 0;

	conn = NULL;
	for (l = options; l; l = l->next) {
		src = l->data;
		if (src->key == SR_CONF_CONN) {
			conn = g_variant_get_string(src->data, NULL);
			break;
		}
	}
	if (conn)
		conn_devices = sr_usb_find(drvc->sr_ctx->libusb_ctx, conn);
	else
		conn_devices = NULL;

	/* Find all Hantek DSO devices and upload firmware to all of them. */
	libusb_get_device_list(drvc->sr_ctx->libusb_ctx, &devlist);
	for (i = 0; devlist[i]; i++) {
		if (conn) {
			usb = NULL;
			for (l = conn_devices; l; l = l->next) {
				usb = l->data;
				if (usb->bus == libusb_get_bus_number(devlist[i])
					&& usb->address == libusb_get_device_address(devlist[i]))
					break;
			}
			if (!l)
				/* This device matched none of the ones that
				 * matched the conn specification. */
				continue;
		}

		if ((ret = libusb_get_device_descriptor(devlist[i], &des))) {
			sr_err("Failed to get device descriptor: %s.",
					libusb_error_name(ret));
			continue;
		}

		prof = NULL;
		for (j = 0; dev_profiles[j].orig_vid; j++) {
			if (des.idVendor == dev_profiles[j].orig_vid
				&& des.idProduct == dev_profiles[j].orig_pid) {
				/* Device matches the pre-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = dso_dev_new(devcnt, prof);
				devices = g_slist_append(devices, sdi);
				devc = sdi->priv;
				if (ezusb_upload_firmware(devlist[i], USB_CONFIGURATION,
						prof->firmware) == SR_OK)
					/* Remember when the firmware on this device was updated */
					devc->fw_updated = g_get_monotonic_time();
				else
					sr_err("Firmware upload failed for "
					        "device %d.", devcnt);
				/* Dummy USB address of 0xff will get overwritten later. */
				sdi->conn = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]), 0xff, NULL);
				devcnt++;
				break;
			} else if (des.idVendor == dev_profiles[j].fw_vid
				&& des.idProduct == dev_profiles[j].fw_pid) {
				/* Device matches the post-firmware profile. */
				prof = &dev_profiles[j];
				sr_dbg("Found a %s %s.", prof->vendor, prof->model);
				sdi = dso_dev_new(devcnt, prof);
				sdi->status = SR_ST_INACTIVE;
				devices = g_slist_append(devices, sdi);
				devc = sdi->priv;
				sdi->inst_type = SR_INST_USB;
				sdi->conn = sr_usb_dev_inst_new(
						libusb_get_bus_number(devlist[i]),
						libusb_get_device_address(devlist[i]), NULL);
				devcnt++;
				break;
			}
		}
		if (!prof)
			/* not a supported VID/PID */
			continue;
	}
	libusb_free_device_list(devlist, 1);

	return devices;
}