Permalink
Browse files

- Data to write to an USB device must be passed as a Buffer object - …

…and not as an array.

- bulk and interrupt transfer mode can now READ data from an USB device
1 parent 59d3d99 commit 2061876bb76c2d371e207212468a4181683a32a0 Christopher Klein committed Mar 26, 2012
Showing with 33 additions and 35 deletions.
  1. +8 −6 README
  2. +3 −3 examples/kinect/kinect.js
  3. +12 −10 src/bindings.h
  4. +2 −8 src/device.h
  5. +7 −5 src/endpoint.cc
  6. +1 −3 src/endpoint.h
View
14 README
@@ -61,8 +61,9 @@ Device
.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
+ * Buffer object, then controlTransfer works in write mode (write data TO USB device)
+ _timeout parameter is optional.
+ afterTransfer contains a Buffer object with the data read from device.
Interface
.__idxInterface : int
property for internal interface index
@@ -96,14 +97,15 @@ Endpoint
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.
+ .bulkTransfer(mixed read|write, function afterTransfer(data) [, int _timeout])
+ .interruptTransfer(mixed read|write, function afterTransfer(data) [, int _timeout]) : undefined
+ [async] bulkTransfer and interruptTransfer are more or less equal. If 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)
+ * Buffer object, the function will work in write mode (write buffer 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.
+ afterTransfer contains a Buffer object as first parameter
.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.
@@ -59,7 +59,7 @@ http.createServer(function(req, res) {
var lightId = LED_OPTIONS[light];
// send control information
- motor.controlTransfer(new Array("0"), 0x40, 0x06, lightId, 0x0, function(data) {
+ motor.controlTransfer(new Buffer(0), 0x40, 0x06, lightId, 0x0, function(data) {
console.log(" + LED toggled");
});
}
@@ -73,8 +73,8 @@ http.createServer(function(req, res) {
angle = (angle < MIN_TILT_ANGLE) ? MIN_TILT_ANGLE : ((angle > MAX_TILT_ANGLE) ? MAX_TILT_ANGLE : angle);
angle = angle * 2;
-console.log("Angle set to " + angle);
- motor.controlTransfer(new Array("0"), 0x40, 0x31, angle, 0x0, function(data) {
+ console.log("Angle set to " + angle);
+ motor.controlTransfer(new Buffer(0), 0x40, 0x31, angle, 0x0, function(data) {
console.log(" + Angle set");
});
View
@@ -136,23 +136,18 @@
if (args.Length() < MINIMUM_ARG_LENGTH || !args[CALLBACK_ARG_IDX]->IsFunction()) { \
THROW_BAD_ARGS("Endpoint::Transfer missing arguments!!") \
} \
-\
- if (args[0]->IsArray()) { \
+ if (Buffer::HasInstance(args[0])) { \
modus = LIBUSB_ENDPOINT_OUT; \
} else { \
modus = LIBUSB_ENDPOINT_IN; \
if (!args[0]->IsUint32()) { \
- THROW_BAD_ARGS("Endpoint::Transfer in READ mode expects uint32_t as first parameter") \
+ THROW_BAD_ARGS("Endpoint::Transfer in READ mode expects uint32_t as first parameter. If you want to write something, you must provide a Buffer instance as first parameter") \
} \
} \
if (modus == LIBUSB_ENDPOINT_OUT) {\
- Local<Array> _buffer = Local<Array>::Cast(args[0]);\
- buflen = _buffer->Length(); \
- buf = new unsigned char[buflen]; \
- for (int i = 0; i < buflen; i++) { \
- Local<Value> val = _buffer->Get(i); \
- buf[i] = (uint8_t)val->Uint32Value();\
- }\
+ Local<Object> _buffer = args[0]->ToObject();\
+ buflen = Buffer::Length(_buffer); \
+ buf = reinterpret_cast<unsigned char*>(Buffer::Data(_buffer));\
DEBUG("Dumping byte stream...")\
DUMP_BYTE_STREAM(buf, buflen);\
}\
@@ -199,6 +194,13 @@ namespace NodeUsb {
const char * errsource;
};
+ struct nodeusb_transfer:request {
+ unsigned char *data;
+ unsigned int timeout;
+ uint16_t bytesTransferred;
+ };
+
+
static inline Local<Value> errno_exception(int errorno) {
Local<Value> e = Exception::Error(String::NewSymbol(strerror(errorno)));
Local<Object> obj = e->ToObject();
View
@@ -6,17 +6,11 @@
namespace NodeUsb {
// intermediate EIO structure for device
- struct device_request:request {
+ struct device_request:nodeusb_transfer {
Device * device;
};
- struct nodeusb_transfer:device_request {
- unsigned char *data;
- unsigned int timeout;
- uint16_t bytesTransferred;
- };
-
- struct control_transfer_request:nodeusb_transfer {
+ struct control_transfer_request:device_request {
uint8_t bmRequestType;
uint8_t bRequest;
uint16_t wValue;
View
@@ -246,14 +246,16 @@ namespace NodeUsb {
EIO_CUSTOM(EIO_TO_EXECUTE, bulk_interrupt_transfer_req, EIO_AFTER)\
return Undefined();
-#define BULK_INTERRUPT_FREE TRANSFER_REQUEST_FREE(bulk_interrupt_transfer_request, endpoint)
-
#define BULK_INTERRUPT_EXECUTE(METHOD, SOURCE)\
EIO_CAST(bulk_interrupt_transfer_request, bit_req)\
Endpoint * self = bit_req->endpoint;\
- bit_req->errcode = libusb_bulk_transfer(self->device_container->handle, self->descriptor->bEndpointAddress, bit_req->data, bit_req->length, &(bit_req->transferred), bit_req->timeout);\
+ bit_req->errcode = METHOD(self->device_container->handle, self->descriptor->bEndpointAddress, bit_req->data, bit_req->length, &(bit_req->transferred), bit_req->timeout);\
if (bit_req->errcode < LIBUSB_SUCCESS) {\
bit_req->errsource = SOURCE;\
+ bit_req->bytesTransferred = 0;\
+ }\
+ else {\
+ bit_req->bytesTransferred = bit_req->transferred;\
}
Handle<Value> Endpoint::BulkTransfer(const Arguments& args) {
@@ -265,7 +267,7 @@ namespace NodeUsb {
}
void Endpoint::EIO_After_BulkTransfer(uv_work_t *req) {
- BULK_INTERRUPT_FREE
+ TRANSFER_REQUEST_FREE_WITH_DATA(bulk_interrupt_transfer_request, endpoint)
}
Handle<Value> Endpoint::InterruptTransfer(const Arguments& args) {
@@ -277,6 +279,6 @@ namespace NodeUsb {
}
void Endpoint::EIO_After_InterruptTransfer(uv_work_t *req) {
- BULK_INTERRUPT_FREE
+ TRANSFER_REQUEST_FREE_WITH_DATA(bulk_interrupt_transfer_request, endpoint)
}
}
View
@@ -12,13 +12,11 @@ namespace NodeUsb {
static void DispatchAsynchronousUsbTransfer(libusb_transfer *_transfer);
};
- struct endpoint_request:request {
+ struct endpoint_request:nodeusb_transfer {
Endpoint * endpoint;
};
struct bulk_interrupt_transfer_request:endpoint_request {
- unsigned char *data;
- unsigned int timeout;
int length;
int transferred;
};

0 comments on commit 2061876

Please sign in to comment.