int main(int argc, char *argv[])
{
  std::string program_path(argv[0]);
  size_t executable_name_idx = program_path.rfind("Protonect");

  std::string binpath = "/";

  if(executable_name_idx != std::string::npos)
  {
    binpath = program_path.substr(0, executable_name_idx);
  }

  uint16_t vid = 0x045E;
  uint16_t pid = 0x02C4;
  uint16_t mi = 0x00;

  bool debug_mode = false;

  libusb_device_handle *handle;
  libusb_device *dev;
  uint8_t bus;
  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)" };

  int r;

  const struct libusb_version* version;
  version = libusb_get_version();
  printf("Using libusbx v%d.%d.%d.%d\n\n", version->major, version->minor, version->micro, version->nano);

  r = libusb_init(NULL);
  if (r < 0)
    return r;

  libusb_set_debug(NULL, debug_mode ? LIBUSB_LOG_LEVEL_DEBUG : LIBUSB_LOG_LEVEL_INFO);

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

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

  dev = libusb_get_device(handle);
  bus = libusb_get_bus_number(dev);
  /*
   struct libusb_device_descriptor dev_desc;

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

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  int active_cfg = -5;
  r = libusb_get_configuration(handle, &active_cfg);

  printf("active configuration: %d, err: %d", active_cfg, r);
  int configId = 1;
  if (active_cfg != configId)
  {
    printf("Setting config: %d\n", configId);
    r = libusb_set_configuration(handle, configId);
    if (r != LIBUSB_SUCCESS)
    {
      perr("  Can't set configuration. Error code: %d (%s)\n", r, libusb_error_name(r));
    }
  }

  int iface = 0;
  printf("\nClaiming interface %d...\n", iface);
  r = libusb_claim_interface(handle, iface);
  if (r != LIBUSB_SUCCESS)
  {
    perr("   Failed: %d.\n", r);
  }

  iface = 1;
  printf("\nClaiming interface %d...\n", iface);
  r = libusb_claim_interface(handle, iface);
  if (r != LIBUSB_SUCCESS)
  {
    perr("   Failed: %d.\n", r);
  }

  InitKinect(handle);

  // install signal handler now
  signal(SIGINT,sigint_handler);
  shutdown = false;

  libfreenect2::usb::EventLoop usb_loop;
  usb_loop.start();

  libfreenect2::FrameMap frames;
  libfreenect2::FrameListener frame_listener(libfreenect2::Frame::Color | libfreenect2::Frame::Ir | libfreenect2::Frame::Depth);

  //libfreenect2::DumpRgbPacketProcessor rgb_processor;
  libfreenect2::TurboJpegRgbPacketProcessor rgb_processor;
  rgb_processor.setFrameListener(&frame_listener);
  libfreenect2::RgbPacketStreamParser rgb_packet_stream_parser(&rgb_processor);

  libfreenect2::usb::BulkTransferPool rgb_bulk_transfers(handle, 0x83);
  rgb_bulk_transfers.allocate(50, 0x4000);
  rgb_bulk_transfers.setCallback(&rgb_packet_stream_parser);
  rgb_bulk_transfers.enableSubmission();

  libfreenect2::CpuDepthPacketProcessor depth_processor;
  depth_processor.setFrameListener(&frame_listener);
  depth_processor.load11To16LutFromFile((binpath + "../11to16.bin").c_str());
  depth_processor.loadXTableFromFile((binpath + "../xTable.bin").c_str());
  depth_processor.loadZTableFromFile((binpath + "../zTable.bin").c_str());

  libfreenect2::DepthPacketStreamParser depth_packet_stream_parser(&depth_processor);

  size_t max_packet_size = libusb_get_max_iso_packet_size(dev, 0x84);
  std::cout << "iso max_packet_size: " << max_packet_size << std::endl;

  libfreenect2::usb::IsoTransferPool depth_iso_transfers(handle, 0x84);
  depth_iso_transfers.allocate(80, 8, max_packet_size);
  depth_iso_transfers.setCallback(&depth_packet_stream_parser);
  depth_iso_transfers.enableSubmission();

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  RunKinect(handle, depth_processor);

  rgb_bulk_transfers.submit(10);
  depth_iso_transfers.submit(60);

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  while(!shutdown)
  {
    frame_listener.waitForNewFrame(frames);

    libfreenect2::Frame *rgb = frames[libfreenect2::Frame::Color];
    libfreenect2::Frame *ir = frames[libfreenect2::Frame::Ir];
    libfreenect2::Frame *depth = frames[libfreenect2::Frame::Depth];

    cv::imshow("rgb", cv::Mat(rgb->height, rgb->width, CV_8UC3, rgb->data));
    cv::imshow("ir", cv::Mat(ir->height, ir->width, CV_32FC1, ir->data) / 20000.0f);
    cv::imshow("depth", cv::Mat(depth->height, depth->width, CV_32FC1, depth->data) / 4500.0f);
    cv::waitKey(1);

    frame_listener.release(frames);
  }

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  rgb_bulk_transfers.disableSubmission();
  depth_iso_transfers.disableSubmission();

  CloseKinect(handle);

  rgb_bulk_transfers.cancel();
  depth_iso_transfers.cancel();

  // wait for all transfers to cancel
  // TODO: better implementation
  libfreenect2::this_thread::sleep_for(libfreenect2::chrono::seconds(2));

  rgb_bulk_transfers.deallocate();
  depth_iso_transfers.deallocate();

  r = libusb_get_device_speed(dev);
  if ((r < 0) || (r > 4))
    r = 0;
  printf("             speed: %s\n", speed_name[r]);

  iface = 0;
  printf("Releasing interface %d...\n", iface);
  libusb_release_interface(handle, iface);

  iface = 1;
  printf("Releasing interface %d...\n", iface);
  libusb_release_interface(handle, iface);

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

  usb_loop.stop();

  libusb_exit(NULL);

  //system("PAUSE");
  return 0;
}
bool ofxCrazyradio::init() {
  int ret = libusb_init(&ctx_);
//  std::cout << "libusb_init: " << ret << std::endl;
//  libusb_set_debug(ctx_, 3);
  
  bool found = false;
  libusb_device **list;
  ssize_t count = libusb_get_device_list(ctx_, &list);
//  std::cout << "libusb_get_device_list: " << count << std::endl;
  for (int i = 0; i < count; i++) {
    struct libusb_device_descriptor desc;
    ret = libusb_get_device_descriptor(list[i], &desc);
    if (desc.idVendor == 0x1915 && desc.idProduct == 0x7777) {
      found = true;
      ret = libusb_open(list[i], &handle_);
//      std::cout << "libusb_open: " << ret << std::endl;
      
//      std::cout << "version: " << std::hex << desc.bcdDevice << std::dec << std::endl;
      
//      uint8_t string_desc[256];
//      ret = libusb_get_string_descriptor_ascii(handle_, desc.iManufacturer, string_desc, 256);
//      std::cout << "libusb_get_string_descriptor_ascii: " << ret << std::endl;
//      std::cout << string_desc << std::endl;
//
      
//      for (int n = 0; n < desc.bNumConfigurations; n++) {
//        libusb_config_descriptor *config_desc;
//        const libusb_interface_descriptor *inter_desc;
//        const libusb_endpoint_descriptor *ep_desc;
//        const libusb_interface *inter;
//        libusb_get_config_descriptor(list[i], n, &config_desc);
//        std::cout << "config: " << (int)config_desc->bConfigurationValue << std::endl;
//        std::cout << "bNumInterfaces: " << (int)config_desc->bNumInterfaces << std::endl;
//        for (int i = 0; i < (int)config_desc->bNumInterfaces; i++) {
//          inter = &config_desc->interface[i];
//          std::cout << "  num_altsetting: " << inter->num_altsetting << std::endl;
//          for (int j = 0; j < inter->num_altsetting; j++) {
//            inter_desc = &inter->altsetting[j];
//            std::cout << "    Interface number: " << (int)inter_desc->bInterfaceNumber << std::endl;
//            std::cout << "    number of endpoint: " << (int)inter_desc->bNumEndpoints << std::endl;
//            for (int k = 0; k < (int)inter_desc->bNumEndpoints; k++) {
//              ep_desc = &inter_desc->endpoint[k];
//              std::cout << "     desc type: " << (int)ep_desc->bDescriptorType << std::endl;
//              std::cout << "     ep address: " << (int)ep_desc->bEndpointAddress << std::endl;
//              std::cout << "     attributes: " << std::hex << (int)ep_desc->bmAttributes << std::dec << std::endl;
//            }
//          }
//        }
//      }
      
//      ret = libusb_kernel_driver_active(handle_, 0);
//      std::cout << "libusb_kernel_driver_active: " << ret << std::endl;
      
      ret = libusb_claim_interface(handle_, 0);
//      std::cout << "libusb_claim_interface: " << ret << std::endl;
      
      libusb_set_configuration(handle_, 1);
      SetDataRate(DR_250KPS);
      SetChannel(2);
      arc_ = -1;
      SetContCarrier(false);
      uint8_t address[] = "\xe7\xe7\xe7\xe7\xe7";
      SetAddress(address);
      SetPower(P_0DBM);
      SetArc(3);
      SetArdBytes(32);
      break;
    }
  }
  libusb_free_device_list(list, 1);
  
  return found;
}
Exemple #3
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;
}
static int 
probe(std::unique_ptr<usb_handle> &h, ifc_match_func callback)
{
	usb_ifc_info info;
	libusb_device_descriptor ddesc;
	libusb_config_descriptor *pcfg;
	int i, j;

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

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

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

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

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

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

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

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

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

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

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

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

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

	libusb_free_config_descriptor(pcfg);
	libusb_close(h->handle);
	return (-1);
}
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;

	

	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;
}
Exemple #6
0
/**
 * Wraps a CDB mass storage command in the appropriate gunk to get it down
 * @param handle
 * @param endpoint
 * @param cdb
 * @param cdb_length
 * @param lun
 * @param flags
 * @param expected_rx_size
 * @return 
 */
int send_usb_mass_storage_command(libusb_device_handle *handle, uint8_t endpoint_out,
                              uint8_t *cdb, uint8_t cdb_length,
                              uint8_t lun, uint8_t flags, uint32_t expected_rx_size) {
    DLOG("Sending usb m-s cmd: cdblen:%d, rxsize=%d\n", cdb_length, expected_rx_size);
    dump_CDB_command(cdb, cdb_length);

    static uint32_t tag;
    if (tag == 0) {
        tag = 1;
    }

    int try = 0;
    int ret = 0;
    int real_transferred;
    int i = 0;

    uint8_t c_buf[STLINK_SG_SIZE];
    // tag is allegedly ignored... TODO - verify
    c_buf[i++] = 'U';
    c_buf[i++] = 'S';
    c_buf[i++] = 'B';
    c_buf[i++] = 'C';
    write_uint32(&c_buf[i], tag);
    uint32_t this_tag = tag++;
    write_uint32(&c_buf[i+4], expected_rx_size);
    i+= 8;
    c_buf[i++] = flags;
    c_buf[i++] = lun;

    c_buf[i++] = cdb_length;

    // Now the actual CDB request
    assert(cdb_length <= CDB_SL);
    memcpy(&(c_buf[i]), cdb, cdb_length);
    
    int sending_length = STLINK_SG_SIZE;
    
    // send....
    do {
        ret = libusb_bulk_transfer(handle, endpoint_out, c_buf, sending_length,
                                   &real_transferred, SG_TIMEOUT_MSEC);
        if (ret == LIBUSB_ERROR_PIPE) {
            libusb_clear_halt(handle, endpoint_out);
        }
        try++;
    } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));
    if (ret != LIBUSB_SUCCESS) {
        WLOG("sending failed: %d\n", ret);
        return -1;
    }
    return this_tag;
}


/**
 * Straight from stm8 stlink code...
 * @param handle
 * @param endpoint_in
 * @param endpoint_out
 */
static void
get_sense(libusb_device_handle *handle, uint8_t endpoint_in, uint8_t endpoint_out)
{
    DLOG("Fetching sense...\n");
    uint8_t cdb[16];
    memset(cdb, 0, sizeof(cdb));
#define REQUEST_SENSE 0x03
#define REQUEST_SENSE_LENGTH 18
    cdb[0] = REQUEST_SENSE;
    cdb[4] = REQUEST_SENSE_LENGTH;
    uint32_t tag = send_usb_mass_storage_command(handle, endpoint_out, cdb, sizeof(cdb), 0,
                                                 LIBUSB_ENDPOINT_IN, REQUEST_SENSE_LENGTH);
    if (tag == 0) {
        WLOG("refusing to send request sense with tag 0\n");
        return;
    }
    unsigned char sense[REQUEST_SENSE_LENGTH];
    int transferred;
    int ret;
    int try = 0;
    do {
        ret = libusb_bulk_transfer(handle, endpoint_in, sense, sizeof(sense),
                                   &transferred, SG_TIMEOUT_MSEC);
        if (ret == LIBUSB_ERROR_PIPE) {
            libusb_clear_halt(handle, endpoint_in);
        }
        try++;
    } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));
    if (ret != LIBUSB_SUCCESS) {
        WLOG("receiving sense failed: %d\n", ret);
        return;
    }
    if (transferred != sizeof(sense)) {
        WLOG("received unexpected amount of sense: %d != %d\n", transferred, sizeof(sense));
    }
    uint32_t received_tag;
    int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag);
    if (status != 0) {
        WLOG("receiving sense failed with status: %02x\n", status);
        return;
    }
    if (sense[0] != 0x70 && sense[0] != 0x71) {
        WLOG("No sense data\n");
    } else {
        WLOG("Sense KCQ: %02X %02X %02X\n", sense[2] & 0x0f, sense[12], sense[13]);
    }
}

/**
 * Just send a buffer on an endpoint, no questions asked.
 * Handles repeats, and time outs.  Also handles reading status reports and sense
 * @param handle libusb device *
 * @param endpoint_out sends 
 * @param endpoint_in used to read status reports back in 
 * @param cbuf  what to send
 * @param length how much to send
 * @return number of bytes actually sent, or -1 for failures.
 */
int send_usb_data_only(libusb_device_handle *handle, unsigned char endpoint_out,
    unsigned char endpoint_in, unsigned char *cbuf, unsigned int length) {
    int ret;
    int real_transferred;
    int try = 0;
    do {
        ret = libusb_bulk_transfer(handle, endpoint_out, cbuf, length,
                                   &real_transferred, SG_TIMEOUT_MSEC);
        if (ret == LIBUSB_ERROR_PIPE) {
            libusb_clear_halt(handle, endpoint_out);
        }
        try++;
    } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));
    if (ret != LIBUSB_SUCCESS) {
        WLOG("sending failed: %d\n", ret);
        return -1;
    }
    
    // now, swallow up the status, so that things behave nicely...
    uint32_t received_tag;
    // -ve is for my errors, 0 is good, +ve is libusb sense status bytes
    int status = get_usb_mass_storage_status(handle, endpoint_in, &received_tag);
    if (status < 0) {
        WLOG("receiving status failed: %d\n", status);
        return -1;
    }
    if (status != 0) {
        WLOG("receiving status not passed :(: %02x\n", status);
    }
    if (status == 1) {
        get_sense(handle, endpoint_in, endpoint_out);
        return -1;
    }
    
    return real_transferred;
}


int stlink_q(stlink_t *sl) {
    struct stlink_libsg* sg = sl->backend_data;
    //uint8_t cdb_len = 6;  // FIXME varies!!!
    uint8_t cdb_len = 10;  // FIXME varies!!!
    uint8_t lun = 0;  // always zero...
    uint32_t tag = send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, 
        sg->cdb_cmd_blk, cdb_len, lun, LIBUSB_ENDPOINT_IN, sl->q_len);
    
    
    // now wait for our response...
    // length copied from stlink-usb...
    int rx_length = sl->q_len;
    int try = 0;
    int real_transferred;
    int ret;
    if (rx_length > 0) {
        do {
            ret = libusb_bulk_transfer(sg->usb_handle, sg->ep_rep, sl->q_buf, rx_length, 
                &real_transferred, SG_TIMEOUT_MSEC);
            if (ret == LIBUSB_ERROR_PIPE) {
                libusb_clear_halt(sg->usb_handle, sg->ep_req);
            }
            try++;
        } while ((ret == LIBUSB_ERROR_PIPE) && (try < 3));

        if (ret != LIBUSB_SUCCESS) {
            WLOG("Receiving failed: %d\n", ret);
            return -1;
        }

        if (real_transferred != rx_length) {
            WLOG("received unexpected amount: %d != %d\n", real_transferred, rx_length);
        }
    }

    uint32_t received_tag;
    // -ve is for my errors, 0 is good, +ve is libusb sense status bytes
    int status = get_usb_mass_storage_status(sg->usb_handle, sg->ep_rep, &received_tag);
    if (status < 0) {
        WLOG("receiving status failed: %d\n", status);
        return -1;
    }
    if (status != 0) {
        WLOG("receiving status not passed :(: %02x\n", status);
    }
    if (status == 1) {
        get_sense(sg->usb_handle, sg->ep_rep, sg->ep_req);
        return -1;
    }
    if (received_tag != tag) {
        WLOG("received tag %d but expected %d\n", received_tag, tag);
        //return -1;
    }
    if (rx_length > 0 && real_transferred != rx_length) {
        return -1;
    }
    return 0;
}

// TODO thinking, cleanup

void stlink_stat(stlink_t *stl, char *txt) {
    if (stl->q_len <= 0)
        return;

    stlink_print_data(stl);

    switch (stl->q_buf[0]) {
        case STLINK_OK:
            DLOG("  %s: ok\n", txt);
            return;
        case STLINK_FALSE:
            DLOG("  %s: false\n", txt);
            return;
        default:
            DLOG("  %s: unknown\n", txt);
    }
}


void _stlink_sg_version(stlink_t *stl) {
    struct stlink_libsg *sl = stl->backend_data;
    clear_cdb(sl);
    sl->cdb_cmd_blk[0] = STLINK_GET_VERSION;
    stl->q_len = 6;
    sl->q_addr = 0;
    stlink_q(stl);
}

// Get stlink mode:
// STLINK_DEV_DFU_MODE || STLINK_DEV_MASS_MODE || STLINK_DEV_DEBUG_MODE
// usb dfu             || usb mass             || jtag or swd

int _stlink_sg_current_mode(stlink_t *stl) {
    struct stlink_libsg *sl = stl->backend_data;
    clear_cdb(sl);
    sl->cdb_cmd_blk[0] = STLINK_GET_CURRENT_MODE;
    stl->q_len = 2;
    sl->q_addr = 0;
    stlink_q(stl);
    return stl->q_buf[0];
}

// Exit the mass mode and enter the swd debug mode.

void _stlink_sg_enter_swd_mode(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER;
    sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_SWD;
    sl->q_len = 0; // >0 -> aboard
    stlink_q(sl);
}

// Exit the mass mode and enter the jtag debug mode.
// (jtag is disabled in the discovery's stlink firmware)

void _stlink_sg_enter_jtag_mode(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_enter_jtag_mode ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_ENTER;
    sg->cdb_cmd_blk[2] = STLINK_DEBUG_ENTER_JTAG;
    sl->q_len = 0;
    stlink_q(sl);
}

// XXX kernel driver performs reset, the device temporally disappears
// Suspect this is no longer the case when we have ignore on? RECHECK
void _stlink_sg_exit_dfu_mode(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_exit_dfu_mode ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[0] = STLINK_DFU_COMMAND;
    sg->cdb_cmd_blk[1] = STLINK_DFU_EXIT;
    sl->q_len = 0; // ??
    stlink_q(sl);
    /*
     [135121.844564] sd 19:0:0:0: [sdb] Unhandled error code
     [135121.844569] sd 19:0:0:0: [sdb] Result: hostbyte=DID_ERROR driverbyte=DRIVER_OK
     [135121.844574] sd 19:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 10 00 00 00 08 00
     [135121.844584] end_request: I/O error, dev sdb, sector 4096
     [135121.844590] Buffer I/O error on device sdb, logical block 512
     [135130.122567] usb 6-1: reset full speed USB device using uhci_hcd and address 7
     [135130.274551] usb 6-1: device firmware changed
     [135130.274618] usb 6-1: USB disconnect, address 7
     [135130.275186] VFS: busy inodes on changed media or resized disk sdb
     [135130.275424] VFS: busy inodes on changed media or resized disk sdb
     [135130.286758] VFS: busy inodes on changed media or resized disk sdb
     [135130.292796] VFS: busy inodes on changed media or resized disk sdb
     [135130.301481] VFS: busy inodes on changed media or resized disk sdb
     [135130.304316] VFS: busy inodes on changed media or resized disk sdb
     [135130.431113] usb 6-1: new full speed USB device using uhci_hcd and address 8
     [135130.629444] usb-storage 6-1:1.0: Quirks match for vid 0483 pid 3744: 102a1
     [135130.629492] scsi20 : usb-storage 6-1:1.0
     [135131.625600] scsi 20:0:0:0: Direct-Access     STM32                          PQ: 0 ANSI: 0
     [135131.627010] sd 20:0:0:0: Attached scsi generic sg2 type 0
     [135131.633603] sd 20:0:0:0: [sdb] 64000 512-byte logical blocks: (32.7 MB/31.2 MiB)
     [135131.633613] sd 20:0:0:0: [sdb] Assuming Write Enabled
     [135131.633620] sd 20:0:0:0: [sdb] Assuming drive cache: write through
     [135131.640584] sd 20:0:0:0: [sdb] Assuming Write Enabled
     [135131.640592] sd 20:0:0:0: [sdb] Assuming drive cache: write through
     [135131.640609]  sdb:
     [135131.652634] sd 20:0:0:0: [sdb] Assuming Write Enabled
     [135131.652639] sd 20:0:0:0: [sdb] Assuming drive cache: write through
     [135131.652645] sd 20:0:0:0: [sdb] Attached SCSI removable disk
     [135131.671536] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
     [135131.671548] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current]
     [135131.671553] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range
     [135131.671560] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00
     [135131.671570] end_request: I/O error, dev sdb, sector 63872
     [135131.671575] Buffer I/O error on device sdb, logical block 7984
     [135131.678527] sd 20:0:0:0: [sdb] Result: hostbyte=DID_OK driverbyte=DRIVER_SENSE
     [135131.678532] sd 20:0:0:0: [sdb] Sense Key : Illegal Request [current]
     [135131.678537] sd 20:0:0:0: [sdb] Add. Sense: Logical block address out of range
     [135131.678542] sd 20:0:0:0: [sdb] CDB: Read(10): 28 00 00 00 f9 80 00 00 08 00
     [135131.678551] end_request: I/O error, dev sdb, sector 63872
     ...
     [135131.853565] end_request: I/O error, dev sdb, sector 4096
     */
}

void _stlink_sg_core_id(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READCOREID;
    sl->q_len = 4;
    sg->q_addr = 0;
    stlink_q(sl);
    sl->core_id = read_uint32(sl->q_buf, 0);
}

// Arm-core reset -> halted state.

void _stlink_sg_reset(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_RESETSYS;
    sl->q_len = 2;
    sg->q_addr = 0;
    stlink_q(sl);
    stlink_stat(sl, "core reset");
}

// Arm-core reset -> halted state.

void _stlink_sg_jtag_reset(stlink_t *sl, int value) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_JTAG_DRIVE_NRST;
    sg->cdb_cmd_blk[2] = (value)?0:1;
    sl->q_len = 3;
    sg->q_addr = 2;
    stlink_q(sl);
    stlink_stat(sl, "core reset");
}

// Arm-core status: halted or running.

void _stlink_sg_status(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_GETSTATUS;
    sl->q_len = 2;
    sg->q_addr = 0;
    stlink_q(sl);
}

// Force the core into the debug mode -> halted state.

void _stlink_sg_force_debug(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_FORCEDEBUG;
    sl->q_len = 2;
    sg->q_addr = 0;
    stlink_q(sl);
    stlink_stat(sl, "force debug");
}

// Read all arm-core registers.

void _stlink_sg_read_all_regs(stlink_t *sl, reg *regp) {
    struct stlink_libsg *sg = sl->backend_data;

    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READALLREGS;
    sl->q_len = 84;
    sg->q_addr = 0;
    stlink_q(sl);
    stlink_print_data(sl);

    // TODO - most of this should be re-extracted up....
    
    // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71   | 72-75      | 76-79 | 80-83
    // r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2
    for (int i = 0; i < 16; i++) {
        regp->r[i] = read_uint32(sl->q_buf, 4 * i);
        if (sl->verbose > 1)
            DLOG("r%2d = 0x%08x\n", i, regp->r[i]);
    }
    regp->xpsr = read_uint32(sl->q_buf, 64);
    regp->main_sp = read_uint32(sl->q_buf, 68);
    regp->process_sp = read_uint32(sl->q_buf, 72);
    regp->rw = read_uint32(sl->q_buf, 76);
    regp->rw2 = read_uint32(sl->q_buf, 80);
    if (sl->verbose < 2)
        return;

    DLOG("xpsr       = 0x%08x\n", regp->xpsr);
    DLOG("main_sp    = 0x%08x\n", regp->main_sp);
    DLOG("process_sp = 0x%08x\n", regp->process_sp);
    DLOG("rw         = 0x%08x\n", regp->rw);
    DLOG("rw2        = 0x%08x\n", regp->rw2);
}

// Read an arm-core register, the index must be in the range 0..20.
//  0  |  1  | ... |  15   |  16   |   17    |   18       |  19   |  20
// r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2

void _stlink_sg_read_reg(stlink_t *sl, int r_idx, reg *regp) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READREG;
    sg->cdb_cmd_blk[2] = r_idx;
    sl->q_len = 4;
    sg->q_addr = 0;
    stlink_q(sl);
    //  0  |  1  | ... |  15   |  16   |   17    |   18       |  19   |  20
    // 0-3 | 4-7 | ... | 60-63 | 64-67 | 68-71   | 72-75      | 76-79 | 80-83
    // r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2
    stlink_print_data(sl);

    uint32_t r = read_uint32(sl->q_buf, 0);
    DLOG("r_idx (%2d) = 0x%08x\n", r_idx, r);

    switch (r_idx) {
        case 16:
            regp->xpsr = r;
            break;
        case 17:
            regp->main_sp = r;
            break;
        case 18:
            regp->process_sp = r;
            break;
        case 19:
            regp->rw = r; //XXX ?(primask, basemask etc.)
            break;
        case 20:
            regp->rw2 = r; //XXX ?(primask, basemask etc.)
            break;
        default:
            regp->r[r_idx] = r;
    }
}

// Write an arm-core register. Index:
//  0  |  1  | ... |  15   |  16   |   17    |   18       |  19   |  20
// r0  | r1  | ... | r15   | xpsr  | main_sp | process_sp | rw    | rw2

void _stlink_sg_write_reg(stlink_t *sl, uint32_t reg, int idx) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEREG;
    //   2: reg index
    // 3-6: reg content
    sg->cdb_cmd_blk[2] = idx;
    write_uint32(sg->cdb_cmd_blk + 3, reg);
    sl->q_len = 2;
    sg->q_addr = 0;
    stlink_q(sl);
    stlink_stat(sl, "write reg");
}

// Write a register of the debug module of the core.
// XXX ?(atomic writes)
// TODO test

void stlink_write_dreg(stlink_t *sl, uint32_t reg, uint32_t addr) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_write_dreg ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEDEBUGREG;
    // 2-5: address of reg of the debug module
    // 6-9: reg content
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint32(sg->cdb_cmd_blk + 6, reg);
    sl->q_len = 2;
    sg->q_addr = addr;
    stlink_q(sl);
    stlink_stat(sl, "write debug reg");
}

// Force the core exit the debug mode.

void _stlink_sg_run(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_RUNCORE;
    sl->q_len = 2;
    sg->q_addr = 0;
    stlink_q(sl);
    stlink_stat(sl, "run core");
}

// Step the arm-core.

void _stlink_sg_step(stlink_t *sl) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_STEPCORE;
    sl->q_len = 2;
    sg->q_addr = 0;
    stlink_q(sl);
    stlink_stat(sl, "step core");
}

// TODO test
// see Cortex-M3 Technical Reference Manual
// TODO make delegate!
void stlink_set_hw_bp(stlink_t *sl, int fp_nr, uint32_t addr, int fp) {
    DLOG("\n*** stlink_set_hw_bp ***\n");
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_SETFP;
    // 2:The number of the flash patch used to set the breakpoint
    // 3-6: Address of the breakpoint (LSB)
    // 7: FP_ALL (0x02) / FP_UPPER (0x01) / FP_LOWER (0x00)
    sl->q_buf[2] = fp_nr;
    write_uint32(sl->q_buf, addr);
    sl->q_buf[7] = fp;

    sl->q_len = 2;
    stlink_q(sl);
    stlink_stat(sl, "set flash breakpoint");
}

// TODO test

// TODO make delegate!
void stlink_clr_hw_bp(stlink_t *sl, int fp_nr) {
    struct stlink_libsg *sg = sl->backend_data;
    DLOG("\n*** stlink_clr_hw_bp ***\n");
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_CLEARFP;
    sg->cdb_cmd_blk[2] = fp_nr;

    sl->q_len = 2;
    stlink_q(sl);
    stlink_stat(sl, "clear flash breakpoint");
}

// Read a "len" bytes to the sl->q_buf from the memory, max 6kB (6144 bytes)

void _stlink_sg_read_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_READMEM_32BIT;
    // 2-5: addr
    // 6-7: len
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint16(sg->cdb_cmd_blk + 6, len);

    // data_in 0-0x40-len
    // !!! len _and_ q_len must be max 6k,
    //     i.e. >1024 * 6 = 6144 -> aboard)
    // !!! if len < q_len: 64*k, 1024*n, n=1..5  -> aboard
    //     (broken residue issue)
    sl->q_len = len;
    sg->q_addr = addr;
    stlink_q(sl);
    stlink_print_data(sl);
}

// Write a "len" bytes from the sl->q_buf to the memory, max 64 Bytes.

void _stlink_sg_write_mem8(stlink_t *sl, uint32_t addr, uint16_t len) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_8BIT;
    // 2-5: addr
    // 6-7: len (>0x40 (64) -> aboard)
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint16(sg->cdb_cmd_blk + 6, len);

    // this sends the command...
    send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0);
    // This sends the data...
    send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len);
    stlink_print_data(sl);
}

// Write a "len" bytes from the sl->q_buf to the memory, max Q_BUF_LEN bytes.

void _stlink_sg_write_mem32(stlink_t *sl, uint32_t addr, uint16_t len) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_DEBUG_WRITEMEM_32BIT;
    // 2-5: addr
    // 6-7: len "unlimited"
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint16(sg->cdb_cmd_blk + 6, len);

    // this sends the command...
    send_usb_mass_storage_command(sg->usb_handle, sg->ep_req, sg->cdb_cmd_blk, CDB_SL, 0, 0, 0);
    // This sends the data...
    send_usb_data_only(sg->usb_handle, sg->ep_req, sg->ep_rep, sl->q_buf, len);

    stlink_print_data(sl);
}

// Write one DWORD data to memory

void _stlink_sg_write_debug32(stlink_t *sl, uint32_t addr, uint32_t data) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_JTAG_WRITEDEBUG_32BIT;
    // 2-5: addr
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    write_uint32(sg->cdb_cmd_blk + 6, data);
    sl->q_len = 2;
    stlink_q(sl);

}

// Read one DWORD data from memory

uint32_t _stlink_sg_read_debug32(stlink_t *sl, uint32_t addr) {
    struct stlink_libsg *sg = sl->backend_data;
    clear_cdb(sg);
    sg->cdb_cmd_blk[1] = STLINK_JTAG_READDEBUG_32BIT;
    // 2-5: addr
    write_uint32(sg->cdb_cmd_blk + 2, addr);
    sl->q_len = 8;
    stlink_q(sl);

    return read_uint32(sl->q_buf, 4);
}

// Exit the jtag or swd mode and enter the mass mode.

void _stlink_sg_exit_debug_mode(stlink_t *stl) {

    if (stl) {
        struct stlink_libsg* sl = stl->backend_data;
        clear_cdb(sl);
        sl->cdb_cmd_blk[1] = STLINK_DEBUG_EXIT;
        stl->q_len = 0; // >0 -> aboard
        stlink_q(stl);
    }
}


// 1) open a sg device, switch the stlink from dfu to mass mode
// 2) wait 5s until the kernel driver stops reseting the broken device
// 3) reopen the device
// 4) the device driver is now ready for a switch to jtag/swd mode
// TODO thinking, better error handling, wait until the kernel driver stops reseting the plugged-in device

stlink_backend_t _stlink_sg_backend = {
    _stlink_sg_close,
    _stlink_sg_exit_debug_mode,
    _stlink_sg_enter_swd_mode,
    _stlink_sg_enter_jtag_mode,
    _stlink_sg_exit_dfu_mode,
    _stlink_sg_core_id,
    _stlink_sg_reset,
    _stlink_sg_jtag_reset,
    _stlink_sg_run,
    _stlink_sg_status,
    _stlink_sg_version,
    _stlink_sg_read_debug32,
    _stlink_sg_read_mem32,
    _stlink_sg_write_debug32,
    _stlink_sg_write_mem32,
    _stlink_sg_write_mem8,
    _stlink_sg_read_all_regs,
    _stlink_sg_read_reg,
    _stlink_sg_write_reg,
    _stlink_sg_step,
    _stlink_sg_current_mode,
    _stlink_sg_force_debug
};

static stlink_t* stlink_open(const int verbose) {
    
    stlink_t *sl = malloc(sizeof (stlink_t));
    memset(sl, 0, sizeof(stlink_t));
    struct stlink_libsg *slsg = malloc(sizeof (struct stlink_libsg));
    if (sl == NULL || slsg == NULL) {
        WLOG("Couldn't malloc stlink and stlink_sg structures out of memory!\n");
        return NULL;
    }
    
    if (libusb_init(&(slsg->libusb_ctx))) {
        WLOG("failed to init libusb context, wrong version of libraries?\n");
        free(sl);
        free(slsg);
        return NULL;
    }
    
    libusb_set_debug(slsg->libusb_ctx, 3);
    
    slsg->usb_handle = libusb_open_device_with_vid_pid(slsg->libusb_ctx, USB_ST_VID, USB_STLINK_PID);
    if (slsg->usb_handle == NULL) {
        WLOG("Failed to find an stlink v1 by VID:PID\n");
        libusb_close(slsg->usb_handle);
        libusb_exit(slsg->libusb_ctx);
        free(sl);
        free(slsg);
        return NULL;
    }
    
    // TODO 
    // Could read the interface config descriptor, and assert lots of the assumptions
    
    // assumption: numInterfaces is always 1...
    if (libusb_kernel_driver_active(slsg->usb_handle, 0) == 1) {
        int r = libusb_detach_kernel_driver(slsg->usb_handle, 0);
        if (r < 0) {
            WLOG("libusb_detach_kernel_driver(() error %s\n", strerror(-r));
            libusb_close(slsg->usb_handle);
            libusb_exit(slsg->libusb_ctx);
            free(sl);
            free(slsg);
            return NULL;
        }
        DLOG("Kernel driver was successfully detached\n");
    }

    int config;
    if (libusb_get_configuration(slsg->usb_handle, &config)) {
        /* this may fail for a previous configured device */
        WLOG("libusb_get_configuration()\n");
        libusb_close(slsg->usb_handle);
        libusb_exit(slsg->libusb_ctx);
        free(sl);
        free(slsg);
        return NULL;

    }
    
    // assumption: bConfigurationValue is always 1
    if (config != 1) {
        WLOG("Your stlink got into a real weird configuration, trying to fix it!\n");
        DLOG("setting new configuration (%d -> 1)\n", config);
        if (libusb_set_configuration(slsg->usb_handle, 1)) {
            /* this may fail for a previous configured device */
            WLOG("libusb_set_configuration() failed\n");
            libusb_close(slsg->usb_handle);
            libusb_exit(slsg->libusb_ctx);
            free(sl);
            free(slsg);
            return NULL;
        }
    }

    if (libusb_claim_interface(slsg->usb_handle, 0)) {
        WLOG("libusb_claim_interface() failed\n");
        libusb_close(slsg->usb_handle);
        libusb_exit(slsg->libusb_ctx);
        free(sl);
        free(slsg);
        return NULL;
    }

    // assumption: endpoint config is fixed mang. really.
    slsg->ep_rep = 1 /* ep rep */ | LIBUSB_ENDPOINT_IN;
    slsg->ep_req = 2 /* ep req */ | LIBUSB_ENDPOINT_OUT;
    
    DLOG("Successfully opened stlinkv1 by libusb :)\n");
    
    sl->verbose = verbose;
    sl->backend_data = slsg;
    sl->backend = &_stlink_sg_backend;

    sl->core_stat = STLINK_CORE_STAT_UNKNOWN;
    slsg->q_addr = 0;

    return sl;
}
hid_device * HID_API_EXPORT hid_open_path(const char *path)
{
	hid_device *dev = NULL;

	dev = new_hid_device();

	libusb_device **devs;
	libusb_device *usb_dev;
	ssize_t num_devs;
	int res;
	int d = 0;
	int good_open = 0;
	
	setlocale(LC_ALL,"");
	
	if (!initialized) {
		libusb_init(NULL);
		initialized = 1;
	}
	
	num_devs = libusb_get_device_list(NULL, &devs);
	while ((usb_dev = devs[d++]) != NULL) {
		struct libusb_device_descriptor desc;
		struct libusb_config_descriptor *conf_desc = NULL;
		int i,j,k;
		libusb_get_device_descriptor(usb_dev, &desc);

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

						// OPEN HERE //
						res = libusb_open(usb_dev, &dev->device_handle);
						if (res < 0) {
							LOG("can't open device\n");
 							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");
								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);
							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;
	}
}
Exemple #8
0
static int icdi_usb_open(struct hl_interface_param_s *param, void **fd)
{
	int retval;
	struct icdi_usb_handle_s *h;

	LOG_DEBUG("icdi_usb_open");

	h = calloc(1, sizeof(struct icdi_usb_handle_s));

	if (h == 0) {
		LOG_ERROR("unable to allocate memory");
		return ERROR_FAIL;
	}

	LOG_DEBUG("transport: %d vid: 0x%04x pid: 0x%04x", param->transport,
		param->vid, param->pid);

	if (libusb_init(&h->usb_ctx) != 0) {
		LOG_ERROR("libusb init failed");
		goto error_open;
	}

	h->usb_dev = libusb_open_device_with_vid_pid(h->usb_ctx, param->vid, param->pid);
	if (!h->usb_dev) {
		LOG_ERROR("open failed");
		goto error_open;
	}

	if (libusb_claim_interface(h->usb_dev, 2)) {
		LOG_DEBUG("claim interface failed");
		goto error_open;
	}

	/* check if mode is supported */
	retval = ERROR_OK;

	switch (param->transport) {
#if 0
		/* TODO place holder as swd is not currently supported */
		case HL_TRANSPORT_SWD:
#endif
		case HL_TRANSPORT_JTAG:
			break;
		default:
			retval = ERROR_FAIL;
			break;
	}

	if (retval != ERROR_OK) {
		LOG_ERROR("mode (transport) not supported by device");
		goto error_open;
	}

	/* allocate buffer */
	h->read_buffer = malloc(ICDI_PACKET_SIZE);
	h->write_buffer = malloc(ICDI_PACKET_SIZE);
	h->max_packet = ICDI_PACKET_SIZE;

	if (h->read_buffer == 0 || h->write_buffer == 0) {
		LOG_DEBUG("malloc failed");
		goto error_open;
	}

	/* query icdi version etc */
	retval = icdi_usb_version(h);
	if (retval != ERROR_OK)
		goto error_open;

	/* query icdi support */
	retval = icdi_usb_query(h);
	if (retval != ERROR_OK)
		goto error_open;

	*fd = h;

	/* set the max target read/write buffer in bytes
	 * as we are using gdb binary packets to transfer memory we have to
	 * reserve half the buffer for any possible escape chars plus
	 * at least 64 bytes for the gdb packet header */
	h->max_rw_packet = (((h->max_packet - 64) / 4) * 4) / 2;

	return ERROR_OK;

error_open:
	icdi_usb_close(h);

	return ERROR_FAIL;
}
int fnusb_open_subdevices(freenect_device *dev, int index)
{
	freenect_context *ctx = dev->parent;

	dev->usb_cam.parent = dev;
	dev->usb_cam.dev = NULL;
	dev->usb_motor.parent = dev;
	dev->usb_motor.dev = NULL;

	libusb_device **devs; //pointer to pointer of device, used to retrieve a list of devices
	ssize_t cnt = libusb_get_device_list (dev->parent->usb.ctx, &devs); //get the list of devices
	if (cnt < 0)
		return -1;

	int i = 0, nr_cam = 0, nr_mot = 0;
	int res;
	struct libusb_device_descriptor desc;

	for (i = 0; i < cnt; i++) {
		int r = libusb_get_device_descriptor (devs[i], &desc);
		if (r < 0)
			continue;

		if (desc.idVendor != VID_MICROSOFT)
			continue;

		// Search for the camera
		if (!dev->usb_cam.dev && desc.idProduct == PID_NUI_CAMERA) {
			// If the index given by the user matches our camera index
			if (nr_cam == index) {
				res = libusb_open (devs[i], &dev->usb_cam.dev);
				if (res < 0 || !dev->usb_cam.dev) {
					FN_ERROR("Could not open camera: %d\n", res);
					dev->usb_cam.dev = NULL;
					break;
				}
				res = libusb_claim_interface (dev->usb_cam.dev, 0);
				if (res < 0) {
					FN_ERROR("Could not claim interface on camera: %d\n", res);
					libusb_close(dev->usb_cam.dev);
					dev->usb_cam.dev = NULL;
					break;
				}
			} else {
				nr_cam++;
			}
		}

		// Search for the motor
		if (!dev->usb_motor.dev && desc.idProduct == PID_NUI_MOTOR) {
			// If the index given by the user matches our camera index
			if (nr_mot == index) {
				res = libusb_open (devs[i], &dev->usb_motor.dev);
				if (res < 0 || !dev->usb_motor.dev) {
					FN_ERROR("Could not open motor: %d\n", res);
					dev->usb_motor.dev = NULL;
					break;
				}
				res = libusb_claim_interface (dev->usb_motor.dev, 0);
				if (res < 0) {
					FN_ERROR("Could not claim interface on motor: %d\n", res);
					libusb_close(dev->usb_motor.dev);
					dev->usb_motor.dev = NULL;
					break;
				}
			} else {
				nr_mot++;
			}
		}
	}

	libusb_free_device_list (devs, 1);  // free the list, unref the devices in it

	if (dev->usb_cam.dev && dev->usb_motor.dev) {
		return 0;
	} else {
		if (dev->usb_cam.dev) {
			libusb_release_interface(dev->usb_cam.dev, 0);
			libusb_close(dev->usb_cam.dev);
		}
		if (dev->usb_motor.dev) {
			libusb_release_interface(dev->usb_motor.dev, 0);
			libusb_close(dev->usb_motor.dev);
		}
		return -1;
	}
}
Exemple #10
0
int main(int argc, char*argv[])
{
    fx_known_device known_device[] = FX_KNOWN_DEVICES;
    const char *path[] = { NULL, NULL };
    const char *device_id = NULL;
    const char *device_path = getenv("DEVICE");
    const char *type = NULL;
    const char *fx_name[FX_TYPE_MAX] = FX_TYPE_NAMES;
    const char *ext, *img_name[] = IMG_TYPE_NAMES;
    int fx_type = FX_TYPE_UNDEFINED, img_type[ARRAYSIZE(path)];
    int i, j, opt, status;
    unsigned vid = 0, pid = 0;
    unsigned busnum = 0, devaddr = 0, _busnum, _devaddr;
    libusb_device *dev, **devs;
    libusb_device_handle *device = NULL;
    struct libusb_device_descriptor desc;

    while ((opt = getopt(argc, argv, "qvV?hd:p:i:I:t:")) != EOF)
        switch (opt) {

        case 'd':
            device_id = optarg;
            if (sscanf(device_id, "%x:%x" , &vid, &pid) != 2 ) {
                fputs ("please specify VID & PID as \"vid:pid\" in hexadecimal format\n", stderr);
                return -1;
            }
            break;

        case 'p':
            device_path = optarg;
            if (sscanf(device_path, "%u,%u", &busnum, &devaddr) != 2 ) {
                fputs ("please specify bus number & device number as \"bus,dev\" in decimal format\n", stderr);
                return -1;
            }
            break;

        case 'i':
        case 'I':
            path[FIRMWARE] = optarg;
            break;

        case 'V':
            puts(FXLOAD_VERSION);
            return 0;

        case 't':
            type = optarg;
            break;

        case 'v':
            verbose++;
            break;

        case 'q':
            verbose--;
            break;

        case '?':
        case 'h':
        default:
            return print_usage(-1);

    }

    if (path[FIRMWARE] == NULL) {
        logerror("no firmware specified!\n");
        return print_usage(-1);
    }
    if ((device_id != NULL) && (device_path != NULL)) {
        logerror("only one of -d or -p can be specified\n");
        return print_usage(-1);
    }

    /* determine the target type */
    if (type != NULL) {
        for (i=0; i<FX_TYPE_MAX; i++) {
            if (strcmp(type, fx_name[i]) == 0) {
                fx_type = i;
                break;
            }
        }
        if (i >= FX_TYPE_MAX) {
            logerror("illegal microcontroller type: %s\n", type);
            return print_usage(-1);
        }
    }

    /* open the device using libusb */
    status = libusb_init(NULL);
    if (status < 0) {
        logerror("libusb_init() failed: %s\n", libusb_error_name(status));
        return -1;
    }
    libusb_set_debug(NULL, verbose);

    /* try to pick up missing parameters from known devices */
    if ((type == NULL) || (device_id == NULL) || (device_path != NULL))
    {
        if (libusb_get_device_list(NULL, &devs) < 0)
        {
            logerror("libusb_get_device_list() failed: %s\n", libusb_error_name(status));
            goto err;
        }
        for (i=0; (dev=devs[i]) != NULL; i++)
        {
            _busnum = libusb_get_bus_number(dev);
            _devaddr = libusb_get_device_address(dev);
            if ((type != NULL) && (device_path != NULL))
            {
                printf("Check Point 1\n");
                // if both a type and bus,addr were specified, we just need to find our match
                if ((libusb_get_bus_number(dev) == busnum) && (libusb_get_device_address(dev) == devaddr))
                {
                  printf("Check Point 2\n");
                    break;
                }
            }
            else
            {
                status = libusb_get_device_descriptor(dev, &desc);
                if (status >= 0)
                {
                    if (verbose >= 3)
                    {
                        logerror("examining %04x:%04x (%d,%d)\n",
                            desc.idVendor, desc.idProduct, _busnum, _devaddr);
                    }
                    for (j=0; j<ARRAYSIZE(known_device); j++)
                    {
                        if ((desc.idVendor == known_device[j].vid)
                            && (desc.idProduct == known_device[j].pid))
                            {
                            printf("Check Point 3\n");
                            if (// nothing was specified
                                ((type == NULL) && (device_id == NULL) && (device_path == NULL)) ||
                                // vid:pid was specified and we have a match
                                ((type == NULL) && (device_id != NULL) && (vid == desc.idVendor) && (pid == desc.idProduct)) ||
                                // bus,addr was specified and we have a match
                                ((type == NULL) && (device_path != NULL) && (busnum == _busnum) && (devaddr == _devaddr)) ||
                                // type was specified and we have a match
                                ((type != NULL) && (device_id == NULL) && (device_path == NULL) && (fx_type == known_device[j].type)) )
                              {
                                printf("Check Point 4\n");
                                fx_type = known_device[j].type;
                                vid = desc.idVendor;
                                pid = desc.idProduct;
                                busnum = _busnum;
                                devaddr = _devaddr;
                                break;
                              }
                            }
                            printf("Check Point 5\n");
                    }

                    if (j < ARRAYSIZE(known_device))
                    {
                      printf("Check Point 6\n");
                        if (verbose)
                            logerror("found device '%s' [%04x:%04x] (%d,%d)\n",
                                known_device[j].designation, vid, pid, busnum, devaddr);
                        break;
                    }
                }
            }
        }
        if (dev == NULL) {
            printf("Check Point 7\n");
            libusb_free_device_list(devs, 1);
            logerror("could not find a known device - please specify type and/or vid:pid and/or bus,dev\n");
            return print_usage(-1);
        }
        status = libusb_open(dev, &device);
        if (status < 0) {
            logerror("libusb_open() failed: %s\n", libusb_error_name(status));
            goto err;
        }
        libusb_free_device_list(devs, 1);
    } else if (device_id != NULL) {
        printf("Check Point 9\n");
        printf("Check Point 9  vid %d\n", pid);
        printf("Check Point 9  pid %d\n", vid);
        device = libusb_open_device_with_vid_pid(NULL, (uint16_t)vid, (uint16_t)pid);
        if (device == NULL) {
            logerror("libusb_open() failed\n");
            goto err;
        }
    }

    /* We need to claim the first interface */
    printf("Check Point 10\n");
    libusb_set_auto_detach_kernel_driver(device, 1);
    status = libusb_claim_interface(device, 0);
    if (status != LIBUSB_SUCCESS) {
        logerror("libusb_claim_interface failed: %s\n", libusb_error_name(status));
        goto err;
    }

    if (verbose)
        logerror("microcontroller type: %s\n", fx_name[fx_type]);

    for (i=0; i<ARRAYSIZE(path); i++) {
        if (path[i] != NULL) {
            ext = path[i] + strlen(path[i]) - 4;
            if ((_stricmp(ext, ".hex") == 0) || (strcmp(ext, ".ihx") == 0))
                img_type[i] = IMG_TYPE_HEX;
            else if (_stricmp(ext, ".iic") == 0)
                img_type[i] = IMG_TYPE_IIC;
            else if (_stricmp(ext, ".bix") == 0)
                img_type[i] = IMG_TYPE_BIX;
            else if (_stricmp(ext, ".img") == 0)
                img_type[i] = IMG_TYPE_IMG;
            else {
                logerror("%s is not a recognized image type\n", path[i]);
                goto err;
            }
        }
        if (verbose && path[i] != NULL)
            logerror("%s: type %s\n", path[i], img_name[img_type[i]]);
    }

    printf("Check Point 11\n");
    printf("Check Point 11  img_type[FIRMWARE]  %d\n", img_type[FIRMWARE]);
    printf("Check Point 11  fx_type  %d\n", fx_type);

    /* single stage, put into internal memory */
    if (verbose > 1)
        logerror("single stage: load on-chip memory\n");
    status = ezusb_load_ram(device, path[FIRMWARE], fx_type, img_type[FIRMWARE], 0);

    libusb_release_interface(device, 0);
    libusb_close(device);
    libusb_exit(NULL);
    return status;
err:
    libusb_exit(NULL);
    return -1;
}
Exemple #11
0
int main(int argc, char **argv) {
    struct libusb_device_descriptor desc;
    const struct t_pid *ppid = pidtab;
    ssize_t nr;
    int offset = 0, size = 0;
    uint16_t crc16;
    uint8_t flag = 0;
    char action;
    char *partname = NULL;

    info("rkflashtool v%d.%d\n", RKFLASHTOOL_VERSION_MAJOR,
                                 RKFLASHTOOL_VERSION_MINOR);

    NEXT; if (!argc) usage();

    action = **argv; NEXT;

    switch(action) {
    case 'b':
        if (argc > 1) usage();
        else if (argc == 1)
            flag = strtoul(argv[0], NULL, 0);
        break;
    case 'l':
    case 'L':
        if (argc) usage();
        break;
    case 'e':
    case 'r':
    case 'w':
        if (argc < 1 || argc > 2) usage();
        if (argc == 1) {
            partname = argv[0];
        } else {
            offset = strtoul(argv[0], NULL, 0);
            size   = strtoul(argv[1], NULL, 0);
        }
        break;
    case 'm':
    case 'M':
    case 'B':
    case 'i':
        if (argc != 2) usage();
        offset = strtoul(argv[0], NULL, 0);
        size   = strtoul(argv[1], NULL, 0);
        break;
    case 'n':
    case 'v':
    case 'p':
    case 'P':
        if (argc) usage();
        offset = 0;
        size   = 1024;
        break;
    default:
        usage();
    }

    /* Initialize libusb */

    if (libusb_init(&c)) fatal("cannot init libusb\n");

    libusb_set_debug(c, 3);

    /* Detect connected RockChip device */

    while ( !h && ppid->pid) {
        h = libusb_open_device_with_vid_pid(c, 0x2207, ppid->pid);
        if (h) {
            info("Detected %s...\n", ppid->name);
            break;
        }
        ppid++;
    }
    if (!h) fatal("cannot open device\n");

    /* Connect to device */

    if (libusb_kernel_driver_active(h, 0) == 1) {
        info("kernel driver active\n");
        if (!libusb_detach_kernel_driver(h, 0))
            info("driver detached\n");
    }

    if (libusb_claim_interface(h, 0) < 0)
        fatal("cannot claim interface\n");
    info("interface claimed\n");

    if (libusb_get_device_descriptor(libusb_get_device(h), &desc) != 0)
        fatal("cannot get device descriptor\n");

    if (desc.bcdUSB == 0x200)
        info("MASK ROM MODE\n");

    switch(action) {
    case 'l':
        info("load DDR init\n");
        crc16 = 0xffff;
        while ((nr = read(0, buf, 4096)) == 4096) {
            crc16 = rkcrc16(crc16, buf, nr);
            libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, nr, 0);
        }
        if (nr != -1) {
            crc16 = rkcrc16(crc16, buf, nr);
            buf[nr++] = crc16 >> 8;
            buf[nr++] = crc16 & 0xff;
            libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1137, buf, nr, 0);
        }
        goto exit;
    case 'L':
        info("load USB loader\n");
        crc16 = 0xffff;
        while ((nr = read(0, buf, 4096)) == 4096) {
            crc16 = rkcrc16(crc16, buf, nr);
            libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, nr, 0);
        }
        if (nr != -1) {
            crc16 = rkcrc16(crc16, buf, nr);
            buf[nr++] = crc16 >> 8;
            buf[nr++] = crc16 & 0xff;
            libusb_control_transfer(h, LIBUSB_REQUEST_TYPE_VENDOR, 12, 0, 1138, buf, nr, 0);
        }
static bool CheckDeviceAccess(libusb_device* device)
{
	int ret;
	libusb_device_descriptor desc;
	int dRet = libusb_get_device_descriptor(device, &desc);
	if (dRet)
	{
		// could not acquire the descriptor, no point in trying to use it.
		ERROR_LOG(SERIALINTERFACE, "libusb_get_device_descriptor failed with error: %d", dRet);
		return false;
	}

	if (desc.idVendor == 0x057e && desc.idProduct == 0x0337)
	{
		NOTICE_LOG(SERIALINTERFACE, "Found GC Adapter with Vendor: %X Product: %X Devnum: %d", desc.idVendor, desc.idProduct, 1);

		u8 bus = libusb_get_bus_number(device);
		u8 port = libusb_get_device_address(device);
		ret = libusb_open(device, &s_handle);
		if (ret)
		{
			if (ret == LIBUSB_ERROR_ACCESS)
			{
				if (dRet)
				{
					ERROR_LOG(SERIALINTERFACE, "Dolphin does not have access to this device: Bus %03d Device %03d: ID ????:???? (couldn't get id).",
						bus,
						port
						);
				}
				else
				{
					ERROR_LOG(SERIALINTERFACE, "Dolphin does not have access to this device: Bus %03d Device %03d: ID %04X:%04X.",
						bus,
						port,
						desc.idVendor,
						desc.idProduct
						);
				}
			}
			else
			{
				ERROR_LOG(SERIALINTERFACE, "libusb_open failed to open device with error = %d", ret);
				if (ret == LIBUSB_ERROR_NOT_SUPPORTED)
					s_libusb_driver_not_supported = true;
			}
			return false;
		}
		else if ((ret = libusb_kernel_driver_active(s_handle, 0)) == 1)
		{
			if ((ret = libusb_detach_kernel_driver(s_handle, 0)) && ret != LIBUSB_ERROR_NOT_SUPPORTED)
			{
				ERROR_LOG(SERIALINTERFACE, "libusb_detach_kernel_driver failed with error: %d", ret);
			}
		}
		// this split is needed so that we don't avoid claiming the interface when
		// detaching the kernel driver is successful
		if (ret != 0 && ret != LIBUSB_ERROR_NOT_SUPPORTED)
		{
			return false;
		}
		else if ((ret = libusb_claim_interface(s_handle, 0)))
		{
			ERROR_LOG(SERIALINTERFACE, "libusb_claim_interface failed with error: %d", ret);
		}
		else
		{
			return true;
		}
	}
	return false;
}
Exemple #13
0
int main(int argc, char **argv)
{
	libusb_device_handle *handle;
	unsigned char buf[1024];
	int length;
	int actual_length;
	int i;
	int res;
	
	if (argc < 2) {
		fprintf(stderr, "%s: [bytes to send]\n", argv[0]);
		return 1;
	}

	length = atoi(argv[1]);
	if (length > sizeof(buf))
		length = sizeof(buf);

	printf("Sending %d bytes\n", length);

	/* Init Libusb */
	if (libusb_init(NULL))
		return -1;

	handle = libusb_open_device_with_vid_pid(NULL, 0xa0a0, 0x0001);
	if (!handle) {
		perror("libusb_open failed: ");
		return 1;
	}
	
	res = libusb_claim_interface(handle, 0);
	if (res < 0) {
		perror("claim interface");
		return 1;
	}

	for (i = 0; i < sizeof(buf); i++) {
		buf[i] = i;
	}

	/* Send some data to the device */
	res = libusb_bulk_transfer(handle, 0x01, buf, length, &actual_length, 5000);
	if (res < 0) {
		fprintf(stderr, "bulk transfer (out): %s\n", libusb_error_name(res));
		return 1;
	}

	/* Receive data from the device */
	res = libusb_bulk_transfer(handle, 0x81, buf, length, &actual_length, 5000);
	if (res < 0) {
		fprintf(stderr, "bulk transfer (in): %s\n", libusb_error_name(res));
		return 1;
	}
	for (i = 0; i < actual_length; i++) {
		printf("%02hhx ", buf[i]);
		if ((i+1) % 8 == 0)
			printf("   ");
		if ((i+1) % 16 == 0)
			printf("\n");
	}
	printf("\n\n");


	return 0;
}
Exemple #14
0
int musb_open(MUSB_INTERFACE **musb_interface, int vendor, int product, int instance, int configuration, int usbinterface)
{
#if defined(HAVE_LIBUSB)
   
   struct usb_bus *bus;
   struct usb_device *dev;
   int count = 0;
   
   usb_init();
   usb_find_busses();
   usb_find_devices();
   usb_set_debug(3);
   
   for (bus = usb_get_busses(); bus; bus = bus->next)
      for (dev = bus->devices; dev; dev = dev->next)
         if (dev->descriptor.idVendor == vendor && dev->descriptor.idProduct == product) {
            if (count == instance) {
               int status;
               usb_dev_handle *udev;

               udev = usb_open(dev);
               if (!udev) {
                  fprintf(stderr, "musb_open: usb_open() error\n");
                  return MUSB_ACCESS_ERROR;
               }

               status = usb_set_configuration(udev, configuration);
               if (status < 0) {
                  fprintf(stderr, "musb_open: usb_set_configuration() error %d (%s)\n", status,
                     strerror(-status));
                  fprintf(stderr,
                     "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\" and \"/dev/bus/usb/%s/%s\"\n",
                     vendor, product, instance, bus->dirname, dev->filename, bus->dirname, dev->filename);
                  return MUSB_ACCESS_ERROR;
               }

               /* see if we have write access */
               status = usb_claim_interface(udev, usbinterface);
               if (status < 0) {
                  fprintf(stderr, "musb_open: usb_claim_interface() error %d (%s)\n", status,
                     strerror(-status));

#ifdef _MSC_VER
                  fprintf(stderr,
                     "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n",
                     vendor, product, instance);
#else
                  fprintf(stderr,
                     "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%s/%s\"\n",
                     vendor, product, instance, bus->dirname, dev->filename);
#endif

                  return MUSB_ACCESS_ERROR;
               }

               *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE));
               (*musb_interface)->dev = udev;
               (*musb_interface)->usb_configuration = configuration;
               (*musb_interface)->usb_interface     = usbinterface;
               return MUSB_SUCCESS;
            }

            count++;
         }
   
   return MUSB_NOT_FOUND;
   
#elif defined(HAVE_LIBUSB10)
   
   static int first_call = 1;

   libusb_device **dev_list;
   libusb_device_handle *dev;
   struct libusb_device_descriptor desc;
   
   int status, i, n;
   int count = 0;
   
   if (first_call) {
      first_call = 0;
      libusb_init(NULL);
      // libusb_set_debug(NULL, 3);
   }
      
   n = libusb_get_device_list(NULL, &dev_list);
   
   for (i=0 ; i<n ; i++) {
      status = libusb_get_device_descriptor(dev_list[i], &desc);
      if (desc.idVendor == vendor && desc.idProduct == product) {
         if (count == instance) {
            status = libusb_open(dev_list[i], &dev);
            if (status < 0) {
               fprintf(stderr, "musb_open: libusb_open() error %d\n", status);
               return MUSB_ACCESS_ERROR;
            }

            status = libusb_set_configuration(dev, configuration);
            if (status < 0) {
               fprintf(stderr, "musb_open: usb_set_configuration() error %d\n", status);
               fprintf(stderr,
                       "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\" and \"/dev/bus/usb/%d/%d\"\n",
                       vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]), libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]));
               return MUSB_ACCESS_ERROR;
            }
            
            /* see if we have write access */
            status = libusb_claim_interface(dev, usbinterface);
            if (status < 0) {
               fprintf(stderr, "musb_open: libusb_claim_interface() error %d\n", status);
               
#ifdef _MSC_VER
               fprintf(stderr,
                       "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it:\nDevice is probably used by another program\n",
                       vendor, product, instance);
#else
               fprintf(stderr,
                       "musb_open: Found USB device 0x%04x:0x%04x instance %d, but cannot initialize it: please check permissions on \"/proc/bus/usb/%d/%d\"\n",
                       vendor, product, instance, libusb_get_bus_number(dev_list[i]), libusb_get_device_address(dev_list[i]));
#endif
               
               return MUSB_ACCESS_ERROR;
            }

            *musb_interface = (MUSB_INTERFACE*)calloc(1, sizeof(MUSB_INTERFACE));
            (*musb_interface)->dev = dev;
            (*musb_interface)->usb_configuration = configuration;
            (*musb_interface)->usb_interface     = usbinterface;
            return MUSB_SUCCESS;

         }
         count++;
      }
   }
   
   libusb_free_device_list(dev_list, 1);
   
   return MUSB_NOT_FOUND;
     
#elif defined(OS_DARWIN)
   
   kern_return_t status;
   io_iterator_t iter;
   io_service_t service;
   IOCFPlugInInterface **plugin;
   SInt32 score;
   IOUSBDeviceInterface **device;
   UInt16 xvendor, xproduct;
   int count = 0;

   *musb_interface = calloc(1, sizeof(MUSB_INTERFACE));
   
   status = IORegistryCreateIterator(kIOMasterPortDefault, kIOUSBPlane, kIORegistryIterateRecursively, &iter);
   assert(status == kIOReturnSuccess);

   while ((service = IOIteratorNext(iter))) {
      status =
          IOCreatePlugInInterfaceForService(service, kIOUSBDeviceUserClientTypeID, kIOCFPlugInInterfaceID,
                                            &plugin, &score);
      assert(status == kIOReturnSuccess);

      status = IOObjectRelease(service);
      assert(status == kIOReturnSuccess);

      status =
          (*plugin)->QueryInterface(plugin, CFUUIDGetUUIDBytes(kIOUSBDeviceInterfaceID), (void *) &device);
      assert(status == kIOReturnSuccess);

      status = (*plugin)->Release(plugin);

      status = (*device)->GetDeviceVendor(device, &xvendor);
      assert(status == kIOReturnSuccess);
      status = (*device)->GetDeviceProduct(device, &xproduct);
      assert(status == kIOReturnSuccess);

      //fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x\n", xvendor, xproduct);

      if (xvendor == vendor && xproduct == product) {
         if (count == instance) {

            fprintf(stderr, "musb_open: Found USB device: vendor 0x%04x, product 0x%04x, instance %d\n", xvendor, xproduct, instance);

            status = (*device)->USBDeviceOpen(device);
            fprintf(stderr, "musb_open: USBDeviceOpen status 0x%x\n", status);

            assert(status == kIOReturnSuccess);

            (*musb_interface)->usb_configuration = configuration;
            (*musb_interface)->usb_interface     = usbinterface;
            (*musb_interface)->device = (void*)device;
            (*musb_interface)->interface = NULL;

            status = darwin_configure_device(*musb_interface);

            if (status == kIOReturnSuccess)
               return MUSB_SUCCESS;

            fprintf(stderr, "musb_open: USB device exists, but configuration fails!");
            return MUSB_NOT_FOUND;
         }

         count++;
      }

      (*device)->Release(device);
   }

   return MUSB_NOT_FOUND;
#elif defined(_MSC_VER)
   GUID guid;
   HDEVINFO hDevInfoList;
   SP_DEVICE_INTERFACE_DATA deviceInfoData;
   PSP_DEVICE_INTERFACE_DETAIL_DATA functionClassDeviceData;
   ULONG predictedLength, requiredLength;
   int status;
   char device_name[256], str[256];

   *musb_interface = (MUSB_INTERFACE *)calloc(1, sizeof(MUSB_INTERFACE));

   guid = GUID_CLASS_MSCB_BULK;

   // Retrieve device list for GUID that has been specified.
   hDevInfoList = SetupDiGetClassDevs(&guid, NULL, NULL, (DIGCF_PRESENT | DIGCF_DEVICEINTERFACE));

   status = FALSE;
   if (hDevInfoList != NULL) {

      // Clear data structure
      memset(&deviceInfoData, 0, sizeof(deviceInfoData));
      deviceInfoData.cbSize = sizeof(SP_DEVICE_INTERFACE_DATA);

      // retrieves a context structure for a device interface of a device information set.
      if (SetupDiEnumDeviceInterfaces(hDevInfoList, 0, &guid, instance, &deviceInfoData)) {
         // Must get the detailed information in two steps
         // First get the length of the detailed information and allocate the buffer
         // retrieves detailed information about a specified device interface.
         functionClassDeviceData = NULL;

         predictedLength = requiredLength = 0;

         SetupDiGetDeviceInterfaceDetail(hDevInfoList, &deviceInfoData, NULL,   // Not yet allocated
                                         0,     // Set output buffer length to zero
                                         &requiredLength,       // Find out memory requirement
                                         NULL);

         predictedLength = requiredLength;
         functionClassDeviceData = (PSP_DEVICE_INTERFACE_DETAIL_DATA) malloc(predictedLength);
         functionClassDeviceData->cbSize = sizeof(SP_DEVICE_INTERFACE_DETAIL_DATA);

         // Second, get the detailed information
         if (SetupDiGetDeviceInterfaceDetail(hDevInfoList,
                                             &deviceInfoData, functionClassDeviceData,
                                             predictedLength, &requiredLength, NULL)) {

            // Save the device name for subsequent pipe open calls
            strcpy(device_name, functionClassDeviceData->DevicePath);
            free(functionClassDeviceData);

            // Signal device found
            status = TRUE;
         } else
            free(functionClassDeviceData);
      }
   }
   // SetupDiDestroyDeviceInfoList() destroys a device information set
   // and frees all associated memory.
   SetupDiDestroyDeviceInfoList(hDevInfoList);

   if (status) {

      // Get the read handle
      sprintf(str, "%s\\PIPE00", device_name);
      (*musb_interface)->rhandle = CreateFile(str,
                                    GENERIC_WRITE | GENERIC_READ,
                                    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL,
                                    OPEN_EXISTING, FILE_FLAG_OVERLAPPED, NULL);

      if ((*musb_interface)->rhandle == INVALID_HANDLE_VALUE)
         return MUSB_ACCESS_ERROR;

      // Get the write handle
      sprintf(str, "%s\\PIPE01", device_name);
      (*musb_interface)->whandle = CreateFile(str,
                                    GENERIC_WRITE | GENERIC_READ,
                                    FILE_SHARE_WRITE | FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, NULL);

      if ((*musb_interface)->whandle == INVALID_HANDLE_VALUE)
         return MUSB_ACCESS_ERROR;

      return MUSB_SUCCESS;
   } 
     
   return MUSB_NOT_FOUND;
#endif
}
Exemple #15
0
///////////////////////////////////////////////////////////////////////////////
///@author      Nicolae Bodislav
///@brief       Writes data from the USB device on bulk.
///@param       [in]p_pData - the buffer that contains the data to write
///@param       [in]p_nLength - size of the data contained in the buffer
///@retval      how many bytes were actually written; or < 0 for error
///////////////////////////////////////////////////////////////////////////////
int CUSBLink::WriteBulk(const unsigned char* p_pData, uint32_t p_nLength)
{
    m_nCb = 0;
    m_nTrasferedLength = 0;
    if(p_nLength > MAX_LENGTH)
    {
         NLOG_ERR("[CUSBLink][WriteBulk] To much data to write. Maz is %d", MAX_LENGTH);
         return -1;
    }

    if(m_pDevh == NULL)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] Device not open.");
        return -1;
    }

    int rez = libusb_claim_interface(m_pDevh, 0);
    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] USB_claim_interface error %d\n", rez);
        return -2;
    }

    m_enumDealoc = CUSBLink::INTERFACE;

    m_pData_transfer = NULL;
    m_pData_transfer = libusb_alloc_transfer(0);
    if (!m_pData_transfer)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] Transfer couldn't be allocated.");
        return -ENOMEM;
    }

    libusb_fill_bulk_transfer(m_pData_transfer, m_pDevh, m_cWriteEndpoint, (unsigned char*)p_pData, p_nLength, Cb_TransferRead, this, 1000);

    m_enumDealoc = CUSBLink::TRANSFER;


    rez = libusb_submit_transfer(m_pData_transfer);

    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][WriteBulk] Transfer couldn't be submitted.");

        libusb_cancel_transfer(m_pData_transfer);
        m_enumDealoc = CUSBLink::INTERFACE;

        while (!m_nCb)
        {   rez = libusb_handle_events(m_pContex);
            if (rez < 0)
            {   break;
            }
        }

        libusb_free_transfer(m_pData_transfer);

        return -1;
    }

    while (!m_nCb)
    {
        rez = libusb_handle_events(m_pContex);
        if (rez < 0)
        {
            libusb_free_transfer(m_pData_transfer);
            return -1;
        }
    }

    if (m_bRawLog)
    {   NLOG_DBG_HEX("[CUSBLink][WriteBulk] Wrote packet:", p_pData, m_nTrasferedLength);
    }

    return m_nTrasferedLength;
}
Exemple #16
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) {
      logd ("Expected Error libusb_get_config_descriptor usb_err: %d (%s)", usb_err, iusb_error_get (usb_err));    // !! ???? Normal error now ???
      //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);
  }
dc_status_t
atomics_cobalt_device_open (dc_device_t **out, dc_context_t *context)
{
	if (out == NULL)
		return DC_STATUS_INVALIDARGS;

#ifdef HAVE_LIBUSB
	// Allocate memory.
	atomics_cobalt_device_t *device = (atomics_cobalt_device_t *) malloc (sizeof (atomics_cobalt_device_t));
	if (device == NULL) {
		ERROR (context, "Failed to allocate memory.");
		return DC_STATUS_NOMEMORY;
	}

	// Initialize the base class.
	device_init (&device->base, context, &atomics_cobalt_device_vtable);

	// Set the default values.
	device->context = NULL;
	device->handle = NULL;
	device->simulation = 0;
	memset (device->fingerprint, 0, sizeof (device->fingerprint));

	int rc = libusb_init (&device->context);
	if (rc < 0) {
		ERROR (context, "Failed to initialize usb support.");
		free (device);
		return DC_STATUS_IO;
	}

	device->handle = libusb_open_device_with_vid_pid (device->context, VID, PID);
	if (device->handle == NULL) {
		ERROR (context, "Failed to open the usb device.");
		libusb_exit (device->context);
		free (device);
		return DC_STATUS_IO;
	}

	rc = libusb_claim_interface (device->handle, 0);
	if (rc < 0) {
		ERROR (context, "Failed to claim the usb interface.");
		libusb_close (device->handle);
		libusb_exit (device->context);
		free (device);
		return DC_STATUS_IO;
	}

	dc_status_t status = atomics_cobalt_device_version ((dc_device_t *) device, device->version, sizeof (device->version));
	if (status != DC_STATUS_SUCCESS) {
		ERROR (context, "Failed to identify the dive computer.");
		libusb_close (device->handle);
		libusb_exit (device->context);
		free (device);
		return status;
	}

	*out = (dc_device_t*) device;

	return DC_STATUS_SUCCESS;
#else
	return DC_STATUS_UNSUPPORTED;
#endif
}
Exemple #18
0
XN_C_API XnStatus xnUSBOpenDeviceImpl(libusb_device* pDevice, XN_USB_DEV_HANDLE* pDevHandlePtr)
{
	XnStatus nRetVal = XN_STATUS_OK;

	if (pDevice == NULL)
	{
		return (XN_STATUS_USB_DEVICE_NOT_FOUND);
	}

	// allocate device handle
	libusb_device_handle* handle;
	
	// open device
	int rc = libusb_open(pDevice, &handle);
	
	// in any case, unref the device (we don't need it anymore)
	libusb_unref_device(pDevice);
	pDevice = NULL;
	
	// now check if open failed
	if (rc != 0)
	{
		return (XN_STATUS_USB_DEVICE_OPEN_FAILED);
	}
	
/*	
	// set for the first (and only) configuration (this will perform a light-weight reset)
	rc = libusb_set_configuration(handle, 1);
	if (rc != 0)
	{
		libusb_close(handle);
		return (XN_STATUS_USB_SET_CONFIG_FAILED);
	}
*/	
	// claim the interface (you cannot open any end point before claiming the interface)
	rc = libusb_claim_interface(handle, 0);
	if (rc != 0)
	{
		libusb_close(handle);
		return (XN_STATUS_USB_SET_INTERFACE_FAILED);
	}
	
/*	
	// set the alternate setting to default
	rc = libusb_set_interface_alt_setting(handle, 0, 0);
	if (rc != 0)
	{
		libusb_close(handle);
		return (XN_STATUS_USB_SET_INTERFACE_FAILED);
	}
*/	
	XN_VALIDATE_ALLOC(*pDevHandlePtr, XnUSBDeviceHandle);
	XN_USB_DEV_HANDLE pDevHandle = *pDevHandlePtr;
	pDevHandle->hDevice = handle;
	pDevHandle->nInterface = 0;
	pDevHandle->nAltSetting = 0;
	
	// mark the device is of high-speed
	pDevHandle->nDevSpeed = XN_USB_DEVICE_HIGH_SPEED;
	
	nRetVal = xnUSBAsynchThreadAddRef();
	if (nRetVal != XN_STATUS_OK)
	{
		xnOSFree(*pDevHandlePtr);
		return (nRetVal);
	}
	
	return (XN_STATUS_OK);
}
struct hid_device_info  HID_API_EXPORT *hid_enumerate(unsigned short vendor_id, unsigned short product_id)
{
	libusb_device **devs;
	libusb_device *dev;
	libusb_device_handle *handle;
	ssize_t num_devs;
	int i = 0;
	
	struct hid_device_info *root = NULL; // return object
	struct hid_device_info *cur_dev = NULL;
	
	setlocale(LC_ALL,"");
	
	if (!initialized) {
		libusb_init(NULL);
		initialized = 1;
	}
	
	num_devs = libusb_get_device_list(NULL, &devs);
	if (num_devs < 0)
		return NULL;
	while ((dev = devs[i++]) != NULL) {
		struct libusb_device_descriptor desc;
		struct libusb_config_descriptor *conf_desc = NULL;
		int 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;
}
/*
 * provided as a separate method (not inside constructor) so we can return error codes
 */
int SickTimCommonUsb::init_device()
{
  /*
   * Create and initialize a new LIBUSB session.
   */
  int result = libusb_init(&ctx_);
  if (result != 0)
  {
    ROS_ERROR("LIBUSB - Initialization failed with the following error code: %i.", result);
    diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "LIBUSB - Initialization failed.");
    return ExitError;
  }

  /*
   * Set the verbosity level to 3 as suggested in the documentation.
   */
  libusb_set_debug(ctx_, 3);

  /*
   * Get a list of all SICK TIM3xx devices connected to the USB bus.
   *
   * As a shortcut, you can also use the LIBUSB function:
   * libusb_open_device_with_vid_pid(ctx, 0x19A2, 0x5001).
   */
  int vendorID = 0x19A2; // SICK AG
  int deviceID = 0x5001; // TIM3XX
  numberOfDevices_ = getSOPASDeviceList(ctx_, vendorID, deviceID, &devices_);

  /*
   * If available, open the first SICK TIM3xx device.
   */
  if (numberOfDevices_ == 0)
  {
    ROS_ERROR("No SICK TiM devices connected!");
    diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "No SICK TiM devices connected!");
    return ExitError;
  }
  else if (numberOfDevices_ > 1)
  {
    ROS_WARN("%zu TiM3xx scanners connected, using the first one", numberOfDevices_);
    diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::WARN, "Multiple TiMxxx scanners connected, using the first one.");
  }

  /*
   * Print out the SOPAS device information to the console.
   */
  printSOPASDeviceInformation(numberOfDevices_, devices_);

  /*
   * Open the device handle and detach all kernel drivers.
   */
  libusb_open(devices_[0], &device_handle_);
  if (device_handle_ == NULL)
  {
    ROS_ERROR("LIBUSB - Cannot open device; please read sick_tim/udev/README");
    diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "LIBUSB - Cannot open device; please read sick_tim/udev/README.");
    return ExitError;
  }
  else
  {
    ROS_DEBUG("LIBUSB - Device opened");
  }

  if (libusb_kernel_driver_active(device_handle_, 0) == 1)
  {
    ROS_DEBUG("LIBUSB - Kernel driver active");
    if (libusb_detach_kernel_driver(device_handle_, 0) == 0)
    {
      ROS_DEBUG("LIBUSB - Kernel driver detached!");
    }
  }

  /*
   * Claim the interface 0
   */
  result = libusb_claim_interface(device_handle_, 0);
  if (result < 0)
  {
    ROS_ERROR("LIBUSB - Cannot claim interface");
    diagnostics_.broadcast(diagnostic_msgs::DiagnosticStatus::ERROR, "LIBUSB - Cannot claim interface.");
    return ExitError;
  }
  else
  {
    ROS_INFO("LIBUSB - Claimed interface");
  }

  return ExitSuccess;
}
Exemple #21
0
int main(int argc, char **argv)
{
	int expected_size = 0;
	unsigned int transfer_size = 0;
	enum mode mode = MODE_NONE;
	struct dfu_status status;
	libusb_context *ctx;
	struct dfu_file file;
	char *end;
	int final_reset = 0;
	int ret;
	int dfuse_device = 0;
	int fd;
	const char *dfuse_options = NULL;
	int detach_delay = 5;
	int dfu_has_suffix = 1;
	uint16_t runtime_vendor;
	uint16_t runtime_product;

	memset(&file, 0, sizeof(file));

	/* make sure all prints are flushed */
	setvbuf(stdout, NULL, _IONBF, 0);

	while (1) {
		int c, option_index = 0;
		c = getopt_long(argc, argv, "hVvleE:d:p:c:i:a:S:t:U:D:Rs:Z:", opts,
				&option_index);
		if (c == -1)
			break;

		switch (c) {
		case 'h':
			help();
			break;
		case 'V':
			mode = MODE_VERSION;
			break;
		case 'v':
			verbose++;
			break;
		case 'l':
			mode = MODE_LIST;
			break;
		case 'e':
			mode = MODE_DETACH;
			match_iface_alt_index = 0;
			match_iface_index = 0;
			break;
		case 'E':
			detach_delay = atoi(optarg);
			break;
		case 'd':
			parse_vendprod(optarg);
			break;
		case 'p':
			/* Parse device path */
			ret = resolve_device_path(optarg);
			if (ret < 0)
				errx(EX_SOFTWARE, "Unable to parse '%s'", optarg);
			if (!ret)
				errx(EX_SOFTWARE, "Cannot find '%s'", optarg);
			break;
		case 'c':
			/* Configuration */
			match_config_index = atoi(optarg);
			break;
		case 'i':
			/* Interface */
			match_iface_index = atoi(optarg);
			break;
		case 'a':
			/* Interface Alternate Setting */
			match_iface_alt_index = strtoul(optarg, &end, 0);
			if (*end) {
				match_iface_alt_name = optarg;
				match_iface_alt_index = -1;
			}
			break;
		case 'S':
			parse_serial(optarg);
			break;
		case 't':
			transfer_size = atoi(optarg);
			break;
		case 'U':
			mode = MODE_UPLOAD;
			file.name = optarg;
			break;
		case 'Z':
			expected_size = atoi(optarg);
			break;
		case 'D':
			mode = MODE_DOWNLOAD;
			file.name = optarg;
			break;
		case 'R':
			final_reset = 1;
			break;
		case 's':
			dfuse_options = optarg;
			dfu_has_suffix = 0;
			break;
		default:
			help();
			break;
		}
	}

	print_version();
	if (mode == MODE_VERSION) {
		exit(0);
	}

	if (mode == MODE_NONE) {
		fprintf(stderr, "You need to specify one of -D or -U\n");
		help();
	}

	if (mode == MODE_DOWNLOAD) {
		dfu_load_file(&file, dfu_has_suffix, 0);
		/* If the user didn't specify product and/or vendor IDs to match,
		 * use any IDs from the file suffix for device matching */
		if (match_vendor < 0 && file.idVendor != 0xffff) {
			match_vendor = file.idVendor;
			printf("Match vendor ID from file: %04x\n", match_vendor);
		}
		if (match_product < 0 && file.idProduct != 0xffff) {
			match_product = file.idProduct;
			printf("Match product ID from file: %04x\n", match_product);
		}
	}

	ret = libusb_init(&ctx);
	if (ret)
		errx(EX_IOERR, "unable to initialize libusb: %i", ret);

	if (verbose > 2) {
		libusb_set_debug(ctx, 255);
	}

	probe_devices(ctx);

	if (mode == MODE_LIST) {
		list_dfu_interfaces();
		exit(0);
	}

	if (dfu_root == NULL) {
		errx(EX_IOERR, "No DFU capable USB device found");
	} else if (dfu_root->next != NULL) {
		/* We cannot safely support more than one DFU capable device
		 * with same vendor/product ID, since during DFU we need to do
		 * a USB bus reset, after which the target device will get a
		 * new address */
		errx(EX_IOERR, "More than one DFU capable USB device found! "
		       "Try `--list' and specify the serial number "
		       "or disconnect all but one device\n");
	}

	/* We have exactly one device. Its libusb_device is now in dfu_root->dev */

	printf("Opening DFU capable USB device...\n");
	ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
	if (ret || !dfu_root->dev_handle)
		errx(EX_IOERR, "Cannot open device");

	printf("ID %04x:%04x\n", dfu_root->vendor, dfu_root->product);

	printf("Run-time device DFU version %04x\n",
	       libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion));

	/* Transition from run-Time mode to DFU mode */
	if (!(dfu_root->flags & DFU_IFF_DFU)) {
		int err;
		/* In the 'first round' during runtime mode, there can only be one
		* DFU Interface descriptor according to the DFU Spec. */

		/* FIXME: check if the selected device really has only one */

		runtime_vendor = dfu_root->vendor;
		runtime_product = dfu_root->product;

		printf("Claiming USB DFU Runtime Interface...\n");
		if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) {
			errx(EX_IOERR, "Cannot claim interface %d",
				dfu_root->interface);
		}

		if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, 0) < 0) {
			errx(EX_IOERR, "Cannot set alt interface zero");
		}

		printf("Determining device status: ");

		err = dfu_get_status(dfu_root->dev_handle, dfu_root->interface, &status);
		if (err == LIBUSB_ERROR_PIPE) {
			printf("Device does not implement get_status, assuming appIDLE\n");
			status.bStatus = DFU_STATUS_OK;
			status.bwPollTimeout = 0;
			status.bState  = DFU_STATE_appIDLE;
			status.iString = 0;
		} else if (err < 0) {
			errx(EX_IOERR, "error get_status");
		} else {
			printf("state = %s, status = %d\n",
			       dfu_state_to_string(status.bState), status.bStatus);
		}

		if (!(dfu_root->quirks & QUIRK_POLLTIMEOUT))
			milli_sleep(status.bwPollTimeout);

		switch (status.bState) {
		case DFU_STATE_appIDLE:
		case DFU_STATE_appDETACH:
			printf("Device really in Runtime Mode, send DFU "
			       "detach request...\n");
			if (dfu_detach(dfu_root->dev_handle,
				       dfu_root->interface, 1000) < 0) {
				errx(EX_IOERR, "error detaching");
			}
			libusb_release_interface(dfu_root->dev_handle,
						 dfu_root->interface);
			if (dfu_root->func_dfu.bmAttributes & USB_DFU_WILL_DETACH) {
				printf("Device will detach and reattach...\n");
			} else {
				printf("Resetting USB...\n");
				ret = libusb_reset_device(dfu_root->dev_handle);
				if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND)
					errx(EX_IOERR, "error resetting "
						"after detach");
			}
			break;
		case DFU_STATE_dfuERROR:
			printf("dfuERROR, clearing status\n");
			if (dfu_clear_status(dfu_root->dev_handle,
					     dfu_root->interface) < 0) {
				errx(EX_IOERR, "error clear_status");
			}
			/* fall through */
		default:
			warnx("WARNING: Runtime device already in DFU state ?!?");
			goto dfustate;
			break;
		}
		libusb_release_interface(dfu_root->dev_handle,
					 dfu_root->interface);
		libusb_close(dfu_root->dev_handle);
		dfu_root->dev_handle = NULL;

		if (mode == MODE_DETACH) {
			libusb_exit(ctx);
			exit(0);
		}

		/* keeping handles open might prevent re-enumeration */
		disconnect_devices();

		milli_sleep(detach_delay * 1000);

		/* Change match vendor and product to impossible values to force
		 * only DFU mode matches in the following probe */
		match_vendor = match_product = 0x10000;

		probe_devices(ctx);

		if (dfu_root == NULL) {
			errx(EX_IOERR, "Lost device after RESET?");
		} else if (dfu_root->next != NULL) {
			errx(EX_IOERR, "More than one DFU capable USB device found! "
				"Try `--list' and specify the serial number "
				"or disconnect all but one device");
		}

		/* Check for DFU mode device */
		if (!(dfu_root->flags | DFU_IFF_DFU))
			errx(EX_SOFTWARE, "Device is not in DFU mode");

		printf("Opening DFU USB Device...\n");
		ret = libusb_open(dfu_root->dev, &dfu_root->dev_handle);
		if (ret || !dfu_root->dev_handle) {
			errx(EX_IOERR, "Cannot open device");
		}
	} else {
		/* we're already in DFU mode, so we can skip the detach/reset
		 * procedure */
		/* If a match vendor/product was specified, use that as the runtime
		 * vendor/product, otherwise use the DFU mode vendor/product */
		runtime_vendor = match_vendor < 0 ? dfu_root->vendor : match_vendor;
		runtime_product = match_product < 0 ? dfu_root->product : match_product;
	}

dfustate:
#if 0
	printf("Setting Configuration %u...\n", dfu_root->configuration);
	if (libusb_set_configuration(dfu_root->dev_handle, dfu_root->configuration) < 0) {
		errx(EX_IOERR, "Cannot set configuration");
	}
#endif
	printf("Claiming USB DFU Interface...\n");
	if (libusb_claim_interface(dfu_root->dev_handle, dfu_root->interface) < 0) {
		errx(EX_IOERR, "Cannot claim interface");
	}

	printf("Setting Alternate Setting #%d ...\n", dfu_root->altsetting);
	if (libusb_set_interface_alt_setting(dfu_root->dev_handle, dfu_root->interface, dfu_root->altsetting) < 0) {
		errx(EX_IOERR, "Cannot set alternate interface");
	}

status_again:
	printf("Determining device status: ");
	if (dfu_get_status(dfu_root->dev_handle, dfu_root->interface, &status ) < 0) {
		errx(EX_IOERR, "error get_status");
	}
	printf("state = %s, status = %d\n",
	       dfu_state_to_string(status.bState), status.bStatus);
	if (!(dfu_root->quirks & QUIRK_POLLTIMEOUT))
		milli_sleep(status.bwPollTimeout);

	switch (status.bState) {
	case DFU_STATE_appIDLE:
	case DFU_STATE_appDETACH:
		errx(EX_IOERR, "Device still in Runtime Mode!");
		break;
	case DFU_STATE_dfuERROR:
		printf("dfuERROR, clearing status\n");
		if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0) {
			errx(EX_IOERR, "error clear_status");
		}
		goto status_again;
		break;
	case DFU_STATE_dfuDNLOAD_IDLE:
	case DFU_STATE_dfuUPLOAD_IDLE:
		printf("aborting previous incomplete transfer\n");
		if (dfu_abort(dfu_root->dev_handle, dfu_root->interface) < 0) {
			errx(EX_IOERR, "can't send DFU_ABORT");
		}
		goto status_again;
		break;
	case DFU_STATE_dfuIDLE:
		printf("dfuIDLE, continuing\n");
		break;
	default:
		break;
	}

	if (DFU_STATUS_OK != status.bStatus ) {
		printf("WARNING: DFU Status: '%s'\n",
			dfu_status_to_string(status.bStatus));
		/* Clear our status & try again. */
		if (dfu_clear_status(dfu_root->dev_handle, dfu_root->interface) < 0)
			errx(EX_IOERR, "USB communication error");
		if (dfu_get_status(dfu_root->dev_handle, dfu_root->interface, &status) < 0)
			errx(EX_IOERR, "USB communication error");
		if (DFU_STATUS_OK != status.bStatus)
			errx(EX_SOFTWARE, "Status is not OK: %d", status.bStatus);
		if (!(dfu_root->quirks & QUIRK_POLLTIMEOUT))
			milli_sleep(status.bwPollTimeout);
	}

	printf("DFU mode device DFU version %04x\n",
	       libusb_le16_to_cpu(dfu_root->func_dfu.bcdDFUVersion));

	if (dfu_root->func_dfu.bcdDFUVersion == libusb_cpu_to_le16(0x11a))
		dfuse_device = 1;

	/* If not overridden by the user */
	if (!transfer_size) {
		transfer_size = libusb_le16_to_cpu(
		    dfu_root->func_dfu.wTransferSize);
		if (transfer_size) {
			printf("Device returned transfer size %i\n",
			       transfer_size);
		} else {
			errx(EX_IOERR, "Transfer size must be "
				"specified");
		}
	}

#ifdef HAVE_GETPAGESIZE
/* autotools lie when cross-compiling for Windows using mingw32/64 */
#ifndef __MINGW32__
	/* limitation of Linux usbdevio */
	if ((int)transfer_size > getpagesize()) {
		transfer_size = getpagesize();
		printf("Limited transfer size to %i\n", transfer_size);
	}
#endif /* __MINGW32__ */
#endif /* HAVE_GETPAGESIZE */

	if (transfer_size < dfu_root->bMaxPacketSize0) {
		transfer_size = dfu_root->bMaxPacketSize0;
		printf("Adjusted transfer size to %i\n", transfer_size);
	}

	switch (mode) {
	case MODE_UPLOAD:
		/* open for "exclusive" writing */
		fd = open(file.name, O_WRONLY | O_CREAT | O_EXCL | O_TRUNC, 0666);
		if (fd < 0)
			err(EX_IOERR, "Cannot open file %s for writing", file.name);

		if (dfuse_device || dfuse_options) {
		    if (dfuse_do_upload(dfu_root, transfer_size, fd,
					dfuse_options) < 0)
			exit(1);
		} else {
		    if (dfuload_do_upload(dfu_root, transfer_size,
			expected_size, fd) < 0) {
			exit(1);
		    }
		}
		close(fd);
		break;

	case MODE_DOWNLOAD:
		if (((file.idVendor  != 0xffff && file.idVendor  != runtime_vendor) ||
		     (file.idProduct != 0xffff && file.idProduct != runtime_product)) &&
		    ((file.idVendor  != 0xffff && file.idVendor  != dfu_root->vendor) ||
		     (file.idProduct != 0xffff && file.idProduct != dfu_root->product))) {
			errx(EX_IOERR, "Error: File ID %04x:%04x does "
				"not match device (%04x:%04x or %04x:%04x)",
				file.idVendor, file.idProduct,
				runtime_vendor, runtime_product,
				dfu_root->vendor, dfu_root->product);
		}
		if (dfuse_device || dfuse_options || file.bcdDFU == 0x11a) {
		        if (dfuse_do_dnload(dfu_root, transfer_size, &file,
							dfuse_options) < 0)
				exit(1);
		} else {
			if (dfuload_do_dnload(dfu_root, transfer_size, &file) < 0)
				exit(1);
	 	}
		break;
	case MODE_DETACH:
		if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) {
			errx(EX_IOERR, "can't detach");
		}
		break;
	default:
		errx(EX_IOERR, "Unsupported mode: %u", mode);
		break;
	}

	if (final_reset) {
		if (dfu_detach(dfu_root->dev_handle, dfu_root->interface, 1000) < 0) {
			errx(EX_IOERR, "can't detach");
		}
		printf("Resetting USB to switch back to runtime mode\n");
		ret = libusb_reset_device(dfu_root->dev_handle);
		if (ret < 0 && ret != LIBUSB_ERROR_NOT_FOUND) {
			errx(EX_IOERR, "error resetting after download");
		}
	}

	libusb_close(dfu_root->dev_handle);
	dfu_root->dev_handle = NULL;
	libusb_exit(ctx);

	return (0);
}
Exemple #22
0
int main(int argc, char **argv)
{
	int rc;
	libusb_device_handle *handle = NULL;
	int iface_detached = -1;
	rc = libusb_init(NULL);
	assert(rc == 0);

	if (argc <= 1) {
		printf("Usage: %s command arguments... [command...]\n"
			"	hex[dump] address length	Dumps memory region in hex\n"
			"	dump address length		Binary memory dump\n"
			"	exe[cute] address		Call function address\n"
			"	read address length file	Write memory contents into file\n"
			"	write address file		Store file contents into memory\n"
			"	ver[sion]			Show BROM version\n"
			"	clear address length		Clear memory\n"
			"	fill address length value	Fill memory\n"
			, argv[0]
		);
	}

	handle = libusb_open_device_with_vid_pid(NULL, 0x1f3a, 0xefe8);
	if (!handle) {
		fprintf(stderr, "ERROR: Allwinner USB FEL device not found!\n");
		exit(1);
	}
	rc = libusb_claim_interface(handle, 0);
#if defined(__linux__)
	if (rc != LIBUSB_SUCCESS) {
		libusb_detach_kernel_driver(handle, 0);
		iface_detached = 0;
		rc = libusb_claim_interface(handle, 0);
	}
#endif
	assert(rc == 0);

	while (argc > 1 ) {
		int skip = 1;
		if (strncmp(argv[1], "hex", 3) == 0 && argc > 3) {
			aw_fel_hexdump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0));
			skip = 3;
		} else if (strncmp(argv[1], "dump", 4) == 0 && argc > 3) {
			aw_fel_dump(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0));
			skip = 3;
		} else if ((strncmp(argv[1], "exe", 3) == 0 && argc > 2)
			) {
			aw_fel_execute(handle, strtoul(argv[2], NULL, 0));
			skip=3;
		} else if (strncmp(argv[1], "ver", 3) == 0 && argc > 1) {
			aw_fel_get_version(handle);
			skip=1;
		} else if (strcmp(argv[1], "write") == 0 && argc > 3) {
			size_t size;
			void *buf = load_file(argv[3], &size);
			aw_fel_write(handle, buf, strtoul(argv[2], NULL, 0), size);
			free(buf);
			skip=3;
		} else if (strcmp(argv[1], "read") == 0 && argc > 4) {
			size_t size = strtoul(argv[3], NULL, 0);
			void *buf = malloc(size);
			aw_fel_read(handle, strtoul(argv[2], NULL, 0), buf, size);
			save_file(argv[4], buf, size);
			free(buf);
			skip=4;
		} else if (strcmp(argv[1], "clear") == 0 && argc > 2) {
			aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), 0);
			skip=3;
		} else if (strcmp(argv[1], "fill") == 0 && argc > 3) {
			aw_fel_fill(handle, strtoul(argv[2], NULL, 0), strtoul(argv[3], NULL, 0), (unsigned char)strtoul(argv[4], NULL, 0));
			skip=4;
		} else {
			fprintf(stderr,"Invalid command %s\n", argv[1]);
			exit(1);
		}
		argc-=skip;
		argv+=skip;
	}

#if defined(__linux__)
	if (iface_detached >= 0)
		libusb_attach_kernel_driver(handle, iface_detached);
#endif

	return 0;
}
Exemple #23
0
static int dev_open(struct sr_dev_inst *sdi)
{
    struct sr_dev_driver *di = sdi->driver;
    struct dev_context *devc;
    struct drv_context *drvc;
    struct sr_usb_dev_inst *usb;
    libusb_device **devlist, *dev;
    int device_count, ret, i;
    char connection_id[64];

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

    if (!(devc = sdi->priv)) {
        sr_err("%s: sdi->priv was NULL", __func__);
        return SR_ERR_ARG;
    }

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

    dev = NULL;
    for (i = 0; i < device_count; i++) {
        usb_get_port_path(devlist[i], connection_id, sizeof(connection_id));
        if (!strcmp(sdi->connection_id, connection_id)) {
            dev = devlist[i];
            break;
        }
    }
    if (!dev) {
        sr_err("Device on %d.%d (logical) / %s (physical) disappeared!",
               usb->bus, usb->address, sdi->connection_id);
        return SR_ERR;
    }

    if (!(ret = libusb_open(dev, &(usb->devhdl)))) {
        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(ret));
        return SR_ERR;
    }

    ret = libusb_set_configuration(usb->devhdl, USB_CONFIGURATION);
    if (ret < 0) {
        sr_err("Unable to set USB configuration %d: %s.",
               USB_CONFIGURATION, libusb_error_name(ret));
        return SR_ERR;
    }

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

    /* Set default configuration after power on. */
    if (analyzer_read_status(usb->devhdl) == 0)
        analyzer_configure(usb->devhdl);

    analyzer_reset(usb->devhdl);
    analyzer_initialize(usb->devhdl);

    //analyzer_set_memory_size(MEMORY_SIZE_512K);
    // analyzer_set_freq(g_freq, g_freq_scale);
    analyzer_set_trigger_count(1);
    // analyzer_set_ramsize_trigger_address((((100 - g_pre_trigger)
    // * get_memory_size(g_memory_size)) / 100) >> 2);

#if 0
    if (g_double_mode == 1)
        analyzer_set_compression(COMPRESSION_DOUBLE);
    else if (g_compression == 1)
        analyzer_set_compression(COMPRESSION_ENABLE);
    else
#endif
        analyzer_set_compression(COMPRESSION_NONE);

    if (devc->cur_samplerate == 0) {
        /* Samplerate hasn't been set. Default to 1MHz. */
        analyzer_set_freq(1, FREQ_SCALE_MHZ);
        devc->cur_samplerate = SR_MHZ(1);
    }

    if (devc->cur_threshold == 0)
        set_voltage_threshold(devc, 1.5);

    return SR_OK;
}
struct libusb_device *dfu_device_init( const uint32_t vendor,
                                       const uint32_t product,
                                       dfu_device_t *dfu_device,
                                       const dfu_bool initial_abort,
                                       const dfu_bool honor_interfaceclass )
{
    libusb_device **list;
    size_t i,devicecount;
    extern libusb_context *usbcontext;
    int32_t retries = 4;
    
    TRACE( "%s( %u, %u, %p, %s, %s )\n", __FUNCTION__, vendor, product,
           dfu_device, ((true == initial_abort) ? "true" : "false"),
           ((true == honor_interfaceclass) ? "true" : "false") );

    DEBUG( "%s(%08x, %08x)\n",__FUNCTION__, vendor, product );

retry:
    devicecount = libusb_get_device_list( usbcontext, &list );
    
    for( i = 0; i < devicecount; i++ ) {
        libusb_device *device = list[i];
        struct libusb_device_descriptor descriptor;

        if( libusb_get_device_descriptor(device, &descriptor) ) {
             DEBUG( "Failed in libusb_get_device_descriptor\n" );
             break;
        }
        
        DEBUG( "%2d: 0x%04x, 0x%04x\n", (int) i,
                descriptor.idVendor, descriptor.idProduct );

        if( (vendor  == descriptor.idVendor) &&
            (product == descriptor.idProduct) )
        {
            int32_t tmp;
            /* We found a device that looks like it matches...
             * let's try to find the DFU interface, open the device
             * and claim it. */
            tmp = dfu_find_interface( device, honor_interfaceclass,
                                      descriptor.bNumConfigurations );
            
            if( 0 <= tmp ) {    /* The interface is valid. */
                dfu_device->interface = tmp;

                if( 0 == libusb_open(device, &dfu_device->handle) ) {
                    DEBUG( "opened interface %d...\n", tmp );
                    if( 0 == libusb_set_configuration(dfu_device->handle, 1) ) {
                        DEBUG( "set configuration %d...\n", 1 );
                        if( 0 == libusb_claim_interface(dfu_device->handle, dfu_device->interface) )
                        {
                            DEBUG( "claimed interface %d...\n", dfu_device->interface );

                            switch( dfu_make_idle(dfu_device, initial_abort) )
                            {
                                case 0:
                                    libusb_free_device_list( list, 1 );
                                    return device;

                                case 1:
                                    retries--;
                                    libusb_free_device_list( list, 1 );
                                    goto retry;
                            }

                            DEBUG( "Failed to put the device in dfuIDLE mode.\n" );
                            libusb_release_interface( dfu_device->handle, dfu_device->interface );
                            retries = 4;
                        } else {
                            DEBUG( "Failed to claim the DFU interface.\n" );
                        }
                    } else {
                        DEBUG( "Failed to set configuration.\n" );
                    }

                    libusb_close(dfu_device->handle);
                }
            }
        }
    }

    libusb_free_device_list( list, 1 );
    dfu_device->handle = NULL;
    dfu_device->interface = 0;

    return NULL;
}
Exemple #25
0
bool CameraUSB::connect(const CameraInfo &info)
{
    int ret;

    // com settings
    _vendorId = info.getParam("vendorId").toString().toInt(0, 16);
    _productId = info.getParam("productId").toString().toInt(0, 16);
    _epIn = info.getParam("EPIN").toString().toInt(0, 16);
    _epOut = info.getParam("EPOUT").toString().toInt(0, 16);
    _interfaceNumber = info.getParam("interface").toString().toInt(0, 16);
    if(_vendorId == 0 || _productId == 0)
    {
        qDebug()<<"USB bad vendorId/productId settings";
        return false;
    }

    // connect
    if(info.addr().isEmpty())
    {
        qDebug()<<"addr empty";
        _devHandle = libusb_open_device_with_vid_pid(_ctx, _vendorId, _productId);
    }
    else
    {
        // get list usb device
        libusb_device **devs;
        ssize_t cnt = libusb_get_device_list(_ctx, &devs);
        for(int i = 0; i < cnt; i++)
        {
            libusb_device_descriptor desc;
            if(libusb_get_device_descriptor(devs[i], &desc)==LIBUSB_SUCCESS)
            {
                if(desc.idVendor==_vendorId && desc.idProduct==_productId)
                {
                    QString addr = QString("%1.%2").arg((int)libusb_get_bus_number(devs[i]))
                                                   .arg((int)libusb_get_device_address(devs[i]));
                    if(addr==info.addr())
                    {
                        _device = devs[i];
                        libusb_open(devs[i], &_devHandle);
                    }
                }
            }
        }
        libusb_free_device_list(devs, 1);
    }

    if(_devHandle == NULL)
    {
        qDebug()<<"Cannot open device"<<endl;
        return false;
    }

    // reset device
    if((ret = libusb_reset_device(_devHandle)) != 0)
        qDebug()<<"Cannot reset device"<<libusb_strerror(libusb_error(ret));

    if(libusb_kernel_driver_active(_devHandle, _interfaceNumber) == 1)   //find out if kernel driver is attached
    {
        printf("Kernel Driver Active\n");
        if(libusb_detach_kernel_driver(_devHandle, _interfaceNumber) == 0) //detach it
            printf("Kernel Driver Detached!\n");
    }

    ret = libusb_claim_interface(_devHandle, _interfaceNumber);
    if(ret != 0)
    {
        qDebug()<<"Cannot claim device"<<libusb_strerror(libusb_error(ret));
        return false;
    }
    if((ret = libusb_clear_halt(_devHandle, _epOut)) != 0)
        qDebug()<<"Cannot clear EPOUT"<<libusb_strerror(libusb_error(ret));
    if((ret = libusb_clear_halt(_devHandle, _epIn)) != 0)
        qDebug()<<"Cannot clear EPIN"<<libusb_strerror(libusb_error(ret));

    //libusb_set_debug(_ctx, LIBUSB_LOG_LEVEL_DEBUG);

    //flush();

    return true;
}
int main(void)
{
	struct sigaction sigact;
	int r = 1;

	exit_sem = sem_open (SEM_NAME, O_CREAT, 0);
	if (!exit_sem) {
		fprintf(stderr, "failed to initialise semaphore error %d", errno);
		exit(1);
	}

	/* only using this semaphore in this process so go ahead and unlink it now */
	sem_unlink (SEM_NAME);

	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)
		sem_wait(exit_sem);

	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;
}
Exemple #27
0
bool alienFx::cAlienfx_device::Init() {
	if (lUsbContext != NULL) {
		std::cerr << "Init() called more than once, fix this!" << std::endl;
		exit(1);
	}
	libusb_init(&lUsbContext);
	for (auto fxDevice : gAlienfx_devices) {
		lDevice = &fxDevice;
		if (lVerbosity > 1) {
			std::cout << "Looking for " << lDevice->devName << "... ";
		}
		lAlienFx = libusb_open_device_with_vid_pid(lUsbContext, lDevice->VID, lDevice->PID);
		if (lAlienFx == NULL && (lVerbosity > 1)) {
			std::cout << "not found." << std::endl;
		}
		if (lAlienFx != NULL) {
			if (lVerbosity > 1) {
				std::cout << " found!" << std::endl;
			}
			// Steal device: 
			int res = libusb_kernel_driver_active(lAlienFx, 0);
			if (res == 1) {
				if (lVerbosity > 1) {
					std::cout << "Another kernel driver is active, detaching it... ";
				}
				res = libusb_detach_kernel_driver(lAlienFx, 0);
				if (res == 0) {
					if (lVerbosity > 1) {
						std::cout << "success!" << std::endl;
					}
				} else {
					if (lVerbosity > 1) {
						std::cout << "failure!" << std::endl;
					}
				}
			}
			if (lVerbosity > 1) {
				std::cout << "Claiming interface... " << std::endl;
			}
			res = libusb_claim_interface(lAlienFx, 0);
			if (res == 0) {
				if (lVerbosity > 1) {
					std::cout << "success!" << std::endl;
				}
				if (lVerbosity > 0) {
					std::cout << "Found " << lDevice->devName << ", using it." << std::endl;
				}
				break;
			} else {
				std::cerr << "Could not claim interface!" << std::endl;	
				UnInit();
				exit(1);
			}
			if (res == LIBUSB_ERROR_NOT_FOUND) {
				std::cerr << "Failed to get USB device! Are you running two instances of this tool?" << std::endl;
				UnInit();
				exit(1);
			}
		}
	}
	if (lAlienFx == NULL)	 {
		return false;
	} else {
		return true;
	}
}
Exemple #28
0
///////////////////////////////////////////////////////////////////////////////
///@author      Nicolae Bodislav
///@brief       Reads data from the USB device on bulk.
///@param       [out]p_pData - Buffer to store output data
///@param       [in]p_nLegth - Size of the output buffer
///@param       [in]p_nMiliSec - How much to wait for data before abandoning the read operation
///@retval      size of the data written in the output buffer or < 0 for error
///////////////////////////////////////////////////////////////////////////////
int CUSBLink::ReadBulk(unsigned char* p_pData, uint32_t p_nLegth, unsigned int p_nMiliSec /*= 10*/ )
{
    m_nCb = 0;
    m_nTrasferedLength = 0;

    if(m_pDevh == NULL)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Device not open.");
        return -1;
    }

    int rez = libusb_claim_interface(m_pDevh, 0);
    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Couldn't claim interface.");
        return -1;
    }

    m_enumDealoc = CUSBLink::INTERFACE;

    m_pData_transfer = NULL;
    m_pData_transfer = libusb_alloc_transfer(0);
    if (!m_pData_transfer)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Transfer couldn't be allocated.");
        return -ENOMEM;
    }

    m_pDev = libusb_get_device(m_pDevh);
    int max_packet_size = libusb_get_max_packet_size(m_pDev, m_cReadEndpoint);

    libusb_fill_bulk_transfer(m_pData_transfer, m_pDevh, m_cReadEndpoint, m_pData, max_packet_size, Cb_TransferRead, this, p_nMiliSec);

    m_enumDealoc = CUSBLink::TRANSFER;

    rez = libusb_submit_transfer(m_pData_transfer);

    if (rez < 0)
    {
        NLOG_ERR("[CUSBLink][ReadBulk] Transfer couldn't be submitted.");

        libusb_cancel_transfer(m_pData_transfer);
        m_enumDealoc = CUSBLink::INTERFACE;

        while (!m_nCb)
        {   rez = libusb_handle_events(m_pContex);
            if (rez < 0)
            {   break;
            }
        }

        libusb_free_transfer(m_pData_transfer);

        return -1;
    }

    while (!m_nCb)
    {   rez = libusb_handle_events(m_pContex);
        if (rez < 0)
        {   libusb_free_transfer(m_pData_transfer);
            return -1;
        }
    }


    if(m_bHaveData)
    {
        if(m_nTrasferedLength > 0)
        {   memcpy(p_pData, m_pData, m_nTrasferedLength);
            if (m_bRawLog)
            {   NLOG_DBG_HEX("[CUSBLink][ReadBulk] Received packet:", m_pData, m_nTrasferedLength);
            }
        }
        else
            p_pData = NULL;
    }

    return m_nTrasferedLength;
}
Exemple #29
0
GSM_Error GSM_USB_Probe(GSM_StateMachine *s, GSM_USB_Match_Function matcher)
{
	libusb_device **devs;
	libusb_device *dev;
	GSM_Device_USBData *d = &s->Device.Data.USB;
	ssize_t cnt;
	int rc;
	int i = 0;
	struct libusb_device_descriptor desc;
	struct libusb_config_descriptor *config;
	GSM_Error error;
	int vendor = -1, product = -1, bus = -1, deviceid = -1;
	char *serial = NULL;
	char buffer[300];
	gboolean do_match;

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

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

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

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

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

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

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

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

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

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

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


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

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

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

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

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

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

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

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

done:

	return error;
}
Exemple #30
0
/**
 * Attempts to put USB device in Accessory mode.
 * On success, PID/VID switches to accessory PID/VID
 * and proper application is launched. Application must match
 * Accessory manufacturer, model and version which are defined in
 * "android.hardware.us.action.USB_ACCESSORY_ATTACHED" meta-data
 */
static int setupAccessory(
	char* manufacturer,
	char* modelName,
	char* description,
	char* version,
	char* uri,
	char* serialNumber){
	
	unsigned char ioBuffer[2];
	int devVersion;
	int response;

	/* Open Nexus One device */
	if((handle = libusb_open_device_with_vid_pid(NULL, VID, PID_DBG)) == NULL){
		fprintf(stdout, "Problem acquireing handle\n");
		return -1;
	}
	libusb_claim_interface(handle, 0);
	//libusb_reset_device(handle);
	
	
	/* Send GET_PROTOCOL (0x51) request to figure out whether the device supports ADK
	 * If protocol is  not 0 the device supports it
	 */
	response = libusb_control_transfer(
		handle, //handle
		0xC0, //bmRequestType
		51, //bRequest
		0, //wValue
		0, //wIndex
		ioBuffer, //data
		2, //wLength
		0 //timeout
	);

	if(response < 0){
		error(response);
		return -1;
	}

	/* Extract protocol version to check whether Accessory mode is supported */
	devVersion = ioBuffer[1] << 8 | ioBuffer[0];
	fprintf(stdout,"Version Code Device: %d\n", devVersion);

	if(devVersion == 0){
		fprintf(stdout,"Sorry, device is not supporting Accessory mode\n");
		return -1;
	}
	
	usleep(1000);//sometimes hangs on the next transfer :(

	/* Accessory mode is supported: send out IDs */
	response = libusb_control_transfer(handle,0x40,52,0,0,(unsigned char*)manufacturer,strlen(manufacturer),0);
	if(response < 0){error(response);return -1;}

	response = libusb_control_transfer(handle,0x40,52,0,1,(unsigned char*)modelName,strlen(modelName)+1,0);
	if(response < 0){error(response);return -1;}

	response = libusb_control_transfer(handle,0x40,52,0,2,(unsigned char*)description,strlen(description)+1,0);
	if(response < 0){error(response);return -1;}

	response = libusb_control_transfer(handle,0x40,52,0,3,(unsigned char*)version,strlen(version)+1,0);
	if(response < 0){error(response);return -1;}

	response = libusb_control_transfer(handle,0x40,52,0,4,(unsigned char*)uri,strlen(uri)+1,0);
	if(response < 0){error(response);return -1;}

	response = libusb_control_transfer(handle,0x40,52,0,5,(unsigned char*)serialNumber,strlen(serialNumber)+1,0);
	if(response < 0){error(response);return -1;}

	fprintf(stdout,"Accessory Identification sent\n");

	/* Request device to start up in accessory mode */
	response = libusb_control_transfer(handle,0x40,53,0,0,NULL,0,0);
	if(response < 0){
		error(response);
		return -1;
	}

	fprintf(stdout,"Attempted to put device into accessory mode\n");

	/* Close phone handles as we need to connect to Accessory device in a while */
	if(handle != NULL){
		libusb_release_interface(handle, 0);
		libusb_close(handle);
	}

	response = connectAccessory();
	if(response < 0){
		fprintf(stderr, "Could not connect to Accessory device\n");
		return -1;
	}
	
	return 0;
}