View topic - reading USB serial number?

reading USB serial number?

anything that doesn't fit to other groups.

reading USB serial number?

Postby jinma » Fri May 28, 2010 12:26 am

I took this code from the forums here
http://www.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
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby Tim » Fri May 28, 2010 1:14 pm

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
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Postby jinma » Fri May 28, 2010 3:58 pm

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?
jinma
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby jinma » Fri May 28, 2010 4:01 pm

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
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby Tim » Fri May 28, 2010 5:43 pm

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
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Postby jinma » Fri May 28, 2010 5:47 pm

I wish I could but QNX is slow in giving me access :(
I have been asking for it for months now.......
jinma
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby Tim » Tue Jun 01, 2010 1:16 pm

Jinma,

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



Looping

Another way to attach is to loop and attach to all devices (in which
case you build the instance yourself). For example:

for (devno = 0; devno < 64; ++devno) {
memset(&instance, USBD_CONNECT_WILDCARD,
sizeof(usbd_device_instance_t));
instance.path = 0, instance.devno = devno;
if (usbd_attach(connection, &instance, 0, &device) == EOK) {
......
}
}


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.



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
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Postby jinma » Tue Jun 01, 2010 4:56 pm

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
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby Tim » Tue Jun 01, 2010 5:40 pm

Jinma,

Are you sure you filled out the connection structure correctly?

The code you posted shows:

Code: Select all
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
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Postby jinma » Tue Jun 01, 2010 8:23 pm

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
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby Tim » Tue Jun 01, 2010 8:55 pm

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
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am

Postby jinma » Tue Jun 01, 2010 9:20 pm

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
Senior Member
 
Posts: 428
Joined: Thu Oct 28, 2004 10:13 pm

Postby Tim » Wed Jun 02, 2010 1:09 pm

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:

By passing NULL as the usbd_funcs, you're saying that you're not
interested in receiving dynamic insertion/removal notifications, which
means that you won't be a fully operational class driver. No
asynchronous I/O will be allowed, no event thread, etc. This approach is
taken, for example, by the usb display utility.


Tim
Tim
Senior Member
 
Posts: 1466
Joined: Wed Mar 10, 2004 12:28 am


Return to General Programming

Who is online

Users browsing this forum: No registered users and 2 guests