BaH.libusb

BlitzMax Forums/Brucey's Modules/BaH.libusb

Brucey(Posted 2009) [#1]
Decided to add another of my long-standing modules to maxmods SVN. This one, BaH.libusb, enables direct access to USB devices attached to your PC.

There's a small example provided which lists attached devices. It can also be set to display lots of more verbose information about the specific devices.

Basic example output looks like this :
Executing:example_01.debug
 0: 0x8005
 0: 0x8005
 0: 0x8005
 0: 0x8005
 0: 0x8005
 0: 0x8005
 0: 0x8006
 0: Seagate - FreeAgentDesktop
 0: 0x0264
 0: Apple, Inc. - Keyboard Hub
 0: Hewlett-Packard - HP LaserJet P2015 Series
 0: Logitech - Logitech USB Headset
 0: Apple, Inc - Apple Keyboard
 0: Logitech - USB-PS/2 Optical Mouse
 0: ????????y - USB Mass Storage Device

Process complete

Descriptive text is displayed when the device returns it.

You can also "claim" an interface, with which you can then read and write to it - if you really want to do such interesting low level things like that ;-)

Docs are... okay... but I'll need to try and pad them out a little before a proper release.


More niche modules by Brucey.... :-p


Htbaa(Posted 2009) [#2]
What platforms are supported? All?


Brucey(Posted 2009) [#3]
Yes, All :-)

libusb is standard on Mac and Linux.
For Win32, is uses the libusb-win32 project (LGPL), which implements the same interface as libusb on the other platforms. (you need to include libusb0.dll - from the lib/win32 folder)
... in theory - just tried it in Parallels, and it didn't find anything :-/


Ole JR(Posted 2009) [#4]
Doesn't find anything on a real Windows XP box either.
As USBFindBusses() always return null.
But I guess you already figured that by now..

Found this though:
If you are porting a libusb based program from Unix style systems to Windows, remove all references to the library's global variable usb_busses. Use the function usb_get_busses() instead to get this variable. Global variables in shared libraries (DLLs) do not work on Windows systems across different compilers.



Brucey(Posted 2009) [#5]
It's the wrong DLL :-)

(yes, there were two binary packages to choose from, and I picked the wrong one).


xlsior(Posted 2009) [#6]
doesn't seem to work under windows (Vista 64)

all I get is:

Executing:libusbtest.exe
0: 0x0000 - 0x0000



(And I do have half a dozen USB devices connected)

As a sidenote, it looks like you also did an update to bah.volumes on your SVN, and that one is no longer working:

MakeMods - Compiling New Modules
Compiling:main.bmx
Compile Error: Identifier 'strlen_' not found
[c:/code/blitzmax/mod/bah.mod/volumes.mod/main.bmx;221;3]
Build Error: failed to compile c:/code/blitzmax/mod/bah.mod/volumes.mod/main.bmx
MakeMods - Compiling New Threading Modules
Compiling:main.bmx
Compile Error: Identifier 'strlen_' not found
[c:/code/blitzmax/mod/bah.mod/volumes.mod/main.bmx;221;3]
Build Error: failed to compile c:/code/blitzmax/mod/bah.mod/volumes.mod/main.bmx


Did the prerequisites change, by any chance?


Ole JR(Posted 2009) [#7]
A download & install of 'libusb-win32-filter-bin-0.1.12.1.exe' made it work for me here.
Seems that's the only way to get it working on Windows, cause it installs a needed (device ?) driver.

link: http://sourceforge.net/project/showfiles.php?group_id=78138&package_id=79216

And same issue with volumes here too :-)

edit:
One more thingy. After the above it works on my winXP box,
with names & stuff on the plugged usb devices.

But on Linux it doesn't, with the same devices plugged.
All I get there is a list kind of like:
0: 0x0001
0: 0xC20B
0: 0x0001

Only thing that happens is that the list grow/shrink as I plug/unplug the devices..


Brucey(Posted 2009) [#8]
Did the prerequisites change, by any chance?

Ah... bugger... no... I included a new function (which will hopefully appear in BlitzMax core at some point) and forgot to include an extern for strlen_ also... *sigh*
It worked for me, obviously, since my BlitzMax is now unicode friendly, and therefore has everything already... argh.

Apologies... Fixed now.


As for the libusb thing... I've checked some changes which exposes a couple of new Functions... One is to install a new filter service (USBInstallService), which libusb seems to want in order to gain access to the usb devices.
I think, after the install function has been run once, it doesn't need to be run again. It certainly works here after I've called the function. If I then call USBUninstallService(), I get nothing back.

All I get there is a list kind of like:

Same here. Perhaps it's a Linux thing...


Ole JR(Posted 2009) [#9]
Uninstalled that other package, and it works without it now.. kind of.

On first run of the example it returns 2/3 devices, next run all 3..

Unless I add USBUninstallService() right before End, then it's back to 2/3 on each run.


Brucey(Posted 2009) [#10]
But on Linux it doesn't, with the same devices plugged.

Seems if you run with "sudo", it can get the device names properly...
brucey@...$ sudo ./example_01.debug
 1: Linux 2.6.24-22-generic ehci_hcd - EHCI Host Controller
             2: Generic - USB 2.0 Reader
 1: Linux 2.6.24-22-generic ehci_hcd - EHCI Host Controller
 1: Linux 2.6.24-22-generic uhci_hcd - UHCI Host Controller
 1: Linux 2.6.24-22-generic uhci_hcd - UHCI Host Controller
 1: Linux 2.6.24-22-generic uhci_hcd - UHCI Host Controller
             4: Kensington - USB Input Device
 1: Linux 2.6.24-22-generic uhci_hcd - UHCI Host Controller
 1: Linux 2.6.24-22-generic uhci_hcd - UHCI Host Controller
 1: Linux 2.6.24-22-generic uhci_hcd - UHCI Host Controller


Hmm... I suppose some low-level access is better than none?


Ole JR(Posted 2009) [#11]
Probably yes :-)

But my Windows box didn't like it much after some testing..
Nothing advanced mind you. Just ran the example from cmd and
got a BSOD, and after reboot there was something fishy with my usb.
As in didn't detect anything anymore.

Oh well.. After removing everything -usb under hardwaredrivers/settings it's up & running again :-)


Brucey(Posted 2009) [#12]
But on Linux it doesn't, with the same devices plugged.

Interestingly... "lsusb" does return some basic names...

But I found the source, and it appears to cheat... in that it is matching the ids with this : http://www.linux-usb.org/usb.ids
...which maybe isn't such a crazy idea.


xlsior(Posted 2009) [#13]
As far as no names returned when not running with sudo under Linux: I expect that the config files that contain the lookup info aren't readable by all users under Linux. It contains aconfiguration file with all the ID's as part of the standard distribution.

Here's a link to the USB ID list in case you want to program them in straight into the app itself:

http://www.linux-usb.org/usb.ids

It contains a full list of known USB manufactueres and device id's, eg:
03ee  Mitsumi
	0000  CD-R/RW Drive
	2501  eHome Infrared Receiver
	2502  eHome Infrared Receiver
	5609  Japanese Keyboard
	641f  WIF-0402C Bluetooth Adapter
	6438  Bluetooth Device
	6440  WML-C52APR Bluetooth Adapter
	6901  SmartDisk FDD
	6902  Floppy Disk Drive
	7500  CD-R/RW
	ffff  Dongle with BlueCore in DFU mode
03f0  Hewlett-Packard
	0004  DeskJet 895c
	0011  OfficeJet G55
	0012  DeskJet 1125C Printer Port
	0024  KU-0316 Keyboard
	0101  ScanJet 4100c
	0102  PhotoSmart S20
	0104  DeskJet 880c/970c


Of course hardcoding them means that you may not benefit from an updated list spread with Linux itself... But maybe you can use it as a fallback in case you aren't getting any info from the built-in ID's?


Difference(Posted 2009) [#14]
WARNING: This totally crashed my XP, so that everything froze and I could only boot again by choosing, "last working installation" from the boot screen

Looks interesting though.


Brucey(Posted 2009) [#15]
Okay... I guess not using it on Windows, is a good idea :-/


Ole JR(Posted 2009) [#16]
Nah, me like to live on the edge :-)

But seriously, I think that installing the *.exe package from
http://sourceforge.net/project/showfiles.php?group_id=78138&package_id=79216
seem like a small price to pay, even if the enduser of an app also had to.

When doing that it didn't trash my machine atleast..

The crash might have something to do with the "Please remove all usb devices before installing the filter/driver" message that comes with the above installer..


Queller(Posted 2009) [#17]
Sadly, I have not gotten to the point any of you have... I built this module and it gives me the error:

Building Modules
Compiling:glue.cpp
/Developer/BlitzMax/mod/BaH.mod/libusb.mod/glue.cpp:23:18: error: usb.h: No such file or directory
/Developer/BlitzMax/mod/BaH.mod/libusb.mod/glue.cpp:35: error: expected constructor, destructor, or type conversion before '*' token
/Developer/BlitzMax/mod/BaH.mod/libusb.mod/glue.cpp:38: error: 'usb_dev_handle' has not been declared


etc etc... with a huge stream of stuff after that is clearly related to the contents of the header file it apparently can not find :(

Please will someone tell me how might i fix this?


Ole JR(Posted 2009) [#18]
Your missing the libusb-devel package..


Queller(Posted 2009) [#19]
ah. well that was easy. thanks. also, brucey: you rule. this mod means i can do some fun stuff with webcams on an apple, right?


Brucey(Posted 2009) [#20]
this mod means i can do some fun stuff with webcams on an apple, right

Possibly. But you might find there's much less work involved - i.e. not so low level - by using the Quicktime APIs.
(no I don't have a mod for that, yet ;-)


Queller(Posted 2009) [#21]
Hey Brucey, after tinkering with this fantastic mod i found myself having to deal with stall conditions being issued by a usb device during a bulk transfer. The problem is detecting a stall condition so i can handle it elegantly with clearHalt and retry a transfer.

After looking at the libusb API, i saw there is a way to query a transfer status (libusb.h, lines 640 - 659), but this stuff seems missing in the mod. How do I go about getting access to the transfer status so i can tell if i need clear the halt? is there something i have skipped over?


Brucey(Posted 2009) [#22]
I believe USBDeviceHandle.controlMsg(...) provides the same functionality. (see here).

BaH.libusb uses the 0.1.x API, which appears to be the latest available for Win32. There is a new 1.0 API (for Mac & linux) which is much friendlier as far as using it is concerned, but I haven't found a working build on Win32... so for now we stick with legacy, I'm afraid.


allos(Posted 2009) [#23]
thank you Brucey
do you think BaH.libusb allows low level access to USB port in real time (and on Windows...)?
I need my software to emit a signal with milliseconds precision (or at least with an error in the order of 10 milliseconds) and the only way I found was using a serial port library... but PCs now don't come with serial ports...


allos(Posted 2009) [#24]
brucey,
do you think BaH.libusb allows low level access to USB port in real time (and on Windows...)?
I need my software to emit a signal with milliseconds precision (or at least with an error in the order of 10 milliseconds) and the only way I found was using a serial port library... but PCs now don't come with serial ports...


xlsior(Posted 2009) [#25]
Quite a few of them still do... Plus you have the USB-to-Serial dongles which you can talk to like a normal serial adapter.


allos(Posted 2009) [#26]
xlsior, can you better explain to me?


JetFireDX(Posted 2009) [#27]
Is this module still available? I can't seem to find it on your Google Code page or your other page.

Thanks!


plash(Posted 2009) [#28]
http://www.google.com/codesearch/p?hl=en&sa=N&cd=10&ct=rc#5jiG3hroW30/trunk/libusb.mod&q=libusb%20package:http://maxmods\.googlecode\.com

It's still there, you just have to search for it (trunk browser doesn't show the full tree).


JetFireDX(Posted 2009) [#29]
Thanks Plash!


FredR(Posted 2010) [#30]
Hi all, I'm looking for a way to make my blitzmax code to talk to a CDC USB serial driver on windows (XP and 7) for a home made device (PIC18F4550 and CCS C CDC sources). I did that often with previous homemade boards with real serial interface. It creates a virtual COM12 (in my case). Visual Basic 6 opens the port and talks to the board nicely but I need to do it blitzmax (I tried OpenStream and TCOMM Open with no success). Can this lib do that ?


Brucey(Posted 2010) [#31]
If it appears as a standard "serial port", you should be able to connect to is as you would a real one.

This lib is more low-level than you need for this.


FredR(Posted 2010) [#32]
Thank you for your answer (and your modules as I used some)
Yes the board appears in the Devices list in windows under Ports COM & LPT as "USB to UART (COM12)" but Blitzmax do not want to open it (I use the same code that works well with an older board using real serial port COM1 and TComm functions).
I continue my investigation...


Difference(Posted 2011) [#33]
Sorry to be necromancing, but I'd like to get this running on Snow Leopard, in an attempt to talk to my LEGO NXT.

First hitch is "libusb.h not found" in glue.cpp.

Any pointers?


Difference(Posted 2011) [#34]
I think have found another way to do this:

http://blitzmax.com/Community/posts.php?topic=64573#1111921

Last edited 2011


Difference(Posted 2011) [#35]
I've got by NXT running very well via Bluetooth now.
It is as simple as writing/reading to the correct /dev device, in my case "/dev/tty.NXT-DevB"

I would still like to shift to USB for better speed and reliability.

Any pointers on where I need to start to get Bah.libusb to compile?


[EDIT] should I get this: http://sourceforge.net/projects/libusb/files/libusb-1.0/libusb-1.0.8/

And where do I put it?

Last edited 2011


matt!(Posted 2012) [#36]
I have a single button USB gadget here that I want to write something for. When the button is pressed I want to do something.

Does anybody have any tips on how to "claim" a USB device?
What ID do I use to claim the device? Vendor? Product? Both?
And after claimed how do I watch for an interrupt on the button press?

Any help or pointers appreciated.

Thanks,
matt

Last edited 2012


matt!(Posted 2012) [#37]
OK, so I've managed to read from the device with a Ruby script.

https://github.com/gingerbeardman/dream_cheeky

Basically, it polls the device repeatedly with a command buffer asking for it's state. The device returns a default value, and another when depressed. The code only does something when it's depressed.

Now, to convert that concept and code to cross-platform BMX code!


Bobysait(Posted 2016) [#38]


I might be wrong, but I'm almost sure of two things :
- descriptor:USBDeviceDescriptor and its description don't fit together
- there is no prevDevice (which one would better fit the documentation of descriptor)

So, maybe the "Descriptor" method returns the previous device on the list ? If so, it's really not implicit, Else, there is definetely something to fix here.

Whatever, I don't need the method actually ... But I just wanted to let you know.
I still have to test the library on windows 10.
Do I have to cross the fingers and hope it does not crash the PC ?