Discussion:
[Libusb-devel] Help Communicating With Device
Christopher Moore
2008-10-08 13:20:27 UTC
Permalink
(sorry for the repeat .. if it does show up ... I've been having problems
sending email to this list)

Hello Everyone,

I'm using python's implementation of libusb (pyusb) to try to communicate
with my phone device. I've finally understood the protocol and generally
get what the usb sniffer logs mean. Now it's finally time to start coding
this thing. Thank you all for your help so far on this mailing list to
get up to this point!

I've successfully been able to find the device, detach the hid driver from
it (which is what I'm after) , claim it's interface and reset it. I can
also successfully retrieve a report descriptor from it (HID device
report).

Now this is where I have some questions:

In my log it shows the following communication:

1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00

host -> device is the controlMsg sending a report to HID Report #4 in a 2
part command ... and I'm formatted my code as follows:

reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)

and then I do this same thing for line 1a) ... you can also see this in
the attached log.

Once I type this in the python terminal, I get returned: "9" in my python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct? Also, what does "9" mean? 9 bytes successfully
sent?

Now, after, this according to the log, I should do a bulk/Interrupt read,
which occurs to HID Report #3. So I tried the following:

handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #also doesn't work
#usb.USBError: error submitting URB: No such file or directory

Is there something I'm missing?

I've attached the usb sniffer log.

Thanks

Christopher
Alan Stern
2008-10-08 14:57:08 UTC
Permalink
Post by Christopher Moore
Hello Everyone,
I'm using python's implementation of libusb (pyusb) to try to communicate
with my phone device. I've finally understood the protocol and generally
get what the usb sniffer logs mean. Now it's finally time to start coding
this thing. Thank you all for your help so far on this mailing list to
get up to this point!
I've successfully been able to find the device, detach the hid driver from
it (which is what I'm after) , claim it's interface and reset it. I can
also successfully retrieve a report descriptor from it (HID device
report).
1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00
host -> device is the controlMsg sending a report to HID Report #4 in a 2
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
I'm not familiar with the Python bindings. It would clarify the
code a little if you replaced REQ_SET_CONFIGURATION with something
closer to REQ_SET_REPORT, although the value (9) is the same for both.
Post by Christopher Moore
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
Once I type this in the python terminal, I get returned: "9" in my python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct?
It agrees with what you told Python to do. That doesn't mean it is
correct.

For instance, this says to send a Feature report with ID 4. Is that
what you want? Normally one would use an Output report, not a Feature
report; it depends on the device.

Is the interface number supposed to be 3? I rather doubt it, since the
log shows only one interface, number 0.
Post by Christopher Moore
Also, what does "9" mean? 9 bytes successfully
sent?
"09" appears twice in the setup packet. The first appearance in
essentially REQ_SET_REPORT. The second appearance means that you are
going to send 9 bytes of report data. It doesn't mean that the bytes
were successfully sent.

Most likely the return value from that library call is the number of
bytes sent successfully.
Post by Christopher Moore
Now, after, this according to the log, I should do a bulk/Interrupt read,
handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
It doesn't make much sense to read from an OUT endpoint.
Post by Christopher Moore
handle.interruptRead(endpoint.address,8) #also doesn't work
#usb.USBError: error submitting URB: No such file or directory
Is there something I'm missing?
Undoubtedly. I can't tell what it is, though, since you haven't
provided enough information.

Alan Stern
Christopher Moore
2008-10-08 15:24:32 UTC
Permalink
Post by Alan Stern
Post by Christopher Moore
Hello Everyone,
I'm using python's implementation of libusb (pyusb) to try to
communicate
with my phone device. I've finally understood the protocol and generally
get what the usb sniffer logs mean. Now it's finally time to start coding
this thing. Thank you all for your help so far on this mailing list to
get up to this point!
I've successfully been able to find the device, detach the hid driver from
it (which is what I'm after) , claim it's interface and reset it. I can
also successfully retrieve a report descriptor from it (HID device
report).
1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00
host -> device is the controlMsg sending a report to HID Report #4 in a 2
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
I'm not familiar with the Python bindings. It would clarify the
code a little if you replaced REQ_SET_CONFIGURATION with something
closer to REQ_SET_REPORT, although the value (9) is the same for both.
The closest thing I was able to find in the python docs was
REQ_SET_CONFIGURATION
(http://wiki.erazor-zone.de/wiki:projects:python:pyusb:pydoc ... scroll
towards bottom)
Post by Alan Stern
Post by Christopher Moore
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
Once I type this in the python terminal, I get returned: "9" in my python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct?
It agrees with what you told Python to do. That doesn't mean it is
correct.
For instance, this says to send a Feature report with ID 4. Is that
what you want? Normally one would use an Output report, not a Feature
report; it depends on the device.
Is the interface number supposed to be 3? I rather doubt it, since the
log shows only one interface, number 0.
Report #4 is used to transport the host-to-device side of the CIT200's
control protocol. Report 4 is defined as Feature data, and thus it will
need to be sent by the host as a Feature-type Report.

The other report, Report #3 is an Input-Type Report (device -> host) ...
as seen in line #2

Also, just curious, how did you know this was a feature-type report? B/c
it had 0x03 in the returned setupPacket?


As for the interfaces:

Interface 1 - streaming ... Endpoint OUT (Speaker Out)
Interface 2 - streaming ... Endpoint In, iso transfer type (Mic In)
Interface 3 - HID Interface ... Endpoint IN, interrupt transfer type

The HID Interface on my device is interface #3 as shown in the output from
lsusb -vvv, and also in python doing the following:

# shows interface #3 is class 3 (HID)
for interface in config.interfaces:
print "Interface:",interface[0].interfaceNumber
for alt in interface:
print "Class:",alt.interfaceClass
Post by Alan Stern
Post by Christopher Moore
Also, what does "9" mean? 9 bytes successfully
sent?
"09" appears twice in the setup packet. The first appearance in
essentially REQ_SET_REPORT. The second appearance means that you are
going to send 9 bytes of report data. It doesn't mean that the bytes
were successfully sent.
Most likely the return value from that library call is the number of
bytes sent successfully.
Post by Christopher Moore
Now, after, this according to the log, I should do a bulk/Interrupt read,
handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
It doesn't make much sense to read from an OUT endpoint.
Ok, I'll find out what the main endpoint is. That makes sense now.
Post by Alan Stern
Post by Christopher Moore
handle.interruptRead(endpoint.address,8) #also doesn't work
#usb.USBError: error submitting URB: No such file or directory
Is there something I'm missing?
Undoubtedly. I can't tell what it is, though, since you haven't
provided enough information.
Alan Stern
My code:

import usb

# linksys CIT200 Device Info
vendor_id = 5041
product_id = 29

buses = usb.busses()

for bus in buses :
for device in bus.devices :
if device.idVendor == vendor_id :
if device.idProduct == product_id :
# found the CIT200
linksys = device

# open device
handle = linksys.open()
# detach kernel drivers
handle.detachKernelDriver(3)

# setup interface and configs ... there are 4 interfaces for this device...
config = linksys.configurations[0]
interface = config.interfaces[3][0]
endpoint = interface.endpoints[0]

# set configuration and claim interface(s?)
#handle.setConfiguration(config)
"""
Post by Alan Stern
Post by Christopher Moore
handle.setConfiguration(config)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
usb.USBError: could not set config 1: Device or resource busy
"""

handle.claimInterface(interface) # this actually assigns the interface
config I believe ...
handle.setAltInterface(interface)

# reset device
handle.reset()

# HID Report Descriptor
handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)
#(5, 11, 9, 1, 161, 1, 133, 1, 9, 6, 161, 2, 25, 176, 41, 187, 21, 0, 37,
12, 117, 4, 149, 1, 129, 0, 192, 9, 32, 21, 0, 37, 1, 117, 1, 149, 1, 129,
2, 9, 4, 161, 2, 5, 12, 9, 224, 21, 255, 37, 1, 117, 2, 149, 1, 129, 6, 9,
226, 21, 0, 37, 1, 117, 1, 149, 1, 129, 2, 192, 133, 2, 21, 0, 37, 1, 117,
1, 149, 1, 5, 11, 9, 32, 177, 2, 5, 11, 9, 24, 177, 2, 117, 6, 177, 7,5,
20, 9, 1, 38, 255, 0, 117, 8, 149, 1, 9, 44, 177, 2, 149, 15, 9, 44, 177,
2, 133, 3, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 7, 9, 44, 129, 0,
133, 4, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 8, 9, 44, 177, 0,
192)

"""
# shows interface #3 is class 3 (HID)
for interface in config.interfaces:
print "Interface:",interface[0].interfaceNumber
for alt in interface:
print "Class:",alt.interfaceClass
"""

reqType = usb.ENDPOINT_OUT | usb.TYPE_CLASS | usb.RECIP_INTERFACE
reqBuffer = (0x03 << 8) | 0x04 #(HID_REPORT_FEATURE << 8) + SEND_REPORT_ID
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#(152, 243, 183, 0, 152, 243, 183, 0, 80, 41, 22, 8, 80, 41, 22, 8, 136,
45, 22, 8, 10, 0, 0, 0, 32, 228, 183, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 156, 42, 22, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 80, 160, 14, 8, 7, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 252, 41, 22, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
55, 147, 229, 164, 44, 224, 248, 183, 56, 223, 14, 8, 0, 0, 0, 0, 224,
217, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 20, 233, 249, 249,
172, 165, 248, 183, 44, 223, 14, 8, 0, 0, 0, 0, 0, 0, 0,0, 0, 0, 0, 0, 22,
169, 74, 181, 44, 162, 248, 183, 32, 223, 14, 8, 119, 168, 147, 27, 44,
163, 248, 183, 8, 223, 14, 8, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 62, 37, 3, 68, 223, 14, 8, 73, 2, 0, 0,
112, 241, 183, 0, 112, 241, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 112, 241, 183, 0, 112, 241, 183, 0, 0, 0, 0, 0, 0, 0, 0, 0,
224, 123, 37, 3, 156, 0, 0, 0, 8, 223, 14, 8, 192, 222, 14, 8, 216, 222,
14, 8, 56, 223, 14, 8, 40, 231, 14, 8, 56, 223, 14, 8, 192, 224, 14, 8,
56, 223, 14, 8, 216, 222, 14, 8, 252, 222, 14, 8, 40, 231, 14, 8, 44,
223, 14, 8, 24, 222, 14, 8, 1, 0, 0, 0, 0, 0, 0, 0, 116, 66, 248, 183,
116, 66, 248, 183, 1, 0, 0, 0, 0, 0, 0, 0, 252, 107, 34, 3, 0, 0, 0, 0,
0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 240, 224, 14, 8, 68, 223, 14, 8,
180, 229, 14, 8,216, 222, 14, 8, 196, 221, 14, 8, 72, 222, 14, 8, 68,
223, 14, 8, 136, 221, 14, 8, 56, 223, 14, 8, 128, 225, 14, 8, 56, 223,
14, 8, 0, 224, 14, 8, 56, 223, 14, 8, 240, 224, 14, 8, 44, 223, 14, 8,
216, 222, 14, 8, 20, 223, 14, 8, 40, 231, 14, 8, 44, 223, 14,
8, 8, 223, 14, 8, 180, 222, 14, 8, 216, 222, 14, 8, 52, 228, 14, 8, 72,
222, 14, 8, 120, 234, 14, 8, 136, 221,14, 8, 56, 223, 14, 8, 128, 225,
14, 8, 44, 223, 14, 8, 0, 224, 14, 8, 56, 223, 14, 8, 240, 224, 14, 8,
252, 222, 14, 8, 216, 222, 14, 8, 28, 228, 14, 8, 72, 222, 14, 8, 68,
223, 14, 8, 136, 221, 14, 8, 56, 223, 14, 8, 128, 225, 14, 8, 56, 223,
14, 8, 0, 224, 14, 8, 56, 223, 14, 8, 240, 224, 14, 8, 44, 223, 14, 8,
180, 229, 14, 8, 192, 224, 14, 8, 44, 223, 14, 8, 72, 222, 14, 8, 68,
223, 14, 8, 136, 221, 14, 8, 56, 223, 14, 8, 128, 225, 14, 8, 56, 223,
14, 8, 0, 224, 14, 8, 56, 223, 14,8, 8, 223, 14, 8, 192, 222, 14, 8, 216,
222, 14, 8, 196, 221, 14, 8, 104, 230, 14, 8, 44, 223, 14, 8, 8, 223, 14,
8, 192, 222, 14, 8, 216, 222, 14, 8, 36, 222, 14, 8, 104, 230, 14, 8, 44,
223, 14, 8, 128, 225, 14, 8, 252, 222, 14, 8, 104, 230, 14, 8, 240, 222,
14, 8, 8, 223, 14, 8)




#reqBuffer = [0] * 8
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
#handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer,
00000304, 0x03)
# returns 8

""" Look Here (Begin) """

reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#returns 9

reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#returns 9


handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #doesn't work
#usb.USBError: error submitting URB: No such file or directory

""" Look here (END) """

# release device
handle.releaseInterface()

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


Do you need any more information?

Thanks

Christopher
Christopher Moore
2008-10-08 13:03:53 UTC
Permalink
Hello Everyone,

I'm using python's implementation of libusb (pyusb) to try to communicate
with my phone device. I've finally understood the protocol and generally
get what the usb sniffer logs mean. Now it's finally time to start coding
this thing. Thank you all for your help so far on this mailing list to
get up to this point!

I've successfully been able to find the device, detach the hid driver from
it (which is what I'm after) , claim it's interface and reset it. I can
also successfully retrieve a report descriptor from it (HID device
report).

Now this is where I have some questions:

In my log it shows the following communication:

1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00

host -> device is the controlMsg sending a report to HID Report #4 in a 2
part command ... and I'm formatted my code as follows:

reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)

and then I do this same thing for line 1a) ... you can also see this in
the attached log.

Once I type this in the python terminal, I get returned: "9" in my python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct? Also, what does "9" mean? 9 bytes successfully
sent?

Now, after, this according to the log, I should do a bulk/Interrupt read,
which occurs to HID Report #3. So I tried the following:

handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #also doesn't work
#usb.USBError: error submitting URB: No such file or directory

Is there something I'm missing?

I've attached my code and my usb sniffer log.

Thanks

Christopher
Tim Roberts
2008-10-08 16:25:14 UTC
Permalink
Post by Christopher Moore
I'm using python's implementation of libusb (pyusb) to try to communicate
with my phone device. I've finally understood the protocol and generally
get what the usb sniffer logs mean. Now it's finally time to start coding
this thing. Thank you all for your help so far on this mailing list to
get up to this point!
I've successfully been able to find the device, detach the hid driver from
it (which is what I'm after) , claim it's interface and reset it. I can
also successfully retrieve a report descriptor from it (HID device
report).
1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00
That's different from the log you attached. The string "04 05 08" never
appears.
Post by Christopher Moore
host -> device is the controlMsg sending a report to HID Report #4 in a 2
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
00000304 is not right. Constants starting with 0 are interpreted as
octal numbers. You need hex: 0x00000304.
Post by Christopher Moore
Once I type this in the python terminal, I get returned: "9" in my python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct? Also, what does "9" mean? 9 bytes successfully
sent?
Yes. controlMsg returns the number of bytes transferred, and the Python
interactive prompt automatically prints out the value of an expression,
Post by Christopher Moore
1+2
3
Post by Christopher Moore
Now, after, this according to the log, I should do a bulk/Interrupt read,
which occurs to HID Report #3.
No, it goes to endpoint #3. A report is just a data packet that gets
returned from the endpoint.
Post by Christopher Moore
handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #also doesn't work
#usb.USBError: error submitting URB: No such file or directory
Is there something I'm missing?
What's the value of endpoint.address? It needs to be 0x83.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Christopher Moore
2008-10-08 16:46:30 UTC
Permalink
Post by Tim Roberts
Post by Christopher Moore
I'm using python's implementation of libusb (pyusb) to try to
communicate
with my phone device. I've finally understood the protocol and generally
get what the usb sniffer logs mean. Now it's finally time to start coding
this thing. Thank you all for your help so far on this mailing list to
get up to this point!
I've successfully been able to find the device, detach the hid driver from
it (which is what I'm after) , claim it's interface and reset it. I can
also successfully retrieve a report descriptor from it (HID device
report).
1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00
That's different from the log you attached. The string "04 05 08" never
appears.
Yes, those numbers seem to change on me every time I take a log of the usb
traffic. (I'm working without a spec here.) so I suppose just substitute
in "08 16" for "0c 35". I know that "05" means it's transmitting 5 more
pieces of data to finish the command started with "04 c1".

9a4f is something related to PC_STATUS to the phone (Skype Online/Offline,
etc..)
Post by Tim Roberts
Post by Christopher Moore
host -> device is the controlMsg sending a report to HID Report #4 in a 2
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
00000304 is not right. Constants starting with 0 are interpreted as
octal numbers. You need hex: 0x00000304.
ok, I will try that.
Post by Tim Roberts
Post by Christopher Moore
Once I type this in the python terminal, I get returned: "9" in my python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct? Also, what does "9" mean? 9 bytes successfully
sent?
Yes. controlMsg returns the number of bytes transferred, and the Python
interactive prompt automatically prints out the value of an expression,
Post by Christopher Moore
1+2
3
OK, cool. I had a feeling that was it, but wasn't exactly correct. I
guess I was expecting a "SetupPacket" like in the log.
Post by Tim Roberts
Post by Christopher Moore
Now, after, this according to the log, I should do a bulk/Interrupt read,
which occurs to HID Report #3.
No, it goes to endpoint #3. A report is just a data packet that gets
returned from the endpoint.
Post by Christopher Moore
handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #also doesn't work
#usb.USBError: error submitting URB: No such file or directory
Is there something I'm missing?
What's the value of endpoint.address? It needs to be 0x83.
I have to look into this when I get home (at work now), but I believe it
was the same as .usb.ENDPOINT_OUT. As Alen replied, I have to make sure
that this is the correct endpoint. However, the HID endpoint is 0x83.

Thanks
Tim Roberts
2008-10-08 17:36:14 UTC
Permalink
Post by Christopher Moore
Post by Tim Roberts
Post by Christopher Moore
1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00
That's different from the log you attached. The string "04 05 08" never
appears.
Yes, those numbers seem to change on me every time I take a log of the usb
traffic. (I'm working without a spec here.)
Why? The specs are all freely downloadable from www.usb.org. Don't
leave home without them...
Post by Christopher Moore
...so I suppose just substitute
in "08 16" for "0c 35". I know that "05" means it's transmitting 5 more
pieces of data to finish the command started with "04 c1".
Well, you're going to need to understand that. What if it's a
challenge/response thing to prevent people from doing what you are
trying to do? It could be initializing a clock or something as well.
Post by Christopher Moore
Post by Tim Roberts
Post by Christopher Moore
host -> device is the controlMsg sending a report to HID Report #4 in a 2
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
usb.REQ_SET_CONFIGURATION is not really what this is. It's a SET_REPORT
command. This is a class-specific transfer, so the standard command
names don't apply. It happens to have the same number, but it would be
better to define a constant with the proper code:
SET_REPORT = 0x09
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Christopher Moore
2008-10-08 17:51:56 UTC
Permalink
Post by Tim Roberts
Post by Christopher Moore
Post by Tim Roberts
Post by Christopher Moore
1) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
1a) 04 05 08 16 00 01 00 00 68
2) [ device -> host ] 03 83 34 00 43 00 00 00
3) [ host -> device ] 04 c1 33 00 43 07 9a 4f 68
3a) 04 05 08 16 00 00 00 00 68
4) [ device -> host ] 03 83 34 00 43 00 00 00
That's different from the log you attached. The string "04 05 08" never
appears.
Yes, those numbers seem to change on me every time I take a log of the usb
traffic. (I'm working without a spec here.)
Why? The specs are all freely downloadable from www.usb.org. Don't
leave home without them...
Sorry, I meant protocol (for the phone) not the spec (as in usb spec)
Post by Tim Roberts
Post by Christopher Moore
...so I suppose just substitute
in "08 16" for "0c 35". I know that "05" means it's transmitting 5 more
pieces of data to finish the command started with "04 c1".
Well, you're going to need to understand that. What if it's a
challenge/response thing to prevent people from doing what you are
trying to do? It could be initializing a clock or something as well.
Yes. I'm going to have to take some more logs and pay closer attention.
Post by Tim Roberts
Post by Christopher Moore
Post by Tim Roberts
Post by Christopher Moore
host -> device is the controlMsg sending a report to HID Report #4 in
a
2
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
usb.REQ_SET_CONFIGURATION is not really what this is. It's a SET_REPORT
command. This is a class-specific transfer, so the standard command
names don't apply. It happens to have the same number, but it would be
SET_REPORT = 0x09
Sure.

Thanks
Alan Stern
2008-10-08 19:17:55 UTC
Permalink
Post by Christopher Moore
Post by Alan Stern
Post by Christopher Moore
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer,
00000304,
0x03)
I'm not familiar with the Python bindings. It would clarify the
code a little if you replaced REQ_SET_CONFIGURATION with something
closer to REQ_SET_REPORT, although the value (9) is the same for both.
The closest thing I was able to find in the python docs was
REQ_SET_CONFIGURATION
(http://wiki.erazor-zone.de/wiki:projects:python:pyusb:pydoc ... scroll
towards bottom)
You don't have to rely solely on the predefined codes. You can always
add one of your own.
Post by Christopher Moore
Post by Alan Stern
Post by Christopher Moore
and then I do this same thing for line 1a) ... you can also see this in
the attached log.
Once I type this in the python terminal, I get returned: "9" in my
python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09 00)
... is this correct?
It agrees with what you told Python to do. That doesn't mean it is
correct.
For instance, this says to send a Feature report with ID 4. Is that
what you want? Normally one would use an Output report, not a Feature
report; it depends on the device.
Is the interface number supposed to be 3? I rather doubt it, since the
log shows only one interface, number 0.
Report #4 is used to transport the host-to-device side of the CIT200's
control protocol. Report 4 is defined as Feature data, and thus it will
need to be sent by the host as a Feature-type Report.
The other report, Report #3 is an Input-Type Report (device -> host) ...
as seen in line #2
Also, just curious, how did you know this was a feature-type report? B/c
it had 0x03 in the returned setupPacket?
The Setup packet isn't _returned_; it is _sent_ from your computer to
the device.

Once again you are confusing matters by making ambiguous remarks: The
Setup packet contains _two_ 0x03's. The first is part of a pair which
forms a little-endian 16-bit integer: 0x0304. This is the wValue field
of the packet (presumably the same as the second-to-last argument of
your handle.controlMsg() call, although it's hard to be sure). For
Set-Report transfers, the wValue field has the report type in its
high-order byte and the report number in its low-order byte (documented
in the HID spec). So I knew the report type was 3, which means
Feature.
Post by Christopher Moore
Interface 1 - streaming ... Endpoint OUT (Speaker Out)
Interface 2 - streaming ... Endpoint In, iso transfer type (Mic In)
Interface 3 - HID Interface ... Endpoint IN, interrupt transfer type
The HID Interface on my device is interface #3 as shown in the output from
# shows interface #3 is class 3 (HID)
print "Interface:",interface[0].interfaceNumber
print "Class:",alt.interfaceClass
Okay, I was deceived by misleading output from your USB sniffer.
Those programs sometimes change config descriptor values without
warning. Or maybe the real fault lies inside Windows.

You know, since you have the "lsusb -v" output, it wouldn't hurt for
you to post it.
Post by Christopher Moore
import usb
# linksys CIT200 Device Info
vendor_id = 5041
product_id = 29
buses = usb.busses()
# found the CIT200
linksys = device
A little error-checking here wouldn't hurt. What if your device isn't
found?
Post by Christopher Moore
# open device
handle = linksys.open()
# detach kernel drivers
handle.detachKernelDriver(3)
# setup interface and configs ... there are 4 interfaces for this device...
config = linksys.configurations[0]
interface = config.interfaces[3][0]
endpoint = interface.endpoints[0]
# set configuration and claim interface(s?)
#handle.setConfiguration(config)
"""
Post by Alan Stern
Post by Christopher Moore
Post by Christopher Moore
handle.setConfiguration(config)
File "<stdin>", line 1, in <module>
usb.USBError: could not set config 1: Device or resource busy
"""
handle.claimInterface(interface) # this actually assigns the interface
config I believe ...
All it does is give your program ownership of the interface. Maybe
that's what you meant by "assigns the interface config".
Post by Christopher Moore
handle.setAltInterface(interface)
# reset device
handle.reset()
Why on Earth do you want to reset the device? And if you do want to
reset it, why don't you reset it _before_ claiming the interface and
establishing an altsetting?
Post by Christopher Moore
# HID Report Descriptor
handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)
#(5, 11, 9, 1, 161, 1, 133, 1, 9, 6, 161, 2, 25, 176, 41, 187, 21, 0, 37,
12, 117, 4, 149, 1, 129, 0, 192, 9, 32, 21, 0, 37, 1, 117, 1, 149, 1, 129,
2, 9, 4, 161, 2, 5, 12, 9, 224, 21, 255, 37, 1, 117, 2, 149, 1, 129, 6, 9,
226, 21, 0, 37, 1, 117, 1, 149, 1, 129, 2, 192, 133, 2, 21, 0, 37, 1, 117,
1, 149, 1, 5, 11, 9, 32, 177, 2, 5, 11, 9, 24, 177, 2, 117, 6, 177, 7,5,
20, 9, 1, 38, 255, 0, 117, 8, 149, 1, 9, 44, 177, 2, 149, 15, 9, 44, 177,
2, 133, 3, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 7, 9, 44, 129, 0,
133, 4, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 8, 9, 44, 177, 0,
192)
No doubt you will agree that the output from "lsusb -v" is a lot easier
to comprehend...
Post by Christopher Moore
"""
# shows interface #3 is class 3 (HID)
print "Interface:",interface[0].interfaceNumber
print "Class:",alt.interfaceClass
"""
reqType = usb.ENDPOINT_OUT | usb.TYPE_CLASS | usb.RECIP_INTERFACE
reqBuffer = (0x03 << 8) | 0x04 #(HID_REPORT_FEATURE << 8) + SEND_REPORT_ID
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#(152, 243, 183, 0, 152, 243, 183, 0, 80, 41, 22, 8, 80, 41, 22, 8, 136,
...
Post by Christopher Moore
14, 8, 8, 223, 14, 8)
#reqBuffer = [0] * 8
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
#handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer,
00000304, 0x03)
# returns 8
""" Look Here (Begin) """
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#returns 9
Tim already mentioned that 00000304 is an octal constant, not hex.
(And incidentally, you don't really need so many leading zeros. They
don't contribute anything to the meaning and they only detract from the
readability.)
Post by Christopher Moore
reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#returns 9
handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #doesn't work
#usb.USBError: error submitting URB: No such file or directory
I don't know what went wrong here. It appears that your read request
timed out and was cancelled, which would mean the device didn't have
any data to send.
Post by Christopher Moore
""" Look here (END) """
# release device
handle.releaseInterface()
--------------------------------
Do you need any more information?
The lsusb -v output would help.

Alan Stern
Christopher Moore
2008-10-08 20:12:12 UTC
Permalink
Post by Alan Stern
Post by Christopher Moore
Post by Alan Stern
Post by Christopher Moore
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
I'm not familiar with the Python bindings. It would clarify the
code a little if you replaced REQ_SET_CONFIGURATION with something
closer to REQ_SET_REPORT, although the value (9) is the same for both.
The closest thing I was able to find in the python docs was
REQ_SET_CONFIGURATION
(http://wiki.erazor-zone.de/wiki:projects:python:pyusb:pydoc ... scroll
towards bottom)
You don't have to rely solely on the predefined codes. You can always
add one of your own.
Ah, that's good to know. I thought I was locked into these variables b/c
pyusb is a wrapper with (predefined functions/values).
Post by Alan Stern
Post by Christopher Moore
Post by Alan Stern
Post by Christopher Moore
and then I do this same thing for line 1a) ... you can also see this
in
Post by Alan Stern
Post by Christopher Moore
the attached log.
Once I type this in the python terminal, I get returned: "9" in my
python
prompt. In my logs, I recieve a setup packet: (21 09 04 03 03 00 09
00)
Post by Alan Stern
Post by Christopher Moore
... is this correct?
It agrees with what you told Python to do. That doesn't mean it is
correct.
For instance, this says to send a Feature report with ID 4. Is that
what you want? Normally one would use an Output report, not a Feature
report; it depends on the device.
Is the interface number supposed to be 3? I rather doubt it, since
the
Post by Alan Stern
log shows only one interface, number 0.
Report #4 is used to transport the host-to-device side of the CIT200's
control protocol. Report 4 is defined as Feature data, and thus it will
need to be sent by the host as a Feature-type Report.
The other report, Report #3 is an Input-Type Report (device -> host) ...
as seen in line #2
Also, just curious, how did you know this was a feature-type report?
B/c
it had 0x03 in the returned setupPacket?
The Setup packet isn't _returned_; it is _sent_ from your computer to
the device.
Once again you are confusing matters by making ambiguous remarks: The
Setup packet contains _two_ 0x03's. The first is part of a pair which
forms a little-endian 16-bit integer: 0x0304. This is the wValue field
of the packet (presumably the same as the second-to-last argument of
your handle.controlMsg() call, although it's hard to be sure). For
Set-Report transfers, the wValue field has the report type in its
high-order byte and the report number in its low-order byte (documented
in the HID spec). So I knew the report type was 3, which means
Feature.
I see.
Post by Alan Stern
Post by Christopher Moore
Interface 1 - streaming ... Endpoint OUT (Speaker Out)
Interface 2 - streaming ... Endpoint In, iso transfer type (Mic In)
Interface 3 - HID Interface ... Endpoint IN, interrupt transfer type
The HID Interface on my device is interface #3 as shown in the output from
# shows interface #3 is class 3 (HID)
print "Interface:",interface[0].interfaceNumber
print "Class:",alt.interfaceClass
Okay, I was deceived by misleading output from your USB sniffer.
Those programs sometimes change config descriptor values without
warning. Or maybe the real fault lies inside Windows.
You know, since you have the "lsusb -v" output, it wouldn't hurt for
you to post it.
Post by Christopher Moore
import usb
# linksys CIT200 Device Info
vendor_id = 5041
product_id = 29
buses = usb.busses()
# found the CIT200
linksys = device
A little error-checking here wouldn't hurt. What if your device isn't
found?
I'll get to that after the basics are in place. Good point though.
Post by Alan Stern
Post by Christopher Moore
# open device
handle = linksys.open()
# detach kernel drivers
handle.detachKernelDriver(3)
# setup interface and configs ... there are 4 interfaces for this device...
config = linksys.configurations[0]
interface = config.interfaces[3][0]
endpoint = interface.endpoints[0]
# set configuration and claim interface(s?)
#handle.setConfiguration(config)
"""
Post by Alan Stern
Post by Christopher Moore
Post by Christopher Moore
handle.setConfiguration(config)
File "<stdin>", line 1, in <module>
usb.USBError: could not set config 1: Device or resource busy
"""
handle.claimInterface(interface) # this actually assigns the interface
config I believe ...
All it does is give your program ownership of the interface. Maybe
that's what you meant by "assigns the interface config".
Post by Christopher Moore
handle.setAltInterface(interface)
# reset device
handle.reset()
Why on Earth do you want to reset the device? And if you do want to
reset it, why don't you reset it _before_ claiming the interface and
establishing an altsetting?
Right now I'm copying/pasting from various examples I've come across.
Besides that, no reason in particular.
Post by Alan Stern
Post by Christopher Moore
# HID Report Descriptor
handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)
#(5, 11, 9, 1, 161, 1, 133, 1, 9, 6, 161, 2, 25, 176, 41, 187, 21, 0, 37,
12, 117, 4, 149, 1, 129, 0, 192, 9, 32, 21, 0, 37, 1, 117, 1, 149, 1, 129,
2, 9, 4, 161, 2, 5, 12, 9, 224, 21, 255, 37, 1, 117, 2, 149, 1, 129, 6, 9,
226, 21, 0, 37, 1, 117, 1, 149, 1, 129, 2, 192, 133, 2, 21, 0, 37, 1, 117,
1, 149, 1, 5, 11, 9, 32, 177, 2, 5, 11, 9, 24, 177, 2, 117, 6, 177, 7,5,
20, 9, 1, 38, 255, 0, 117, 8, 149, 1, 9, 44, 177, 2, 149, 15, 9, 44, 177,
2, 133, 3, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 7, 9, 44, 129, 0,
133, 4, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 8, 9, 44, 177, 0,
192)
No doubt you will agree that the output from "lsusb -v" is a lot easier
to comprehend...
This is actually the HID Report ... and actually does make sense to the
"t" :)
Post by Alan Stern
Post by Christopher Moore
"""
# shows interface #3 is class 3 (HID)
print "Interface:",interface[0].interfaceNumber
print "Class:",alt.interfaceClass
"""
reqType = usb.ENDPOINT_OUT | usb.TYPE_CLASS | usb.RECIP_INTERFACE
reqBuffer = (0x03 << 8) | 0x04 #(HID_REPORT_FEATURE << 8) +
SEND_REPORT_ID
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#(152, 243, 183, 0, 152, 243, 183, 0, 80, 41, 22, 8, 80, 41, 22, 8, 136,
...
Post by Christopher Moore
14, 8, 8, 223, 14, 8)
#reqBuffer = [0] * 8
reqType = usb.TYPE_CLASS | usb.RECIP_INTERFACE | usb.ENDPOINT_OUT
#handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer,
00000304, 0x03)
# returns 8
""" Look Here (Begin) """
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#returns 9
Tim already mentioned that 00000304 is an octal constant, not hex.
(And incidentally, you don't really need so many leading zeros. They
don't contribute anything to the meaning and they only detract from the
readability.)
Post by Christopher Moore
reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
handle.controlMsg(reqType, usb.REQ_SET_CONFIGURATION, reqBuffer, 00000304,
0x03)
#returns 9
handle.interruptRead(usb.ENDPOINT_OUT,8) #doesn't work
handle.interruptRead(endpoint.address,8) #doesn't work
#usb.USBError: error submitting URB: No such file or directory
I don't know what went wrong here. It appears that your read request
timed out and was cancelled, which would mean the device didn't have
any data to send.
Post by Christopher Moore
""" Look here (END) """
# release device
handle.releaseInterface()
--------------------------------
Do you need any more information?
The lsusb -v output would help.
Alan Stern
Here's the lsusb output (I had it sitting in an old email):

Device: 005
Device class: 0
Device sub class: 0
Device protocol: 0
Max packet size: 8
idVendor: 5041
idProduct: 29
Device Version: 01.40
Configuration: 1
Total length: 215
selfPowered: 0
remoteWakeup: 0
maxPower: 232
Interface: 0
Alternate Setting: 0
Interface class: 1
Interface sub class: 1
Interface protocol: 0
Interface: 1
Alternate Setting: 0
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Alternate Setting: 1
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Endpoint: 0x2L
Type: 1
Max packet size: 64
Interval: 1
Interface: 2
Alternate Setting: 0
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Alternate Setting: 1
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Endpoint: 0x81L
Type: 1
Max packet size: 64
Interval: 1
Interface: 3
Alternate Setting: 0
Interface class: 3
Interface sub class: 0
Interface protocol: 0
Endpoint: 0x83L
Type: 3
Max packet size: 8
Interval: 1


Thanks for your patience Alen :)
Tim Roberts
2008-10-08 20:52:11 UTC
Permalink
Post by Christopher Moore
Post by Alan Stern
Post by Christopher Moore
# HID Report Descriptor
handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)
#(5, 11, 9, 1, 161, 1, 133, 1, 9, 6, 161, 2, 25, 176, 41, 187, 21, 0, 37,
12, 117, 4, 149, 1, 129, 0, 192, 9, 32, 21, 0, 37, 1, 117, 1, 149, 1, 129,
2, 9, 4, 161, 2, 5, 12, 9, 224, 21, 255, 37, 1, 117, 2, 149, 1, 129, 6, 9,
226, 21, 0, 37, 1, 117, 1, 149, 1, 129, 2, 192, 133, 2, 21, 0, 37, 1, 117,
1, 149, 1, 5, 11, 9, 32, 177, 2, 5, 11, 9, 24, 177, 2, 117, 6, 177, 7,5,
20, 9, 1, 38, 255, 0, 117, 8, 149, 1, 9, 44, 177, 2, 149, 15, 9, 44, 177,
2, 133, 3, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 7, 9, 44, 129, 0,
133, 4, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 8, 9, 44, 177, 0,
192)
No doubt you will agree that the output from "lsusb -v" is a lot easier
to comprehend...
This is actually the HID Report ... and actually does make sense to the
"t" :)
Well, it may be a HID report, but you are printing it as a Python list
of decimal integers. What Alan was saying, I think, is that it would be
easier to read this as a list of hex values. For example:

rpt = handle.getDescriptor(usb.DT_REPORT, 0, 0x9c, usb.ENDPOINT_OUT)
' '.join( ['%02x' % k for k in rpt] )
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Christopher Moore
2008-10-08 21:01:30 UTC
Permalink
Post by Tim Roberts
Post by Christopher Moore
Post by Alan Stern
Post by Christopher Moore
# HID Report Descriptor
handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)
#(5, 11, 9, 1, 161, 1, 133, 1, 9, 6, 161, 2, 25, 176, 41, 187, 21, 0, 37,
12, 117, 4, 149, 1, 129, 0, 192, 9, 32, 21, 0, 37, 1, 117, 1, 149, 1, 129,
2, 9, 4, 161, 2, 5, 12, 9, 224, 21, 255, 37, 1, 117, 2, 149, 1, 129,
6,
9,
226, 21, 0, 37, 1, 117, 1, 149, 1, 129, 2, 192, 133, 2, 21, 0, 37, 1, 117,
1, 149, 1, 5, 11, 9, 32, 177, 2, 5, 11, 9, 24, 177, 2, 117, 6, 177, 7,5,
20, 9, 1, 38, 255, 0, 117, 8, 149, 1, 9, 44, 177, 2, 149, 15, 9, 44, 177,
2, 133, 3, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 7, 9, 44, 129, 0,
133, 4, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8, 149, 8, 9, 44, 177, 0,
192)
No doubt you will agree that the output from "lsusb -v" is a lot easier
to comprehend...
This is actually the HID Report ... and actually does make sense to the
"t" :)
Well, it may be a HID report, but you are printing it as a Python list
of decimal integers. What Alan was saying, I think, is that it would be
rpt = handle.getDescriptor(usb.DT_REPORT, 0, 0x9c, usb.ENDPOINT_OUT)
' '.join( ['%02x' % k for k in rpt] )
Ah Ok. That was just the output from python. I just posted another email
with a "legible" version :)

That's a neat little trick there for converting to hex.

Thanks
Alan Stern
2008-10-08 20:27:57 UTC
Permalink
Post by Christopher Moore
Device: 005
Device class: 0
Device sub class: 0
Device protocol: 0
Max packet size: 8
idVendor: 5041
idProduct: 29
Device Version: 01.40
Configuration: 1
Total length: 215
selfPowered: 0
remoteWakeup: 0
maxPower: 232
Interface: 0
Alternate Setting: 0
Interface class: 1
Interface sub class: 1
Interface protocol: 0
Interface: 1
Alternate Setting: 0
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Alternate Setting: 1
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Endpoint: 0x2L
Type: 1
Max packet size: 64
Interval: 1
Interface: 2
Alternate Setting: 0
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Alternate Setting: 1
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Endpoint: 0x81L
Type: 1
Max packet size: 64
Interval: 1
Interface: 3
Alternate Setting: 0
Interface class: 3
Interface sub class: 0
Interface protocol: 0
Endpoint: 0x83L
Type: 3
Max packet size: 8
Interval: 1
Thanks for your patience Alen :)
This output is incomplete. Maybe you're using an old version of lsusb
(the output certainly looks old-fashioned) or maybe interface 3 was
bound to a driver when you ran lsusb. If you unbind it and use an
up-to-date lsusb, the output will contain the HID descriptor and the
report descriptors.

Alan Stern
Christopher Moore
2008-10-08 20:47:20 UTC
Permalink
Bus 002 Device 002: ID 13b1:001d Linksys
Device Descriptor:
bLength 18
bDescriptorType 1
bcdUSB 1.01
bDeviceClass 0 (Defined at Interface level)
bDeviceSubClass 0
bDeviceProtocol 0
bMaxPacketSize0 8
idVendor 0x13b1 Linksys
idProduct 0x001d
bcdDevice 1.40
iManufacturer 4
iProduct 20
iSerial 50
bNumConfigurations 1
Configuration Descriptor:
bLength 9
bDescriptorType 2
wTotalLength 215
bNumInterfaces 4
bConfigurationValue 1
iConfiguration 0
bmAttributes 0x80
MaxPower 500mA
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 0
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 1 Control Device
bInterfaceProtocol 0
iInterface 0
AudioControl Interface Descriptor:
bLength 10
bDescriptorType 36
bDescriptorSubtype 1 (HEADER)
bcdADC 1.00
wTotalLength 68
bInCollection 2
baInterfaceNr( 0) 1
baInterfaceNr( 1) 2
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 1
wTerminalType 0x0101 USB Streaming
bAssocTerminal 5
bNrChannels 1
wChannelConfig 0x0000
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 12
bDescriptorType 36
bDescriptorSubtype 2 (INPUT_TERMINAL)
bTerminalID 2
wTerminalType 0x0201 Microphone
bAssocTerminal 6
bNrChannels 1
wChannelConfig 0x0000
iChannelNames 0
iTerminal 0
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 3
bSourceID 1
bControlSize 1
bmaControls( 0) 0x03
Mute
Volume
iFeature 0
AudioControl Interface Descriptor:
bLength 8
bDescriptorType 36
bDescriptorSubtype 6 (FEATURE_UNIT)
bUnitID 4
bSourceID 2
bControlSize 1
bmaControls( 0) 0x03
Mute
Volume
iFeature 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 5
wTerminalType 0x0301 Speaker
bAssocTerminal 1
bSourceID 3
iTerminal 0
AudioControl Interface Descriptor:
bLength 9
bDescriptorType 36
bDescriptorSubtype 3 (OUTPUT_TERMINAL)
bTerminalID 6
wTerminalType 0x0101 USB Streaming
bAssocTerminal 2
bSourceID 4
iTerminal 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 1
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 1
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 8000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x02 EP 2 OUT
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 0
bNumEndpoints 0
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 2
bAlternateSetting 1
bNumEndpoints 1
bInterfaceClass 1 Audio
bInterfaceSubClass 2 Streaming
bInterfaceProtocol 0
iInterface 0
AudioStreaming Interface Descriptor:
bLength 7
bDescriptorType 36
bDescriptorSubtype 1 (AS_GENERAL)
bTerminalLink 6
bDelay 1 frames
wFormatTag 1 PCM
AudioStreaming Interface Descriptor:
bLength 11
bDescriptorType 36
bDescriptorSubtype 2 (FORMAT_TYPE)
bFormatType 1 (FORMAT_TYPE_I)
bNrChannels 1
bSubframeSize 2
bBitResolution 16
bSamFreqType 1 Discrete
tSamFreq[ 0] 8000
Endpoint Descriptor:
bLength 9
bDescriptorType 5
bEndpointAddress 0x81 EP 1 IN
bmAttributes 5
Transfer Type Isochronous
Synch Type Asynchronous
Usage Type Data
wMaxPacketSize 0x0040 1x 64 bytes
bInterval 1
bRefresh 0
bSynchAddress 0
AudioControl Endpoint Descriptor:
bLength 7
bDescriptorType 37
bDescriptorSubtype 1 (EP_GENERAL)
bmAttributes 0x00
bLockDelayUnits 0 Undefined
wLockDelay 0 Undefined
Interface Descriptor:
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
HID Device Descriptor:
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 156
Report Descriptors:
** UNAVAILABLE **
Endpoint Descriptor:
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1


As for the Report. I have it laid out here:

/* USAGE_PAGE (Telephony Devices) */ 0x05, 0x0B,
/* USAGE (Phone) */ 0x09, 0x01,
/* COLLECTION (Application) */ 0xA1, 0x01,
/* REPORT_ID (1) */ 0x85, 0x01,
/* USAGE (Telephony Key Pad) */ 0x09, 0x06,
/* COLLECTION (Logical) */ 0xA1, 0x02,
/* USAGE_MINIMUM (Phone Key 0) */ 0x19, 0xB0,
/* USAGE_MAXIMUM (Phone Key Pound) */ 0x29, 0xBB,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (12) */ 0x25, 0x0C,
/* REPORT_SIZE (4) */ 0x75, 0x04,
/* REPORT_COUNT (1) */ 0x95, 0x01,
/* INPUT (Data,Ary,Abs) */ 0x81, 0x00,
/* END_COLLECTION */ 0xC0,
/* USAGE (Hook Switch) */ 0x09, 0x20,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (1) */ 0x25, 0x01,
/* REPORT_SIZE (1) */ 0x75, 0x01,
/* REPORT_COUNT (1) */ 0x95, 0x01,
/* INPUT (Data,Var,Abs) */ 0x81, 0x02,
/* USAGE (Handset) */ 0x09, 0x04,
/* COLLECTION (Logical) */ 0xA1, 0x02,
/* USAGE_PAGE (Consumer Devices) */ 0x05, 0x0C,
/* USAGE (Volume) */ 0x09, 0xE0,
/* LOGICAL_MINIMUM (-1) */ 0x15, 0xFF,
/* LOGICAL_MAXIMUM (1) */ 0x25, 0x01,
/* REPORT_SIZE (2) */ 0x75, 0x02,
/* REPORT_COUNT (1) */ 0x95, 0x01,
/* INPUT (Data,Var,Rel) */ 0x81, 0x06,
/* USAGE (Mute) */ 0x09, 0xE2,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (1) */ 0x25, 0x01,
/* REPORT_SIZE (1) */ 0x75, 0x01,
/* REPORT_COUNT (1) */ 0x95, 0x01,
/* INPUT (Data,Var,Abs) */ 0x81, 0x02,
/* END_COLLECTION */ 0xC0,
/* REPORT_ID (2) */ 0x85, 0x02,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (1) */ 0x25, 0x01,
/* REPORT_SIZE (1) */ 0x75, 0x01,
/* REPORT_COUNT (1) */ 0x95, 0x01,
/* USAGE_PAGE (Telephony Devices) */ 0x05, 0x0B,
/* USAGE (Hook Switch) */ 0x09, 0x20,
/* FEATURE (Data,Var,Abs) */ 0xB1, 0x02,
/* USAGE_PAGE (Telephony Devices) */ 0x05, 0x0B,
/* USAGE (Unassigned) */ 0x09, 0x18,
/* FEATURE (Data,Var,Abs) */ 0xB1, 0x02,
/* REPORT_SIZE (6) */ 0x75, 0x06,
/* FEATURE (Cnst,Var,Rel) */ 0xB1, 0x07,
/* USAGE_PAGE (Alphnumeric Display) */ 0x05, 0x14,
/* USAGE (Alphanumeric Display) */ 0x09, 0x01,
/* LOGICAL_MAXIMUM (255) */ 0x26, 0xFF, 0x00,
/* REPORT_SIZE (8) */ 0x75, 0x08,
/* REPORT_COUNT (1) */ 0x95, 0x01,
/* USAGE (Display Data) */ 0x09, 0x2C,
/* FEATURE (Data,Var,Abs) */ 0xB1, 0x02,
/* REPORT_COUNT (15) */ 0x95, 0x0F,
/* USAGE (Display Data) */ 0x09, 0x2C,
/* FEATURE (Data,Var,Abs) */ 0xB1, 0x02,
/* REPORT_ID (3) */ 0x85, 0x03,
/* USAGE_PAGE (Alphnumeric Display) */ 0x05, 0x14,
/* USAGE (Alphanumeric Display) */ 0x09, 0x01,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (255) */ 0x26, 0xFF, 0x00,
/* REPORT_SIZE (8) */ 0x75, 0x08,
/* REPORT_COUNT (7) */ 0x95, 0x07,
/* USAGE (Display Data) */ 0x09, 0x2C,
/* INPUT (Data,Ary,Abs) */ 0x81, 0x00,
/* REPORT_ID (4) */ 0x85, 0x04,
/* USAGE_PAGE (Alphnumeric Display) */ 0x05, 0x14,
/* USAGE (Alphanumeric Display) */ 0x09, 0x01,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (255) */ 0x26, 0xFF, 0x00,
/* REPORT_SIZE (8) */ 0x75, 0x08,
/* REPORT_COUNT (8) */ 0x95, 0x08,
/* USAGE (Display Data) */ 0x09, 0x2C,
/* FEATURE (Data,Ary,Abs) */ 0xB1, 0x00,
/* END_COLLECTION */ 0xC0


Does that help?


Thanks


Christopher
Post by Alan Stern
Post by Christopher Moore
Device: 005
Device class: 0
Device sub class: 0
Device protocol: 0
Max packet size: 8
idVendor: 5041
idProduct: 29
Device Version: 01.40
Configuration: 1
Total length: 215
selfPowered: 0
remoteWakeup: 0
maxPower: 232
Interface: 0
Alternate Setting: 0
Interface class: 1
Interface sub class: 1
Interface protocol: 0
Interface: 1
Alternate Setting: 0
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Alternate Setting: 1
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Endpoint: 0x2L
Type: 1
Max packet size: 64
Interval: 1
Interface: 2
Alternate Setting: 0
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Alternate Setting: 1
Interface class: 1
Interface sub class: 2
Interface protocol: 0
Endpoint: 0x81L
Type: 1
Max packet size: 64
Interval: 1
Interface: 3
Alternate Setting: 0
Interface class: 3
Interface sub class: 0
Interface protocol: 0
Endpoint: 0x83L
Type: 3
Max packet size: 8
Interval: 1
Thanks for your patience Alen :)
This output is incomplete. Maybe you're using an old version of lsusb
(the output certainly looks old-fashioned) or maybe interface 3 was
bound to a driver when you ran lsusb. If you unbind it and use an
up-to-date lsusb, the output will contain the HID descriptor and the
report descriptors.
Alan Stern
Tim Roberts
2008-10-08 22:28:07 UTC
Permalink
Post by Christopher Moore
Bus 002 Device 002: ID 13b1:001d Linksys
...
/* USAGE_PAGE (Telephony Devices) */ 0x05, 0x0B,
/* USAGE (Phone) */ 0x09, 0x01,
/* COLLECTION (Application) */ 0xA1, 0x01,
...
/* REPORT_ID (4) */ 0x85, 0x04,
/* USAGE_PAGE (Alphnumeric Display) */ 0x05, 0x14,
/* USAGE (Alphanumeric Display) */ 0x09, 0x01,
/* LOGICAL_MINIMUM (0) */ 0x15, 0x00,
/* LOGICAL_MAXIMUM (255) */ 0x26, 0xFF, 0x00,
/* REPORT_SIZE (8) */ 0x75, 0x08,
/* REPORT_COUNT (8) */ 0x95, 0x08,
/* USAGE (Display Data) */ 0x09, 0x2C,
/* FEATURE (Data,Ary,Abs) */ 0xB1, 0x00,
/* END_COLLECTION */ 0xC0
Does that help?
Well, since I believe all of the reports you showed were dinking with
report #4, if nothing else this tells us that it's trying to talk to the
alphanumeric display.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Christopher Moore
2008-10-09 12:46:19 UTC
Permalink
Post by Tim Roberts
Well, since I believe all of the reports you showed were dinking with
report #4, if nothing else this tells us that it's trying to talk to the
alphanumeric display.
Yes, that is correct. This will display status, phonebook from skype,
etc...

Everything related to sending to this device is going to report #4
(Feature, Alphanumeric) via a Class Interface controlMsg. While,
everything returning from the device is coming from report #3 (Input,
Alphanumeric) via bulk/interrupt.


Now Alen, I've monitored my traffic via usbmon and got the following:

# Python Code
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(0x21,0x09,reqBuffer,0x0304,0x03)

reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
handle.controlMsg(0x21,0x09, reqBuffer, 0x0304, 0x03)

# corresponding usbmon entries
f4806700 3753376921 S Co:2:013:0 s 21 09 0304 0003 0009 9 = 04c13300
43079a4f 68
f4806700 3753378298 C Co:2:013:0 0 9 >

f4806180 3755864710 S Co:2:013:0 s 21 09 0304 0003 0009 9 = 04050816
00010000 68
f4806180 3755866096 C Co:2:013:0 0 9 >


That looks correct. What I don't get... is how do I get data back from
the device via the interruptRead call. It keeps telling me
"usb.USBError: error submitting URB: No such file or directory"
Tim Roberts
2008-10-09 16:21:04 UTC
Permalink
handle.bulkRead(0x83,8) # I've also tried 0x08 for the heck of it)
"usb.USBError: error submitting URB: No such file or directory"
Does the Python interface have an interruptRead? A bulk pipe and an
interrupt pipe are identical from an interface point of view, so it's
possible they use the same API. (Windows does.)

And you're sure you've selected interface #3? That's the only one with
endpoint 0x83.
--
Tim Roberts, ***@probo.com
Providenza & Boekelheide, Inc.
Christopher Moore
2008-10-09 21:19:46 UTC
Permalink
Post by Tim Roberts
handle.bulkRead(0x83,8) # I've also tried 0x08 for the heck of it)
"usb.USBError: error submitting URB: No such file or directory"
Does the Python interface have an interruptRead? A bulk pipe and an
interrupt pipe are identical from an interface point of view, so it's
possible they use the same API. (Windows does.)
Yes, what I pasted above, should've actually been a
interruptRead(endpoint,size). bulkRead(endpoint,buffer,size) ... or
something to that effect.
Post by Tim Roberts
And you're sure you've selected interface #3? That's the only one with
endpoint 0x83.
Yes, I verified that: (1) interface #3 was the HID Interface (2) this
was the interface I detached and claimed and (3) that it's endpoint
matched 0x83.

I'm going to look into this some more now that I have a few minutes...

Thanks
Alan Stern
2008-10-08 21:05:21 UTC
Permalink
Post by Christopher Moore
Bus 002 Device 002: ID 13b1:001d Linksys
...
Post by Christopher Moore
bLength 9
bDescriptorType 4
bInterfaceNumber 3
bAlternateSetting 0
bNumEndpoints 1
bInterfaceClass 3 Human Interface Device
bInterfaceSubClass 0 No Subclass
bInterfaceProtocol 0 None
iInterface 0
bLength 9
bDescriptorType 33
bcdHID 1.01
bCountryCode 0 Not supported
bNumDescriptors 1
bDescriptorType 34 Report
wDescriptorLength 156
** UNAVAILABLE **
This would have been available if the interface was not claimed
by a driver at the time.
Post by Christopher Moore
bLength 7
bDescriptorType 5
bEndpointAddress 0x83 EP 3 IN
bmAttributes 3
Transfer Type Interrupt
Synch Type None
Usage Type Data
wMaxPacketSize 0x0008 1x 8 bytes
bInterval 1
...
Post by Christopher Moore
Does that help?
Maybe. It's better than not having the information.

You should try monitoring the USB traffic when you run your program.
On a Linux system you can use usbmon (see Documentation/usb/usbmon.txt
in the kernel source). That will tell you if the program really is
sending the data you want it to send.

Alan Stern
Alan Stern
2008-10-08 21:07:06 UTC
Permalink
Post by Tim Roberts
Post by Christopher Moore
This is actually the HID Report ... and actually does make sense to the
"t" :)
Well, it may be a HID report, but you are printing it as a Python list
of decimal integers. What Alan was saying, I think, is that it would be
rpt = handle.getDescriptor(usb.DT_REPORT, 0, 0x9c, usb.ENDPOINT_OUT)
' '.join( ['%02x' % k for k in rpt] )
Actually, what I meant was that it would be easier to read if it was
translated into English words, as in the report descriptor dump Chris
just posted.

Alan Stern
Alan Stern
2008-10-09 15:01:25 UTC
Permalink
Post by Christopher Moore
Now Alen,
I do wish you would spell my name correctly.
Is this _all_ of your traffic?
Post by Christopher Moore
# Python Code
reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(0x21,0x09,reqBuffer,0x0304,0x03)
reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
handle.controlMsg(0x21,0x09, reqBuffer, 0x0304, 0x03)
# corresponding usbmon entries
f4806700 3753376921 S Co:2:013:0 s 21 09 0304 0003 0009 9 = 04c13300
43079a4f 68
f4806700 3753378298 C Co:2:013:0 0 9 >
f4806180 3755864710 S Co:2:013:0 s 21 09 0304 0003 0009 9 = 04050816
00010000 68
f4806180 3755866096 C Co:2:013:0 0 9 >
That looks correct.
Does it? In the sniffer log you posted before, the contents of the
second URB were: 04050c35 00010000 68. This differs from your data in
two bytes. Maybe that difference doesn't matter, maybe it does.

Also, the sniffer log shows two transfers that you haven't listed here,
so presumably your program isn't doing them. The first is the Set-Idle
request (URB 5 in the log) and the second is the Get-Report-Descriptor
request (URB 6 in the log). For all we know, the device may want to
see those requests before it will function.
Post by Christopher Moore
What I don't get... is how do I get data back from
the device via the interruptRead call. It keeps telling me
"usb.USBError: error submitting URB: No such file or directory"
Does it produce no output at all in the usbmon trace? If so then you
must not be using the function correctly. Does it really take only two
arguments?
Christopher Moore
2008-10-09 21:46:30 UTC
Permalink
Ok. Starting fresh here.

I just re-plugged the device, started a new python session and actually
had success, albeit a wrong return from interruptRead, but it did at
least return something now :)

Also, thanks everyone for your patience, helping a newbie here. Every
step of the way, I think I got it, but then realize, I'm clueless. I'm
getting close now! I think when I'm done, I'm going to write a
tutorial. Especially on how to wade through the hundreds of pages of
docs between usb specs and hid.

Anyways, here's what worked and what usbmon said:

Python code:

#!/usr/bin/python

import usb

# linksys CIT200 Device Info
vendor_id = 5041
product_id = 29

buses = usb.busses()

for bus in buses :
for device in bus.devices :
if device.idVendor == vendor_id :
if device.idProduct == product_id :
# found the CIT200
linksys = device

# open device
handle = linksys.open()
# detach kernel drivers
handle.detachKernelDriver(3)

# setup interface and configs ... there are 4 interfaces for this device...
config = linksys.configurations[0]
interface = config.interfaces[3][0]
endpoint = interface.endpoints[0]

handle.claimInterface(interface)
handle.setAltInterface(interface)

handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)

reqType = usb.ENDPOINT_OUT | usb.TYPE_CLASS | usb.RECIP_INTERFACE

reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(0x21,0x09,reqBuffer,0x0304,0x03)

reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
handle.controlMsg(0x21,0x09, reqBuffer, 0x0304, 0x03)

handle.interruptRead(endpoint.address,8)

----------------------------------------------------------------
Returns from python prompt given above code:
handle.getDescriptor(usb.DT_REPORT,0,0x9c,usb.ENDPOINT_OUT)

(5, 11, 9, 1, 161, 1, 133, 1, 9, 6, 161, 2, 25, 176, 41, 187, 21, 0, 37,
12, 117, 4, 149, 1, 129, 0, 192, 9, 32, 21, 0, 37, 1, 117, 1, 149, 1,
129, 2, 9, 4, 161, 2, 5, 12, 9, 224, 21, 255, 37, 1, 117, 2, 149, 1,
129, 6, 9, 226, 21, 0, 37, 1, 117, 1, 149, 1, 129, 2, 192, 133, 2, 21,
0, 37, 1, 117, 1, 149, 1, 5, 11, 9, 32, 177, 2, 5, 11, 9, 24, 177, 2,
117, 6, 177, 7, 5, 20, 9, 1, 38, 255, 0, 117, 8, 149, 1, 9, 44, 177, 2,
149, 15, 9, 44, 177, 2, 133, 3, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8,
149, 7, 9, 44, 129, 0, 133, 4, 5, 20, 9, 1, 21, 0, 38, 255, 0, 117, 8,
149, 8, 9, 44, 177, 0, 192)

(report descriptor ... correct)
Post by Christopher Moore
handle.controlMsg(0x21,0x09,reqBuffer,0x0304,0x03)
9
Post by Christopher Moore
handle.controlMsg(0x21,0x09, reqBuffer, 0x0304, 0x03)
9
Post by Christopher Moore
handle.interruptRead(endpoint.address,8)
(3, 131, 52, 0, 67, 0, 0, 0)
Incorrect. 03, 131 ( = 0x83) is correct, but not 52 nor 67, they should
be 34 and 43 respectively. Now to look into that...


---------------------------
what usbmon says:

e4872700 723533881 S Co:2:005:0 s 21 09 0304 0003 0009 9 = 04c13300
43079a4f 68
e4872700 723536265 C Co:2:005:0 0 9 >
e4872780 730732967 S Co:2:005:0 s 21 09 0304 0003 0009 9 = 04050816
00010000 68
e4872780 730734696 C Co:2:005:0 0 9 >
f614b800 741884348 S Ii:2:005:3 -115:1 8 <
f614b800 741885761 C Ii:2:005:3 0:1 8 = 03833400 43000000
e4874180 788987295 S Co:2:005:0 s 21 09 0304 0003 0009 9 = 04c13300
43079a4f 68
e4874180 788988913 C Co:2:005:0 0 9 >
e4874180 788998287 S Co:2:005:0 s 21 09 0304 0003 0009 9 = 04050816
00010000 68
e4874180 788999925 C Co:2:005:0 0 9 >
e4874100 790280271 S Ii:2:005:3 -115:1 8 <
e4874100 790381795 C Ii:2:005:3 -2:1 0
e4874400 795303770 S Ii:2:005:3 -115:1 8 <
e4874400 795404384 C Ii:2:005:3 -2:1 0


Notice the second set of commands (I tried a repeat) and it failed the
interruptRead. Time to investigate that as well.

As mentioned in your reply , it seems I'm missing the set idle (urb 5)
command. That was from an older log where I watched what occured during
a "replug". The log I was using now, I didn't watch the "replug", only
what the cit200.exe was doing ... I will try the "set idle " command
and see what it says. I'm also going to try it w/ skype running in
linux now and see if the interruptRead response matches.

Thanks

Christopher
Christopher Moore
2008-10-09 22:16:45 UTC
Permalink
Post by Christopher Moore
handle.interruptRead(endpoint.address,8)
(3, 131, 52, 0, 67, 0, 0, 0)
Incorrect. 03, 131 ( = 0x83) is correct, but not 52 nor 67, they should
be 34 and 43 respectively. Now to look into that...
Note that 0x34 = 52 and 0x43 = 67. I think your Python output is
correct.
woohoo!!!
Notice the second set of commands (I tried a repeat) and it failed the
interruptRead. Time to investigate that as well.
Evidently the device doesn't like to get the same commands twice in a
row.
Alan Stern
Well finally.. I got it to display (for a short time anyway), that skype
was online!

Now I know what the command actually does... The first one:

reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(0x21,0x09,reqBuffer,0x0304,0x03)

reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x01, 0x00, 0x00, 0x68)
#notice 0x01
handle.controlMsg(0x21,0x09, reqBuffer, 0x0304, 0x03)


says skype offline (on the phone)

and the second command (after further review):

reqBuffer = (0x04, 0xc1, 0x33, 0x00, 0x43, 0x07, 0x9a, 0x4f, 0x68)
handle.controlMsg(0x21,0x09,reqBuffer,0x0304,0x03)

reqBuffer = (0x04, 0x05, 0x08, 0x16, 0x00, 0x00, 0x00, 0x00, 0x68)
#notice it's 0x00 instead of 0x01
handle.controlMsg(0x21,0x09, reqBuffer, 0x0304, 0x03)

says skype is online (which is displayed on the phone)


Now this set idle command is driving me nuts, but I'll figure it out.
I've bugged you guys enough :)

Thanks and finally some good tangible progress!

Christopher
Alan Stern
2008-10-09 22:03:13 UTC
Permalink
Post by Christopher Moore
handle.interruptRead(endpoint.address,8)
(3, 131, 52, 0, 67, 0, 0, 0)
Incorrect. 03, 131 ( = 0x83) is correct, but not 52 nor 67, they should
be 34 and 43 respectively. Now to look into that...
Note that 0x34 = 52 and 0x43 = 67. I think your Python output is
correct.
Notice the second set of commands (I tried a repeat) and it failed the
interruptRead. Time to investigate that as well.
Evidently the device doesn't like to get the same commands twice in a
row.

Alan Stern

Continue reading on narkive:
Loading...