From: Axel R. <axe...@gm...> - 2010-06-13 11:03:19
|
Hi everybody! I've observed the following weird behaviour when obtaining the string descriptors via libusb_get_string_descriptor_ascii( ): I'm using usblib-1.0 on windows to communicate with a ATmega32U2 HID device based on LUFA. That device's firmware implements three string descriptors with the following indices: 0x01: Manufacturer descriptor string 0x02: Product descriptor string 0xDC: SerialNumber descriptor string All three are successfully retrieved by the standard Windows HID driver. The unusual value for the SN descriptor string index is because of the way LUFA implements the automatic generation of that string based on the internal unique ID of the microcontroller. http://www.fourwalledcubicle.com/files/MyUSB/Doc/100513/html/group___group___descriptors.html#gae91cf5b90df788954090bcbd8bf1bece The problem arises when my software on the host tries to obtain the serial number string by calling: r=libusb_get_string_descriptor_ascii(pHandle, oDeviceDescriptor.iSerialNumber, (unsigned char*) szSN, 255 ); ... it returns with error code -2 (LIBUSB_ERROR_INVALID_PARAM). I ran the xusb example on my device and it successfully manages to obtain the SN-string, so I had a look at the xusb source to see what I am doing wrong. Here is an excerpt from line 688 of: http://git.libusb.org/?p=libusb-pbatard.git;a=blob;f=examples/xusb.c;h=4ebd37a15977ef48a728658db02c7751c1a094b6;hb=HEAD for (i=1; i<nb_strings; i++) { if (libusb_get_string_descriptor_ascii(handle, (uint8_t)i, string, 128) >= 0) { printf(" String (%d/%d): \"%s\"\n", i, nb_strings-1, string); } } As you can see, it doesn't use the string index reported by the device-descriptor (0xDC) , but a sequentially incremented counter i, so it successfully manages to obtain the SN-string with index=3; The funny thing, is that the device descriptor obtained by xusb states that the SN-string-decriptor-index indeed is 220 (=0xDC). I modified my host software accordingly and it now succeeds retrieving the SN-string by requesting index=3 instead of index=0xDC. Since the Windows HID driver manages to obtain the SN string, I first thought it might be a bug in libusb-1.0, so I dived into the source of libusb, but everything looks as it should and I can't come up with a plausible explanation for that LIBUSB_ERROR_INVALID_PARAM error code. Did I misunderstand the documentation of libusb_get_string_descriptor_ascii()? http://libusb.sourceforge.net/api-1.0/group__desc.html#gaf3f92d0a7465d49a5e61eb3f8689fae4 I assumed the descriptor index is the one reported by the device-descriptor. Regards, Axel. |
From: Xiaofan C. <xia...@gm...> - 2010-06-13 12:44:13
|
On Sun, Jun 13, 2010 at 7:03 PM, Axel Rohde <axe...@gm...> wrote: > Since the Windows HID driver manages to obtain the SN string, I first > thought it might be a bug in libusb-1.0, so I dived into the source of > libusb, but everything looks as it should and I can't come up with a > plausible explanation for that LIBUSB_ERROR_INVALID_PARAM error code. > I tend to think it is a bug. http://git.libusb.org/?p=libusb-pbatard.git;a=blob;f=libusb/os/windows_usb.c;h=8b9408422f60a28017de561fc99af280e9637b21;hb=HEAD 2938 d.iManufacturer = _hid_wcslen(dev->man_string) ? 1 : 0; 2939 d.iProduct = _hid_wcslen(dev->prod_string) ? 2 : 0; 2940 d.iSerialNumber = _hid_wcslen(dev->ser_string) ? 3 : 0; 3025 static int _hid_get_string_descriptor(struct hid_device_priv* dev, int index, 3026 void *data, size_t *size) 3027 { 3028 void *tmp = NULL; 3029 size_t tmp_size = 0; 3030 3031 /* language ID, EN-US */ 3032 char string_langid[] = { 3033 0x09, 3034 0x04 3035 }; 3036 3037 if ((*size < 2) || (*size > 255)) { 3038 return LIBUSB_ERROR_OVERFLOW; 3039 } 3041 switch(index) { 3042 case 0: 3043 tmp = string_langid; 3044 tmp_size = sizeof(string_langid)+2; 3045 break; 3046 case 1: 3047 tmp = dev->man_string; 3048 tmp_size = (_hid_wcslen(dev->man_string)+1) * sizeof(WCHAR); 3049 break; 3050 case 2: 3051 tmp = dev->prod_string; 3052 tmp_size = (_hid_wcslen(dev->prod_string)+1) * sizeof(WCHAR); 3053 break; 3054 case 3: 3055 tmp = dev->ser_string; 3056 tmp_size = (_hid_wcslen(dev->ser_string)+1) * sizeof(WCHAR); 3057 break; 3058 default: 3059 return LIBUSB_ERROR_INVALID_PARAM; 3060 } The index are hard-coded to be 1/2/3 (or 0 if not existed). I think this is not correct. -- Xiaofan http://mcuee.blogspot.com |
From: Pete B. <pb...@gm...> - 2010-06-13 14:34:26
|
Yeah, this is a bug. This comes from using the Windows API's HidD_GetManufacturerString, HidD_GetProductString, HidD_GetSerialNumberString calls, that don't care about string index, and overlooking the fact that Manufacturer, Product and S/N don't necessarily use 1, 2, 3, unlike language ID, which is always set to 0. I'll fix that. Regards, /Pete |
From: Axel R. <axe...@gm...> - 2010-06-13 18:53:50
|
Thanks Xiaofan for pointing at the right spot of the source code. I somehow got lost and looked in the wrong files. And thank you Pete for your restless fight with the Windows APIs. I hope you don't get tired of me and my unusual USB device implementations. :-/ Cheers, Axel. |
From: Peter S. <pe...@st...> - 2010-06-13 19:40:01
|
Axel Rohde wrote: > I hope you don't get tired of me and my unusual USB device > implementations. :-/ It is clearly very important that the Windows code, maybe in particular the niched HID driver on Windows, is tested with all sorts of devices, and the more unusual they are the better it is. //Peter |
From: Pete B. <pb...@gm...> - 2010-06-13 20:29:43
|
> Axel Rohde wrote: >> I hope you don't get tired of me and my unusual USB device >> implementations. :-/ Not at all. If anything, just like Peter, I think we haven't had enough testers for the Windows code yet. The more we get the new backend tested against unusual devices, or in unusual situations, the better. So please keep it up, and don't hesitate to submit reports about any oddity you see. Regards, /Pete |
From: Pete B. <pb...@gm...> - 2010-06-14 21:17:01
|
Should be fixed in pbr283. Regards, /Pete |
From: Axel R. <axe...@gm...> - 2010-06-15 07:53:30
|
On 14/06/2010 23:16, Pete Batard wrote: > Should be fixed in pbr283. It works! Thank you. Axel. |
From: Xiaofan C. <xia...@gm...> - 2010-06-14 02:00:26
|
On Mon, Jun 14, 2010 at 2:53 AM, Axel Rohde <axe...@gm...> wrote: > I hope you don't get tired of me and my unusual USB device implementations. > :-/ Actually LUFA seems to be quite good even though I am not using USB AVRs. I am mainly using USB PICs. I have an Olimex LPC-P2148 board (with lpcusb stack) but I am not that familiar with it. Then I have also an ADI USB DAC demo board with Cypress EZUSB-FX2 (not FX2LP) but again I am not that familiar with it. And I think your HID device implementation is not unusual at all but rather quite compliant.;-) My main HID testbed is the Generic HID Firmware from Jan Axelson and the PICkit 2. Both are using USB stack from Microchip (V2.x and V1.x). Pete also has access to them. I think it is very good that you are using a different device and a different stack. -- Xiaofan http://mcuee.blogspot.com |
From: Peter S. <pe...@st...> - 2010-06-14 03:36:04
|
Xiaofan Chen wrote: > I have an Olimex LPC-P2148 board (with lpcusb stack) but I am not > that familiar with it. I'm also using lpcusb on the LPC-2148 MCU with libusb-1.0. It works perfectly. I will be using it in a Windows app fairly soon, with vendor-specific interface and WinUSB.sys. //Peter |
From: Xiaofan C. <xia...@gm...> - 2010-06-14 05:02:55
|
On Mon, Jun 14, 2010 at 11:35 AM, Peter Stuge <pe...@st...> wrote: > Xiaofan Chen wrote: >> I have an Olimex LPC-P2148 board (with lpcusb stack) but I am not >> that familiar with it. > > I'm also using lpcusb on the LPC-2148 MCU with libusb-1.0. It works > perfectly. I will be using it in a Windows app fairly soon, with > vendor-specific interface and WinUSB.sys. > Glad to know that. I have not looked in depth of the lpcusb stack. But I want to do one test with it: I would like to port the Linux usbfs based host example to libusb-1.0 to test out isochronous transfer under Linux. Probably I will also try it out with the asynchronous API of libusb-win32, just to compare the results. It could be the test device for future libusb0.sys integration as well. http://lpcusb.svn.sourceforge.net/viewvc/lpcusb/trunk/host/linux_isoc_sample/src/linux_usbfs_isoc_io_test.c?revision=178&view=markup -- Xiaofan http://mcuee.blogspot.com |