Esempio n. 1
0
int fnusb_process_events(fnusb_ctx *ctx)
{
	return libusb_handle_events(ctx->ctx);
}
Esempio n. 2
0
static void *read_thread(void *param)
{
	hid_device *dev = param;
	unsigned char *buf;
	const size_t length = dev->input_ep_max_packet_size;

	/* Set up the transfer object. */
	buf = malloc(length);
	dev->transfer = libusb_alloc_transfer(0);
	libusb_fill_interrupt_transfer(dev->transfer,
		dev->device_handle,
		dev->input_endpoint,
		buf,
		length,
		read_callback,
		dev,
		5000/*timeout*/);
	
	/* Make the first submission. Further submissions are made
	   from inside read_callback() */
	libusb_submit_transfer(dev->transfer);

	// Notify the main thread that the read thread is up and running.
	pthread_barrier_wait(&dev->barrier);
	
	/* Handle all the events. */
	while (!dev->shutdown_thread) {
		int res;
		res = libusb_handle_events(NULL);
		if (res < 0) {
			/* There was an error. Break out of this loop. */
			break;
		}
	}
	
	/* Cancel any transfer that may be pending. This call will fail
	   if no transfers are pending, but that's OK. */
	if (libusb_cancel_transfer(dev->transfer) == 0) {
		/* The transfer was cancelled, so wait for its completion. */
		libusb_handle_events(NULL);
	}
	
	/* Now that the read thread is stopping, Wake any threads which are
	   waiting on data (in hid_read_timeout()). Do this under a mutex to
	   make sure that a thread which is about to go to sleep waiting on
	   the condition acutally will go to sleep before the condition is
	   signaled. */
	pthread_mutex_lock(&dev->mutex);
	pthread_cond_broadcast(&dev->condition);
	pthread_mutex_unlock(&dev->mutex);

	/* The dev->transfer->buffer and dev->transfer objects are cleaned up
	   in hid_close(). They are not cleaned up here because this thread
	   could end either due to a disconnect or due to a user
	   call to hid_close(). In both cases the objects can be safely
	   cleaned up after the call to pthread_join() (in hid_close()), but
	   since hid_close() calls libusb_cancel_transfer(), on these objects,
	   they can not be cleaned up here. */
	
	return NULL;
}
Esempio n. 3
0
int main(void)
{
	struct sigaction sigact;
	int r = 1;

	r = libusb_init(NULL);
	if (r < 0) {
		fprintf(stderr, "failed to initialise libusb\n");
		exit(1);
	}

	r = find_dpfp_device();
	if (r < 0) {
		fprintf(stderr, "Could not find/open device\n");
		goto out;
	}

	r = libusb_claim_interface(devh, 0);
	if (r < 0) {
		fprintf(stderr, "usb_claim_interface error %d %s\n", r, strerror(-r));
		goto out;
	}
	printf("claimed interface\n");

	r = print_f0_data();
	if (r < 0)
		goto out_release;

	r = do_init();
	if (r < 0)
		goto out_deinit;

	/* async from here onwards */

	sigact.sa_handler = sighandler;
	sigemptyset(&sigact.sa_mask);
	sigact.sa_flags = 0;
	sigaction(SIGINT, &sigact, NULL);
	sigaction(SIGTERM, &sigact, NULL);
	sigaction(SIGQUIT, &sigact, NULL);

	r = pthread_create(&poll_thread, NULL, poll_thread_main, NULL);
	if (r)
		goto out_deinit;

	r = alloc_transfers();
	if (r < 0) {
		request_exit(1);
		pthread_join(poll_thread, NULL);
		goto out_deinit;
	}

	r = init_capture();
	if (r < 0) {
		request_exit(1);
		pthread_join(poll_thread, NULL);
		goto out_deinit;
	}

	while (!do_exit) {
		pthread_mutex_lock(&exit_cond_lock);
		pthread_cond_wait(&exit_cond, &exit_cond_lock);
		pthread_mutex_unlock(&exit_cond_lock);
	}

	printf("shutting down...\n");
	pthread_join(poll_thread, NULL);

	r = libusb_cancel_transfer(irq_transfer);
	if (r < 0) {
		request_exit(1);
		goto out_deinit;
	}

	r = libusb_cancel_transfer(img_transfer);
	if (r < 0) {
		request_exit(1);
		goto out_deinit;
	}

	while (img_transfer || irq_transfer)
		if (libusb_handle_events(NULL) < 0)
			break;

	if (do_exit == 1)
		r = 0;
	else
		r = 1;

out_deinit:
	libusb_free_transfer(img_transfer);
	libusb_free_transfer(irq_transfer);
	set_mode(0);
	set_hwstat(0x80);
out_release:
	libusb_release_interface(devh, 0);
out:
	libusb_close(devh);
	libusb_exit(NULL);
	return r >= 0 ? r : -r;
}
Esempio n. 4
0
 bool USBMgr::handleEvents()
 {
     return (libusb_handle_events(instance()->usb_context) == 0);
 }
int main (int argc, char **argv)
{
  bool daemonize = false;

  while (true) {
      int c;
      static struct option long_options[] =
          {
              {"help",    no_argument, NULL, 'h'},
              {"version", no_argument, NULL, 'v'},
              {"daemon",  no_argument, NULL, 'd'},
              {"fork",    no_argument, NULL, 'f'},
              {0, 0, 0, 0}
          };

      c = getopt_long(argc, argv, "hvd", long_options, NULL);
      if (c == -1)
        break;
      switch (c) {
      case 'h':
        print_usage(argv[0]);
        exit(EXIT_SUCCESS);
      case 'v':
        msg("HAMA MCE remote event client v%s for XBMC\n", VERSION);
        exit(EXIT_SUCCESS);
      case 'd':
        daemonize = true;
        break;
      default:
        print_usage(argv[0]);
        exit(EXIT_FAILURE);
      }
  }

  if (optind < (argc - 1)) {
      err("%s: too many arguments\n", argv[0]);
      exit(EXIT_FAILURE);
  }

  struct sigaction sa;
  sigemptyset(&sa.sa_mask);
  sa.sa_handler = handle_exit;
  PCHK(sigaction(SIGINT,  &sa, NULL));
  PCHK(sigaction(SIGTERM, &sa, NULL));

  libusb_context *ctx;
  libusb_device_handle *dev;
  struct libusb_transfer *transfer0x81 = libusb_alloc_transfer(0);
  struct libusb_transfer *transfer0x82 = libusb_alloc_transfer(0);
  unsigned char buf0x81 [8];
  unsigned char buf0x82 [5];

  UCHK(libusb_init(&ctx));

  if (!(dev = libusb_open_device_with_vid_pid(ctx, 0x05a4, 0x9881))) {
      err("%s: No HAMA MCE remote control found.\n", argv[0]);
      exit(EXIT_FAILURE);
  }

  int exit_code = EXIT_SUCCESS;

  if (libusb_kernel_driver_active(dev, 0))
    UCHK(libusb_detach_kernel_driver(dev, 0));
  if (libusb_kernel_driver_active(dev, 1))
    UCHK(libusb_detach_kernel_driver(dev, 1));
  UCHK(libusb_claim_interface(dev, 0));
  UCHK(libusb_claim_interface(dev, 1));

  libusb_fill_interrupt_transfer(transfer0x81, dev, 0x81, buf0x81, sizeof(buf0x81), transfer0x81_cb, NULL, 215);
  UCHK(libusb_submit_transfer(transfer0x81));

  libusb_fill_interrupt_transfer(transfer0x82, dev, 0x82, buf0x82, sizeof(buf0x82), transfer0x82_cb, NULL, 200);
  UCHK(libusb_submit_transfer(transfer0x82));

  msg("Connected HAMA MCE Remote\n");
  xbmc.SendHELO("HAMA MCE Remote", ICON_NONE);

  if (daemonize) {
      if (daemon(0,0) == -1) {
          err("Failed to fork\n");
          perror(argv[0]);
          exit_code = EXIT_FAILURE;
          goto exit;
      }
  }

  while (!(disconnected || quit)) {
      UCHK(libusb_handle_events(ctx));
  }
  exit:
  if (disconnected) {
      msg("Disconnected HAMA MCE Remote\n");
      xbmc.SendNOTIFICATION("Disconnected", "HAMA MCE Remote", ICON_NONE);
  }
  else {
      msg("Closing HAMA MCE Remote\n");
      xbmc.SendNOTIFICATION("Closing", "HAMA MCE Remote", ICON_NONE);
  }

  libusb_free_transfer(transfer0x81);
  libusb_free_transfer(transfer0x82);

  if (!disconnected) {
      // Release the remote back to the system
      UCHK(libusb_release_interface(dev, 0));
      UCHK(libusb_release_interface(dev, 1));
      UCHK(libusb_attach_kernel_driver(dev, 0));
      UCHK(libusb_attach_kernel_driver(dev, 1));
  }

  libusb_close(dev);
  libusb_exit(ctx);

  exit(exit_code);
}
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); */
}
Esempio n. 7
0
/** \ingroup syncio
 * Perform a USB control transfer.
 *
 * The direction of the transfer is inferred from the bmRequestType field of
 * the setup packet.
 *
 * The wValue, wIndex and wLength fields values should be given in host-endian
 * byte order.
 *
 * \param dev_handle a handle for the device to communicate with
 * \param bmRequestType the request type field for the setup packet
 * \param bRequest the request field for the setup packet
 * \param wValue the value field for the setup packet
 * \param wIndex the index field for the setup packet
 * \param data a suitably-sized data buffer for either input or output
 * (depending on direction bits within bmRequestType)
 * \param wLength the length field for the setup packet. The data buffer should
 * be at least this size.
 * \param timeout timeout (in millseconds) that this function should wait
 * before giving up due to no response being received. For no timeout, use
 * value 0.
 * \returns on success, the number of bytes actually transferred
 * \returns LIBUSB_ERROR_TIMEOUT if the transfer timed out
 * \returns LIBUSB_ERROR_PIPE if the control request was not supported by the
 * device
 * \returns LIBUSB_ERROR_NO_DEVICE if the device has been disconnected
 * \returns another LIBUSB_ERROR code on other failures
 */
API_EXPORTED int libusb_control_transfer(libusb_device_handle *dev_handle,
	uint8_t bmRequestType, uint8_t bRequest, uint16_t wValue, uint16_t wIndex,
	unsigned char *data, uint16_t wLength, unsigned int timeout)
{
	struct libusb_transfer *transfer = libusb_alloc_transfer(0);
	unsigned char *buffer;
	int completed = 0;
	int r;

	if (!transfer)
		return LIBUSB_ERROR_NO_MEM;
	
	buffer = malloc(LIBUSB_CONTROL_SETUP_SIZE + wLength);
	if (!buffer) {
		libusb_free_transfer(transfer);
		return LIBUSB_ERROR_NO_MEM;
	}

	libusb_fill_control_setup(buffer, bmRequestType, bRequest, wValue, wIndex,
		wLength);
	if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_OUT)
		memcpy(buffer + LIBUSB_CONTROL_SETUP_SIZE, data, wLength);

	libusb_fill_control_transfer(transfer, dev_handle, buffer,
		ctrl_transfer_cb, &completed, timeout);
	transfer->flags = LIBUSB_TRANSFER_FREE_BUFFER;
	r = libusb_submit_transfer(transfer);
	if (r < 0) {
		libusb_free_transfer(transfer);
		return r;
	}

	while (!completed) {
		r = libusb_handle_events(HANDLE_CTX(dev_handle));
		if (r < 0) {
			libusb_cancel_transfer(transfer);
			while (!completed)
				if (libusb_handle_events(HANDLE_CTX(dev_handle)) < 0)
					break;
			libusb_free_transfer(transfer);
			return r;
		}
	}

	if ((bmRequestType & LIBUSB_ENDPOINT_DIR_MASK) == LIBUSB_ENDPOINT_IN)
		memcpy(data, libusb_control_transfer_get_data(transfer),
			transfer->actual_length);

	switch (transfer->status) {
	case LIBUSB_TRANSFER_COMPLETED:
		r = transfer->actual_length;
		break;
	case LIBUSB_TRANSFER_TIMED_OUT:
		r = LIBUSB_ERROR_TIMEOUT;
		break;
	case LIBUSB_TRANSFER_STALL:
		r = LIBUSB_ERROR_PIPE;
		break;
	case LIBUSB_TRANSFER_NO_DEVICE:
		r = LIBUSB_ERROR_NO_DEVICE;
		break;
	default:
		usbi_warn(HANDLE_CTX(dev_handle),
			"unrecognised status code %d", transfer->status);
		r = LIBUSB_ERROR_OTHER;
	}

	libusb_free_transfer(transfer);
	return r;
}
Esempio n. 8
0
KeyCode activity(const char* cmd, const char* value)
{
    libusb_handle_events(context);
    return key;
}
Esempio n. 9
0
UsbNotifier::~UsbNotifier()
{
    d->end = true;
    terminate();

    struct timeval emitTimer = (struct timeval){0};
    libusb_handle_events_timeout_completed(NULL, &emitTimer, NULL);

    // callbacks are eliminated on exit
    // http://libusb.sourceforge.net/api-1.0/hotplug.html
    libusb_exit(NULL);

    delete d;
}

UsbDevice* UsbNotifier::extractUsbDevice(libusb_device *device)
{
    struct libusb_device_descriptor descriptor;
    struct libusb_device_handle *myHandle = nullptr;
    int operationResult = 0;

    if (libusb_get_device_descriptor(device, &descriptor) < 0) {
        qDebug("COMPLETE FAIL");
        return nullptr;
    }

    // I need to open the device to get more information about the usb
    operationResult = libusb_open(device, &myHandle);

    if (operationResult < 0) {
        qDebug() << "UsbNotifier::deviceInsertCallback - Can't open usb device @ " << libusb_get_device_address(device) << " ERROR NO: " << operationResult;
        return nullptr;
    }

    char manufacturer[256];
    char product[256];

    operationResult = libusb_get_string_descriptor_ascii(myHandle
    , descriptor.iManufacturer
    , (unsigned char*)manufacturer
    , sizeof(manufacturer));

    if (operationResult < 0) {
        qDebug() << "UsbNotifier::deviceInsertCallback - something went wrong while extracting the manufacturer";
        return nullptr;
    }

    operationResult = libusb_get_string_descriptor_ascii(myHandle
    , descriptor.iProduct
    , (unsigned char*)product
    , sizeof(product));

    if (operationResult < 0) {
        qDebug() << "UsbNotifier::deviceInsertCallback - something went wrong while extracting the product";
        return nullptr;
    }

    libusb_close(myHandle);

    return new UsbDevice(libusb_get_device_address(device)
                        , libusb_get_bus_number(device)
                        , descriptor.idVendor
                        , libusb_get_port_number(device)
                        , descriptor.idProduct
                        , manufacturer
                        , product
                        , device);
}


void UsbNotifier::run()
{
    // do a quick check for already plugged in usb devices
    int result = 0;
    d->end = false;
    libusb_device **deviceList;

    result = libusb_get_device_list(NULL, &deviceList);

    if (result < 0) {
        // TODO handle error
        qDebug() << "[UsbNotifier::run] result value: " << result;
        qDebug() << "UsbNotifier::run] ERROR: " << libusb_error_name(result);
    } else {
        libusb_device_handle *handle = nullptr;

        for (int i = 0; i < result; ++i) {
            // test if the device is usable. There might be some usb device which we don't have permission
            // to operate on. This test is done by a simple libusb_open/close test.
            if (libusb_open(deviceList[i], &handle) == LIBUSB_SUCCESS) {
                libusb_close(handle);

                UsbDevice *usbDevice = extractUsbDevice(deviceList[i]);

                if (usbDevice && (d->product == 0 || d->vendor == 0)) {
                    Q_EMIT deviceAttached(usbDevice);
                } else {
                    if (usbDevice
                        && (usbDevice->productId() == d->product && usbDevice->vendorId() == d->vendor)) {
                        Q_EMIT deviceAttached(usbDevice);
                    }
                }
            }
        }

        libusb_free_device_list(deviceList, 1);
    }

    // and now start watching for events
    setTerminationEnabled(true);
    while (!d->end) {
        libusb_handle_events(NULL);
    }
}