/**
 * @brief Check if this platform supports hotplug.
 * @returns true if hotplug is supported and enabled on this platform, false
 *   otherwise.
 */
bool AsyncPluginImpl::HotplugSupported() {
#ifdef HAVE_LIBUSB_HOTPLUG_API
  return libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) != 0;
#else
  return false;
#endif
}
Exemple #2
0
struct libusb_device *usbi_alloc_device(struct libusb_context *ctx,
                                        unsigned long session_id)
{
    size_t priv_size = usbi_backend->device_priv_size;
    struct libusb_device *dev = calloc(1, sizeof(*dev) + priv_size);
    int r;

    if (!dev)
        return NULL;

    r = usbi_mutex_init(&dev->lock, NULL);
    if (r) {
        free(dev);
        return NULL;
    }

    dev->ctx = ctx;
    dev->refcnt = 1;
    dev->session_data = session_id;
    dev->speed = LIBUSB_SPEED_UNKNOWN;

    if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
        usbi_connect_device (dev);
    }

    return dev;
}
Exemple #3
0
void LibUsbDevice::initializeDevice()
{
    int status;
    status = libusb_init(&context); //initialize the library for the session we just declared
    if(status != 0)
    {
        cstatus = tr("Initialization Error!");
        qDebug()<<"Initialization Error! "<<status<<endl; //there was an error
        isInitialiazed = false;
        return;
    }
    isInitialiazed = true;
    if(libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)&&0)
    {
       hasHotPlugSupport = true;
       //status = libusb_hotplug_register_callback (context, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, LIBUSB_HOTPLUG_ENUMERATE , VENDOR_ID,
                                              //  PRODUCT_ID, CLASS_ID, hotplugAttachCallback, this, &hotplugHandle[0]);
       if (LIBUSB_SUCCESS != status)
       {
           hasHotPlugSupport = false;
       }

       //status = libusb_hotplug_register_callback (context, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, LIBUSB_HOTPLUG_ENUMERATE , VENDOR_ID,
                                                 // PRODUCT_ID, CLASS_ID, hotplugDetachCallback, this, &hotplugHandle[1]);
       if (LIBUSB_SUCCESS != status)
       {
           hasHotPlugSupport = false;
       }
       future = QtConcurrent::run (this,&LibUsbDevice::eventThread);
    }
    libusb_set_debug(context, LIBUSB_LOG_LEVEL_INFO); //set verbosity level to 3
}
Exemple #4
0
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx,
	libusb_hotplug_callback_handle handle)
{
	struct libusb_hotplug_callback *hotplug_cb;
	libusb_hotplug_message message;
	ssize_t ret;

	/* check for hotplug support */
	if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
		return;
	}

	USBI_GET_CONTEXT(ctx);

	usbi_mutex_lock(&ctx->hotplug_cbs_lock);
	list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list,
			    struct libusb_hotplug_callback) {
		if (handle == hotplug_cb->handle) {
			/* Mark this callback for deregistration */
			hotplug_cb->needs_free = 1;
		}
	}
	usbi_mutex_unlock(&ctx->hotplug_cbs_lock);

	/* wakeup handle_events to do the actual free */
	memset(&message, 0, sizeof(message));
	ret = usbi_write(ctx->hotplug_pipe[1], &message, sizeof(message));
	if (sizeof(message) != ret) {
		usbi_err(ctx, "error writing hotplug message");
	}
}
int main(int argc, char *argv[])
{
	libusb_hotplug_callback_handle hp[2];
	int product_id, vendor_id, class_id;
	int rc;

	vendor_id  = (argc > 1) ? strtol (argv[1], NULL, 0) : 0x045a;
	product_id = (argc > 2) ? strtol (argv[2], NULL, 0) : 0x5005;
	class_id   = (argc > 3) ? strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY;

	rc = libusb_init (NULL);
	if (rc < 0)
	{
		printf("failed to initialise libusb: %s\n", libusb_error_name(rc));
		return EXIT_FAILURE;
	}

	if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
		printf ("Hotplug capabilites are not supported on this platform\n");
		libusb_exit (NULL);
		return EXIT_FAILURE;
	}

	rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id,
		product_id, class_id, hotplug_callback, NULL, &hp[0]);
	if (LIBUSB_SUCCESS != rc) {
		fprintf (stderr, "Error registering callback 0\n");
		libusb_exit (NULL);
		return EXIT_FAILURE;
	}

	rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id,
		product_id,class_id, hotplug_callback_detach, NULL, &hp[1]);
	if (LIBUSB_SUCCESS != rc) {
		fprintf (stderr, "Error registering callback 1\n");
		libusb_exit (NULL);
		return EXIT_FAILURE;
	}

	while (done < 2) {
		rc = libusb_handle_events (NULL);
		if (rc < 0)
			printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc));
	}

	if (handle) {
		libusb_close (handle);
	}

	libusb_exit (NULL);

	return EXIT_SUCCESS;
}
UsbNotifier::UsbNotifier(int vendor, int product, QObject *parent)
    : QThread(parent)
    , d(new UsbNotifierPrivate)
{
    // register to the QMetaSystem so Qt knows how to pass arount the object
    qRegisterMetaType<UsbDevice>("UsbDevice");

    if (!s_me) {
        s_me = this;
    }

    d->vendor = vendor;
    d->product = product;

    libusb_hotplug_callback_handle attachHandle;
    libusb_hotplug_callback_handle detachHandle;
    libusb_init(NULL);
    libusb_set_debug(NULL, LIBUSB_LOG_LEVEL_WARNING);

    if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
        // TODO setup hotplug callbacks
        qDebug("This device correctly supports callback");
    } else {
        // TODO use thread with manual update
    }

    int result = libusb_hotplug_register_callback(NULL
                                                , LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED
                                                , LIBUSB_HOTPLUG_ENUMERATE
                                                , d->vendor == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->vendor
                                                , d->product == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->product
                                                , LIBUSB_HOTPLUG_MATCH_ANY
                                                , &deviceInsertCallback
                                                , NULL
                                                , &attachHandle);

    // TODO handle callback registration fail
    qDebug() << "CALLBACK BIND RESULT: " << result;

    result = libusb_hotplug_register_callback(NULL
                                            , LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT
                                            , LIBUSB_HOTPLUG_ENUMERATE
                                            , d->vendor == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->vendor
                                            , d->product == 0 ? LIBUSB_HOTPLUG_MATCH_ANY : d->product
                                            , LIBUSB_HOTPLUG_MATCH_ANY
                                            , &deviceDetachCallback
                                            , NULL
                                            , &detachHandle);

    // TODO handle callback registration fail
    qDebug() << "CALLBACK BIND RESULT: " << result;
}
Exemple #7
0
static gboolean
g_usb_context_initable_init (GInitable     *initable,
                             GCancellable  *cancellable,
                             GError       **error)
{
	GUsbContext *context = G_USB_CONTEXT (initable);
	GUsbContextPrivate *priv;
	gint rc;
	libusb_context *ctx;

	priv = context->priv;

	rc = libusb_init (&ctx);
	if (rc < 0) {
		g_set_error (error,
		             G_USB_CONTEXT_ERROR,
		             G_USB_CONTEXT_ERROR_INTERNAL,
		             "failed to init libusb: %s [%i]",
		             g_usb_strerror (rc), rc);
		return FALSE;
	}

	priv->main_ctx = g_main_context_ref (g_main_context_default ());
	priv->ctx = ctx;
	priv->thread_event_run = 1;
	priv->thread_event = g_thread_new ("GUsbEventThread",
	                                   g_usb_context_event_thread_cb,
	                                   context);

	/* watch for add/remove */
	if (libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
		rc = libusb_hotplug_register_callback (priv->ctx,
		                                       LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
		                                       LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
		                                       0,
		                                       LIBUSB_HOTPLUG_MATCH_ANY,
		                                       LIBUSB_HOTPLUG_MATCH_ANY,
		                                       LIBUSB_HOTPLUG_MATCH_ANY,
		                                       g_usb_context_hotplug_cb,
		                                       context,
		                                       &context->priv->hotplug_id);
		if (rc != LIBUSB_SUCCESS) {
			g_warning ("Error creating a hotplug callback: %s",
			           g_usb_strerror (rc));
		}
	}

	return TRUE;
}
Exemple #8
0
int usb_can_callback(struct usb_sock_t *usb)
{
	IGNORE(usb);

	if (!g_options.vendor_id ||
	    !g_options.product_id)
	{
		NOTE("Exit-on-unplug requires vid & pid");
		return 0;
	}

	int works = !!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG);
	if (!works)
		WARN("Libusb cannot tell us when to disconnect");
	return works;
}
Exemple #9
0
/**
 * HWStubBackendHelper
 */
HWStubBackendHelper::HWStubBackendHelper()
{
    libusb_init(NULL);
#ifdef LIBUSB_NO_HOTPLUG
    m_hotplug = false;
#else
    m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG);
    if(m_hotplug)
    {
        m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback(
            NULL,   (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
            LIBUSB_HOTPLUG_ENUMERATE, HWSTUB_USB_VID, HWSTUB_USB_PID, HWSTUB_CLASS,
            &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this), &m_hotplug_handle);
    }
#endif
}
Exemple #10
0
/**
 * HWStubBackendHelper
 */
HWStubBackendHelper::HWStubBackendHelper()
{
#ifdef LIBUSB_NO_HOTPLUG
    m_hotplug = false;
#else
    m_hotplug = libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG);
    if(m_hotplug)
    {
        int evt = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
            LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT;
        m_hotplug = LIBUSB_SUCCESS == libusb_hotplug_register_callback(
            NULL, (libusb_hotplug_event)evt, LIBUSB_HOTPLUG_ENUMERATE,
            LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY, LIBUSB_HOTPLUG_MATCH_ANY,
            &HWStubBackendHelper::HotPlugCallback, reinterpret_cast< void* >(this),
            &m_hotplug_handle);
    }
#endif /* LIBUSB_NO_HOTPLUG */
}
Exemple #11
0
/**
 * g_usb_context_enumerate:
 * @context: a #GUsbContext
 *
 * Enumerates all the USB devices and adds them to the context.
 *
 * You only need to call this function once, and any subsequent calls
 * are silently ignored.
 *
 * Since: 0.2.2
 **/
void
g_usb_context_enumerate (GUsbContext *context)
{
	GUsbContextPrivate *priv = context->priv;

	/* only ever initially scan once, then rely on hotplug / poll */
	if (priv->done_enumerate)
		return;

	g_usb_context_rescan (context);
	if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
		g_debug ("platform does not do hotplug, using polling");
		priv->hotplug_poll_id = g_timeout_add_seconds (1,
							       g_usb_context_rescan_cb,
							       context);
	}
	priv->done_enumerate = TRUE;
}
Exemple #12
0
int
main(int argc, const char *argv[]) {
    int rc;
    libusb_context *ctx = NULL;
    libusb_hotplug_callback_handle handles[3];

    _init(ctx);

    if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
        printf("Hotplug not supported by this build of libusb\n");
        libusb_exit (NULL);
        return EXIT_FAILURE;
    }

    rc = libusb_hotplug_register_callback(ctx,
      LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
      0, ROMVID, ROMPID, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handles[0]);

    rc = libusb_hotplug_register_callback(ctx,
      LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
      0, SPLVID, SPLPID, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handles[1]);

    rc = libusb_hotplug_register_callback(ctx,
      LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED | LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT,
      0, UBOOTVID, UBOOTPID, LIBUSB_HOTPLUG_MATCH_ANY, hotplug_callback, NULL, &handles[2]);

    if (LIBUSB_SUCCESS != rc) {
        fprintf(stderr, "Error registering callback 0\n");
        libusb_exit(NULL);
        return EXIT_FAILURE;
    }

    while (!finished) {
        rc = libusb_handle_events(ctx);
        if (rc) {
			printf("libusb_handle_events() failed: %s\n", libusb_error_name(rc));
        }
    }

    _destroy(ctx);

    return 0;
}
Exemple #13
0
bool FCServer::startUSB(libusb_context *usb)
{
    mUSB = usb;

    // Enumerate all attached devices, and get notified of hotplug events
    libusb_hotplug_register_callback(mUSB,
        libusb_hotplug_event(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
                             LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
        LIBUSB_HOTPLUG_ENUMERATE,
        LIBUSB_HOTPLUG_MATCH_ANY,
        LIBUSB_HOTPLUG_MATCH_ANY,
        LIBUSB_HOTPLUG_MATCH_ANY,
        cbHotplug, this, 0);

    // On platforms without real USB hotplug, emulate it with a polling thread
    if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
        mUSBHotplugThread = new tthread::thread(usbHotplugThreadFunc, this);
    }

    return true;
}
Exemple #14
0
void usbi_connect_device(struct libusb_device *dev)
{
    libusb_hotplug_message message;
    ssize_t ret;

    memset(&message, 0, sizeof(message));
    message.event = LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED;
    message.device = dev;
    dev->attached = 1;

    usbi_mutex_lock(&dev->ctx->usb_devs_lock);
    list_add(&dev->list, &dev->ctx->usb_devs);
    usbi_mutex_unlock(&dev->ctx->usb_devs_lock);

    if (libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG) && dev->ctx->hotplug_pipe[1] > 0) {
        ret = usbi_write(dev->ctx->hotplug_pipe[1], &message, sizeof(message));
        if (sizeof (message) != ret) {
            usbi_err(DEVICE_CTX(dev), "error writing hotplug message");
        }
    }
}
Exemple #15
0
int main (int argc, char *argv[]) {
  libusb_hotplug_callback_handle hp[2];
  int product_id, vendor_id, class_id;
  int rc;

  vendor_id  = (argc > 1) ? strtol (argv[1], NULL, 0) : 0x045a;
  product_id = (argc > 2) ? strtol (argv[2], NULL, 0) : 0x5005;
  class_id   = (argc > 3) ? strtol (argv[3], NULL, 0) : LIBUSB_HOTPLUG_MATCH_ANY;

  libusb_init (NULL);

  if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
    printf ("Hotplug not supported by this build of libusb\n");
    libusb_exit (NULL);
    return EXIT_FAILURE;
  }

  rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id,
                                         product_id, class_id, hotplug_callback, NULL, &hp[0]);
  if (LIBUSB_SUCCESS != rc) {
    fprintf (stderr, "Error registering callback 0\n");
    libusb_exit (NULL);
    return EXIT_FAILURE;
  }

  rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id,
                                         product_id,class_id, hotplug_callback_detach, NULL, &hp[1]);
  if (LIBUSB_SUCCESS != rc) {
    fprintf (stderr, "Error registering callback 1\n");
    libusb_exit (NULL);
    return EXIT_FAILURE;
  }

  while (done < 2) {
    libusb_handle_events (NULL);
  }

  libusb_exit (NULL);
}
Exemple #16
0
void API_EXPORTED libusb_hotplug_deregister_callback (struct libusb_context *ctx,
	libusb_hotplug_callback_handle handle)
{
	struct libusb_hotplug_callback *hotplug_cb;

	/* check for hotplug support */
	if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
		return;
	}

	USBI_GET_CONTEXT(ctx);

	usbi_mutex_lock(&ctx->hotplug_cbs_lock);
	list_for_each_entry(hotplug_cb, &ctx->hotplug_cbs, list,
			    struct libusb_hotplug_callback) {
		if (handle == hotplug_cb->handle) {
			/* Mark this callback for deregistration */
			hotplug_cb->needs_free = 1;
		}
	}
	usbi_mutex_unlock(&ctx->hotplug_cbs_lock);
}
static void *libusb_hid_init(void)
{
   unsigned i, count;
   int ret;
   struct libusb_device **devices;
   libusb_hid_t *hid = (libusb_hid_t*)calloc(1, sizeof(*hid));

   if (!hid)
      goto error;

   ret = libusb_init(&hid->ctx);

   if (ret < 0)
      goto error;

   if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG))
      goto error;

   hid->slots = pad_connection_init(MAX_USERS);

   if (!hid->slots)
      goto error;

   count = libusb_get_device_list(hid->ctx, &devices);

   for (i = 0; i < count; i++)
   {
      struct libusb_device_descriptor desc;
      libusb_get_device_descriptor(devices[i], &desc);

      if (desc.idVendor > 0 && desc.idProduct > 0)
         add_adapter(hid, devices[i]);
   }

   if (count > 0)
      libusb_free_device_list(devices, 1);

   ret = libusb_hotplug_register_callback(
         hid->ctx,
         (libusb_hotplug_event)(LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED |
         LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT),
         (libusb_hotplug_flag)LIBUSB_HOTPLUG_ENUMERATE,
         LIBUSB_HOTPLUG_MATCH_ANY,
         LIBUSB_HOTPLUG_MATCH_ANY,
         LIBUSB_HOTPLUG_MATCH_ANY,
         libusb_hid_hotplug_callback,
         hid,
         &hid->hp);

   if (ret != LIBUSB_SUCCESS)
   {
      RARCH_ERR("Error creating a hotplug callback.\n");
      goto error;
   }

   hid->poll_thread = sthread_create(poll_thread, hid);

   if (!hid->poll_thread)
   {
      RARCH_ERR("Error creating polling thread");
      goto error;
   }

   return hid;

error:
   if (hid)
      libusb_hid_free(hid);
   return NULL;
}
int API_EXPORTED libusb_hotplug_register_callback(libusb_context *ctx,
	libusb_hotplug_event events, libusb_hotplug_flag flags,
	int vendor_id, int product_id, int dev_class,
	libusb_hotplug_callback_fn cb_fn, void *user_data,
	libusb_hotplug_callback_handle *handle)
{
	libusb_hotplug_callback *new_callback;
	static int handle_id = 1;

	/* check for hotplug support */
	if (!libusb_has_capability(LIBUSB_CAP_HAS_HOTPLUG)) {
		return LIBUSB_ERROR_NOT_SUPPORTED;
	}

	/* check for sane values */
	if ((LIBUSB_HOTPLUG_MATCH_ANY != vendor_id && (~0xffff & vendor_id)) ||
	    (LIBUSB_HOTPLUG_MATCH_ANY != product_id && (~0xffff & product_id)) ||
	    (LIBUSB_HOTPLUG_MATCH_ANY != dev_class && (~0xff & dev_class)) ||
	    !cb_fn) {
		return LIBUSB_ERROR_INVALID_PARAM;
	}

	USBI_GET_CONTEXT(ctx);

	new_callback = (libusb_hotplug_callback *)calloc(1, sizeof (*new_callback));
	if (!new_callback) {
		return LIBUSB_ERROR_NO_MEM;
	}

	new_callback->ctx = ctx;
	new_callback->vendor_id = vendor_id;
	new_callback->product_id = product_id;
	new_callback->dev_class = dev_class;
	new_callback->flags = flags;
	new_callback->events = events;
	new_callback->cb = cb_fn;
	new_callback->user_data = user_data;
	new_callback->needs_free = 0;

	usbi_mutex_lock(&ctx->hotplug_cbs_lock);

	/* protect the handle by the context hotplug lock. it doesn't matter if the same handle
	 * is used for different contexts only that the handle is unique for this context */
	new_callback->handle = handle_id++;

	list_add(&new_callback->list, &ctx->hotplug_cbs);

	usbi_mutex_unlock(&ctx->hotplug_cbs_lock);


	if (flags & LIBUSB_HOTPLUG_ENUMERATE) {
		int i, len;
		struct libusb_device **devs;

		len = (int) libusb_get_device_list(ctx, &devs);
		if (len < 0) {
			libusb_hotplug_deregister_callback(ctx,
							new_callback->handle);
			return len;
		}

		for (i = 0; i < len; i++) {
			usbi_hotplug_match_cb(ctx, devs[i],
					LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED,
					new_callback);
		}

		libusb_free_device_list(devs, 1);
	}


	if (handle) {
		*handle = new_callback->handle;
	}

	return LIBUSB_SUCCESS;
}
int main(int argc, char *argv[])
{
  libusb_hotplug_callback_handle hp[2];
  int product_id, vendor_id, class_id = LIBUSB_HOTPLUG_MATCH_ANY;
  g_Command_Attach = "";
  g_Command_Detach = "";
  int rc;
  char flag_initial_search = 0;
  
  /* getopt */
  while ((rc = getopt(argc, argv, "c:a:d:ih")) != -1) {
    switch (rc) {
      case 'c':
        class_id = strtol(optarg, NULL, 0);
        break;
      case 'a':
        g_Command_Attach = optarg;
        break;
      case 'd':
        g_Command_Detach = optarg;
        break;
      case 'i':
        flag_initial_search = 1;
        break;
      case 'h':
      default: /* '?' */
        print_usage(argv[0]);
        exit(EXIT_FAILURE);
    }
  }
  if (optind + 2 > argc)
  {
    print_usage(argv[0]);
    exit(EXIT_FAILURE);
  }
  vendor_id = strtol(argv[optind++], NULL, 0);
  product_id = strtol(argv[optind++], NULL, 0);
  
  /* 初期化 */
  rc = libusb_init (NULL);
  if (rc < 0)
  {
    fprintf(stderr, "failed to initialise libusb: %s\n", libusb_error_name(rc));
    return EXIT_FAILURE;
  }

  /* シグナルハンドリング */
  signal(SIGINT, finish);
  signal(SIGTERM, finish);

  /* ホットプラグ対応のプラットフォームか調べる */
  if (!libusb_has_capability (LIBUSB_CAP_HAS_HOTPLUG)) {
    fprintf (stderr, "Hotplug capabilites are not supported on this platform\n");
    libusb_exit (NULL);
    return EXIT_FAILURE;
  }

  /* (オプションi)起動した時点での状態から目的のUSBデバイスを探す。 */
  if (flag_initial_search)
  {
    if (find_device(vendor_id, product_id))
    {
      func_attached();
    }
    else
    {
      func_detached();
    }
  }

  /* デバイスが接続されたら実行される関数を登録 */
  rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_ARRIVED, 0, vendor_id,
                                         product_id, class_id, hotplug_callback, NULL, &hp[0]);
  if (LIBUSB_SUCCESS != rc) {
    fprintf (stderr, "Error registering callback 0\n");
    libusb_exit (NULL);
    return EXIT_FAILURE;
  }

  /* デバイスが切断されたら実行される関数を登録 */
  rc = libusb_hotplug_register_callback (NULL, LIBUSB_HOTPLUG_EVENT_DEVICE_LEFT, 0, vendor_id,
                                         product_id,class_id, hotplug_callback_detach, NULL, &hp[1]);
  if (LIBUSB_SUCCESS != rc) {
    fprintf (stderr, "Error registering callback 1\n");
    libusb_exit (NULL);
    return EXIT_FAILURE;
  }

  /* メインループ。イベントを回し続ける */
  while (1) {
    rc = libusb_handle_events (NULL);
    if (rc < 0)
      fprintf(stderr, "libusb_handle_events() failed: %s\n", libusb_error_name(rc));
  }

  /* 到達不能コード。終了処理はシグナルにより呼び出される。 */
  /* libusb_exit (NULL); */
}
Exemple #20
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;
}
Exemple #21
0
static int test_device(uint16_t vid, uint16_t pid)
{
	libusb_device_handle *handle;
	libusb_device *dev;
	uint8_t bus, port_path[8];
	struct libusb_config_descriptor *conf_desc;
	const struct libusb_endpoint_descriptor *endpoint;
	int i, j, k, r;
	int iface, nb_ifaces, first_iface = -1;
	// For attaching/detaching the kernel driver, if needed
	int iface_detached = -1;
	struct libusb_device_descriptor dev_desc;
	const char* speed_name[5] = { "Unknown", "1.5 Mbit/s (USB LowSpeed)", "12 Mbit/s (USB FullSpeed)",
		"480 Mbit/s (USB HighSpeed)", "5000 Mbit/s (USB SuperSpeed)"};
	char string[128];
	uint8_t string_index[3];	// indexes of the string descriptors
	uint8_t endpoint_in = 0, endpoint_out = 0;	// default IN and OUT endpoints

	printf("Opening device %04X:%04X...\n", vid, pid);
	handle = libusb_open_device_with_vid_pid(NULL, vid, pid);

	if (handle == NULL) {
		perr("  Failed.\n");
		return -1;
	}

	dev = libusb_get_device(handle);
	bus = libusb_get_bus_number(dev);
	if (extra_info) {
		r = libusb_get_port_path(NULL, dev, port_path, sizeof(port_path));
		if (r > 0) {
			printf("\nDevice properties:\n");
			printf("        bus number: %d\n", bus);
			printf("         port path: %d", port_path[0]);
			for (i=1; i<r; i++) {
				printf("->%d", port_path[i]);
			}
			printf(" (from root hub)\n");
		}
		r = libusb_get_device_speed(dev);
		if ((r<0) || (r>4)) r=0;
		printf("             speed: %s\n", speed_name[r]);
	}

	printf("\nReading device descriptor:\n");
	CALL_CHECK(libusb_get_device_descriptor(dev, &dev_desc));
	printf("            length: %d\n", dev_desc.bLength);
	printf("      device class: %d\n", dev_desc.bDeviceClass);
	printf("               S/N: %d\n", dev_desc.iSerialNumber);
	printf("           VID:PID: %04X:%04X\n", dev_desc.idVendor, dev_desc.idProduct);
	printf("         bcdDevice: %04X\n", dev_desc.bcdDevice);
	printf("   iMan:iProd:iSer: %d:%d:%d\n", dev_desc.iManufacturer, dev_desc.iProduct, dev_desc.iSerialNumber);
	printf("          nb confs: %d\n", dev_desc.bNumConfigurations);
	// Copy the string descriptors for easier parsing
	string_index[0] = dev_desc.iManufacturer;
	string_index[1] = dev_desc.iProduct;
	string_index[2] = dev_desc.iSerialNumber;

	printf("\nReading configuration descriptors:\n");
	CALL_CHECK(libusb_get_config_descriptor(dev, 0, &conf_desc));
	nb_ifaces = conf_desc->bNumInterfaces;
	printf("             nb interfaces: %d\n", nb_ifaces);
	if (nb_ifaces > 0)
		first_iface = conf_desc->usb_interface[0].altsetting[0].bInterfaceNumber;
	for (i=0; i<nb_ifaces; i++) {
		printf("              interface[%d]: id = %d\n", i,
			conf_desc->usb_interface[i].altsetting[0].bInterfaceNumber);
		for (j=0; j<conf_desc->usb_interface[i].num_altsetting; j++) {
			printf("interface[%d].altsetting[%d]: num endpoints = %d\n",
				i, j, conf_desc->usb_interface[i].altsetting[j].bNumEndpoints);
			printf("   Class.SubClass.Protocol: %02X.%02X.%02X\n",
				conf_desc->usb_interface[i].altsetting[j].bInterfaceClass,
				conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass,
				conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol);
			if ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceClass == LIBUSB_CLASS_MASS_STORAGE)
			  && ( (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x01)
			  || (conf_desc->usb_interface[i].altsetting[j].bInterfaceSubClass == 0x06) )
			  && (conf_desc->usb_interface[i].altsetting[j].bInterfaceProtocol == 0x50) ) {
				// Mass storage devices that can use basic SCSI commands
				test_mode = USE_SCSI;
			}
			for (k=0; k<conf_desc->usb_interface[i].altsetting[j].bNumEndpoints; k++) {
				endpoint = &conf_desc->usb_interface[i].altsetting[j].endpoint[k];
				printf("       endpoint[%d].address: %02X\n", k, endpoint->bEndpointAddress);
				// Use the first interrupt or bulk IN/OUT endpoints as default for testing
				if ((endpoint->bmAttributes & LIBUSB_TRANSFER_TYPE_MASK) & (LIBUSB_TRANSFER_TYPE_BULK | LIBUSB_TRANSFER_TYPE_INTERRUPT)) {
					if (endpoint->bEndpointAddress & LIBUSB_ENDPOINT_IN) {
						if (!endpoint_in)
							endpoint_in = endpoint->bEndpointAddress;
					} else {
						if (!endpoint_out)
							endpoint_out = endpoint->bEndpointAddress;
					}
				}
				printf("           max packet size: %04X\n", endpoint->wMaxPacketSize);
				printf("          polling interval: %02X\n", endpoint->bInterval);
			}
		}
	}
	libusb_free_config_descriptor(conf_desc);

	for (iface = 0; iface < nb_ifaces; iface++)
	{
		printf("\nClaiming interface %d...\n", iface);
		r = libusb_claim_interface(handle, iface);
		if ((r != LIBUSB_SUCCESS) && libusb_has_capability(LIBUSB_CAP_SUPPORTS_DETACH_KERNEL_DRIVER)
			&& (libusb_kernel_driver_active(handle, iface) > 0)) {
			// Try to detach the kernel driver
			perr("   A kernel driver is active, trying to detach it...\n");
			r = libusb_detach_kernel_driver(handle, iface);
			if (r == LIBUSB_SUCCESS) {
				iface_detached = iface;
				printf("   Claiming interface again...\n");
				r = libusb_claim_interface(handle, iface);
			}
		}
		if (r != LIBUSB_SUCCESS) {
			perr("   Failed.\n");
		}
	}

	printf("\nReading string descriptors:\n");
	for (i=0; i<3; i++) {
		if (string_index[i] == 0) {
			continue;
		}
		if (libusb_get_string_descriptor_ascii(handle, string_index[i], (unsigned char*)string, 128) >= 0) {
			printf("   String (0x%02X): \"%s\"\n", string_index[i], string);
		}
	}
	// Read the OS String Descriptor
	if (libusb_get_string_descriptor_ascii(handle, 0xEE, (unsigned char*)string, 128) >= 0) {
		printf("   String (0x%02X): \"%s\"\n", 0xEE, string);
		// If this is a Microsoft OS String Descriptor,
		// attempt to read the WinUSB extended Feature Descriptors
		if (strncmp(string, "MSFT100", 7) == 0)
			read_ms_winsub_feature_descriptors(handle, string[7], first_iface);
	}

	switch(test_mode) {
	case USE_PS3:
		CALL_CHECK(display_ps3_status(handle));
		break;
	case USE_XBOX:
		CALL_CHECK(display_xbox_status(handle));
		CALL_CHECK(set_xbox_actuators(handle, 128, 222));
		msleep(2000);
		CALL_CHECK(set_xbox_actuators(handle, 0, 0));
		break;
	case USE_HID:
		test_hid(handle, endpoint_in);
		break;
	case USE_SCSI:
		CALL_CHECK(test_mass_storage(handle, endpoint_in, endpoint_out));
	case USE_GENERIC:
		break;
	}

	printf("\n");
	for (iface = 0; iface<nb_ifaces; iface++) {
		printf("Releasing interface %d...\n", iface);
		libusb_release_interface(handle, iface);
	}

	if (iface_detached >= 0) {
		printf("Re-attaching kernel driver...\n");
		libusb_attach_kernel_driver(handle, iface_detached);
	}

	printf("Closing device...\n");
	libusb_close(handle);

	return 0;
}