BaH.libusb

BlitzMax Modules Forums/Brucey's Modules/BaH.libusb

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

What platforms are supported? All?

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 :-/

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.


It's the wrong DLL :-)

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

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?

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..

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...

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.

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?

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 :-)

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.

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?

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.

Okay... I guess not using it on Windows, is a good idea :-/

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..

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?

Your missing the libusb-devel package..

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?

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 ;-)

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?

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.

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...