static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,
				   void *buffer, int length)
{
	struct usb_generic_descriptor **ptr;
	int type = value >> 8;
	int index = value & 0xff;
	int upto, todo;

	debug("%s: type=%d, index=%d, plat=%p\n", __func__, type, index, plat);
	if (type == USB_DT_STRING) {
		return usb_emul_get_string(plat->strings, index, buffer,
					   length);
	}

	ptr = find_descriptor((struct usb_generic_descriptor **)plat->desc_list,
			      type, index);
	if (!ptr) {
		debug("%s: Could not find descriptor type %d, index %d\n",
		      __func__, type, index);
		return -ENOENT;
	}
	for (upto = 0; *ptr && upto < length; ptr++, upto += todo) {
		todo = min(length - upto, (int)(*ptr)->bLength);

		memcpy(buffer + upto, *ptr, todo);
	}

	return upto ? upto : length ? -EIO : 0;
}
Пример #2
0
size_t list_make_sequence(struct list_table* table, size_t a, size_t b)
{
	size_t id = list_allocate_int(table);
	struct list_descriptor* desc = find_descriptor(table, id);
	for(size_t i = a; i <= b; ++i)
		insert_list_element(desc, desc->list_size, &i);
	return id;
}
Пример #3
0
/* Look for a descriptor in the active configuration
 * Will also find extra descriptors which are normally
 * not returned by the standard libusb_get_descriptor() */
int usb_get_any_descriptor(struct libusb_device_handle *dev_handle,
				  uint8_t desc_type,
				  uint8_t desc_index,
				  unsigned char *resbuf, int res_len)
{
	struct libusb_device *dev;
	struct libusb_config_descriptor *config;
	int ret;
	uint16_t conflen;
	unsigned char *cbuf;

	dev = libusb_get_device(dev_handle);
	if (!dev) {
		fprintf(stderr, "Error: Broken device handle\n");
		return -1;
	}
	/* Get the total length of the configuration descriptors */
	ret = libusb_get_active_config_descriptor(dev, &config);
	if (ret == LIBUSB_ERROR_NOT_FOUND) {
		fprintf(stderr, "Error: Device is unconfigured\n");
		return -1;
	} else if (ret) {
		fprintf(stderr, "Error: failed "
			"libusb_get_active_config_descriptor()\n");
		exit(1);
	}
	conflen = config->wTotalLength;
	libusb_free_config_descriptor(config);

	/* Suck in the configuration descriptor list from device */
	cbuf = malloc(conflen);
	ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG,
				    desc_index, cbuf, conflen);
	if (ret < conflen) {
		fprintf(stderr, "Warning: failed to retrieve complete "
			"configuration descriptor, got %i/%i\n",
			ret, conflen);
		conflen = ret;
	}
	/* Search through the configuration descriptor list */
	ret = find_descriptor(cbuf, conflen, desc_type, desc_index,
			      resbuf, res_len);
	free(cbuf);

	/* A descriptor must be at least 2 bytes long */
	if (ret > 1) {
		if (verbose)
			printf("Found descriptor in complete configuration "
			       "descriptor list\n");
		return ret;
	}

	/* Finally try to retrieve it requesting the device directly
	 * This is not supported on all devices for non-standard types */
	return libusb_get_descriptor(dev_handle, desc_type, desc_index,
				     resbuf, res_len);
}
Пример #4
0
void list_insert_bool(struct list_table* table, size_t lid, size_t pos, bool value)
{
	if(!table) return;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return;

	insert_list_element(desc, pos, &value);
}
Пример #5
0
void list_push_back_string(struct list_table* table, size_t lid, size_t value)
{
	if(!table) return;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return;

	insert_list_element(desc, desc->list_size, &value);
}
Пример #6
0
void list_push_front_char(struct list_table* table, size_t lid, char value)
{
	if(!table) return;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return;

	insert_list_element(desc, 0, &value);
}
Пример #7
0
void list_add_reference(struct list_table* table, size_t lid)
{
	if(!table) return;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return;

	desc->ref_count++;
}
Пример #8
0
size_t list_size(struct list_table* table, size_t lid)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	return desc->list_size;
}
Пример #9
0
char list_get_char(struct list_table* table, size_t lid, size_t pos)
{
	if(!table) return '\0';

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return '\0';

	void* value = get_list_element(desc, pos);
	return *((char*)value);
}
Пример #10
0
bool list_back_bool(struct list_table* table, size_t lid)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	void* value = get_list_element(desc, desc->list_size - 1);
	return *((bool*)value);
}
Пример #11
0
float list_front_float(struct list_table* table, size_t lid)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	void* value = get_list_element(desc, 0);
	return *((float*)value);
}
Пример #12
0
size_t list_get_string(struct list_table* table, size_t lid, size_t pos)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	void* value = get_list_element(desc, pos);
	return *((size_t*)value);
}
Пример #13
0
size_t list_pop_back_string(struct list_table* table, size_t lid)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	void* value = remove_list_element(desc, desc->list_size - 1);
	size_t casted_value = *((size_t*)value);
	free(value);
	return casted_value;
}
Пример #14
0
char list_pop_back_char(struct list_table* table, size_t lid)
{
	if(!table) return '\0';

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return '\0';

	void* value = remove_list_element(desc, desc->list_size - 1);
	char casted_value = *((char*)value);
	free(value);
	return casted_value;
}
Пример #15
0
bool list_pop_front_bool(struct list_table* table, size_t lid)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	void* value = remove_list_element(desc, 0);
	bool casted_value = *((bool*)value);
	free(value);
	return casted_value;
}
Пример #16
0
void list_rm_reference(struct list_table* table, size_t lid)
{
	if(!table) return;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return;

	desc->ref_count--;

	if(desc->ref_count == 0) // list shouldn't be freed
		list_deallocate(table, lid);
}
Пример #17
0
char list_remove_char(struct list_table* table, size_t lid, size_t pos)
{
	if(!table) return 0;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return 0;

	void* value = remove_list_element(desc, pos);
	char casted_value = *((char*)value);
	free(value);
	return casted_value;
}
Пример #18
0
enum hxb_datatype endpoint_get_datatype(uint32_t eid)
{
	if (eid % 32 == 0) {
		return HXB_DTYPE_UINT32;
	} else {
		struct endpoint_descriptor ep = {};
		if (find_descriptor(eid, &ep)) {
			return ep.datatype;
		} else {
			return HXB_DTYPE_UNDEFINED;
		}
	}
}
Пример #19
0
enum hxb_error_code endpoint_read(uint32_t eid, struct hxb_value* value)
{
	if (eid % 32 == 0) {
		synthesize_read_m32(eid, value);
		return HXB_ERR_SUCCESS;
	} else {
		struct endpoint_descriptor ep = {};
		if (find_descriptor(eid, &ep)) {
			value->datatype = ep.datatype;
			return ep.read(value);
		} else {
			return HXB_ERR_UNKNOWNEID;
		}
	}
}
Пример #20
0
void list_clear(struct list_table* table, size_t lid)
{
	if(!table) return;

	struct list_descriptor* desc = find_descriptor(table, lid);

	if(!desc) return;

	if(!desc->list_head) // list is already empty
		return;

	// set to null the head and the tail
	desc->list_head = desc->list_tail = free_node_recur(desc->list_head);
	desc->list_size = 0;
}
Пример #21
0
/*  Remove watch associated with (descriptor, id).  */
static void
remove_watch (Lisp_Object descriptor, Lisp_Object id)
{
  Lisp_Object prevtail = find_descriptor (descriptor);
  if (NILP (prevtail))
    return;

  Lisp_Object elt = XCAR (CONSP (prevtail) ? XCDR (prevtail) : watch_list);
  for (Lisp_Object prev = elt; !NILP (XCDR (prev)); prev = XCDR (prev))
    if (EQ (id, XCAR (XCAR (XCDR (prev)))))
      {
	XSETCDR (prev, XCDR (XCDR (prev)));
	if (NILP (XCDR (elt)))
	  remove_descriptor (prevtail, false);
	break;
      }
}
Пример #22
0
/* Look for a descriptor in the active configuration
 * Will also find extra descriptors which are normally
 * not returned by the standard libusb_get_descriptor() */
static int usb_get_any_descriptor(struct libusb_device_handle *dev_handle,
                                  uint8_t desc_type,
                                  uint8_t desc_index,
                                  unsigned char *resbuf, int res_len)
{
    struct libusb_device *dev;
    struct libusb_config_descriptor *config;
    int ret;
    uint16_t conflen;
    unsigned char *cbuf;

    dev = libusb_get_device(dev_handle);
    if (!dev) {
        return -1;
    }
    /* Get the total length of the configuration descriptors */
    ret = libusb_get_active_config_descriptor(dev, &config);
    if (ret)
        return -1;
    conflen = config->wTotalLength;
    libusb_free_config_descriptor(config);

    /* Suck in the configuration descriptor list from device */
    cbuf = (unsigned char *)malloc(conflen);
    ret = libusb_get_descriptor(dev_handle, LIBUSB_DT_CONFIG,
                                desc_index, cbuf, conflen);
    if (ret < conflen) {
        conflen = ret;
    }
    /* Search through the configuration descriptor list */
    ret = find_descriptor(cbuf, conflen, desc_type, desc_index,
                          resbuf, res_len);
    free(cbuf);

    /* A descriptor must be at least 2 bytes long */
    if (ret > 1) {
        return ret;
    }

    /* Finally try to retrieve it requesting the device directly
         * This is not supported on all devices for non-standard types */
    return libusb_get_descriptor(dev_handle, desc_type, desc_index,
                                 resbuf, res_len);
}
Пример #23
0
enum hxb_error_code endpoint_get_name(uint32_t eid, char* buffer, size_t len)
{
	if (eid % 32 == 0) {
		if (len >= nvm_size(domain_name)) {
			len = nvm_size(domain_name) - 1;
		}
		nvm_read_block(domain_name, buffer, len);
		buffer[nvm_size(domain_name)] = '\0';
		return HXB_ERR_SUCCESS;
	} else {
		struct endpoint_descriptor ep;
		if (find_descriptor(eid, &ep)) {
			strncpy_from_rodata(buffer, ep.name, len);
			return HXB_ERR_SUCCESS;
		} else {
			return HXB_ERR_UNKNOWNEID;
		}
	}
}
Пример #24
0
enum hxb_error_code endpoint_write(uint32_t eid, const struct hxb_envelope* env)
{
	if (eid % 32 == 0) {
		return HXB_ERR_WRITEREADONLY;
	} else {
		struct endpoint_descriptor ep = {};
		if (find_descriptor(eid, &ep)) {
			if (ep.write == 0) {
				return HXB_ERR_WRITEREADONLY;
			} else if (ep.datatype != env->value.datatype) {
				return HXB_ERR_DATATYPE;
			} else {
				return ep.write(env);
			}
		} else {
			return HXB_ERR_UNKNOWNEID;
		}
	}
}
Пример #25
0
OptPluginBasePtr OptPluginRegistry::get_instance(const std::string& name)
{
	BlockWriteLock lock(*this);

	OptPluginDescriptor* desc = find_descriptor(name);
	if (desc == NULL)
		return OptPluginBasePtr();

	OptPluginBasePtr inst = desc->create_instance();
	if (!inst)
		return OptPluginBasePtr();

	++descriptors_[desc];
	plugins_[inst.get()] = desc;

	changed(lock);

	return inst;
}
Пример #26
0
/* This callback is called when the FD is available for read.  The inotify
   events are read from FD and converted into input_events.  */
static void
inotify_callback (int fd, void *_)
{
  int to_read;
  if (ioctl (fd, FIONREAD, &to_read) < 0)
    report_file_notify_error ("Error while retrieving file system events",
			      Qnil);
  USE_SAFE_ALLOCA;
  char *buffer = SAFE_ALLOCA (to_read);
  ssize_t n = read (fd, buffer, to_read);
  if (n < 0)
    report_file_notify_error ("Error while reading file system events", Qnil);

  struct input_event event;
  EVENT_INIT (event);
  event.kind = FILE_NOTIFY_EVENT;

  for (ssize_t i = 0; i < n; )
    {
      struct inotify_event *ev = (struct inotify_event *) &buffer[i];
      Lisp_Object descriptor = INTEGER_TO_CONS (ev->wd);
      Lisp_Object prevtail = find_descriptor (descriptor);

      if (! NILP (prevtail))
        {
	  Lisp_Object tail = CONSP (prevtail) ? XCDR (prevtail) : watch_list;
	  for (Lisp_Object watches = XCDR (XCAR (tail)); ! NILP (watches);
	       watches = XCDR (watches))
            {
              event.arg = inotifyevent_to_event (XCAR (watches), ev);
              if (!NILP (event.arg))
                kbd_buffer_store_event (&event);
            }
          /* If event was removed automatically: Drop it from watch list.  */
          if (ev->mask & IN_IGNORED)
	    remove_descriptor (prevtail, true);
        }
      i += sizeof (*ev) + ev->len;
    }

  SAFE_FREE ();
}
Пример #27
0
/* Get cached extra descriptor from libusb for an interface
 * Returns length of found descriptor */
int get_cached_extra_descriptor(struct libusb_device *dev,
				       uint8_t bConfValue,
				       uint8_t intf,
				       uint8_t desc_type, uint8_t desc_index,
				       unsigned char *resbuf, int res_len)
{
	struct libusb_config_descriptor *cfg;
	const unsigned char *extra;
	int extra_len;
	int ret;
	int alt;

	ret = libusb_get_config_descriptor_by_value(dev, bConfValue, &cfg);
	if (ret == LIBUSB_ERROR_NOT_FOUND) {
		fprintf(stderr, "Error: Device is unconfigured\n");
		return -1;
	} else if (ret) {
		fprintf(stderr, "Error: failed "
			"libusb_config_descriptor_by_value()\n");
		exit(1);
	}

	/* Extra descriptors can be shared between alternate settings but
	 * libusb may attach them to one setting. Therefore go through all.
	 * Note that desc_index is per alternate setting, hits will not be
	 * counted from one to another */
	for (alt = 0; alt < cfg->interface[intf].num_altsetting;
	     alt++) {
		extra = cfg->interface[intf].altsetting[alt].extra;
		extra_len = cfg->interface[intf].altsetting[alt].extra_length;
		if (extra_len > 1)
			ret = find_descriptor(extra, extra_len, desc_type,
					      desc_index, resbuf, res_len);
		if (ret > 1)
			break;
	}
	libusb_free_config_descriptor(cfg);
	if (ret < 2 && verbose)
		printf("Did not find cached descriptor\n");

	return ret;
}
Пример #28
0
static void probe_configuration(libusb_device *dev, struct libusb_device_descriptor *desc)
{
	struct usb_dfu_func_descriptor func_dfu;
	libusb_device_handle *devh;
	struct dfu_if *pdfu;
	struct libusb_config_descriptor *cfg;
	const struct libusb_interface_descriptor *intf;
	const struct libusb_interface *uif;
	char alt_name[MAX_DESC_STR_LEN + 1];
	char serial_name[MAX_DESC_STR_LEN + 1];
	int cfg_idx;
	int intf_idx;
	int alt_idx;
	int ret;
	int has_dfu;

	for (cfg_idx = 0; cfg_idx != desc->bNumConfigurations; cfg_idx++) {
		memset(&func_dfu, 0, sizeof(func_dfu));
		has_dfu = 0;

		ret = libusb_get_config_descriptor(dev, cfg_idx, &cfg);
		if (ret != 0)
			return;
		if (match_config_index > -1 && match_config_index != cfg->bConfigurationValue) {
			libusb_free_config_descriptor(cfg);
			continue;
		}

		/*
		 * In some cases, noticably FreeBSD if uid != 0,
		 * the configuration descriptors are empty
		 */
		if (!cfg)
			return;

		ret = find_descriptor(cfg->extra, cfg->extra_length,
		    USB_DT_DFU, &func_dfu, sizeof(func_dfu));
		if (ret > -1)
			goto found_dfu;

		for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
		     intf_idx++) {
			uif = &cfg->interface[intf_idx];
			if (!uif)
				break;

			for (alt_idx = 0; alt_idx < cfg->interface[intf_idx].num_altsetting;
			     alt_idx++) {
				intf = &uif->altsetting[alt_idx];

				if (intf->bInterfaceClass != 0xfe ||
				    intf->bInterfaceSubClass != 1)
					continue;

				ret = find_descriptor(intf->extra, intf->extra_length, USB_DT_DFU,
				      &func_dfu, sizeof(func_dfu));
				if (ret > -1)
					goto found_dfu;

				has_dfu = 1;
			}
		}
		if (has_dfu) {
			/*
			 * Finally try to retrieve it requesting the
			 * device directly This is not supported on
			 * all devices for non-standard types
			 */
			if (libusb_open(dev, &devh) == 0) {
				ret = libusb_get_descriptor(devh, USB_DT_DFU, 0,
				    (void *)&func_dfu, sizeof(func_dfu));
				libusb_close(devh);
				if (ret > -1)
					goto found_dfu;
			}
			warnx("Device has DFU interface, "
			    "but has no DFU functional descriptor");

			/* fake version 1.0 */
			func_dfu.bLength = 7;
			func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
			goto found_dfu;
		}
		libusb_free_config_descriptor(cfg);
		continue;

found_dfu:
		if (func_dfu.bLength == 7) {
			printf("Deducing device DFU version from functional descriptor "
			    "length\n");
			func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
		} else if (func_dfu.bLength < 9) {
			printf("Error obtaining DFU functional descriptor\n");
			printf("Please report this as a bug!\n");
			printf("Warning: Assuming DFU version 1.0\n");
			func_dfu.bcdDFUVersion = libusb_cpu_to_le16(0x0100);
			printf("Warning: Transfer size can not be detected\n");
			func_dfu.wTransferSize = 0;
		}

		for (intf_idx = 0; intf_idx < cfg->bNumInterfaces;
		     intf_idx++) {
			if (match_iface_index > -1 && match_iface_index != intf_idx)
				continue;

			uif = &cfg->interface[intf_idx];
			if (!uif)
				break;

			for (alt_idx = 0;
			     alt_idx < uif->num_altsetting; alt_idx++) {
				int dfu_mode;

				intf = &uif->altsetting[alt_idx];

				if (intf->bInterfaceClass != 0xfe ||
				    intf->bInterfaceSubClass != 1)
					continue;

				dfu_mode = (intf->bInterfaceProtocol == 2);
				/* e.g. DSO Nano has bInterfaceProtocol 0 instead of 2 */
				if (func_dfu.bcdDFUVersion == 0x011a && intf->bInterfaceProtocol == 0)
					dfu_mode = 1;

				/* LPC DFU bootloader has bInterfaceProtocol 1 (Runtime) instead of 2 */
				if (desc->idVendor == 0x1fc9 && desc->idProduct == 0x000c && intf->bInterfaceProtocol == 1)
					dfu_mode = 1;

				if (dfu_mode &&
				    match_iface_alt_index > -1 && match_iface_alt_index != alt_idx)
					continue;

				if (dfu_mode) {
					if ((match_vendor_dfu >= 0 && match_vendor_dfu != desc->idVendor) ||
					    (match_product_dfu >= 0 && match_product_dfu != desc->idProduct)) {
						continue;
					}
				} else {
					if ((match_vendor >= 0 && match_vendor != desc->idVendor) ||
					    (match_product >= 0 && match_product != desc->idProduct)) {
						continue;
					}
				}

				if (libusb_open(dev, &devh)) {
					warnx("Cannot open DFU device %04x:%04x", desc->idVendor, desc->idProduct);
					break;
				}
				if (intf->iInterface != 0)
					ret = libusb_get_string_descriptor_ascii(devh,
					    intf->iInterface, (void *)alt_name, MAX_DESC_STR_LEN);
				else
					ret = -1;
				if (ret < 1)
					strcpy(alt_name, "UNKNOWN");
				if (desc->iSerialNumber != 0)
					ret = libusb_get_string_descriptor_ascii(devh,
					    desc->iSerialNumber, (void *)serial_name, MAX_DESC_STR_LEN);
				else
					ret = -1;
				if (ret < 1)
					strcpy(serial_name, "UNKNOWN");
				libusb_close(devh);

				if (dfu_mode &&
				    match_iface_alt_name != NULL && strcmp(alt_name, match_iface_alt_name))
					continue;

				if (dfu_mode) {
					if (match_serial_dfu != NULL && strcmp(match_serial_dfu, serial_name))
						continue;
				} else {
					if (match_serial != NULL && strcmp(match_serial, serial_name))
						continue;
				}

				pdfu = dfu_malloc(sizeof(*pdfu));

				memset(pdfu, 0, sizeof(*pdfu));

				pdfu->func_dfu = func_dfu;
				pdfu->dev = libusb_ref_device(dev);
				pdfu->quirks = get_quirks(desc->idVendor,
				    desc->idProduct, desc->bcdDevice);
				pdfu->vendor = desc->idVendor;
				pdfu->product = desc->idProduct;
				pdfu->bcdDevice = desc->bcdDevice;
				pdfu->configuration = cfg->bConfigurationValue;
				pdfu->interface = intf->bInterfaceNumber;
				pdfu->altsetting = intf->bAlternateSetting;
				pdfu->devnum = libusb_get_device_address(dev);
				pdfu->busnum = libusb_get_bus_number(dev);
				pdfu->alt_name = strdup(alt_name);
				if (pdfu->alt_name == NULL)
					errx(EX_SOFTWARE, "Out of memory");
				pdfu->serial_name = strdup(serial_name);
				if (pdfu->serial_name == NULL)
					errx(EX_SOFTWARE, "Out of memory");
				if (dfu_mode)
					pdfu->flags |= DFU_IFF_DFU;
				if (pdfu->quirks & QUIRK_FORCE_DFU11) {
					pdfu->func_dfu.bcdDFUVersion =
					  libusb_cpu_to_le16(0x0110);
				}
				pdfu->bMaxPacketSize0 = desc->bMaxPacketSize0;

				/* queue into list */
				pdfu->next = dfu_root;
				dfu_root = pdfu;
			}
		}
		libusb_free_config_descriptor(cfg);
	}
}