reading USB serial number?

I took this code from the forums here
openqnx.com/index.php?name=P … usb+device

but it doesn’t work, it connects to the USB stack but fails on usbd_attach()
I changed the VENDOR and DEVICE to my usb stick.

#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <string.h>
#include <sys/usbdi.h>

#define VENDOR 0x0d7d
#define DEVICE 0x1400

usbd_device_ident_t interest =
{
VENDOR,
DEVICE,
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD,
};

usbd_funcs_t funcs =
{
_USBDI_NFUNCS,
NULL,//insertion,
NULL,//removal,
NULL
};

usbd_connect_parm_t cparms =
{
NULL,
USB_VERSION,
USBD_VERSION,
0,
0, // argc
NULL, // *argv
0,
&interest,
&funcs
};

struct usbd_connection *connection;
struct usbd_device *device;
usbd_device_instance_t instance;

usbd_device_descriptor_t *ddesc=NULL;
struct usbd_desc_node *node=NULL;
usbd_string_descriptor_t *sdesc=NULL;

int main (void)
{
int error,status;
int devno,hostid;
char* ID;

error = usbd_connect (&cparms, &connection);
 
if (error != EOK) 
{ 
	printf ("\n usbd_connect() error number: %d \n",error); 
	return -1; 
} 
printf("usbd_connect okay\n");
instance.config = 1; 
instance.iface = 0; 
instance.alternate = 0; 

for (hostid =0; hostid < 8; ++hostid) 
{ 
	for (devno = 0; devno < 16; ++devno) 
	{ 
		memset(&instance, USBD_CONNECT_WILDCARD,sizeof(usbd_device_instance_t)); 
		instance.path = hostid;
		instance.devno = devno; 
		
		status = usbd_attach(connection, &instance,0,&device); 
		
		// the device has been found 
		if (status == EOK) 
		{ 
			ddesc = usbd_device_descriptor(device,&node ); 
			if (ddesc == NULL ) 
			{ 
				printf("\n usbd_device_descriptor () error !!\n"); 
				return -1; 
			} 
			// is it a specific device ? 
			if (ddesc->idVendor == VENDOR)
			{ 
				sdesc = usbd_languages_descriptor(device,&node ); 
				ID = usbd_string(device,3,sdesc->bString[0]); 
				printf ("I found it -> hostid: %d, devno: %d, seriall number:%s \n",hostid,devno,ID); 
				if (usbd_detach (device) != EOK) 
				printf ("\n usbd_detach (): error ! \n"); 
			} 
			else 
			{ 
				printf("Vender=%x\n",ddesc->idVendor);
				if (usbd_detach (device) != EOK) 
					printf ("\n usbd_detach (): error ! \n"); 
			} 
		} 
	} 
}
 
if (usbd_disconnect(connection )!= EOK) 
	printf ("\n usbd_disconnect (): error ! \n"); 

return 0; 

}

Jinma,

What kind of device is this that you are trying to attach to?

Depending on the device type (hid device, or USB drive for example), devi-hid or devb-umass may attach to it before your program gets a chance to in which case the attach will fail.

Tim

its a USB memory stick, so devb-umass would be attached automatically in my setup right now. But why can my code attach to this device to get some information like how “usb” command. After my USB stick is mounted I can still type “usb -vv” and it doesn’t have any trouble getting the usb serial number. Is “usb” utile implemented differently?

yes, I just verified that after slaying the devb-umass, my code was able to get the usb serial number. I guess my next logical question is how can I get this info after devb-umass connects to the device first? Like “usb” util.

Jinma,

I don’t know the answer to your question but I assume it must be implemented without doing an attach command.

I’d suggest you download the source (assuming it’s still available) to the usb command and see how its done.

Tim

I wish I could but QNX is slow in giving me access :frowning:
I have been asking for it for months now…

Jinma,

I just looked at usbd_attach() call in the help docs and it says this:

So I am guessing the usb command uses the looping method and does NOT use insertion/removal callbacks so that it gets shared access to read the device configuration.

Tim

I think that is what I did in my code but it fails on the usbd_attach() because devb-umass has control over that usb stick. As soon as slay the devb-umass, the above code works and I’m able to read out the usb serial number.

Jinma,

Are you sure you filled out the connection structure correctly?

The code you posted shows:

struct usbd_connection *connection;
struct usbd_device *device;
usbd_device_instance_t instance;

usbd_device_descriptor_t *ddesc=NULL;
struct usbd_desc_node *node=NULL;
usbd_string_descriptor_t *sdesc=NULL;

int main (void)
{
int error,status;
int devno,hostid;
char* ID;

error = usbd_connect (&cparms, &connection); 

So I don’t see where you fill out anything in the connection structure before calling usbd_connect. So I can’t tell if you passed in NULL’s correctly for the attach/detach functions. I suspect something is incorrectly filled out in the connection structure where it thinks your code is trying to do I/O on the USB drive instead of just reading the device information.

Tim

the only sturucture I know of and is filling is below, notice I set the insert and removal to NULL, I don’t know how else I can fill the structure to tell it that I’m only trying to read device information.

usbd_device_ident_t interest =
{
VENDOR,
DEVICE,
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD,
USBD_CONNECT_WILDCARD,
};

usbd_funcs_t funcs =
{
_USBDI_NFUNCS,
NULL,//insertion,
NULL,//removal,
NULL
};

usbd_connect_parm_t cparms =
{
NULL,
USB_VERSION,
USBD_VERSION,
0,
0, // argc
NULL, // *argv
0,
&interest,
&funcs
};

Jinma,

The documents say you have to pass NULL for the usbd_funcs structure.

So I think you need to do:

usbd_connect_parm_t cparms =
{
NULL,
USB_VERSION,
USBD_VERSION,
0,
0, // argc
NULL, // *argv
0,
&interest,
NULL // NULL for the usbd_funcs structure
};

Tim

fantastic, I got it working now, Thanks alot for looking into it for me.

This is what is said in the document :

“The degree of “attachedness” depends on how you connected. If you specified insertion/removal callback functions, then you’ll get exclusive access to the device and can make I/O to it. If you didn’t use callbacks and you attached as in the loop above, you get shared access, so you can only read device configuration.”

Which I thought putting the NULL inside the insert and removal callback would do.

usbd_funcs_t funcs =
{
_USBDI_NFUNCS,
NULL,//insertion,
NULL,//removal,
NULL
};

Jinma,

Yes, I saw that too.

But if you look in the usbd_connect() function you’ll see the key piece of information that you were missing:

Tim