Example #1
0
/** \ingroup desc
 * Retrieve a string descriptor in C style ASCII.
 *
 * Wrapper around libusb_get_string_descriptor(). Uses the first language
 * supported by the device.
 *
 * \param dev a device handle
 * \param desc_index the index of the descriptor to retrieve
 * \param data output buffer for ASCII string descriptor
 * \param length size of data buffer
 * \returns number of bytes returned in data, or LIBUSB_ERROR code on failure
 */
int API_EXPORTED libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
	uint8_t desc_index, unsigned char *data, int length)
{
	unsigned char tbuf[255]; /* Some devices choke on size > 255 */
	int r, si, di;
	uint16_t langid;

	/* Asking for the zero'th index is special - it returns a string
	 * descriptor that contains all the language IDs supported by the
	 * device. Typically there aren't many - often only one. Language
	 * IDs are 16 bit numbers, and they start at the third byte in the
	 * descriptor. There's also no point in trying to read descriptor 0
	 * with this function. See USB 2.0 specification section 9.6.7 for
	 * more information.
	 */

	if (desc_index == 0)
		return LIBUSB_ERROR_INVALID_PARAM;

	r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
	if (r < 0)
		return r;

	if (r < 4)
		return LIBUSB_ERROR_IO;

	langid = tbuf[2] | (tbuf[3] << 8);

	r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
		sizeof(tbuf));
	if (r < 0)
		return r;

	if (tbuf[1] != LIBUSB_DT_STRING)
		return LIBUSB_ERROR_IO;

	if (tbuf[0] > r)
		return LIBUSB_ERROR_IO;

	for (di = 0, si = 2; si < tbuf[0]; si += 2) {
		if (di >= (length - 1))
			break;

		if ((tbuf[si] & 0x80) || (tbuf[si + 1])) /* non-ASCII */
			data[di++] = '?';
		else
			data[di++] = tbuf[si];
	}

	data[di] = 0;
	return di;
}
Example #2
0
bool USBDevice::open(OpenMode)
{
    close();

    int ret;

    // try to open the device
    ret = libusb_open(m_data->device, &m_data->handle);
    if (ret < 0) {
        setErrorString(ret);
        return false;
    }

    // select the interface
    ret = libusb_claim_interface(m_data->handle, 0);
    if (ret < 0) {
        setErrorString(ret);
        libusb_close(m_data->handle);
        m_data->handle = NULL;
        return false;
    }

    // get serial number
    unsigned char c[64];
    ret = libusb_get_string_descriptor(m_data->handle, m_data->descriptor.iSerialNumber, 0, c, sizeof(c));
    if (ret < 0) {
        setErrorString(ret);
        libusb_release_interface(m_data->handle, 0);
        libusb_close(m_data->handle);
        m_data->handle = NULL;
        return false;
    }
    m_serialNumber = QString::fromUtf16((const ushort *) &c[2], (qMin<int>(ret, c[0]) - 2) / 2);

    // get id
    ret = libusb_get_string_descriptor(m_data->handle, 4, 0, c, sizeof(c));
    if (ret < 0) {
        setErrorString(ret);
        libusb_release_interface(m_data->handle, 0);
        libusb_close(m_data->handle);
        m_data->handle = NULL;
        return false;
    }
    m_id = QString::fromUtf16((const ushort *) &c[2], (qMin<int>(ret, c[0]) - 2) / 2);

    // create transfer for receiving robot status
    startInTransfer();
    return QIODevice::open(ReadWrite | Unbuffered);
}
Example #3
0
char *get_dev_string(libusb_device_handle *dev, u_int8_t id)
{
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV)
	int ret;
	char *buf, unicode_buf[254];
	u_int16_t langid;
#endif

	if (!dev || !id) return strdup("");

#if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV)
	langid = get_any_langid(dev);
	if (!langid) return strdup("(error)");

	ret = libusb_get_string_descriptor(dev, id, langid,
	                                   (unsigned char *) unicode_buf,
	                                   sizeof unicode_buf);
	if (ret < 2) return strdup("(error)");

	if ((unsigned char)unicode_buf[0] < 2 || unicode_buf[1] != LIBUSB_DT_STRING)
		return strdup("(error)");

	buf = usb_string_to_native(unicode_buf + 2,
	                           ((unsigned char) unicode_buf[0] - 2) / 2);

	if (!buf) return get_dev_string_ascii(dev, 127, id);

	return buf;
#else
	return get_dev_string_ascii(dev, 127, id);
#endif
}
Example #4
0
static u_int16_t get_any_langid(libusb_device_handle *dev)
{
	unsigned char buf[4];
	int ret = libusb_get_string_descriptor(dev, 0, 0, buf, sizeof buf);
	if (ret != sizeof buf) return 0;
	return buf[2] | (buf[3] << 8);
}
Example #5
0
uint16_t LibUSB::DeviceImpl::getLangId()
{	

	/// \note This descriptor is described here: http://www.beyondlogic.org/usbnutshell/usb5.shtml

	if((languageId == 0) && isOpen())
	{
		uint8_t data[255];
		memset(data, '\0', sizeof(data));
		int Result = libusb_get_string_descriptor(m_pHandle.get(), 0, 0, data, sizeof(data));
		if (Result < LIBUSB_SUCCESS)
		{
			throw LibUSBException("libusb_get_string_descriptor() failed.", Result);
		}
		
		// First element is the size of the descriptor, in bytes
		uint8_t descriptorSize = data[0];

		// Second element should be 0x03
		if (data[1] != 0x03)
		{
			throw std::runtime_error("USB language string descriptor (index 0) is invalid.");
		}
		
		// Grab the first/default language.
		languageId = data[2] | data[3]<<8;

	}

	return languageId;

}
Example #6
0
std::wstring LibUSB::DeviceImpl::getStringDescriptorW( uint8_t index )
{
	unsigned char descStr[128];
	wmemset((wchar_t*)descStr, L'\0', sizeof(descStr)/sizeof(wchar_t));

	int Result = libusb_get_string_descriptor(m_pHandle.get(), index, getLangId(), (unsigned char*)descStr, sizeof(descStr));

	if (Result < LIBUSB_SUCCESS)
	{
		throw LibUSBException("libusb_get_string_descriptor() failed.", Result);
	}

	// First character is the size of the string descriptor, in bytes
	uint8_t descSize = descStr[0];

	// Second character is 0x03, always
	if (descStr[1] != 0x03)
	{
		throw std::runtime_error("USB string descriptor returned from device is invalid.");
	}



	std::wstring strResult;
	strResult.assign((const wchar_t*)descStr + 1, (descSize-2)/2);

	return strResult;
}
Example #7
0
static int is_language_supported(libusb_device_handle *dev, uint16_t lang)
{
	uint16_t buf[32];
	int len;
	int i;
	
	/* Get the string from libusb. */
	len = libusb_get_string_descriptor(dev,
			0x0, /* String ID */
			0x0, /* Language */
			(unsigned char*)buf,
			sizeof(buf));
	if (len < 4)
		return 0x0;
	
	
	len /= 2; /* language IDs are two-bytes each. */
	/* Start at index 1 because there are two bytes of protocol data. */
	for (i = 1; i < len; i++) {
		if (buf[i] == lang)
			return 1;
	}

	return 0;
}
Example #8
0
API_EXPORTED int usb_get_string(usb_dev_handle *dev, int desc_index, int langid,
	char *buf, size_t buflen)
{
	int r;
	r = libusb_get_string_descriptor(dev->handle, desc_index & 0xff,
		langid & 0xffff, buf, (int) buflen);
	if (r >= 0)
		return r;
	return compat_err(r);
}
Example #9
0
/**
 * Retrieve a string descriptor in C style ASCII.
 */
int  libusb_get_string_descriptor_ascii(libusb_device_handle *dev,
	uint8_t desc_index, unsigned char *data, int length)
{
	unsigned char tbuf[255]; /* Some devices choke on size > 255 */
	int r, si, di;
	uint16_t langid;

	if (desc_index == 0)
		return LIBUSB_ERROR_INVALID_PARAM;

	r = libusb_get_string_descriptor(dev, 0, 0, tbuf, sizeof(tbuf));
	if (r < 0)
		return r;

	if (r < 4)
		return LIBUSB_ERROR_IO;

	langid = tbuf[2] | (tbuf[3] << 8);

	r = libusb_get_string_descriptor(dev, desc_index, langid, tbuf,
		sizeof(tbuf));
	if (r < 0)
		return r;

	if (tbuf[1] != LIBUSB_DT_STRING)
		return LIBUSB_ERROR_IO;

	if (tbuf[0] > r)
		return LIBUSB_ERROR_IO;

	for (di = 0, si = 2; si < tbuf[0]; si += 2) {
		if (di >= (length - 1))
			break;

		if (tbuf[si + 1]) /* high byte */
			data[di++] = '?';
		else
			data[di++] = tbuf[si];
	}

	data[di] = 0;
	return di;
}
Example #10
0
QString QUsbHid::getIndexedString(int index,bool* r)
{
    char ret[256];
    if(!handle || index ==0){
        if(r) *r = false;
        return QString();
    }
    //bool res = HidD_GetIndexedString(Win_Handle, index, ret, sizeof(ret));
    int res = libusb_get_string_descriptor(handle,index,0,(uint8_t*)ret,256);
    if(r) *r = res > 0;
    return translateUSBString(ret,res);
}
Example #11
0
/* Get the first language the device says it reports. This comes from
   USB string #0. */
static uint16_t get_first_language(libusb_device_handle *dev)
{
	uint16_t buf[32];
	int len;
	
	/* Get the string from libusb. */
	len = libusb_get_string_descriptor(dev,
			0x0, /* String ID */
			0x0, /* Language */
			(unsigned char*)buf,
			sizeof(buf));
	if (len < 4)
		return 0x0;
	
	return buf[1]; // First two bytes are len and descriptor type.
}
Example #12
0
//==============================================================================
void USB_Device::string_descriptor_utf8(uint8_t index, uint16_t language, String &data)
{
	check_open();

	uint8_t raw_data[256];
	int result = libusb_get_string_descriptor(handle_, index, language, raw_data,
			sizeof(raw_data));
	if (result < 0)
		on_error("Failed to get string descriptor " + number_to_string(index),
				(libusb_error)result);

	data.assign(raw_data, raw_data + result);

	raw_data[result] = '\0';
	log_info("usb, get string descriptor %u, language: %u, data: %s", index, language, raw_data);
}
Example #13
0
int get_dev_string(char *buf, size_t size, libusb_device_handle *hdev, u_int8_t id)
{
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV)
	int ret;
	unsigned char unicode_buf[254];
	u_int16_t langid;
#endif

	if (!hdev || !id) {
		return 0;
	}
#if defined(HAVE_NL_LANGINFO) && defined(HAVE_ICONV)
	langid = get_any_langid(hdev);
	if (!langid) {
		return snprintf(buf, size, "%s", "(error)");
	}

	ret = libusb_get_string_descriptor(hdev, id, langid,
					   (unsigned char *) unicode_buf,
					   sizeof unicode_buf);
	if (ret < 2) {
		return snprintf(buf, size, "%s", "(error)");
	}
	char *tmp = usb_string_to_native(unicode_buf + 2,
				   ((unsigned char) unicode_buf[0] - 2) / 2);

	if (tmp) {
		snprintf(buf, size, "%s", tmp);
		free(tmp);
	} else {
		get_dev_string_ascii(buf, size, hdev, id);
	}
	return strlen(buf);
#else
	get_dev_string_ascii(buf, size, hdev, id);
	return strlen(buf);
#endif
}
Example #14
0
/* This function returns a newly allocated wide string containing the USB
   device string numbered by the index. The returned string must be freed
   by using free(). */
static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
{
	char buf[512];
	int len;
	wchar_t *str = NULL;
	wchar_t wbuf[256];

	/* iconv variables */
	iconv_t ic;
	size_t inbytes;
	size_t outbytes;
	size_t res;
#ifdef __FreeBSD__
	const char *inptr;
#else
	char *inptr;
#endif
	char *outptr;

	/* Determine which language to use. */
	uint16_t lang;
	lang = get_usb_code_for_current_locale();
	if (!is_language_supported(dev, lang))
		lang = get_first_language(dev);
		
	/* Get the string from libusb. */
	len = libusb_get_string_descriptor(dev,
			idx,
			lang,
			(unsigned char*)buf,
			sizeof(buf));
	if (len < 0)
		return NULL;
	
	/* buf does not need to be explicitly NULL-terminated because
	   it is only passed into iconv() which does not need it. */
	
	/* Initialize iconv. */
	ic = iconv_open("WCHAR_T", "UTF-16LE");
	if (ic == (iconv_t)-1) {
		LOG("iconv_open() failed\n");
		return NULL;
	}
	
	/* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
	   Skip the first character (2-bytes). */
	inptr = buf+2;
	inbytes = len-2;
	outptr = (char*) wbuf;
	outbytes = sizeof(wbuf);
	res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
	if (res == (size_t)-1) {
		LOG("iconv() failed\n");
		goto err;
	}

	/* Write the terminating NULL. */
	wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
	if (outbytes >= sizeof(wbuf[0]))
		*((wchar_t*)outptr) = 0x00000000;
	
	/* Allocate and copy the string. */
	str = wcsdup(wbuf);

err:
	iconv_close(ic);
	
	return str;
}
Example #15
0
/* This function returns a newly allocated wide string containing the USB
   device string numbered by the index. The returned string must be freed
   by using free(). */
static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
{
	char buf[512];
	int len;
	wchar_t *str = NULL;

#ifndef __ANDROID__ /* we don't use iconv on Android */
	wchar_t wbuf[256];
	/* iconv variables */
	iconv_t ic;
	size_t inbytes;
	size_t outbytes;
	size_t res;
#ifdef __FreeBSD__
	const char *inptr;
#else
	char *inptr;
#endif
	char *outptr;
#endif

	/* Determine which language to use. */
	uint16_t lang;
	lang = get_usb_code_for_current_locale();
	if (!is_language_supported(dev, lang))
		lang = get_first_language(dev);

	/* Get the string from libusb. */
	len = libusb_get_string_descriptor(dev,
			idx,
			lang,
			(unsigned char*)buf,
			sizeof(buf));
	if (len < 0)
		return NULL;

#ifdef __ANDROID__

	/* Bionic does not have iconv support nor wcsdup() function, so it
	   has to be done manually.  The following code will only work for
	   code points that can be represented as a single UTF-16 character,
	   and will incorrectly convert any code points which require more
	   than one UTF-16 character.

	   Skip over the first character (2-bytes).  */
	len -= 2;
	str = malloc((len / 2 + 1) * sizeof(wchar_t));
	int i;
	for (i = 0; i < len / 2; i++) {
		str[i] = buf[i * 2 + 2] | (buf[i * 2 + 3] << 8);
	}
	str[len / 2] = 0x00000000;

#else

	/* buf does not need to be explicitly NULL-terminated because
	   it is only passed into iconv() which does not need it. */

	/* Initialize iconv. */
	ic = iconv_open("WCHAR_T", "UTF-16LE");
	if (ic == (iconv_t)-1) {
		LOG("iconv_open() failed\n");
		return NULL;
	}

	/* Convert to native wchar_t (UTF-32 on glibc/BSD systems).
	   Skip the first character (2-bytes). */
	inptr = buf+2;
	inbytes = len-2;
	outptr = (char*) wbuf;
	outbytes = sizeof(wbuf);
	res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
	if (res == (size_t)-1) {
		LOG("iconv() failed\n");
		goto err;
	}

	/* Write the terminating NULL. */
	wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
	if (outbytes >= sizeof(wbuf[0]))
		*((wchar_t*)outptr) = 0x00000000;

	/* Allocate and copy the string. */
	str = wcsdup(wbuf);

err:
	iconv_close(ic);

#endif

	return str;
}
Example #16
0
API_EXPORTED int usb_get_string(usb_dev_handle *dev, int desc_index, int langid,
	char *buf, size_t buflen)
{
	return libusb_get_string_descriptor(dev->handle, desc_index & 0xff,
		langid & 0xffff, buf, (int) buflen);
}
Example #17
0
/* This function returns a newly allocated wide string containing the USB
   device string numbered by the index. The returned string must be freed
   by using free(). */
static wchar_t *get_usb_string(libusb_device_handle *dev, uint8_t idx)
{
	char buf[512];
	int len;
	wchar_t *str = NULL;
	wchar_t wbuf[256];

	/* iconv variables */
	iconv_t ic;
	size_t inbytes;
	size_t outbytes;
	size_t res;
	char *inptr;
	char *outptr;

	/* Determine which language to use. */
	uint16_t lang;
	lang = get_usb_code_for_current_locale();
	if (!is_language_supported(dev, lang))
		lang = get_first_language(dev);
		
	/* Get the string from libusb. */
	len = libusb_get_string_descriptor(dev,
			idx,
			lang,
			(unsigned char*)buf,
			sizeof(buf));
	if (len < 0)
		return NULL;
	
	buf[sizeof(buf)-1] = '\0';
	
	if (len+1 < sizeof(buf))
		buf[len+1] = '\0';
	
	/* Initialize iconv. */
	ic = iconv_open("UTF-32", "UTF-16");
	if (ic == (iconv_t)-1)
		return NULL;
	
	/* Convert to UTF-32 (wchar_t on glibc systems).
	   Skip the first character (2-bytes). */
	inptr = buf+2;
	inbytes = len-2;
	outptr = (char*) wbuf;
	outbytes = sizeof(wbuf);
	res = iconv(ic, &inptr, &inbytes, &outptr, &outbytes);
	if (res == (size_t)-1)
		goto err;

	/* Write the terminating NULL. */
	wbuf[sizeof(wbuf)/sizeof(wbuf[0])-1] = 0x00000000;
	if (outbytes >= sizeof(wbuf[0]))
		*((wchar_t*)outptr) = 0x00000000;
	
	/* Allocate and copy the string. */
	str = wcsdup(wbuf+1);

err:
	iconv_close(ic);
	
	return str;
}
Example #18
0
int cyusb_get_string_descriptor(cyusb_handle *h, unsigned char desc_index, unsigned short langid, 
								unsigned char *data, int len)
{
	return ( libusb_get_string_descriptor(h, desc_index, langid, data, len) );
}