Skip to content

jbrache/node-usb

 
 

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

76 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

libusb-1.0 bindings for Node.js
==============================
node-usb binds libusb-1.0 to Node.js 

Testing the node-usb addon with the beaglebone (http://beagleboard.org/static/beaglebone/latest/README.htm).

At the time of this writing, the beaglebone runs on the the linux Angstrom distribution with:
* node js version v0.4.12

Forked node-usb from: https://github.com/schakko/node-usb (original creator: Christopher Klein <ckl[at]ecw[dot]de>)

Using commit a91ce85870d9fd263bc2d2dc04ecfb53e83f1504 as the beginning of this fork.
Had to use that commit point because the beaglebone does not come installed with libuv (used in the current master of https://github.com/schakko/node-usb.git). 
Not quite sure how to install libuv on the beaglebone correctly and add it as a dependency for node-usb, especially with the older version of node js - v0.4.12
installed on the beaglebone.

Installing a newer version of node js on the beaglebone breaks the Cloud9 IDE, so it's probably best to wait until those issues are resolved.

To get this addon to work on the beaglebone, connect to the beaglebone through the serial console or through ssh and run complete the following steps:

beaglebone setup
==============================
The following instructions assume the image installed on the beaglebone is:
* "The Rev A5 Production 02-14-12 production image"
* http://circuitco.com/support/index.php?title=BeagleBone

Which can be downloaded from:
* http://circuitco.com/support/files/BeagleBone-A5/BeagleBone_Rev_A5_Production_02_14_2012.7z

1. Install Libusb-dev: <- needed to get all the header files...
# opkg update
# opkg install libusb-1.0-dev

2. Install NPM <- OPTIONAL, not needed but nice to have, otherwise skip to the installation section...
# curl http://npmjs.org/install.sh | sh

Installation
==============================
* Make sure you configure the beaglebone before you run the steps below:

1. Go to the Cloud9 workspace to install the node-usb package
# cd /var/lib/cloud9/node_modules
# git clone git://github.com/jbrache/node-usb.git
# cd node-usb

2. This is important, running make:
# make
in current directory and wait. "Unit tests" are automatically executed by default target.

You can although execute the tests by typing:
	node tests/node-usb-test.js

If you want to use the USB vendor ids, execute
	make create-usb-ids

For creating debug output you have to compile node-usb with
	make debug
or
	node-waf clean configure --debug=true build

API
=============================
returned values can always be an error object, so make sure that no error occurs!
The device/interface/endpoint descriptor values are always injected into the proper object. I do not list them.

Usb
	.LIBUSB_* : const
		constant properties from libusb
	.isLibusbInitalized : boolean
		property for getting libusb initalization status
	.refresh() : undefined
		refreshes the node-usb environment
	.setDebugLevel(int _level) : undefined
		wrapper for libusb_set_debug; _level has to be between 0 and 4
	.getDevices() : Device[]
		returns the devices discovered by libusb
	.close() : undefined
		closes node-usb

Device
	.deviceAddress : int
		property for getting device address
	.busNumber : int
		property for getting bus number
	.reset(function _afterReset) : undefined
		[async] resets device, expects callback function after reset
	.getConfigDescriptor() : Object
		returns configuration descriptor of device
	.getExtraData() : Array
		returns byte array with extra data from config descriptor
	.getInterfaces() : Interface[]
		returns interfaces
	.getDeviceDescriptor() : Object
		returns devices descriptor
	.controlTransfer(mixed read|write, int _bmRequestType, int _bRequest, int _wValue, int _wIndex, function afterTransfer(data) [, int _timeout])
		[async] delegates to libusb_control_transfer. First parameter can be either
		  * int, then controlTransfer works in read mode (read data FROM USB device)
		  * Array of ints, then controlTransfer works in write mode (write data TO USB device)
		_timeout parameter is optional
Interface
	.__idxInterface : int
		property for internal interface index
	.__idxAltSetting : int
		property for internal alternate interface setting
	.getEndpoints() : Endpoint[]
		returns an array of Endpoint objects
	.detachKernelDriver() : undefined
		detaches the kernel driver from interface
	.attachKernelDriver() : undefined
		re-attaches the kernel driver to interface
	.claim() : undefined
		claims the interface. this method must be __always__ called if you want to transfer data via the endpoint. There is no hig level API check for this
	.release(function afterClaim(data)) : undefined
		[async] releases prior claimed interface; function wil be called after releasing
	.setAlternateSetting(int _alternateSettingIdx, function afterAlternateSettingChosen(data))
		[async] sets alternate setting of interface; first parameter is the alternate setting index (there is no check for a valid index!), seconds is the callback function which is called after alternate setting has been chosen	
	.isKernelDriverActive() : int
		returns 0  if not active; 1 if active
	.getExtraData() : Array
		returns byte array with extra data from interface descriptor

Endpoint
	.__endpointType : int
		property for getting the endpoint type (IN/OUT), check with Usb.LIBUSB_ENDPOINT_TYPE constants
	.__transferType : int
		property for getting the transfer type (bulk, interrupt, isochronous); check with Usb.LIBUSB_TRANSFER_* constants
	.__maxIsoPacketSize : int
		property for getting the max isochronous packet size if transfer type is isochronous
	.__maxPacketSize : int
		property for getting the max packet size
	.getExtraData() : Array
		byte array with extra data from endpoint descriptor
	.bulkTransfer(mixed read|write, function after(data) [, int _timeout])
	.interruptTransfer(mixed read|write, function after(data) [, int _timeout]) : undefined
		[async] bulkTransfer and interruptTransfer are more or less equal. If an endpoint works in bulk mode, you use bulkTransfer(), if endpoint work in interrupt mode, you use interruptTransfer(). If you use the wrong method, the function call will fail.
		First parameter can be either
		* int, then the function will work in read mode (read _int_ bytes FROM USB device)
		* Array, the function will work in write mode (write byte array TO USB device)
		The _timeout parameter is optional; if not used, an unlimited timeout is used.
		Both functions are working in asynchronous mode, the second parameter is the callback handler after the function has been executed / data arrived.
	.submitNative(mixed read|write, function after(data) [, int _timeout, int _iso_packets, int _flags]) : undefined
		[async] bulkTransfer, controlTransfer and interruptTransfer are using the EV library for threading. submitNative() uses the libusb asynchronous interface. This is not really tested now.
		submitNative() will be the only function to handle isochronous transfer mode and detects the endpoint type automatically.
		First parameter can be either (I'll bet, you know it already):
		* int, the function will be work in read mode (read _int_ bytes FROM USB device)
		* Array, the function will work in write mode (write byte array TO USB device)
		The parameter _iso_packets and _flags can be used, if the endpoint is working in isochronous mode otherwise they are useless. 
Examples
=============================
A simple port of lsusb can be executed by typing
	node examples/lsusb/lsusb.js

If you own a Microsoft Kinect, you can manipulate the LED and motor tilt by typing
	node examples/node-usb-kinect.js
Browse to localhost:8080 and see the magic.

If you have permission issues, you have to add the proper rights to the USB device or execute the examples as root (NOT RECOMMENDED!)

		property for getting bus number
	.reset(function _afterReset) : undefined
		[async] resets device, expects callback function after reset
	.getConfigDescriptor() : Object
		returns configuration descriptor of device
	.getExtraData() : Array
		returns byte array with extra data from config descriptor
	.getInterfaces() : Interface[]
		returns interfaces
	.getDeviceDescriptor() : Object
		returns devices descriptor
	.controlTransfer(mixed read|write, int _bmRequestType, int _bRequest, int _wValue, int _wIndex, function afterTransfer(data) [, int _timeout])
		[async] delegates to libusb_control_transfer. First parameter can be either
		  * int, then controlTransfer works in read mode (read data FROM USB device)
		  * Array of ints, then controlTransfer works in write mode (write data TO USB device)
		_timeout parameter is optional
Interface
	.__idxInterface : int
		property for internal interface index
	.__idxAltSetting : int
		property for internal alternate interface setting
	.getEndpoints() : Endpoint[]
		returns an array of Endpoint objects
	.detachKernelDriver() : undefined
		detaches the kernel driver from interface
	.attachKernelDriver() : undefined
		re-attaches the kernel driver to interface
	.claim() : undefined
		claims the interface. this method must be __always__ called if you want to transfer data via the endpoint. There is no hig level API check for this
	.release(function afterClaim(data)) : undefined
		[async] releases prior claimed interface; function wil be called after releasing
	.setAlternateSetting(int _alternateSettingIdx, function afterAlternateSettingChosen(data))
		[async] sets alternate setting of interface; first parameter is the alternate setting index (there is no check for a valid index!), seconds is the callback function which is called after alternate setting has been chosen	
	.isKernelDriverActive() : int
		returns 0  if not active; 1 if active
	.getExtraData() : Array
		returns byte array with extra data from interface descriptor

Endpoint
	.__endpointType : int
		property for getting the endpoint type (IN/OUT), check with Usb.LIBUSB_ENDPOINT_TYPE constants
	.__transferType : int
		property for getting the transfer type (bulk, interrupt, isochronous); check with Usb.LIBUSB_TRANSFER_* constants
	.__maxIsoPacketSize : int
		property for getting the max isochronous packet size if transfer type is isochronous
	.__maxPacketSize : int
		property for getting the max packet size
	.getExtraData() : Array
		byte array with extra data from endpoint descriptor
	.bulkTransfer(mixed read|write, function after(data) [, int _timeout])
	.interruptTransfer(mixed read|write, function after(data) [, int _timeout]) : undefined
		[async] bulkTransfer and interruptTransfer are more or less equal. If an endpoint works in bulk mode, you use bulkTransfer(), if endpoint work in interrupt mode, you use interruptTransfer(). If you use the wrong method, the function call will fail.
		First parameter can be either
		* int, then the function will work in read mode (read _int_ bytes FROM USB device)
		* Array, the function will work in write mode (write byte array TO USB device)
		The _timeout parameter is optional; if not used, an unlimited timeout is used.
		Both functions are working in asynchronous mode, the second parameter is the callback handler after the function has been executed / data arrived.
	.submitNative(mixed read|write, function after(data) [, int _timeout, int _iso_packets, int _flags]) : undefined
		[async] bulkTransfer, controlTransfer and interruptTransfer are using the EV library for threading. submitNative() uses the libusb asynchronous interface. This is not really tested now.
		submitNative() will be the only function to handle isochronous transfer mode and detects the endpoint type automatically.
		First parameter can be either (I'll bet, you know it already):
		* int, the function will be work in read mode (read _int_ bytes FROM USB device)
		* Array, the function will work in write mode (write byte array TO USB device)
		The parameter _iso_packets and _flags can be used, if the endpoint is working in isochronous mode otherwise they are useless. 
Examples
=============================
A simple port of lsusb can be executed by typing
	node examples/lsusb/lsusb.js

If you own a Microsoft Kinect, you can manipulate the LED and motor tilt by typing
	node examples/node-usb-kinect.js
Browse to localhost:8080 and see the magic.

If you have permission issues, you have to add the proper rights to the USB device or execute the examples as root (NOT RECOMMENDED!)

About

node.js bindings for libusb-1.0

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • JavaScript 94.9%
  • C++ 4.4%
  • C 0.7%