Discussion:
[Libusb-devel] Can't Send Control Messages to usb device in Windows
Jason Kotzin
2010-04-19 20:49:07 UTC
Permalink
Hey Dev Team -

I'm trying to get my firmware and software running with libusb1.0 and am having some trouble in windows.

I've successfully ported my entire application to libusb 1.0 and it works just fine in OSX. I haven't tested it much in linux, but at first glance, everything is fine.

All I really needed to do was change my usb_control_msg calls.

My device appears to the computer as an HID usb keyboard, but I send control messages to the device to do some extra functions. It's critical that the device stays a keyboard, because that's what it's intended to be.

Any control function I send down to the device doesn't really work. I know the message is getting down to the device because I turn on an LED if I see anything. I haven't turned on my debugger, but at first glance it looks only to be libusb_request_type_class and libusb_recipent_interface, nothing to do with my control request.

Here is my code:

int peek(int address)
{
unsigned char data[1];
libusb_control_transfer(handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_ENDPOINT_IN,
PEEK,
address,
0,
(char *)data,
sizeof(data),
5000);

return (data[0]);
}


I've even modified my application and firmware to see if the control message in xusb worked: libusb_control_transfer(handle, LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT <<8)|0x00, 0 , output_report, 06,1000));

LED turns on, but still garbage in data[].

I'm also able to printout the correct Manufacture string so I know that it has the correct handle.

I should also note that my application complained that I was missing the libusb-1.0.0.dll, even though I compiled statically. Not sure why this was the case.

Really appreciate your help, I've been stuck on this for quite some time now.

Thanks so much,
Jason
Tim Roberts
2010-04-19 21:17:28 UTC
Permalink
Post by Jason Kotzin
I'm trying to get my firmware and software running with libusb1.0 and
am having some trouble in windows.
I've successfully ported my entire application to libusb 1.0 and it
works just fine in OSX. I haven't tested it much in linux, but at
first glance, everything is fine.
All I really needed to do was change my usb_control_msg calls.
My device appears to the computer as an HID usb keyboard, but I send
control messages to the device to do some extra functions. It's
critical that the device stays a keyboard, because that's what it's
intended to be.
Any control function I send down to the device doesn't really work. I
know the message is getting down to the device because I turn on an
LED if I see anything. I haven't turned on my debugger, but at first
glance it looks only to be libusb_request_type_class and
libusb_recipent_interface, nothing to do with my control request.
So, what doesn't work? You say the message is getting to device,
because it turns on an LED. Is that the byte you return is not getting
all the way back to you? If you initialize data to something, do you
see that something remain, or does it get changes?

BTW, requests that are not aimed at a specific endpoint should use
LIBUSB_RECIPIENT_DEVICE. When you specify LIBUSB_RECIPIENT_ENDPOINT,
Linux requires that you have claimed the interface that contains the
endpoint number in wIndex. In this case, you're specifying 0, which
should be OK, but most generic vendor commands should go to the device.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Jason Kotzin
2010-04-19 21:55:55 UTC
Permalink
Hey Tim -

Thanks for the reply.

Actually nothing works. I say the LED turns on because in my interrupt
which doesn't check for anything, I turn on the LED. Putting the code that
turns on the LED in the following (bmRequest==VENDOR && bRequest == PEEK)
actually does nothing. It doesn't turn on the LED.

Regardless, wValue and wIndex do not appear in my device and anything that I
report back to the control message, which is supposed to show up in my my
data[] buffer, doesn't come back. I end up with garbage.

I'm essentially sending down an eeprom address, I return the value at that
given address. I don't receive the address in the device, and nothing shows
up in my buffer on the host.

I should also say that the LED turning on can be a coincidence of me using
libusb, the device being recognized as a keyboard, and the host sending down
a generic class request.

I turned on debugging, nothing really useful shows up, it says sending
control request to endpoint 0.

Any thoughts or suggestions I would greatly appreciate.

Jason
Post by Tim Roberts
Post by Jason Kotzin
I'm trying to get my firmware and software running with libusb1.0 and
am having some trouble in windows.
I've successfully ported my entire application to libusb 1.0 and it
works just fine in OSX. I haven't tested it much in linux, but at
first glance, everything is fine.
All I really needed to do was change my usb_control_msg calls.
My device appears to the computer as an HID usb keyboard, but I send
control messages to the device to do some extra functions. It's
critical that the device stays a keyboard, because that's what it's
intended to be.
Any control function I send down to the device doesn't really work. I
know the message is getting down to the device because I turn on an
LED if I see anything. I haven't turned on my debugger, but at first
glance it looks only to be libusb_request_type_class and
libusb_recipent_interface, nothing to do with my control request.
So, what doesn't work? You say the message is getting to device,
because it turns on an LED. Is that the byte you return is not getting
all the way back to you? If you initialize data to something, do you
see that something remain, or does it get changes?
BTW, requests that are not aimed at a specific endpoint should use
LIBUSB_RECIPIENT_DEVICE. When you specify LIBUSB_RECIPIENT_ENDPOINT,
Linux requires that you have claimed the interface that contains the
endpoint number in wIndex. In this case, you're specifying 0, which
should be OK, but most generic vendor commands should go to the device.
--
Providenza & Boekelheide, Inc.
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Tim Roberts
2010-04-19 22:16:34 UTC
Permalink
Post by Jason Kotzin
Actually nothing works. I say the LED turns on because in my
interrupt which doesn't check for anything, I turn on the LED.
Putting the code that turns on the LED in the following
(bmRequest==VENDOR && bRequest == PEEK) actually does nothing. It
doesn't turn on the LED.
What is VENDOR defined as? You're sending vendor/endpoint/incoming,
which is 0xC2.
Post by Jason Kotzin
Regardless, wValue and wIndex do not appear in my device and anything
that I report back to the control message, which is supposed to show
up in my my data[] buffer, doesn't come back. I end up with garbage.
I'm essentially sending down an eeprom address, I return the value at
that given address. I don't receive the address in the device, and
nothing shows up in my buffer on the host.
I should also say that the LED turning on can be a coincidence of me
using libusb, the device being recognized as a keyboard, and the host
sending down a generic class request.
Are you taking control away from the host by detaching the standard HID
driver?
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Pete Batard
2010-04-19 21:58:13 UTC
Permalink
Also:

http://libusb.org/wiki/windows_backend#KnownRestrictions
"Windows does not allow read or write access to HID keyboards and mice"

The reason behind that is that Windows reserves exclusive right to
system devices, and this is a restriction of the HID generic driver (or
rather the fact that HID keyboard and mice wouldn't use the HID generic
driver by default).

If that is really the issue at hand, I believe you should get a warning
from libusb if you have debugging on.

Regards,

/Pete
Jason Kotzin
2010-04-19 22:12:23 UTC
Permalink
Yes, I do receive something that says, attempting to open r/w access, did
not work, assuming HID keyboard or mouse.

However, isn't that the same thing that xusb is doing? I see control
transfer in there that send and receive data.

So if this truly is the case, how in the world do I send and receive
messages in windows? Can I detach the device? I can't use something other
than the HID generic driver because I would lose the ability to be a
keyboard and I don't want to travel down the road of trying to figure out
how to gain that back in a custom driver.

Thanks a lot Pete.

Jason
Post by Pete Batard
http://libusb.org/wiki/windows_backend#KnownRestrictions
"Windows does not allow read or write access to HID keyboards and mice"
The reason behind that is that Windows reserves exclusive right to
system devices, and this is a restriction of the HID generic driver (or
rather the fact that HID keyboard and mice wouldn't use the HID generic
driver by default).
If that is really the issue at hand, I believe you should get a warning
from libusb if you have debugging on.
Regards,
/Pete
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Peter Stuge
2010-04-19 22:14:28 UTC
Permalink
I can't use something other than the HID generic driver because I
would lose the ability to be a keyboard
Can you have two interfaces in the device? One keyboard, one vendor
specific? Attach WinUSB driver to the latter, and libusb should work
like a charm.


//Peter
Jason Kotzin
2010-04-19 22:23:38 UTC
Permalink
I believe this is possible, I'll have to look into it.

How do I attach the WinUSB driver, will this actually show up as two devices
in device manager?

Thanks Peter,
Jason
Post by Peter Stuge
I can't use something other than the HID generic driver because I
would lose the ability to be a keyboard
Can you have two interfaces in the device? One keyboard, one vendor
specific? Attach WinUSB driver to the latter, and libusb should work
like a charm.
//Peter
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Peter Stuge
2010-04-19 22:34:10 UTC
Permalink
Post by Jason Kotzin
I believe this is possible, I'll have to look into it.
How do I attach the WinUSB driver, will this actually show up as
two devices in device manager?
Yep. Eventually there should also be some tools from libusb for
creating .inf and installing the driver automatically.

(Maybe Pete finished it already, that would be libwdi AFAIU?)


//Peter
Jason Kotzin
2010-04-19 22:42:12 UTC
Permalink
Would this help create a custom driver that still presents itself as a
keyboard?

Thanks for the tip Jacob, maybe this is a good link for the libusb1.0 home
page.

Best,
Jason
Post by Peter Stuge
Eventually there should also be some tools from libusb for
creating .inf and installing the driver automatically.
LibUsbDotNet (https://sourceforge.net/projects/libusbdotnet/) already
has a really nice tool for generating .inf files for either libusb or
winusb drivers. Jason, you might want to look into that.
Pete Batard
2010-04-19 22:45:49 UTC
Permalink
Post by Peter Stuge
(Maybe Pete finished it already, that would be libwdi AFAIU?)
I'm afraid libwdi cannot yet be used to replace an existing device
driver (and I still have some way to go to get there - don't think I'll
add that until after the first official release).

Regards,

/Pete
Jacob Page
2010-04-19 22:38:03 UTC
Permalink
Post by Peter Stuge
Eventually there should also be some tools from libusb for
creating .inf and installing the driver automatically.
LibUsbDotNet (https://sourceforge.net/projects/libusbdotnet/) already
has a really nice tool for generating .inf files for either libusb or
winusb drivers. Jason, you might want to look into that.
Peter Stuge
2010-04-19 23:14:37 UTC
Permalink
LibUsbDotNet (https://sourceforge.net/projects/libusbdotnet/)
already has a really nice tool for generating .inf files for
either libusb or winusb drivers.
I think it would make sense to reuse as much of that tool as possible
also in the libusb project. I guess the logic will be replicated in
C..
Would this help create a custom driver that still presents itself
as a keyboard?
No. You still need two interfaces and a driver for each; one keyboard
and one other.

The .inf file is metadata for Windows drivers so you could use the
tool to create the .inf for the "other" interface in your device.
Thanks for the tip Jacob, maybe this is a good link for the
libusb1.0 home page.
I think so! Is there an info page for the tool - or a direct link to
a tool release or download?


//Peter
Jason Kotzin
2010-04-19 23:19:51 UTC
Permalink
Post by Peter Stuge
LibUsbDotNet (https://sourceforge.net/projects/libusbdotnet/)
already has a really nice tool for generating .inf files for
either libusb or winusb drivers.
I think it would make sense to reuse as much of that tool as possible
also in the libusb project. I guess the logic will be replicated in
C..
Would this help create a custom driver that still presents itself
as a keyboard?
No. You still need two interfaces and a driver for each; one keyboard
and one other.
The .inf file is metadata for Windows drivers so you could use the
tool to create the .inf for the "other" interface in your device.
Thanks for the tip Jacob, maybe this is a good link for the
libusb1.0 home page.
I think so! Is there an info page for the tool - or a direct link to
a tool release or download?
Here is the info page: http://libusbdotnet.sourceforge.net/V2/Index.html

Here is the download page:
http://sourceforge.net/projects/libusbdotnet/files/

Best,
Jason
Post by Peter Stuge
//Peter
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Pete Batard
2010-04-19 23:30:00 UTC
Permalink
Post by Peter Stuge
LibUsbDotNet (https://sourceforge.net/projects/libusbdotnet/)
already has a really nice tool for generating .inf files for
either libusb or winusb drivers.
I think it would make sense to reuse as much of that tool as possible
also in the libusb project. I guess the logic will be replicated in
C..
Well, actually, I lied when I said libwdi cannot yet be used to replace
an existing device driver, because it appears to work fine.

libwdi is precisely meant to do inf generation, driver installation and
some more, so once libwdi is released, we should have the edge over any
other tool (we already inf generation by the way).

I hadn't really tested driver replacement until now, but with my HID
dual interface keyboard, overwriting the existing driver for the extra
interface seems to work OK, and unlike what I feared, no extra calls
seems to be needed with regards to the driver installation API.

Still have a few issues with the GUI app, which is still a lot more
alpha than I would like (for instance it currently disappears from the
taskbar during installation, after unsigned driver prompt, and goes
right to the back of the screen, which makes it look like it vanished),
but if someone really needs it, I'll see what I can do to push a new
binary, as you then almost get a one click WinUSB driver installation.

Regards,

/Pete
Jason Kotzin
2010-04-19 23:45:33 UTC
Permalink
That's great to know. I'll definitely try to give this a shot, but
unfortunately, this is going to be a good amount of work to change the
firmware and the host software to test. I've verified that it is doable.

I can also technically send interrupts from this second device no longer
being a keyboard, yes?

I'll post my code later tonight for my current setup which Xiaofan
recommended. Hopefully I'm doing something obvious wrong or it's a problem
with my cross-compiler setup. The motivation which got me to port my code
to libusb1.0 was because I thought I could achieve control transfers to HID
devices in windows.

Thanks everyone for your quick responses and tips.

Jason
Post by Pete Batard
Post by Peter Stuge
LibUsbDotNet (https://sourceforge.net/projects/libusbdotnet/)
already has a really nice tool for generating .inf files for
either libusb or winusb drivers.
I think it would make sense to reuse as much of that tool as possible
also in the libusb project. I guess the logic will be replicated in
C..
Well, actually, I lied when I said libwdi cannot yet be used to replace
an existing device driver, because it appears to work fine.
libwdi is precisely meant to do inf generation, driver installation and
some more, so once libwdi is released, we should have the edge over any
other tool (we already inf generation by the way).
I hadn't really tested driver replacement until now, but with my HID
dual interface keyboard, overwriting the existing driver for the extra
interface seems to work OK, and unlike what I feared, no extra calls
seems to be needed with regards to the driver installation API.
Still have a few issues with the GUI app, which is still a lot more
alpha than I would like (for instance it currently disappears from the
taskbar during installation, after unsigned driver prompt, and goes
right to the back of the screen, which makes it look like it vanished),
but if someone really needs it, I'll see what I can do to push a new
binary, as you then almost get a one click WinUSB driver installation.
Regards,
/Pete
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Peter Stuge
2010-04-20 00:06:11 UTC
Permalink
Post by Jason Kotzin
That's great to know. I'll definitely try to give this a shot, but
unfortunately, this is going to be a good amount of work to change the
firmware and the host software to test. I've verified that it is doable.
Great. I think it results in a superior product, which will be far
more portable to non-Windows systems than something using only HID.
Post by Jason Kotzin
I can also technically send interrupts from this second device no
longer being a keyboard, yes?
There are never hardware interrupts from USB. Software in the PC must
know when to request data from the device. Devices can (and should)
respond with successful data transfer only when it is meaningful, and
NAK otherwise. In the PC software you may need to continuosly read
from the device. But you can use an infinite timeout so that the read
only returns when something has actually happened.
Post by Jason Kotzin
I'll post my code later tonight for my current setup which Xiaofan
recommended. Hopefully I'm doing something obvious wrong or it's a
problem with my cross-compiler setup.
Okey. I'm working on cross-compiling the library for w32 and w64
using mingw-w64. I'll make sure to note to the list if there's
anything special to consider.
Post by Jason Kotzin
The motivation which got me to port my code to libusb1.0 was
because I thought I could achieve control transfers to HID devices
in windows.
Well, it seems not, but in the end you may instead have a platform
independent device and platform independent PC software. :)


//Peter
Peter Stuge
2010-04-20 00:09:24 UTC
Permalink
Post by Peter Stuge
There are never hardware interrupts from USB.
..from USB devices that is!

The USB host controller chip certainly uses interrupts to signal the
operating system on events, but it's all in lower levels of the USB
stack and not so relevant from a driver or application programmer's
perspective. Sorry for the confusion!


//Peter
Jason Kotzin
2010-04-20 00:17:27 UTC
Permalink
This is what I understand from interrupts, and anyone can correct me.

Yes, I know it's not really an interrupt. You basically poll the device
continuously waiting for the device to say, 'hey, I have an interrupt'.

But this is not possible with keyboards or mice because osx in particular,
locks the device from anyone requesting interrupts. This is because, the OS
is already polling the keyboard and mouse for an interrupt, in which when
the device does have an interrupt, it's for a keyboard click or mouse
specific data.

~Jason
Post by Peter Stuge
Post by Peter Stuge
There are never hardware interrupts from USB.
..from USB devices that is!
The USB host controller chip certainly uses interrupts to signal the
operating system on events, but it's all in lower levels of the USB
stack and not so relevant from a driver or application programmer's
perspective. Sorry for the confusion!
//Peter
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Tim Roberts
2010-04-20 20:45:20 UTC
Permalink
Post by Jason Kotzin
This is what I understand from interrupts, and anyone can correct me.
Yes, I know it's not really an interrupt. You basically poll the
device continuously waiting for the device to say, 'hey, I have an
interrupt'.
But this is not possible with keyboards or mice because osx in
particular, locks the device from anyone requesting interrupts. This
is because, the OS is already polling the keyboard and mouse for an
interrupt, in which when the device does have an interrupt, it's for a
keyboard click or mouse specific data.
You say "I know it's not really an interrupt", but you are still
thinking about these as interrupts. That's just going to lead to
confusion on your part. You need to have the right "mental model". In
my humble opinion, the choice of the name "interrupt" was one of the
biggest mistakes made by the USB designers. It would have been much
better to use a word like "periodic".

An interrupt pipe is IDENTICAL to a bulk pipe, except that you can only
use your reserved chunk of the bandwidth. That's the ONLY difference.
Other than that, they are the same. The device does not interrupt. The
OS polls, and if the device has data, it sends it. (Which, it turns
out, is exactly the way a bulk pipe works, except that the controller
retries more often.)
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Pete Batard
2010-04-20 00:24:18 UTC
Permalink
Post by Peter Stuge
Okey. I'm working on cross-compiling the library for w32 and w64
using mingw-w64. I'll make sure to note to the list if there's
anything special to consider.
If you need a version of MinGW-w64 on Windows that has both w32 and w64,
in an easy (but large) single archive download, you can pick WPG
System64 from http://www.cadforte.com/system64.html

That's what I use to create the 32+64 bit compatible version of libwdi
in MinGW. Also what I now use to build and test the MinGW-w64 versions
of libusb.

Regards,

/Pete
Peter Stuge
2010-04-20 00:42:36 UTC
Permalink
Post by Pete Batard
cross-compiling the library for w32 and w64 using mingw-w64
If you need a version of MinGW-w64 on Windows that has both w32 and
w64, in an easy (but large) single archive download, you can pick
WPG System64 from http://www.cadforte.com/system64.html
Thanks! I used the Gentoo crossdev tool to build the two toolchains
with just one command each:

crossdev -t i686-w64-mingw32
crossdev -t x86_64-w64-mingw32

Though I used crossdev-git it seems that crossdev-20091209 and
-20100108 should both be able to do this.
Post by Pete Batard
That's what I use to create the 32+64 bit compatible version of
libwdi in MinGW. Also what I now use to build and test the
MinGW-w64 versions of libusb.
64 support seems very far along and several sources say that 32
support in mingw-w64 has plenty of advantages. It seems that libusb
binaries built with mingw-w64 may be usable for all Windows
development environments - even Cygwin. :) Fingers crossed.


//Peter
Peter Stuge
2010-04-20 00:07:10 UTC
Permalink
Post by Pete Batard
I hadn't really tested driver replacement until now, but with my HID
dual interface keyboard, overwriting the existing driver for the extra
interface seems to work OK, and unlike what I feared, no extra calls
seems to be needed with regards to the driver installation API.
Very cool!


//Peter
Jacob Page
2010-04-19 23:20:45 UTC
Permalink
Post by Peter Stuge
Is there an info page for the tool - or a direct link to
a tool release or download?
Seems http://libusbdotnet.sourceforge.net/V2/Index.html is the best
documentation for the tool.
https://sourceforge.net/projects/libusbdotnet/files/ is the download
page.
Xiaofan Chen
2010-04-19 23:41:41 UTC
Permalink
Post by Peter Stuge
I think so! Is there an info page for the tool - or a direct link to
a tool release or download?
libusbdotnet is linked in the language binding section
http://www.libusb.org/wiki/Libusb1.0
and the Windows backend page.
http://www.libusb.org/wiki/windows_backend
Probably the INF wizard can be advertised in the above page.
--
Xiaofan http://mcuee.blogspot.com
Pete Batard
2010-04-19 22:41:58 UTC
Permalink
Post by Jason Kotzin
How do I attach the WinUSB driver, will this actually show up as two
devices in device manager?
It should.

If you select to show devices by connection, and find your keyboard, you
might end up with the tree attached if your keyboard is a composite device.

In that case, you would need to replace the device driver for the branch
that doesn't end up in the device using the kbdhid.sys driver, as the
latter is the actual keyboard part.
You might have to click the "Driver Details" button to get that information.

In the attached image, you would replace the driver for the "USB
Enhanced Performance Keyboard" (the one below is actually a fake device
without a driver, as HID on Windows adds an extra node). Typically, you
would leave any branch that ends up with a keyboard device icon alone.

Regards,

/Pete
Tim Roberts
2010-04-19 22:17:57 UTC
Permalink
Post by Jason Kotzin
So if this truly is the case, how in the world do I send and receive
messages in windows? Can I detach the device?
Please excuse my last confusing message. I misread your original
message and thought you were working in Linux.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Pete Batard
2010-04-19 22:25:49 UTC
Permalink
Post by Jason Kotzin
However, isn't that the same thing that xusb is doing? I see control
transfer in there that send and receive data.
I'm afraid the HID devices xusb works against does not include HID
keyboards and mice. I tested them on my end as well, and there's very
little we can do, as the system drivers do not provide any kind of
generic USB functionality (the best we could do would be to retrieve key
codes, mice positions, and then simulate a fake USB transfer, but you
still wouldn't be able to do anything else).
Post by Jason Kotzin
So if this truly is the case, how in the world do I send and receive
messages in windows? Can I detach the device? I can't use something
other than the HID generic driver because I would lose the ability to be
a keyboard and I don't want to travel down the road of trying to figure
out how to gain that back in a custom driver.
If your keyboard provides multiple interfaces (or you can reprogram the
firmware to do so), then Peter's suggestion of using either the WinUSB
or generic HID driver on the interface you want to have control would be
the way to go. But that would only work if the standard keyboard control
is done on one interface, and all the extra functionality is done on
another.

Regards,

/Pete
Xiaofan Chen
2010-04-19 22:26:18 UTC
Permalink
Post by Jason Kotzin
Yes, I do receive something that says, attempting to open r/w access, did
not work, assuming HID keyboard or mouse.
However, isn't that the same thing that xusb is doing?  I see control
transfer in there that send and receive data.
I believe you can do control transfer with the HID device, even with the
system keyboard and mouse (but not interrupt transfer), that is
what xusb is doing.

Firstly please update to the latest version by using git.

To help us (and you), please post the HID report descriptor. And please
post your test program and the debug message.

When you do the following, the report ID is 0. Is that the case? Is your
keyboard a USB composite device?
libusb_control_transfer(handle,
LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT <<8)|0x00, 0 , output_report, 06,1000));
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-19 23:53:10 UTC
Permalink
Post by Xiaofan Chen
Post by Jason Kotzin
Yes, I do receive something that says, attempting to open r/w access, did
not work, assuming HID keyboard or mouse.
However, isn't that the same thing that xusb is doing?  I see control
transfer in there that send and receive data.
I believe you can do control transfer with the HID device, even with the
system keyboard and mouse (but not interrupt transfer), that is
what xusb is doing.
I made a mistake here. Yes it can do control transfer, but only for
the feature report.
Post by Xiaofan Chen
Firstly please update to the latest version by using git.
To help us (and you), please post the HID report descriptor. And please
post your test program and the debug message.
When you do the following, the report ID is 0. Is that the case? Is your
keyboard a USB composite device?
libusb_control_transfer(handle,
LIBUSB_ENDPOINT_OUT|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
HID_SET_REPORT, (HID_REPORT_TYPE_OUTPUT <<8)|0x00, 0 , output_report, 06,1000));
Ah, that is an output report. So maybe this is not possible.

You can use feature report (Control-IN and Control-Out) for the system
keyboard/mouse. But for output report, that is problematic. For Input
report, you can use Raw Input.

http://www.lvr.com/hidfaq.htm
1) Why do I receive "Access denied" when attempting to access my HID?

Windows 2000 and later have exclusive read/write access to HIDs
that are configured as a system keyboards or mice. An application
can obtain a handle to a system keyboard or mouse by not requesting
READ or WRITE access with CreateFile. Applications can then use
HidD_SetFeature and HidD_GetFeature (if the device supports
Feature reports).

2) How can applications receive Input reports from a system mouse or keyboard?

The Windows raw input API enables applications to read Input reports
when communicating with system mice and keyboards.
--
Xiaofan http://mcuee.blogspot.com
Peter Stuge
2010-04-20 00:11:37 UTC
Permalink
Post by Xiaofan Chen
Windows 2000 and later have exclusive read/write access to HIDs
that are configured as a system keyboards or mice. An application
can obtain a handle to a system keyboard or mouse by not requesting
READ or WRITE access with CreateFile. Applications can then use
HidD_SetFeature and HidD_GetFeature (if the device supports
Feature reports).
So this would be an alternative approach - but it will make the
device considerably less portable to any other platform than Windows.

(Mac users need to reboot, Linux users need system administrator access.)


//Peter
Xiaofan Chen
2010-04-20 02:10:09 UTC
Permalink
Post by Peter Stuge
Post by Xiaofan Chen
Windows 2000 and later have exclusive read/write access to HIDs
that are configured as a system keyboards or mice. An application
can obtain a handle to a system keyboard or mouse by not requesting
READ or WRITE access with CreateFile. Applications can then use
HidD_SetFeature and HidD_GetFeature (if the device supports
Feature reports).
So this would be an alternative approach - but it will make the
device considerably less portable to any other platform than Windows.
(Mac users need to reboot, Linux users need system administrator access.)
Using feature report is an alternative way. I think in that case, you
do not really use libusb since the Mac OS X HID backend is not
done yet. But I think it should be possible to use control transfer
with Mac OS X native HID API for the feature report.

For Linux, you do not need administrator access for libusb
based program if you have set up proper udev rules. Of
course udev is still one of the not-well-understood tool
for libusb users. Those kits (DeviceKit, PolicyKit, ConsoleKit etc)
add to the confusions even though they are not really necessary
to use for many libusb based programs -- a simple udev rule will
do.

That being said, it is probably better to use the alternative
solution in this case. If the device has one more interface
(custom), it can be used under Mac OS X and Windows along with
Linux, all using libusb.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-21 07:10:12 UTC
Permalink
I'm sorry to backtrack the conversation. I've been doing my reading and am
starting to change my firmware for this, but now I don't quite follow how
this will work....

For example, I create a composite device that is made up of a HID Keyboard,
and a second custom device. The HID keyboard receives the windows default
HID driver, while I can assign a different driver for the second custom
device, specifically libusb-1.0.

However, in my software, when I open the device and receive a handle, I'm
opening the VID/PID, Manufacturer String, etc, which are is the same for
both devices. How does windows know I want to open the second device for
read/write access if it's the same handle? Wont it just complain that it's
a keyboard/mouse again and open without read/write?

Is there a step I'm missing?

Thanks again for the help.

Best,
Jason
Post by Xiaofan Chen
Post by Peter Stuge
Post by Xiaofan Chen
Windows 2000 and later have exclusive read/write access to HIDs
that are configured as a system keyboards or mice. An application
can obtain a handle to a system keyboard or mouse by not requesting
READ or WRITE access with CreateFile. Applications can then use
HidD_SetFeature and HidD_GetFeature (if the device supports
Feature reports).
So this would be an alternative approach - but it will make the
device considerably less portable to any other platform than Windows.
(Mac users need to reboot, Linux users need system administrator access.)
Using feature report is an alternative way. I think in that case, you
do not really use libusb since the Mac OS X HID backend is not
done yet. But I think it should be possible to use control transfer
with Mac OS X native HID API for the feature report.
For Linux, you do not need administrator access for libusb
based program if you have set up proper udev rules. Of
course udev is still one of the not-well-understood tool
for libusb users. Those kits (DeviceKit, PolicyKit, ConsoleKit etc)
add to the confusions even though they are not really necessary
to use for many libusb based programs -- a simple udev rule will
do.
That being said, it is probably better to use the alternative
solution in this case. If the device has one more interface
(custom), it can be used under Mac OS X and Windows along with
Linux, all using libusb.
--
Xiaofan http://mcuee.blogspot.com
------------------------------------------------------------------------------
Download Intel&#174; Parallel Studio Eval
Try the new software tools for yourself. Speed compiling, find bugs
proactively, and fine-tune applications for parallel performance.
See why Intel Parallel Studio got high marks during beta.
http://p.sf.net/sfu/intel-sw-dev
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Xiaofan Chen
2010-04-21 07:13:48 UTC
Permalink
I'm sorry to backtrack the conversation.  I've been doing my reading and am
starting to change my firmware for this, but now I don't quite follow how
this will work....
For example, I create a composite device that is made up of a HID Keyboard,
and a second custom device.  The HID keyboard receives the windows default
HID driver, while I can assign a different driver for the second custom
device, specifically libusb-1.0.
There is no libusb-1.0 driver as of now. You would use WinUSB driver.
However, in my software, when I open the device and receive a handle, I'm
opening the VID/PID, Manufacturer String, etc, which are is the same for
both devices.  How does windows know I want to open the second device for
read/write access if it's the same handle?  Wont it just complain that it's
a keyboard/mouse again and open without read/write?
Is there a step I'm missing?
Thanks again for the help.
You need to call libusb_claim_interface(dev, 1) to claim the custom interface
(if your HID interface is using Interface 0 and the custom interface is
using Interface 1).
http://libusb.sourceforge.net/api-1.0/group__dev.html#ga32fabedf5f13fdecf1cb33acdb19b57a
--
Xiaofan http://mcuee.blogspot.com
Peter Stuge
2010-04-21 07:33:00 UTC
Permalink
Post by Xiaofan Chen
 Wont it just complain that it's a keyboard/mouse again and open
without read/write?
You need to call libusb_claim_interface(dev, 1) to claim the custom interface
On Windows I'm not sure there's any communication at all with the
device drivers until _claim_interface().

This may differ on other systems, but the behavior should be
identical.

(You claim the vendor specific interface, and it always works. :)


//Peter
Jason Kotzin
2010-04-21 22:47:37 UTC
Permalink
Resending without attachment...


As a quick test, I wanted to still make sure I'm not doing something obviously wrong. I changed my device not to be a composite device, but I took out the Keyboard and left it a standard HID class device.

In theory, I should now be able to run the same complied program and it should work, windows is no longer is locking the keyboard as this is just a standard HID device.

Here is what I did:

I ensured that my device is using the windows default dll driver for my usb device
Copied the precompiled libusb-1.0.dll into C:/Windows/System/
Enabled Debugging
Opened the correct interface

But the results were exactly the same.

On my Mac, here is the results of calling ./test peek 0 (returns the contents of my ucontroller eeprom at memory location 0)

~/Projects/flirc/commandline $ ./buildresults/Darwin_i386/gcc_4_2/release/test peek 0
Reading:
Opening device...
libusb:info [process_new_device] using existing device for location 0x04000000
libusb:info [process_new_device] found device with address 1 at 001-05ac-8005-09-00
libusb:info [process_new_device] using existing device for location 0x04500000
libusb:info [process_new_device] found device with address 2 at 002-05ac-8242-00-00
libusb:info [process_new_device] using existing device for location 0x04600000
libusb:info [process_new_device] found device with address 3 at 003-05ac-0236-00-00
libusb:info [process_new_device] using existing device for location 0x24000000
libusb:info [process_new_device] found device with address 1 at 001-05ac-8006-09-00
libusb:info [process_new_device] using existing device for location 0x24400000
libusb:info [process_new_device] found device with address 2 at 002-05ac-8507-ef-02
libusb:info [process_new_device] using existing device for location 0x24100000
libusb:info [process_new_device] found device with address 3 at 003-0424-2512-09-00
libusb:info [process_new_device] using existing device for location 0x24110000
libusb:info [process_new_device] found device with address 4 at 004-0424-2602-09-00
libusb:info [process_new_device] using existing device for location 0x24120000
libusb:info [process_new_device] found device with address 5 at 005-05ac-1005-09-00
libusb:info [process_new_device] using existing device for location 0x24111000
libusb:info [process_new_device] found device with address 6 at 006-0424-2228-00-00
libusb:info [process_new_device] using existing device for location 0x24113000
libusb:info [process_new_device] found device with address 7 at 007-0557-2008-00-00
libusb:info [process_new_device] using existing device for location 0x24122000
libusb:info [process_new_device] found device with address 8 at 008-05ac-021d-00-00
libusb:info [process_new_device] using existing device for location 0x24121000
libusb:info [process_new_device] found device with address 9 at 009-046d-c051-00-00
libusb:info [process_new_device] using existing device for location 0x24123000
libusb:info [process_new_device] found device with address 10 at 010-20a0-0002-00-00
libusb:info [process_new_device] using existing device for location 0x06000000
libusb:info [process_new_device] found device with address 1 at 001-05ac-8005-09-00
libusb:info [process_new_device] allocating new device for location 0x06100000
libusb:warning [process_new_device] could not retrieve device descriptor: device not responding. skipping device
libusb:info [process_new_device] allocating new device for location 0x06110000
libusb:warning [process_new_device] could not retrieve device descriptor: device not responding. skipping device
libusb:info [process_new_device] using existing device for location 0x26000000
libusb:info [process_new_device] found device with address 1 at 001-05ac-8006-09-00
libusb:info [darwin_open] device open for access
libusb:info [darwin_async_io_callback] an async io operation has completed
libusb:info [op_handle_events] checking fd 4 with revents = 0
libusb:info [op_handle_events] checking fd 6 with revents = 0
libusb:info [op_handle_events] checking fd 8 with revents = 1
libusb:info [darwin_control_callback] handling control completion with status 0
Address: 0 Data: FF
libusb:warning [libusb_exit] application left some devices open
libusb:info [event_thread_main] libopenusb/darwin.c event_thread_main: thread exiting

It works on my mac, Address 0 does in fact contain FF in my EEPROM.

Here are the results in windows:

C:\Documents and Settings\Administrator\Desktop>test.exe peek 0
Reading:
Opening device...
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0 for control request
Address: 0 Data: 0
libusb:warning [libusb_exit] application left some devices open

I know I'm not closing my devices, I still have yet to do any of my memory free function calls.

But I'm glad I did this quick check before re-writing a lot of my firmware. As always, thoughts and suggestions are greatly welcomed.

Below is my code:

int peek(int address)
{
libusb_device_handle *handle;
libusb_device *dev;

libusb_set_debug(NULL, 3);

printf("Opening device...\n");
handle = libusb_open_device_with_vid_pid(NULL, 0x20A0, 0x0002);

if (handle == NULL) {
printf(" Failed.\n");
return -1;
}

dev = libusb_get_device(handle);
libusb_claim_interface (handle, 0);


unsigned char data[1];
libusb_control_transfer(handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_ENDPOINT_IN,
PEEK,
address,
0,
(char *)data,
sizeof(data),
5000);

return (data[0]);
}


Thanks Again,
Jason
Post by Peter Stuge
Post by Xiaofan Chen
Wont it just complain that it's a keyboard/mouse again and open
without read/write?
You need to call libusb_claim_interface(dev, 1) to claim the custom interface
On Windows I'm not sure there's any communication at all with the
device drivers until _claim_interface().
This may differ on other systems, but the behavior should be
identical.
(You claim the vendor specific interface, and it always works. :)
//Peter
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Xiaofan Chen
2010-04-21 23:12:40 UTC
Permalink
  libusb_control_transfer(handle,
          LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_ENDPOINT_IN,
          PEEK,
          address,
          0,
          (char *)data,
          sizeof(data),
          5000);
You should either use Interrupt transfer from the IN endpoint or change to use
LIBUSB_RECIPIENT_INTERFACE instead of LIBUSB_RECIPIENT_ENDPOINT.
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-21 23:27:50 UTC
Permalink
Post by Xiaofan Chen
  libusb_control_transfer(handle,
          LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_ENDPOINT_IN,
          PEEK,
          address,
          0,
          (char *)data,
          sizeof(data),
          5000);
You should either use Interrupt transfer from the IN endpoint
Oops, this is obviously wrong since this has nothing to do with interrupt
transfer and the IN Endpoint (0x81).
Post by Xiaofan Chen
or change to use
LIBUSB_RECIPIENT_INTERFACE instead of LIBUSB_RECIPIENT_ENDPOINT.
This is still valid.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-21 23:37:38 UTC
Permalink
Didn't work, same results.
Post by Xiaofan Chen
Post by Jason Kotzin
libusb_control_transfer(handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_ENDPOINT_IN,
PEEK,
address,
0,
(char *)data,
sizeof(data),
5000);
You should either use Interrupt transfer from the IN endpoint or change to use
LIBUSB_RECIPIENT_INTERFACE instead of LIBUSB_RECIPIENT_ENDPOINT.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-21 23:52:03 UTC
Permalink
Ah, not sure if it was my reconfigure, sending to Interface rather than endpoint, or verbose level 4, but here is some more feedback from my program:


C:\Documents and Settings\Administrator\Desktop>test.exe peek 0
DEBUG VERSION

1d6b:0001 (bus 0, device 0)

20a0:0002 (bus 0, device 1)
Vendor: myvendorstring [Vendor Match]

Reading:
Opening device...
libusb:debug [libusb_get_device_list]
libusb:debug [usb_enumerate_hub] busnum 0 devaddr 0 session_id 0
libusb:debug [usb_enumerate_hub] allocating new device for session 0
libusb:debug [initialize_device] active config: 1
libusb:debug [usb_enumerate_hub] 2 ports Hub: \\.\USB#ROOT_HUB#4&2FB9F669&0#{F18A0E88-C30C-11D0-8815-00A0C906BED8}
libusb:debug [usb_enumerate_hub] busnum 0 devaddr 1 session_id 1
libusb:debug [usb_enumerate_hub] using existing device for session 1
libusb:debug [usb_enumerate_hub] busnum 1 devaddr 0 session_id 256
libusb:debug [usb_enumerate_hub] allocating new device for session 256
libusb:debug [initialize_device] active config: 1
libusb:debug [usb_enumerate_hub] 8 ports Hub: \\.\USB#ROOT_HUB20#4&1387C2E6&0#{F18A0E88-C30C-11D0-8815-00A0C906BED8}
libusb:debug [set_device_paths] path (0:1): \\.\USB#VID_20A0&PID_0002#5&46FA7B7&0&1#{A5DCBF10-6530-11D2-901F-00C04FB951ED}
libusb:debug [set_device_paths] driver: HidUsb
libusb:debug [set_hid_device] interface_path[0]: \\.\HID#VID_20A0&PID_0002#6&38687484&2&0000#{4D1E55B2-F16F-11CF-88CB-001111000030}
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_open] open 0.1
libusb:debug [hid_open] set maximum input buffer size to 512
libusb:debug [hid_open] 0 HID input report value(s) found
libusb:debug [hid_open] 0 HID output report value(s) found
libusb:debug [hid_open] 2 HID feature report value(s) found
libusb:debug [hid_open] Report ID: 0x01
libusb:debug [hid_open] Report ID: 0x02
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [hid_claim_interface] claimed interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to interface 0
libusb:debug [hid_submit_control_transfer] will use interface 0
Address: 0 Data: 0
libusb:debug [libusb_exit]
libusb:warning [libusb_exit] application left some devices open
libusb:debug [usbi_remove_pollfd] remove fd 3
libusb:debug [windows_clock_gettime_threaded] timer thread quitting
libusb:debug [libusb_exit] freeing default context

Thanks, you guys are awesome.

Best,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
libusb_control_transfer(handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT | LIBUSB_ENDPOINT_IN,
PEEK,
address,
0,
(char *)data,
sizeof(data),
5000);
You should either use Interrupt transfer from the IN endpoint or change to use
LIBUSB_RECIPIENT_INTERFACE instead of LIBUSB_RECIPIENT_ENDPOINT.
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-21 23:54:53 UTC
Permalink
Post by Jason Kotzin
Ah, not sure if it was my reconfigure, sending to Interface rather than
Glad it works.

I think verbose level 4 will enable the debug message. Sending to the interface
is anyway the correct thing to do.

I am not so sure what you mean by reconfigure -- rewrite the firmware.
I see that you are using feature report now.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-21 23:56:08 UTC
Permalink
Sorry, the application doesn't work, but I get a more verbose output.

The control message still gives back 0 when it should give back 0xFF.

Best,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
Ah, not sure if it was my reconfigure, sending to Interface rather than
Glad it works.
I think verbose level 4 will enable the debug message. Sending to the interface
is anyway the correct thing to do.
I am not so sure what you mean by reconfigure -- rewrite the firmware.
I see that you are using feature report now.
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-22 00:08:02 UTC
Permalink
Post by Jason Kotzin
Sorry, the application doesn't work, but I get a more verbose output.
The control message still gives back 0 when it should give back 0xFF.
Now you are using feature reports judging from the debug log, right?
Please post the HID report descriptor.

In that case, you should use the example in xusb.
r = libusb_control_transfer(handle,
LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer,
(uint16_t)size, 5000);

If you are using report ID 1 and 2, change the above
(HID_REPORT_TYPE_FEATURE<<8)|0
to
(HID_REPORT_TYPE_FEATURE<<8)|1 and
(HID_REPORT_TYPE_FEATURE<<8)|2.

Or here:
http://picusb.googlecode.com/files/libusb1_lvrhid8.c

If you are not using feature report, ignore the above.
But you can use feature report and give it a try.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-22 00:09:21 UTC
Permalink
Really sorry for my beginner questions, I find the spec really hard to follow.

I have a USB HID device that is vendor specific. So do I still need to use feature reports?

Thanks,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
Sorry, the application doesn't work, but I get a more verbose output.
The control message still gives back 0 when it should give back 0xFF.
Now you are using feature reports judging from the debug log, right?
Please post the HID report descriptor.
In that case, you should use the example in xusb.
r = libusb_control_transfer(handle,
LIBUSB_ENDPOINT_IN|LIBUSB_REQUEST_TYPE_CLASS|LIBUSB_RECIPIENT_INTERFACE,
HID_GET_REPORT, (HID_REPORT_TYPE_FEATURE<<8)|0, 0, report_buffer,
(uint16_t)size, 5000);
If you are using report ID 1 and 2, change the above
(HID_REPORT_TYPE_FEATURE<<8)|0
to
(HID_REPORT_TYPE_FEATURE<<8)|1 and
(HID_REPORT_TYPE_FEATURE<<8)|2.
http://picusb.googlecode.com/files/libusb1_lvrhid8.c
If you are not using feature report, ignore the above.
But you can use feature report and give it a try.
--
Xiaofan http://mcuee.blogspot.com
Peter Stuge
2010-04-22 07:03:43 UTC
Permalink
Post by Jason Kotzin
Really sorry for my beginner questions, I find the spec really
hard to follow.
I try reading the HID PDF now and then but they really made a mess. :)
Post by Jason Kotzin
I have a USB HID device that is vendor specific.
Will that work later? You mentioned that it must be a keyboard IIRC?


//Peter
Xiaofan Chen
2010-04-21 23:52:00 UTC
Permalink
Post by Jason Kotzin
As a quick test, I wanted to still make sure I'm not doing something
obviously wrong.  I changed my device not to be a composite device,
but I took out the Keyboard and left it a standard HID class device.
In theory, I should now be able to run the same complied program
and it should work, windows is no longer is locking the keyboard as
this is just a standard HID device.
Yes it should work.
Post by Jason Kotzin
I ensured that my device is using the windows default dll driver for my usb device
Copied the precompiled libusb-1.0.dll into C:/Windows/System/
Should be C:/Windows/System32
Post by Jason Kotzin
Enabled Debugging
Opened the correct interface
But the results were exactly the same.
On my Mac, here is the results of calling ./test peek 0
(returns the contents of my ucontroller eeprom at memory location 0)
If your device is a real HID device, you will need to use the codeless
kext to prevent the kernel HID driver from using it so that your libusb
program can work. Is that the case here?

I second Pete's suggestion to run xusb to test your device.
(under Windows and Mac OS X).
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-21 23:55:03 UTC
Permalink
I can't seem to cross compile xusb, here is what I'm getting:

CC xusb.o
CCLD xusb.exe
libtool: link: Could not determine host path corresponding to
libtool: link: '/Users/snookie/Projects/winusb/libusb/.libs'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link: '/usr/local/i386-mingw32-4.3.0/i386-mingw32/lib'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link: '/Users/snookie/Projects/winusb/libusb/.libs'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link: '/usr/local/i386-mingw32-4.3.0/i386-mingw32/lib'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link: '/usr/local/i386-mingw32-4.3.0/i386-mingw32/bin'
libtool: link: Continuing, but uninstalled executables may not work.
CC lsusb.o
CCLD lsusb.exe

Couldn't figure this one out.

Best,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
As a quick test, I wanted to still make sure I'm not doing something
obviously wrong. I changed my device not to be a composite device,
but I took out the Keyboard and left it a standard HID class device.
In theory, I should now be able to run the same complied program
and it should work, windows is no longer is locking the keyboard as
this is just a standard HID device.
Yes it should work.
Post by Jason Kotzin
I ensured that my device is using the windows default dll driver for my usb device
Copied the precompiled libusb-1.0.dll into C:/Windows/System/
Should be C:/Windows/System32
Post by Jason Kotzin
Enabled Debugging
Opened the correct interface
But the results were exactly the same.
On my Mac, here is the results of calling ./test peek 0
(returns the contents of my ucontroller eeprom at memory location 0)
If your device is a real HID device, you will need to use the codeless
kext to prevent the kernel HID driver from using it so that your libusb
program can work. Is that the case here?
I second Pete's suggestion to run xusb to test your device.
(under Windows and Mac OS X).
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-21 23:59:52 UTC
Permalink
 CC     xusb.o
 CCLD   xusb.exe
libtool: link: Could not determine host path corresponding to
libtool: link:   '/Users/snookie/Projects/winusb/libusb/.libs'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link:   '/usr/local/i386-mingw32-4.3.0/i386-mingw32/lib'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link:   '/Users/snookie/Projects/winusb/libusb/.libs'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link:   '/usr/local/i386-mingw32-4.3.0/i386-mingw32/lib'
libtool: link: Continuing, but uninstalled executables may not work.
libtool: link: Could not determine host path corresponding to
libtool: link:   '/usr/local/i386-mingw32-4.3.0/i386-mingw32/bin'
libtool: link: Continuing, but uninstalled executables may not work.
 CC     lsusb.o
 CCLD   lsusb.exe
Yes there is an issue when doing cross-compiling. You can
compile the example by your self once you have libusb-1.0.a
file and libusb-1.0.dll file.

Copy libusb.h to your MinGW include directory.
Copy libusb-1.0.a to your MinGW lib directory.

gcc -o lsusb lsusb.c -lusb
gcc -o xusb xusb.c -lusb

(change gcc to your mingw gcc name).
--
Xiaofan http://mcuee.blogspot.com
Pete Batard
2010-04-22 00:02:01 UTC
Permalink
So, you're cross compiling. I think you mentioned that before, but I
didn't realise that until now
Post by Jason Kotzin
CCLD xusb.exe
libtool: link: Continuing, but uninstalled executables may not work.
It might still work. For reference, this is what you should replace the
test_hid function with in xusb, to replicate what your original program
does.

------------------------------------------------------------------

int test_hid(libusb_device_handle *handle, uint8_t endpoint_in)
{
int size;
uint8_t data[1];
int address = 0; // use a valid address here
#define PEEK 0 //<YOUR VALUE>

printf("\nReading Data:\n");

size = libusb_control_transfer(handle,
LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_ENDPOINT |
LIBUSB_ENDPOINT_IN,
PEEK,
address,
0,
(char *)data,
sizeof(data),
5000);

if (size < 0) {
printf("failed: %s\n", libusb_strerror(size));
return -1;
} else {
display_buffer_hex(data, size);
}
return 0;
}
Xiaofan Chen
2010-04-20 23:54:04 UTC
Permalink
Post by Xiaofan Chen
I made a mistake here. Yes it can do control transfer, but only for
the feature report.
You can use feature report (Control-IN and Control-Out) for the system
keyboard/mouse. But for output report, that is problematic. For Input
report, you can use Raw Input.
http://www.lvr.com/hidfaq.htm
1) Why do I receive "Access denied" when attempting to access my HID?
Windows 2000 and later have exclusive read/write access to HIDs
that are configured as a system keyboards or mice. An application
can obtain a handle to a system keyboard or mouse by not requesting
READ or WRITE access with CreateFile. Applications can then use
HidD_SetFeature and HidD_GetFeature (if the device supports
Feature reports).
Just to show this. Here is a log running xusb against a USB mouse.
The log is quite clear.

***@AcerPC ~/mcu/libusb1win32/git/cygwin/libusb-pbatard/examples
$ ./xusb.exe -i 046d:c054
libusb:debug [libusb_init]
libusb:debug [init_polling] Will use CancelIoEx for I/O cancellation
libusb:debug [windows_clock_gettime_threaded] hires timer available (Frequency:
25000000 Hz)
libusb:debug [usbi_add_pollfd] add fd 3 events 1
libusb:debug [libusb_init] created default context
Opening device...
libusb:debug [libusb_get_device_list]
libusb:debug [usb_enumerate_hub] busnum 0 devaddr 0 session_id 0
libusb:debug [usb_enumerate_hub] allocating new device for session 0
libusb:debug [initialize_device] active config: 1
libusb:debug [usb_enumerate_hub] 8 ports Hub: \\.\USB#ROOT_HUB20#4&7056C45&0#{F1
8A0E88-C30C-11D0-8815-00A0C906BED8}
libusb:debug [usb_enumerate_hub] busnum 1 devaddr 0 session_id 256
libusb:debug [usb_enumerate_hub] allocating new device for session 256
libusb:debug [initialize_device] active config: 1
libusb:debug [usb_enumerate_hub] 8 ports Hub: \\.\USB#ROOT_HUB#4&278C294E&0#{F18
A0E88-C30C-11D0-8815-00A0C906BED8}
libusb:debug [usb_enumerate_hub] busnum 1 devaddr 1 session_id 257
$
libusb:debug [initialize_device] active config: 1
libusb:debug [cache_config_descriptors] cached config descriptor #1 (32 bytes)
libusb:debug [usb_enumerate_hub] busnum 1 devaddr 2 session_id 258
libusb:debug [usb_enumerate_hub] allocating new device for session 258
libusb:debug [initialize_device] active config: 1
libusb:debug [cache_config_descriptors] cached config descriptor #1 (41 bytes)
libusb:debug [cache_config_descriptors] cached config descriptor #2 (32 bytes)
libusb:debug [usb_enumerate_hub] busnum 1 devaddr 3 session_id 259
libusb:debug [usb_enumerate_hub] allocating new device for session 259
libusb:debug [initialize_device] active config: 1
libusb:debug [cache_config_descriptors] cached config descriptor #1 (34 bytes)
libusb:debug [usb_enumerate_hub] busnum 1 devaddr 4 session_id 260
libusb:debug [usb_enumerate_hub] allocating new device for session 260
libusb:debug [initialize_device] active config: 1
libusb:debug [cache_config_descriptors] cached config descriptor #1 (46 bytes)
libusb:debug [set_device_paths] path (1:3): \\.\USB#VID_046D&PID_C054#5&207B166D
&0&3#{A5DCBF10-6530-11D2-901F-00C04FB951ED}
libusb:debug [set_device_paths] driver: HidUsb
libusb:debug [set_hid_device] interface_path[0]: \\.\HID#VID_046D&PID_C054#6&334
DE466&0&0000#{4D1E55B2-F16F-11CF-88CB-001111000030}
libusb:debug [set_device_paths] path (1:2): \\.\USB#VID_04D8&PID_0033#PK2NEW#{A5
DCBF10-6530-11D2-901F-00C04FB951ED}
libusb:debug [set_device_paths] driver: HidUsb
libusb:debug [set_hid_device] interface_path[0]: \\.\HID#VID_04D8&PID_0033#6&BD5
B18B&0&0000#{4D1E55B2-F16F-11CF-88CB-001111000030}
libusb:debug [set_device_paths] path (1:1): \\.\USB#VID_058F&PID_9360#2004888#{A
5DCBF10-6530-11D2-901F-00C04FB951ED}
libusb:debug [set_device_paths] driver: USBSTOR
libusb:debug [set_device_paths] path (1:4): \\.\USB#VID_0925&PID_1456#5&207B166D
&0&5#{A5DCBF10-6530-11D2-901F-00C04FB951ED}
libusb:debug [set_device_paths] driver: WinUSB
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_get_device_descriptor]
libusb:debug [libusb_open] open 1.3
libusb:warning [hid_open] could not open HID device in R/W mode (keyboard or mou
se?) - trying without
libusb:debug [hid_open] set maximum input buffer size to 512
libusb:debug [hid_open] 4 HID input report value(s) found
libusb:debug [hid_open] will use report ID 0x00 for interrupt transfers
libusb:debug [hid_open] 0 HID output report value(s) found
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
libusb:debug [libusb_unref_device] destroy device 1.1
libusb:debug [libusb_unref_device] destroy device 1.2
libusb:debug [libusb_unref_device] destroy device 1.4

Reading device descriptor:
libusb:debug [libusb_get_device_descriptor]
length: 18
device class: 0
S/N: 0
VID:PID: 046D:C054
bcdDevice: 5400
iMan:iProd:iSer: 1:2:0
nb confs: 1

Reading configuration descriptors:
libusb:debug [libusb_get_config_descriptor] index 0
nb interfaces: 1
interface[0].altsetting[0]: num endpoints = 1
Class.SubClass.Protocol: 03.01.02
endpoint[0].address: 81
max packet size: 0006
polling interval: 0A

Reading string descriptors:
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [hid_claim_interface] claimed interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to interface 0
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0 for contro
l request
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.992920s
libusb:debug [handle_events] poll() 2 fds with timeout in 993ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.997440s
libusb:debug [handle_events] poll() 2 fds with timeout in 998ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.997280s
libusb:debug [handle_events] poll() 2 fds with timeout in 998ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=18
String (1/3): "Logitech"
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.997440s
libusb:debug [handle_events] poll() 2 fds with timeout in 998ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.997400s
libusb:debug [handle_events] poll() 2 fds with timeout in 998ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=36
String (2/3): "USB Optical Mouse"
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.996800s
libusb:debug [handle_events] poll() 2 fds with timeout in 997ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.997440s
libusb:debug [handle_events] poll() 2 fds with timeout in 998ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=2
String (3/3): ""

Reading HID Report Descriptors:
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_REPORT
libusb:debug [usbi_add_pollfd] add fd 5 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.997440s
libusb:debug [handle_events] poll() 2 fds with timeout in 998ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 5 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 5
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=20

06 A0 FF 09 01 A1 01 09 01 15 00 25 FF 75 08 95
06 81 00 C0

Skipping Feature Report readout (None detected)

Reading Input Report (length 6)...
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_report] report ID: 0x00
libusb:debug [_hid_get_report] Failed to Read HID Input Report: [5] Access is de
nied.

Error: Input/output error

Testing interrupt read using endpoint 81...
libusb:debug [hid_submit_bulk_transfer] matched endpoint 81 with interface 0
libusb:debug [hid_submit_bulk_transfer] reading 7 bytes (report ID: 0x00)
libusb:error [hid_submit_bulk_transfer] HID transfer failed: [5] Access is denie
d.

Input/output error

Releasing interface 0...
libusb:debug [libusb_release_interface] interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to interface 0
Closing device...
libusb:debug [libusb_close]
libusb:debug [libusb_unref_device] destroy device 1.3
libusb:debug [libusb_exit]
libusb:debug [usbi_remove_pollfd] remove fd 3
libusb:debug [windows_clock_gettime_threaded] timer thread quitting
libusb:debug [libusb_exit] freeing default context
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-20 02:16:20 UTC
Permalink
Post by Jason Kotzin
I should also note that my application complained that I was missing the
libusb-1.0.0.dll, even though I compiled statically. Not sure why this was
the case.
This is a separate issue. I believe the default configure scripts generated
libusb.a (with MinGW and Cygwin) still is not static and would still
need libusb-1.0.dll.

And if you have libusb-1.0.0.dll, it is an old version. The newer
version generated libusb-1.0.dll.
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-20 02:21:29 UTC
Permalink
Post by Xiaofan Chen
Post by Jason Kotzin
I should also note that my application complained that I was missing the
libusb-1.0.0.dll, even though I compiled statically. Not sure why this was
the case.
This is a separate issue. I believe the default configure scripts generated
libusb.a (with MinGW and Cygwin) still is not static and would still
need libusb-1.0.dll.
And if you have libusb-1.0.0.dll, it is an old version. The newer
version generated libusb-1.0.dll.
You can also use the snapshot from Pete.
http://www.libusb.org/wiki/windows_backend
http://libusb-winusb-wip.googlecode.com/files/libusb_2010.04.19.7z
Michael Plante
2010-04-20 02:25:39 UTC
Permalink
Post by Peter Stuge
Okey. I'm working on cross-compiling the library for w32 and w64
using mingw-w64. I'll make sure to note to the list if there's
anything special to consider.
Pete: here's a patch that Peter needed to apply to fix a problem with
timespec. Also, when you get a chance, please apply Daniel's changes
(diffing against windows_merge2 before pushing, since configure.ac will
conflict).

Thanks,
Michael
Pete Batard
2010-04-20 14:49:19 UTC
Permalink
Post by Michael Plante
Pete: here's a patch that Peter needed to apply to fix a problem with
timespec.
r268
Post by Michael Plante
Also, when you get a chance, please apply Daniel's changes
(diffing against windows_merge2 before pushing, since configure.ac will
conflict).
r267. I didn't diff against merge2 but used a cherry pick of official
(which left me with some residuals as I picked more than I should have
and had to sort some conflicts. I wish that git was smart enough to tell
"hey, looks like you already applied a similar commit - wanna ignore
this one?").

Does this mean that the current commits in merge2 are here to stay now?

Regards,

/Pete
Michael Plante
2010-04-20 02:35:22 UTC
Permalink
Xiaofan wrote:
Xiaofan Chen
2010-04-20 03:17:48 UTC
Permalink
On Tue, Apr 20, 2010 at 10:35 AM, Michael Plante
I have no clue if it's the right way to do things, but I did manage to make
i686-mingw32-gcc -static -Wshadow -std=gnu99 -fgnu89-inline -Wall -Wundef -W
unused -Wstrict-prototypes -Werror-implicit-function-declaration -Wno-pointe
r-sign -g -O2 -o .libs/lsusb.exe lsusb.o
 ../libusb/.libs/libusb-1.0.a -lsetupapi -lole32 -ladvapi32 -L/usr/local/lib
Ah I think this looks about right. I will try it under MinGW and Cygwin.
when linked (crossdev in Linux, like Peter), and copied back to windows,
depends showed no deps on libusb, and it ran fine w/o a dll.  About 330 KB.
YMMV...
We were messing around with exports, and I should point out that the
resulting lsusb.exe exported all of libusb's symbols.  Weird...
I need to understand the exports first...
--
Xiaofan http://mcuee.blogspot.com
Michael Plante
2010-04-20 15:00:34 UTC
Permalink
Post by Pete Batard
Post by Michael Plante
Also, when you get a chance, please apply Daniel's changes
(diffing against windows_merge2 before pushing, since configure.ac will
conflict).
r267. I didn't diff against merge2 but used a cherry pick of official
(which left me with some residuals as I picked more than I should have
and had to sort some conflicts.
Are you sure that's the cause?
Post by Pete Batard
I wish that git was smart enough to tell
"hey, looks like you already applied a similar commit - wanna ignore
this one?").
How similar? Similar enough that picking should be a no-op? If so, in my
experience, it usually does skip that commit like it should. It just
depends. But I have a private branch (you could use a tag, alternatively)
that points to the last commit from Daniel that I've incorporated. I just
reset that branch to a new point whenever I rebase on top of new upstream
commits, to lessen the likelihood that I forget where I left off.
Post by Pete Batard
Does this mean that the current commits in merge2 are here to stay now?
Not sure what you mean. They change anytime new stuff is done by either you
or Peter (or, if requested, me). It is rewritten frequently, if that's what
you're asking. It will become static once the patches go to Daniel, but I
don't know when that will be.

If you're asking about NLS, I still don't know what the story is there, but
we should bring that discussion on-list, as Peter mentioned. Could you
write a new email to the list, incorporating the main points you and Peter
made? Because our branches differ on that right now, and I don't know how
this will be resolved.

Michael
Pete Batard
2010-04-20 15:21:05 UTC
Permalink
Post by Michael Plante
Are you sure that's the cause?
Looks like it, as the darwin_usb.c I should have gotten at the end of
the merge looks like the one I already had in my tree (and the changes
to darwin_usb.c I introduced during the merge had to be reverted).
Post by Michael Plante
Post by Pete Batard
I wish that git was smart enough to tell
"hey, looks like you already applied a similar commit - wanna ignore
this one?").
How similar? Similar enough that picking should be a no-op?
Yes.
Post by Michael Plante
If so, in my
experience, it usually does skip that commit like it should.
OK. I can only report that it doesn't seem to have happened on my end.
Post by Michael Plante
But I have a private branch (you could use a tag, alternatively)
that points to the last commit from Daniel that I've incorporated.
That's an idea, although with proper detection of noops, I should be
able to do what I just did, ie pick all the official commits between
1.0.6 and 1.0.7 and have a clean merge when there's an official version out.
Post by Michael Plante
It is rewritten frequently, if that's what you're asking.
Yes that's what I meant. I've read all over the place that once a git
commit is public, it's a bad idea to delete it, even if it's to recreate
a similar one.
Post by Michael Plante
If you're asking about NLS, I still don't know what the story is there,
Nope, that wasn't about NLS.
Post by Michael Plante
we should bring that discussion on-list, as Peter mentioned.
Will do.

Regards,

/Pete
Michael Plante
2010-04-20 15:17:54 UTC
Permalink
Post by Michael Plante
Post by Pete Batard
Does this mean that the current commits in merge2 are here to stay
now?
Post by Michael Plante
Not sure what you mean. They change anytime new stuff is done by either
you or Peter (or, if requested, me). It is rewritten frequently, if
that's
Post by Michael Plante
what you're asking. It will become static once the patches go to Daniel,
but I don't know when that will be.
I think I have a guess what you might be after. Are you assuming it's
necessary for the commits to be final before you can diff? If so, the
answer is definitely no. Assuming you've checked out your own master, it's
just:

$ git diff mplante/windows_merge2

Very straightforward, and I just wanted you to double-check you resolved the
configure.ac conflict the same way I did, but it turns out it's fine anyway,
without checking work...

If you're looking for the commits where I resolved those, you won't find
them, because, as I probably mentioned at some point, I rebase on top of the
latest upstream.

Michael
Michael Plante
2010-04-20 15:33:49 UTC
Permalink
Post by Pete Batard
That's an idea, although with proper detection of noops, I should be
able to do what I just did, ie pick all the official commits between
1.0.6 and 1.0.7 and have a clean merge when there's an official version
out.

Oh sure, but you're not sharing history with those; you've generally just
cherry-picked instead of merging OR rebasing. And we do have conflicts with
some of those changes that we've already taken the trouble to resolve.
Post by Pete Batard
Yes that's what I meant. I've read all over the place that once a git
commit is public, it's a bad idea to delete it, even if it's to recreate
a similar one.
It has to be made known that it will be done this way, so people are (should
be) careful not to base history on it. But you don't seem to base history
on anything new, so I don't think it's an issue. Ditto Daniel. Peter can
handle it (and said so). I raised this issue with Peter when I started with
git, and he indicated it's more of an issue for you than me, since people
usually won't be making commits on top of my tree. It basically requires
others to rebase when I do, which would be a pain in the neck, since I don't
generally say anything when I do (though I can certainly comment in IRC if
that would actually help anyone...I doubt it). I do it too often to email
the list about it.

But this is not a warning against merging, just rebase/reset/amend/etc.
Treat it as a warning, not an error; think. :)

I also don't see how this is relevant to the matter at hand, which was
diffing, and which could theoretically be done without git, as I'm just
asking about content, not "how it got that way" (commits).

Regards,
Michael
Pete Batard
2010-04-20 15:58:53 UTC
Permalink
Post by Michael Plante
Oh sure, but you're not sharing history with those; you've generally just
cherry-picked instead of merging OR rebasing.
Yes, because whatever has already been applied to official doesn't need
to be broken down in any of our branches, since our branches are meant
for merging back with official. The goal is to keep a clean master, and
anything we pick from official will be ignored when merged back, which
is why I don't have a problem cherry picking and squashing anything that
comes from official into a single commit.

If you think that's a bad idea, I can abstain doing so, but I think it
leaves my tree clearer (just like the commits from my tree that are
squashed/massaged in merge2 for official).
Post by Michael Plante
And we do have conflicts with
some of those changes that we've already taken the trouble to resolve.
Do you mean you currently have conflicts from my squashed official merge
commit + residual (r267/268)?

The only thing I should have changed there, that didn't come from
official, is bump the version minor from 6 to 7 in the new vars we use
in configure.ac.

The rest of the commit diff should be 100% official changes, so if you
applied the same changes, we should end up with the same tree.

If not, just let me know what you guys want me to do.

Regards,

/Pete
Michael Plante
2010-04-20 16:09:39 UTC
Permalink
Post by Pete Batard
Post by Michael Plante
Oh sure, but you're not sharing history with those; you've generally
just
Post by Pete Batard
Post by Michael Plante
cherry-picked instead of merging OR rebasing.
Yes, because whatever has already been applied to official doesn't need
to be broken down in any of our branches, since our branches are meant
for merging back with official. The goal is to keep a clean master, and
anything we pick from official will be ignored when merged back, which
is why I don't have a problem cherry picking and squashing anything that
comes from official into a single commit.
Except that failing to maintain history is likely the root of your conflict
problem. I've gotten used to you doing this, so I'm not complaining. I'm
just saying that git is likely to be more intelligent if it knows that those
commits came from upstream, rather than having git think it's random
duplicated effort, and therefore flagging it as a conflict. And I'm not
even sure that squashing is an issue, though it might contribute; I'm saying
commit parent hierarchy/ancestry is the probable issue. If you want a
linear history, you have to be prepared to only cherry-pick commits you
haven't already dealt with; you can't have it both ways, I don't think.
Post by Pete Batard
If you think that's a bad idea, I can abstain doing so, but I think it
leaves my tree clearer (just like the commits from my tree that are
squashed/massaged in merge2 for official).
Reverting changes that could have easily been avoided is not clean. It's
not entirely clear to me how that even happened. Is this another Tortoise
problem?
Post by Pete Batard
Do you mean you currently have conflicts from my squashed official merge
commit + residual (r267/268)?
No. I mean we have made many changes, and some of those will conflict with
changes in the range you specified (but one of us snipped): v1.0.6..v1.0.7


Michael
Michael Plante
2010-04-21 23:04:24 UTC
Permalink
Post by Jason Kotzin
C:\Documents and Settings\Administrator\Desktop>test.exe peek 0
Opening device...
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0 for
control request
Post by Jason Kotzin
Address: 0 Data: 0
libusb:warning [libusb_exit] application left some devices open
Are you snipping log messages? If not, and if you're using the prebuilt
binary (this advice may not hold true indefinitely, but it is, afaik, true
now), you need to call libusb_set_debug with level 4 to get more messages.
(Pete: correct me if I'm misunderstanding.)

Regards,
Michael
Jason Kotzin
2010-04-21 23:09:49 UTC
Permalink
Nope, not snipping anything. That's all I get.
Post by Jason Kotzin
Post by Jason Kotzin
C:\Documents and Settings\Administrator\Desktop>test.exe peek 0
Opening device...
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0 for
control request
Post by Jason Kotzin
Address: 0 Data: 0
libusb:warning [libusb_exit] application left some devices open
Are you snipping log messages? If not, and if you're using the prebuilt
binary (this advice may not hold true indefinitely, but it is, afaik, true
now), you need to call libusb_set_debug with level 4 to get more messages.
(Pete: correct me if I'm misunderstanding.)
Regards,
Michael
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Pete Batard
2010-04-21 23:17:23 UTC
Permalink
Post by Michael Plante
Are you snipping log messages? If not, and if you're using the prebuilt
binary (this advice may not hold true indefinitely, but it is, afaik, true
now), you need to call libusb_set_debug with level 4 to get more messages.
That's what I was about to suggest, but you need to have generated
libusb with --enable-toggable-debug during the configure step.

This should be the case of the binaries I put only.

Or if you want to have debug always, you need to use --enable-debug-log

Alternatively, you could modify the test_hid part of xusb to replace it
with your function (with a fixed address), as you would then be able to
use 'xusb -i -d 20A0:2'. This would eliminate the remote possibility
that some other part of your code is interfering.

I'll try to do just that on my side, using your code, but I'll have to
see if I can get a device that returns data with this call.

Regards,

/Pete
Xiaofan Chen
2010-04-21 23:25:34 UTC
Permalink
Post by Pete Batard
I'll try to do just that on my side, using your code, but I'll have to
see if I can get a device that returns data with this call.
You can probably add the vendor requests to the Generic HID
device firmware from Jan Axelson.

Vendor specific requests are included in the generic WinUSB
example.
http://www.lvr.com/winusb.htm
http://www.microchip.com/forums/fb.aspx?m=475777
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-21 23:39:11 UTC
Permalink
I tried doing a reconfigure with enable-debug-log and then I removed toggling debug messages in my program, and debug messages didn't show up at all. I also get the following warning when I try to complie:

Warning: resolving _libusb_exit by linking to ***@4
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
Warning: resolving _libusb_control_transfer by linking to ***@32

Not sure if this is related.
Post by Pete Batard
Post by Michael Plante
Are you snipping log messages? If not, and if you're using the prebuilt
binary (this advice may not hold true indefinitely, but it is, afaik, true
now), you need to call libusb_set_debug with level 4 to get more messages.
That's what I was about to suggest, but you need to have generated
libusb with --enable-toggable-debug during the configure step.
This should be the case of the binaries I put only.
Or if you want to have debug always, you need to use --enable-debug-log
Alternatively, you could modify the test_hid part of xusb to replace it
with your function (with a fixed address), as you would then be able to
use 'xusb -i -d 20A0:2'. This would eliminate the remote possibility
that some other part of your code is interfering.
I'll try to do just that on my side, using your code, but I'll have to
see if I can get a device that returns data with this call.
Regards,
/Pete
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Pete Batard
2010-04-21 23:53:43 UTC
Permalink
Did you pick up the sources from git?
If so, running ./autogen.sh should make sure that debugging is enabled
(and you should just run make afterwards)
Post by Jason Kotzin
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
Not sure if this is related.
I don't think it is, but I noticed that one thing you are not doing in
your application is actually checking the value returned by
libusb_control_transfer.

This should be the number of bytes read, or an error, and if the number
of bytes read is 0 or you get an error, then of course your data will be
invalid (which is where the debug would help).

Regards,

/Pete
Jason Kotzin
2010-04-22 00:04:26 UTC
Permalink
Post by Pete Batard
I don't think it is, but I noticed that one thing you are not doing in
your application is actually checking the value returned by
libusb_control_transfer.
This should be the number of bytes read, or an error, and if the number
of bytes read is 0 or you get an error, then of course your data will be
invalid (which is where the debug would help).
Really good suggestion, I got back -2, which looks like

/** Invalid parameter */
LIBUSB_ERROR_INVALID_PARAM = -2

Digging through the doc to figure out what that means,

Thanks,
Jason
Pete Batard
2010-04-22 00:07:48 UTC
Permalink
Post by Jason Kotzin
Really good suggestion, I got back -2, which looks like
/** Invalid parameter */
LIBUSB_ERROR_INVALID_PARAM = -2
Digging through the doc to figure out what that means,
Aha. I can replicate the issue then:

Reading Data:
libusb:debug [hid_submit_control_transfer] will use interface 0
failed: Invalid parameter

Let me see what I can find out.

Regards,

/Pete
Jason Kotzin
2010-04-22 00:17:26 UTC
Permalink
I'm poking around as well, let me know if I can do anything to help on your end.

Thanks guys,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
Really good suggestion, I got back -2, which looks like
/** Invalid parameter */
LIBUSB_ERROR_INVALID_PARAM = -2
Digging through the doc to figure out what that means,
libusb:debug [hid_submit_control_transfer] will use interface 0
failed: Invalid parameter
Let me see what I can find out.
Regards,
/Pete
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Pete Batard
2010-04-22 00:21:55 UTC
Permalink
OK, well, our implementation doesn't support LIBUSB_REQUEST_TYPE_VENDOR,
and returns invalid parameter then.

The only request type we currently support are
LIBUSB_REQUEST_TYPE_STANDARD and LIBUSB_REQUEST_TYPE_CLASS.

Actually, since the HID code I used was pretty much a copy/paste from
libusb-win32, and that wasn't implemented there, I must admit that I
don't really have a clear idea about how we should implement vendor
requests in the Windows backend (or if it's even possible with the HID
API). I'll check what can be achieved, but it might take a little while.

Regards,

/Pete
Jason Kotzin
2010-04-22 00:34:07 UTC
Permalink
Awesome. However, I changed my code to the following:

unsigned char data[1];
result = libusb_control_transfer(handle,
LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_INTERFACE | LIBUSB_ENDPOINT_IN,
PEEK,
address,
0,
(char *)data,
sizeof(data),
5000);
printf("Result of control transfer: %d\n", result);
return (data[0]);

Same results, operation not supported. Do I have to change the interface/endpoint now? I've read the spec a lot, it's really convoluted and abstract, I can't figure out what the real difference is between all those, which is why I was using vendor, so I don't have to care.

Thanks Pete,
Jason
Post by Pete Batard
OK, well, our implementation doesn't support LIBUSB_REQUEST_TYPE_VENDOR,
and returns invalid parameter then.
The only request type we currently support are
LIBUSB_REQUEST_TYPE_STANDARD and LIBUSB_REQUEST_TYPE_CLASS.
Actually, since the HID code I used was pretty much a copy/paste from
libusb-win32, and that wasn't implemented there, I must admit that I
don't really have a clear idea about how we should implement vendor
requests in the Windows backend (or if it's even possible with the HID
API). I'll check what can be achieved, but it might take a little while.
Regards,
/Pete
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Pete Batard
2010-04-22 00:54:12 UTC
Permalink
Post by Jason Kotzin
LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_INTERFACE | LIBUSB_ENDPOINT_IN,
Same results, operation not supported. Do I have to change the interface/endpoint now? I've read the spec a lot, it's really convoluted and abstract, I can't figure out what the real difference is between all those, which is why I was using vendor, so I don't have to care.
I'm not that familiar with HID myself either, but hopefully someone here
will be able to clarify.

All I can tell you is what parameters our HID control requests currently
support:

LIBUSB_REQUEST_TYPE_STANDARD:
LIBUSB_REQUEST_GET_DESCRIPTOR:
LIBUSB_REQUEST_GET_CONFIGURATION:
LIBUSB_REQUEST_SET_CONFIGURATION:
LIBUSB_REQUEST_GET_INTERFACE:
LIBUSB_REQUEST_SET_INTERFACE:

LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
LIBUSB_RECIPIENT_DEVICE only):
set/get HID report/ set/get HID feature

Anything that does not fall into the above categories will return
invalid param.

I think I should be able to add a generic vendor request to the lot, but
that won't happen before tomorrow, and I can't promise it'll do what you
seek.

Regards,

/Pete
Jason Kotzin
2010-04-22 04:43:07 UTC
Permalink
Again, I haven't changed my report descriptor to be a composite device, but I did change it from regular HID, to Vendor Specific. I used the wonderful setrdrv_gui which worked flawlessly to set the driver for the device. I recompiled my original application changing back to all the original usb_control_messages.

It works!

C:\Documents and Settings\Administrator\Desktop>test.exe dump 300
Reading:
0000 00 BF 02 00 05 F2 2A 63 18 00 21 0A 00 00 00 00
0010 51 A1 E0 AD D6 00 28 3E 9B 06 56 00 29 87 BD 33
0020 1C 08 29 5A 2B FD 5A 08 1A D6 B5 03 D6 08 0E 00
0030 34 5C D6 00 4F C7 03 F8 5A 00 50 46 B0 22 D2 08
0040 52 B8 44 10 94 08 51 8A 40 49 5A 08 1A C1 98 98
0050 94 00 1E 66 59 CA 98 00 27 33 2C 86 56 00 1F 96
0060 72 2D D6 00 20 08 06 1B 98 00 21 75 27 F5 56 00
0070 22 E6 BB E3 18 00 23 4A 01 8A 98 00 24 BB 95 78
0080 5A 00 25 F4 C5 DC D6 00 26 67 59 E8 98 00 2C E5
0090 7F 17 56 02 2E 57 13 05 18 00 2D CD 07 18 94 08
00A0 27 42 97 9C 56 00 04 17 71 31 98 00 51 A5 DD 43
00B0 D6 00 52 FE 6D E9 14 00 04 61 B3 90 94 00 04 FF
00C0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00D0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00E0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
00F0 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0100 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0110 FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF FF
0120 FF FF FF FF FF FF FF FF FF FF FF FF FF

I'm going to begin making a composite device and try and get this puppy up and running.

When I set the corresponding interface on the host, do I need to do anything in the device to 'ACK'. Do I need to do anything at all on the device for the set interface and the control message that follows to work?

Thanks everyone, can't tell you how much I appreciate it.

Best,
Jason
Post by Pete Batard
Post by Jason Kotzin
LIBUSB_REQUEST_TYPE_STANDARD | LIBUSB_RECIPIENT_INTERFACE | LIBUSB_ENDPOINT_IN,
Same results, operation not supported. Do I have to change the interface/endpoint now? I've read the spec a lot, it's really convoluted and abstract, I can't figure out what the real difference is between all those, which is why I was using vendor, so I don't have to care.
I'm not that familiar with HID myself either, but hopefully someone here
will be able to clarify.
All I can tell you is what parameters our HID control requests currently
LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
set/get HID report/ set/get HID feature
Anything that does not fall into the above categories will return
invalid param.
I think I should be able to add a generic vendor request to the lot, but
that won't happen before tomorrow, and I can't promise it'll do what you
seek.
Regards,
/Pete
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Peter Stuge
2010-04-22 07:20:01 UTC
Permalink
Post by Jason Kotzin
It works!
C:\Documents and Settings\Administrator\Desktop>test.exe dump 300
0000 00 BF 02 00 05 F2 2A 63 18 00 21 0A 00 00 00 00
0010 51 A1 E0 AD D6 00 28 3E 9B 06 56 00 29 87 BD 33
Score!
Post by Jason Kotzin
When I set the corresponding interface on the host, do I need to do
anything in the device to 'ACK'.
Hm "set" ? Claiming an interface is pretty much a host-only
operation.
Post by Jason Kotzin
Do I need to do anything at all on the device for the set interface
and the control message that follows to work?
Will hosts also send SET_INTERFACE request if there are no alternate
setting interfaces, but only interfaces which can be operated
simultaneously?


//Peter
Pete Batard
2010-04-22 10:39:57 UTC
Permalink
Post by Jason Kotzin
It works!
Good. I think, unless you can work with HID reports with your interface,
using WinUSB instead of HID is the way to go, as WinUSB will allow more
generic access.

For now, I will hold off to implementing vendor requests. The way I see
it is you would need to break down your request in 2 parts (write of the
address, then readout of the data), as we have no means of figuring the
size of the 'address' parameter otherwise.

Apart from that, it is probably useful to try implementing HID vendor
requests that, with LIBUSB_ENDPOINT_OUT, to just write data provided to
the control endpoint and with LIBUSB_ENDPOINT_IN, attempt to read data
from the control endpoint.

As I'd rather be able to test this feature when I implement it, I think
I'll wait till I have a chance to produce a generic HID firmware withs
vendor requests. For now, this will remain lower priority on my tasklist.

Regards,

/Pete
Xiaofan Chen
2010-04-22 05:08:51 UTC
Permalink
Post by Pete Batard
All I can tell you is what parameters our HID control requests currently
LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
       set/get HID report/ set/get HID feature
Anything that does not fall into the above categories will return
invalid param.
Great summary.
Post by Pete Batard
I think I should be able to add a generic vendor request to the lot, but
that won't happen before tomorrow, and I can't promise it'll do what you
seek.
Just another question ( I have not really read your HID codes in detail),
does multiple HID top level collections supported?
http://msdn.microsoft.com/en-us/library/ff539861%28v=VS.85%29.aspx

Slowly and slowly, I realize that the HID backend is much more
complicated than I expect. ;-(
--
Xiaofan http://mcuee.blogspot.com
Pete Batard
2010-04-22 10:41:22 UTC
Permalink
Post by Xiaofan Chen
Just another question ( I have not really read your HID codes in detail),
does multiple HID top level collections supported?
http://msdn.microsoft.com/en-us/library/ff539861%28v=VS.85%29.aspx
The collection implementation from Microsoft is very similar to how they
handle the multiple interfaces of composite devices, and they are
supported as independent devices as far as I could see.

For instance, just like you have a device identified as
"VID_####&PID_####&MI_##" for the interfaces of a composite device, you
have ""VID_####&PID_####&COL_##" (or "VID_####&PID_####&MI_##&COL_##")
for the collections.

Right now, our code will only pick up the first collection and ignore
the others, mostly because this would add a whole new layer of
complexity to HID (handling composite device is already fairly complex),
and I'd prefer dealing with someone who can test HID collections, and
can clarify what they're meant to be used for, when we implement it.

I have now made this limitation more explicit on the wiki page.
Post by Xiaofan Chen
Slowly and slowly, I realize that the HID backend is much more
complicated than I expect. ;-(
Yeah. I kind of though it'd be a walk in the park, since I could just
copy/paste the libusb-win32 code but I see there were a few things not
implemented there, and for something that is meant to deal with human
interaction, it requires quite the effort for a human to understand how
the whole thing is meant to work as a whole (even more so as the HID
specs are probably not the finest example of clarity).

Regards,

/Pete
Tim Roberts
2010-04-22 18:12:59 UTC
Permalink
Post by Pete Batard
I'm not that familiar with HID myself either, but hopefully someone here
will be able to clarify.
All I can tell you is what parameters our HID control requests currently
LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
set/get HID report/ set/get HID feature
Anything that does not fall into the above categories will return
invalid param.
Interesting. And we don't know why this restriction exists? The HID
class spec does not prohibit vendor commands.

If I were writing the code, I think I would have allowed anything with
TYPE_STANDARD, TYPE_CLASS, or TYPE_VENDOR, regardless of subcommand.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Xiaofan Chen
2010-04-22 23:17:12 UTC
Permalink
Interesting.  And we don't know why this restriction exists?  The HID
class spec does not prohibit vendor commands.
If I were writing the code, I think I would have allowed anything with
TYPE_STANDARD, TYPE_CLASS, or TYPE_VENDOR, regardless of subcommand.
Pete is using the following HIDClass Support Routines. It seems
a bit limited and kind of report-oriented.
http://msdn.microsoft.com/en-us/library/ff538865%28v=VS.85%29.aspx

But maybe there are other ways to do it.
--
Xiaofan http://mcuee.blogspot.com
Peter Stuge
2010-04-22 07:08:48 UTC
Permalink
Post by Jason Kotzin
Do I have to change the interface/endpoint now? I've read the spec
a lot, it's really convoluted and abstract, I can't figure out what
the real difference is between all those, which is why I was using
vendor, so I don't have to care.
Oh wait - is this for the non-keyboard part of your device?

Then please drop HID completely and use vendor specific device class,
subclass and protocol for device as well as interface. Sorry if I
wasn't clear about that!


//Peter
Jason Kotzin
2010-04-22 07:13:42 UTC
Permalink
Yeah, I'm in the industry and am no stranger to reading IEEE specs. It's ridiculous. The spec is dreadful. Overlap, multiple specifications, so disorganized, it's the worst I've ever seen.

Yes, just following up on your other email, this is the plan:
A composite device with a HID Keyboard Interface and a Custom Vendor Specific Interface. Assigning the latter device the winusb driver while the HID Keyboard uses the windows driver.

Thanks Peter,
Jason
Post by Peter Stuge
Post by Jason Kotzin
Do I have to change the interface/endpoint now? I've read the spec
a lot, it's really convoluted and abstract, I can't figure out what
the real difference is between all those, which is why I was using
vendor, so I don't have to care.
Oh wait - is this for the non-keyboard part of your device?
Then please drop HID completely and use vendor specific device class,
subclass and protocol for device as well as interface. Sorry if I
wasn't clear about that!
//Peter
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Peter Stuge
2010-04-22 07:25:37 UTC
Permalink
Post by Jason Kotzin
Yeah, I'm in the industry and am no stranger to reading IEEE specs.
It's ridiculous. The spec is dreadful. Overlap, multiple
specifications, so disorganized, it's the worst I've ever seen.
USB itself is pretty OK, but HID gets me every time I look at it..
Post by Jason Kotzin
A composite device with a HID Keyboard Interface and a Custom
Vendor Specific Interface. Assigning the latter device the
winusb driver while the HID Keyboard uses the windows driver.
Right! That should work. So to get a composite device it would be
bDeviceClass = bDeviceSubClass = bDeviceProtocol = 0, and one
configuration with two interfaces, one with bInterfaceClass = 3 for
HID class, and bInterfaceSubClass and bInterfaceProtocol set
according to if you want to support the boot protocol - and then the
other would have bInterfaceClass = 0xff for your vendor specific
interface that gets the winusb driver.


//Peter
Tim Roberts
2010-04-22 18:09:49 UTC
Permalink
Post by Jason Kotzin
Yeah, I'm in the industry and am no stranger to reading IEEE specs. It's ridiculous. The spec is dreadful. Overlap, multiple specifications, so disorganized, it's the worst I've ever seen.
Which spec are you talking about? The base USB specification is one of
the most readable specs I've ever encountered. The software sections in
particular (chapters 5 and 9) include both good background and good
reference material. It has far less legalese than many similar documents.

It certainly makes sense for the device class specs to be separate. The
committee couldn't possibly have imagined all of the USB device classes
that might have been needed, and each device class builds on and extends
the base.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Graeme Gill
2010-04-22 21:53:33 UTC
Permalink
Post by Tim Roberts
Which spec are you talking about? The base USB specification is one of
the most readable specs I've ever encountered. The software sections in
Sorry, can't agree with you there. It's one of the less readable
spec's I've had the misfortune to have to try and extract information
from. I've seen far better ones (and worse ones) than the USB spec.
(The PCI bus spec. and ICC spec. come to mind as better examples.)

Graeme Gill.
Michael Plante
2010-04-21 23:54:06 UTC
Permalink
Post by Jason Kotzin
Use --enable-stdcall-fixup to disable these warnings
Use --disable-stdcall-fixup to disable these fixups
Warning: resolving _libusb_control_transfer by linking to
Not sure if this is related.
If those are the only ones, it's doubtful. Those sound like correct
matches. Peter is working on getting autotools to handle the def file
problem. But if it builds and loads correctly, I wouldn't worry too much.

Regards,
Michael
Alan Stern
2010-04-22 14:17:45 UTC
Permalink
Post by Pete Batard
I'm not that familiar with HID myself either, but hopefully someone here
will be able to clarify.
All I can tell you is what parameters our HID control requests currently
There are a few other standard requests you _might_ want to support,
but they aren't really necessary: Set/Clear device feature (i.e.,
Remote Wakeup), Get device status.
Post by Pete Batard
LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
set/get HID report/ set/get HID feature
This implicitly assumes you never want to send a Get Report request
for an OUT report or a Set Report request for an IN report. That's a
reasonable assumption, but the spec doesn't rule out these
combinations.

There also should be support for Set/Get Idle.

Alan Stern
Pete Batard
2010-04-22 19:06:31 UTC
Permalink
Post by Alan Stern
There are a few other standard requests you _might_ want to support,
but they aren't really necessary: Set/Clear device feature (i.e.,
Remote Wakeup), Get device status.
A lot of this is dependent on what the HIDClass support routine allow us
to do on Windows: http://msdn.microsoft.com/en-us/library/ff538865.aspx

We have a few limitations there, and are at the mercy of what Microsoft
chose to implement. For instance, we can't read raw report descriptors,
but only access predigested values from them, so even the GET_DESCRIPTOR
above is not a 1:1 match of what's embedded in the HID device.

I'll review the set of HIDClass routines we have to see if some of the
requests you mention above can be achieved.
Post by Alan Stern
Post by Pete Batard
LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
set/get HID report/ set/get HID feature
This implicitly assumes you never want to send a Get Report request
for an OUT report or a Set Report request for an IN report. That's a
reasonable assumption, but the spec doesn't rule out these
combinations.
We're definitely filtering things out according to the assumption you
point out.

As this shouldn't be too hard to patch, I'll make a note to fix it after
we have the first release.
Post by Alan Stern
There also should be support for Set/Get Idle.
Is that related to Selective Suspend?
If so, it looks like you need to use a special inf against the HID
device to enable the feature
(http://msdn.microsoft.com/en-us/library/ff538662.aspx), and it doesn't
look like the HID Class API provides the means to set/get idle (then
again, I need to look more closely at each of these calls).

Regards
Xiaofan Chen
2010-04-22 23:15:15 UTC
Permalink
Post by Pete Batard
I'll review the set of HIDClass routines we have to see if some of the
requests you mention above can be achieved.
The set of HIDClass routines seem to be a bit limited.
http://msdn.microsoft.com/en-us/library/ff538865%28v=VS.85%29.aspx
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-22 23:34:47 UTC
Permalink
Post by Xiaofan Chen
Post by Pete Batard
I'll review the set of HIDClass routines we have to see if some of the
requests you mention above can be achieved.
The set of HIDClass routines seem to be a bit limited.
http://msdn.microsoft.com/en-us/library/ff538865%28v=VS.85%29.aspx
Also HidD_GetInputReport and HidD_SetInputReport require Windows
XP or later. So the current HID backend may not support Win2k.
But this is probably a non-issue for the first release as WinUSB
also do not support Win2k.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-26 01:25:34 UTC
Permalink
I successfully made a composite device, recompiled my program, and it unfortunately doesn't work. I think I'm missing a step.

Windows shows two devices, an HID device, which I then tell it to automatically assign a driver, it does.

The second device I assign to winusb.

In my interface descriptor, I left the keyboard as interface 0, and my VID interface as 1.
That looks fine in "Usb Prober" on my mac, application works on my mac, so I fired up Windows.

It didn't work, so I enabled debugging.

In the debug message, libusb auto claims interface 0 before doing the control transfer. I opened up my source code and saw that I was in fact claiming interface 1, why it didn't use that interface, I couldn't figure it out. So even right before the control transfer, I claimed the interface again, but it still auto selected the keyboard interface.

So I changed my usb configuration descriptor such that the VID device was interface 0, and the HID keyboard was interface 1. Re-installed the device in windows and tried again with two programs, the same compiled program that failed, and another that selects interface 0. Libusb now autoclaims interface 1 (the keyboard again) before the control transfer in both situations.

I must be missing something, here is the debug output of my test program:


20a0:0001 (bus 0, device 1)
libusb:debug [libusb_open] open 0.1
libusb:warning [hid_open] could not open HID device in R/W mode (keyboard or mouse?) - trying without
libusb:debug [hid_open] set maximum input buffer size to 512
libusb:debug [hid_open] 0 HID input report value(s) found
libusb:debug [hid_open] 0 HID output report value(s) found
libusb:debug [hid_open] 0 HID feature report value(s) found
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for 'claim_interface' (unrecognized device driver)
libusb:debug [libusb_claim_interface] interface 1
libusb:debug [hid_claim_interface] claimed interface 1
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 83 to interface 1
libusb:warning [hid_submit_control_transfer] auto-claimed interface 1 for control request
libusb:debug [hid_submit_control_transfer] will use interface 1
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 4 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.650682s
libusb:debug [handle_events] poll() 2 fds with timeout in 651ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 4 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 4
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 1
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 4 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.994560s
libusb:debug [handle_events] poll() 2 fds with timeout in 995ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 4 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 4
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=18
Vendor: flirc.tvlibusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for 'claim_interface' (unrecognized device driver)
[Vendor Match]
libusb:debug [libusb_get_device_descriptor]

1d6b:0002 (bus 1, device 0)
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
Reading:
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for 'claim_interface' (unrecognized device driver)
libusb:debug [hid_submit_control_transfer] will use interface 1
failed: Invalid parameter
Address: 0 Data: 0
libusb:debug [libusb_exit]
libusb:warning [libusb_exit] application left some devices open
libusb:debug [usbi_remove_pollfd] remove fd 3
libusb:debug [windows_clock_gettime_threaded] timer thread quitting
libusb:debug [libusb_exit] freeing default context

I know I'm close, wondering if anyone has thoughts.

Thanks so much,
Jason
Post by Xiaofan Chen
Post by Xiaofan Chen
Post by Pete Batard
I'll review the set of HIDClass routines we have to see if some of the
requests you mention above can be achieved.
The set of HIDClass routines seem to be a bit limited.
http://msdn.microsoft.com/en-us/library/ff538865%28v=VS.85%29.aspx
Also HidD_GetInputReport and HidD_SetInputReport require Windows
XP or later. So the current HID backend may not support Win2k.
But this is probably a non-issue for the first release as WinUSB
also do not support Win2k.
--
Xiaofan http://mcuee.blogspot.com
------------------------------------------------------------------------------
_______________________________________________
Libusb-devel mailing list
https://lists.sourceforge.net/lists/listinfo/libusb-devel
Xiaofan Chen
2010-04-26 01:34:45 UTC
Permalink
Post by Jason Kotzin
The second device I assign to winusb.
How did you do this? The INF file has to point to the custom WinUSB interface.
Or you could use Pete's libwdi branch.

http://www.libusb.org/wiki/winusb_driver_installation
(you need to put MI_xx part)
USB\VID_15BA&PID_0004&MI_01 for Interface 1
USB\VID_15BA&PID_0004&MI_00 for interface 0)
Post by Jason Kotzin
Vendor: flirc.tvlibusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for 'claim_interface' (unrecognized device driver)
 [Vendor Match]
libusb:debug [libusb_get_device_descriptor]
1d6b:0002 (bus 1, device 0)
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for 'claim_interface' (unrecognized device driver)
libusb:debug [hid_submit_control_transfer] will use interface 1
I believe you did not installed the WinUSB driver properly
judging from the "unrecognized device driver" debug message.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-26 03:43:23 UTC
Permalink
Good catch. Rebuilt the driver, uninstalled the device, and followed the
directions on the wiki entry you gave me. Here is the contents of my inf.

; =====================================================
; ========= START USER CONFIGURABLE SECTION ===========
; =====================================================

DeviceName = "test"
; Make sure "VID_" and "PID_" are always part of the strings below
VendorID = "VID_20A0"
ProductID = "PID_0001"
InterfaceID = "MI_01"
DeviceGUID = "{18DA0123-748E-40CE-B512-088E2DE6B794}"
DeviceClassGUID = "{78a1c341-4539-11d3-b88d-00c04fad5171}"
; Date MUST be in MM/DD/YYYY format
Date = "04/25/2010"

Here is my new debug message:
C:\Documents and Settings\Administrator\Desktop>test.exe peek 10
DEBUG VERSION
libusb:debug [libusb_get_device_descriptor]

1d6b:0001 (bus 0, device 0)
libusb:debug [libusb_get_device_descriptor]

20a0:0001 (bus 0, device 1)
libusb:debug [libusb_open] open 0.1
libusb:warning [hid_open] could not open HID device in R/W mode (keyboard or
mouse?) - trying without
libusb:debug [hid_open] set maximum input buffer size to 512
libusb:debug [hid_open] 0 HID input report value(s) found
libusb:debug [hid_open] 0 HID output report value(s) found
libusb:debug [hid_open] 0 HID feature report value(s) found
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [hid_claim_interface] claimed interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to
interface 0
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0 for
control request
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 4 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.970697s
libusb:debug [handle_events] poll() 2 fds with timeout in 971ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 4 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 4
libusb:debug [windows_transfer_callback] handling I/O completion with
errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 4 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.988593s
libusb:debug [handle_events] poll() 2 fds with timeout in 989ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 4 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 4
libusb:debug [windows_transfer_callback] handling I/O completion with
errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=18
Vendor: flirc.tvlibusb:debug [libusb_claim_interface] interface 1
libusb:debug [winusb_claim_interface] claimed interface 1
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 83 to
interface 1
[Vendor Match]
libusb:debug [libusb_get_device_descriptor]

1d6b:0002 (bus 1, device 0)
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
Reading:
libusb:debug [hid_submit_control_transfer] will use interface 0
failed: Invalid parameter
Address: A Data: 0
libusb:debug [libusb_exit]
libusb:warning [libusb_exit] application left some devices open
libusb:debug [usbi_remove_pollfd] remove fd 3
libusb:debug [windows_clock_gettime_threaded] timer thread quitting
libusb:debug [libusb_exit] freeing default context

C:\Documents and Settings\Administrator\Desktop>

It is still selecting interface 0 and when I open the device, it thinks it's
a keyboard/mouse.

Thanks so much,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
The second device I assign to winusb.
How did you do this? The INF file has to point to the custom WinUSB interface.
Or you could use Pete's libwdi branch.
http://www.libusb.org/wiki/winusb_driver_installation
(you need to put MI_xx part)
USB\VID_15BA&PID_0004&MI_01 for Interface 1
USB\VID_15BA&PID_0004&MI_00 for interface 0)
Post by Jason Kotzin
Vendor: flirc.tvlibusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for
'claim_interface' (unrecognized device driver)
Post by Jason Kotzin
[Vendor Match]
libusb:debug [libusb_get_device_descriptor]
1d6b:0002 (bus 1, device 0)
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for
'claim_interface' (unrecognized device driver)
Post by Jason Kotzin
libusb:debug [hid_submit_control_transfer] will use interface 1
I believe you did not installed the WinUSB driver properly
judging from the "unrecognized device driver" debug message.
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-26 03:55:04 UTC
Permalink
Just a note. I tried uninstalling the HID keyboard from device manager, and
the program worked. libusb does not like that I have a HID interface and
Vendor specific in one device.
Post by Jason Kotzin
Good catch. Rebuilt the driver, uninstalled the device, and followed the
directions on the wiki entry you gave me. Here is the contents of my inf.
; =====================================================
; ========= START USER CONFIGURABLE SECTION ===========
; =====================================================
DeviceName = "test"
; Make sure "VID_" and "PID_" are always part of the strings below
VendorID = "VID_20A0"
ProductID = "PID_0001"
InterfaceID = "MI_01"
DeviceGUID = "{18DA0123-748E-40CE-B512-088E2DE6B794}"
DeviceClassGUID = "{78a1c341-4539-11d3-b88d-00c04fad5171}"
; Date MUST be in MM/DD/YYYY format
Date = "04/25/2010"
C:\Documents and Settings\Administrator\Desktop>test.exe peek 10
DEBUG VERSION
libusb:debug [libusb_get_device_descriptor]
1d6b:0001 (bus 0, device 0)
libusb:debug [libusb_get_device_descriptor]
20a0:0001 (bus 0, device 1)
libusb:debug [libusb_open] open 0.1
libusb:warning [hid_open] could not open HID device in R/W mode (keyboard
or mouse?) - trying without
libusb:debug [hid_open] set maximum input buffer size to 512
libusb:debug [hid_open] 0 HID input report value(s) found
libusb:debug [hid_open] 0 HID output report value(s) found
libusb:debug [hid_open] 0 HID feature report value(s) found
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [hid_claim_interface] claimed interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to
interface 0
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0 for
control request
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 4 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.970697s
libusb:debug [handle_events] poll() 2 fds with timeout in 971ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 4 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 4
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=4
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING
libusb:debug [usbi_add_pollfd] add fd 4 events 1
libusb:debug [libusb_get_next_timeout] next timeout in 0.988593s
libusb:debug [handle_events] poll() 2 fds with timeout in 989ms
libusb:debug [handle_events] poll() returned 1
libusb:debug [windows_handle_events] checking fd 3 with revents = 0000
libusb:debug [windows_handle_events] checking fd 4 with revents = 0001
libusb:debug [usbi_remove_pollfd] remove fd 4
libusb:debug [windows_transfer_callback] handling I/O completion with errcode 0
libusb:debug [ctrl_transfer_cb] actual_length=18
Vendor: flirc.tvlibusb:debug [libusb_claim_interface] interface 1
libusb:debug [winusb_claim_interface] claimed interface 1
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 83 to interface 1
[Vendor Match]
libusb:debug [libusb_get_device_descriptor]
1d6b:0002 (bus 1, device 0)
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
libusb:debug [hid_submit_control_transfer] will use interface 0
failed: Invalid parameter
Address: A Data: 0
libusb:debug [libusb_exit]
libusb:warning [libusb_exit] application left some devices open
libusb:debug [usbi_remove_pollfd] remove fd 3
libusb:debug [windows_clock_gettime_threaded] timer thread quitting
libusb:debug [libusb_exit] freeing default context
C:\Documents and Settings\Administrator\Desktop>
It is still selecting interface 0 and when I open the device, it thinks
it's a keyboard/mouse.
Thanks so much,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
The second device I assign to winusb.
How did you do this? The INF file has to point to the custom WinUSB interface.
Or you could use Pete's libwdi branch.
http://www.libusb.org/wiki/winusb_driver_installation
(you need to put MI_xx part)
USB\VID_15BA&PID_0004&MI_01 for Interface 1
USB\VID_15BA&PID_0004&MI_00 for interface 0)
Post by Jason Kotzin
Vendor: flirc.tvlibusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for
'claim_interface' (unrecognized device driver)
Post by Jason Kotzin
[Vendor Match]
libusb:debug [libusb_get_device_descriptor]
1d6b:0002 (bus 1, device 0)
libusb:debug [libusb_unref_device] destroy device 0.0
libusb:debug [libusb_unref_device] destroy device 1.0
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [unsupported_claim_interface] unsupported API call for
'claim_interface' (unrecognized device driver)
Post by Jason Kotzin
libusb:debug [hid_submit_control_transfer] will use interface 1
I believe you did not installed the WinUSB driver properly
judging from the "unrecognized device driver" debug message.
--
Xiaofan http://mcuee.blogspot.com
Xiaofan Chen
2010-04-26 04:53:36 UTC
Permalink
Just a note.  I tried uninstalling the HID keyboard from device manager, and
the program worked.  libusb does not like that I have a HID interface and
Vendor specific in one device.
Ok, Pete may have better insight into this issue now.

But just a guess, what if you rebuild libusb-1.0 and take out the
auto-claiming option?

// - Should libusb automatically claim the interfaces it requires?
#define AUTO_CLAIM //(comment out this line in windows_usb.c)
--
Xiaofan http://mcuee.blogspot.com
Jason Kotzin
2010-04-26 08:31:19 UTC
Permalink
I moved my Vendor specific interface to Interface 0 and the HID keyboard to interface 1.
I reinstalled the drivers and it worked.

I swapped the interface back the original way, HID - Interface 0, Vendor Specific - Interface 1, and it didn't work.

I can confirm that it wont work with the HID being in the first interface position (interface 0).

I didn't try to re-compile without autoclaim.

Thanks for all the help, really appreciate it.

Best,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
Just a note. I tried uninstalling the HID keyboard from device manager, and
the program worked. libusb does not like that I have a HID interface and
Vendor specific in one device.
Ok, Pete may have better insight into this issue now.
But just a guess, what if you rebuild libusb-1.0 and take out the
auto-claiming option?
// - Should libusb automatically claim the interfaces it requires?
#define AUTO_CLAIM //(comment out this line in windows_usb.c)
--
Xiaofan http://mcuee.blogspot.com
Pete Batard
2010-04-26 10:46:51 UTC
Permalink
Hi Jason,

I'll look into it. I think it would help if you could send us debug logs
of what happens with vendor specific in 0 and vendor specific in 1, so
we can take a look at how the composite interface assignation works in
both cases.

Also, Xiaofan's suggestion of recompiling without autoclaim and claiming
the interfaces explicitly is a good one.

Regards,

/Pete
Post by Jason Kotzin
I moved my Vendor specific interface to Interface 0 and the HID keyboard to interface 1.
I reinstalled the drivers and it worked.
I swapped the interface back the original way, HID - Interface 0, Vendor Specific - Interface 1, and it didn't work.
I can confirm that it wont work with the HID being in the first interface position (interface 0).
I didn't try to re-compile without autoclaim.
Thanks for all the help, really appreciate it.
Best,
Jason
Post by Xiaofan Chen
Post by Jason Kotzin
Just a note. I tried uninstalling the HID keyboard from device manager, and
the program worked. libusb does not like that I have a HID interface and
Vendor specific in one device.
Ok, Pete may have better insight into this issue now.
But just a guess, what if you rebuild libusb-1.0 and take out the
auto-claiming option?
// - Should libusb automatically claim the interfaces it requires?
#define AUTO_CLAIM //(comment out this line in windows_usb.c)
--
Xiaofan http://mcuee.blogspot.com
Pete Batard
2010-04-26 23:48:29 UTC
Permalink
Post by Xiaofan Chen
libusb:debug [libusb_claim_interface] interface 0
libusb:debug [hid_claim_interface] claimed interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to
interface 0
libusb:warning [hid_submit_control_transfer] auto-claimed interface 0
for control request
libusb:debug [hid_submit_control_transfer] will use interface 0
If libusb_claim_interface/hid_claim_interface report that interface 0
was claimed, then there should never be an "auto-claimed interface 0"
message, as the whole point of auto-claim is to only call
libusb_claim_interface in case none was issued.

I think I'd like to see your code between claim_interface(0) and the
control request for strings.

What is expected is something like this, which I tested with an USB
composite keyboard using HID for interface 0 (keyboard part) and WinUSB
for interface 1 (additional functionality). I'm issuing claims to
interface 0 & 1:

libusb:debug [libusb_claim_interface] interface 0
libusb:debug [hid_claim_interface] claimed interface 0
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 81 to
interface 0
libusb:debug [libusb_claim_interface] interface 1
libusb:debug [winusb_claim_interface] claimed interface 1
libusb:debug [libusb_get_config_descriptor] index 0
libusb:debug [windows_assign_endpoints] (re)assigned endpoint 82 to
interface 1
Reading string descriptors:
libusb:debug [hid_submit_control_transfer] will use interface 0
libusb:debug [_hid_get_descriptor] LIBUSB_DT_STRING


Now, I don't believe this is the cause of your problem. Instead I think
the issue is the continuing story of Microsoft's restrictions for
keyboards and mice HID devices. Because any interface for which we have
a supported API (HID, WinUSB) should be good for control requests, we
always try to pick the first valid interface we find.

Of course, when HID keyboards and mice have restrictions added with
regards to transfers, what would normally be a perfectly valid way of
issuing a control request becomes a problem, if your device is a
composite with a keyboard or mouse part as interface 0.

I guess we probably need to add a special case for when we detect what
looks like an HID keyboard or mouse on an interface then, to try not to
use that interface when issuing a control request from a composite
device. However, I want to see if we can work around the need to add a
new "mouse or keyboard" flag for all the interfaces we keep in our
private struct, as this is quite the heavy handed approach to work
around a very specific Microsoft restriction.

Also, this shouldn't be a problem with interrupt transfers, as endpoints
should be properly assigned to a specific interface, so if you have
means to use interrupt requests instead of control, you might want to
try that.

One way or another, I'll probably come around with a patch tomorrow.

Regards,

/Pete

Alan Stern
2010-04-22 19:26:34 UTC
Permalink
Post by Pete Batard
Post by Alan Stern
There are a few other standard requests you _might_ want to support,
but they aren't really necessary: Set/Clear device feature (i.e.,
Remote Wakeup), Get device status.
A lot of this is dependent on what the HIDClass support routine allow us
to do on Windows: http://msdn.microsoft.com/en-us/library/ff538865.aspx
We have a few limitations there, and are at the mercy of what Microsoft
chose to implement. For instance, we can't read raw report descriptors,
but only access predigested values from them, so even the GET_DESCRIPTOR
above is not a 1:1 match of what's embedded in the HID device.
I'll review the set of HIDClass routines we have to see if some of the
requests you mention above can be achieved.
It doesn't look like they can be... However it's hard to imagine why a
program would want to use any of those requests.
Post by Pete Batard
Post by Alan Stern
Post by Pete Batard
LIBUSB_REQUEST_TYPE_CLASS: (LIBUSB_RECIPIENT_INTERFACE and
set/get HID report/ set/get HID feature
This implicitly assumes you never want to send a Get Report request
for an OUT report or a Set Report request for an IN report. That's a
reasonable assumption, but the spec doesn't rule out these
combinations.
We're definitely filtering things out according to the assumption you
point out.
As this shouldn't be too hard to patch, I'll make a note to fix it after
we have the first release.
Post by Alan Stern
There also should be support for Set/Get Idle.
Is that related to Selective Suspend?
No. It tells the device how often to send Input reports. See section
7.2.4 in the HID spec.
Post by Pete Batard
If so, it looks like you need to use a special inf against the HID
device to enable the feature
(http://msdn.microsoft.com/en-us/library/ff538662.aspx), and it doesn't
look like the HID Class API provides the means to set/get idle (then
again, I need to look more closely at each of these calls).
I don't see any routines listed there for the Idle setting. So maybe
there's no way to do it.

Alan Stern
Loading...