Permalink
Browse files

Restructured files for easier developing

- bindings.cc removed
- every class in NodeUsb namespace has their own .h and .cc file
- added callback handling USB packet submission
  • Loading branch information...
1 parent 886de4c commit af227afedb86b44f45ce5bbbce412e2061fa7fda Christopher Klein committed Nov 18, 2010
Showing with 894 additions and 826 deletions.
  1. +0 −737 src/bindings.cc
  2. +62 −86 src/bindings.h
  3. +202 −0 src/device.cc
  4. +33 −0 src/device.h
  5. +185 −0 src/endpoint.cc
  6. +32 −0 src/endpoint.h
  7. +95 −0 src/interface.cc
  8. +26 −0 src/interface.h
  9. +4 −2 src/node_usb.cc
  10. +216 −0 src/usb.cc
  11. +30 −0 src/usb.h
  12. +8 −0 tests/node-usb-test.js
  13. +1 −1 wscript
View

Large diffs are not rendered by default.

Oops, something went wrong.
View
@@ -16,104 +16,80 @@
#define DEBUG(str)
#endif
-namespace NodeUsb {
- class Usb : public EventEmitter {
- public:
- static void Initalize(Handle<Object> target);
- Usb();
- ~Usb();
- protected:
- // members
- bool is_initalized;
- int num_devices;
- libusb_device **devices;
- // internal methods
- int Init();
+#define THROW_BAD_ARGS(fail) return ThrowException(Exception::TypeError(V8STR(fail)));
+#define THROW_NOT_YET return ThrowException(Exception::TypeError(String::Concat(String::New(__FUNCTION__), String::New("not yet supported"))));
+#define CHECK_USB(r, scope) \
+ if (r < LIBUSB_SUCCESS) { \
+ return scope.Close(ThrowException(errno_exception(r)));\
+ }
- // V8 getter
- static Handle<Value> IsLibusbInitalizedGetter(Local<String> property, const AccessorInfo &info);
-
- // exposed to V8
- static Handle<Value> New(const Arguments& args);
- static Handle<Value> GetDeviceList(const Arguments& args);
- static Handle<Value> Refresh(const Arguments& args);
- static Handle<Value> Close(const Arguments& args);
- };
+#define LOCAL(type, varname, ref) \
+ HandleScope scope;\
+ type *varname = OBJUNWRAP<type>(ref);
- class Device : public EventEmitter {
- public:
- // called from outside to initalize V8 class template
- static void Initalize(Handle<Object> target);
- static Persistent<FunctionTemplate> constructor_template;
- Device(libusb_device*);
- ~Device();
-
- protected:
- // members
- struct libusb_device *device;
- struct libusb_device_descriptor device_descriptor;
- struct libusb_config_descriptor *config_descriptor;
+namespace NodeUsb {
+ static inline Local<Value> errno_exception(int errorno) {
+ Local<Value> e = Exception::Error(String::NewSymbol(strerror(errorno)));
+ Local<Object> obj = e->ToObject();
+ std::string err = "";
+
+ obj->Set(NODE_PSYMBOL("errno"), Integer::New(errorno));
+ // taken from pyusb
+ switch (errorno) {
+ case LIBUSB_ERROR_IO:
+ err = "Input/output error";
+ break;
+ case LIBUSB_ERROR_INVALID_PARAM:
+ err = "Invalid parameter";
+ break;
+ case LIBUSB_ERROR_ACCESS:
+ err = "Access denied (insufficient permissions)";
+ break;
+ case LIBUSB_ERROR_NO_DEVICE:
+ err = "No such device (it may have been disconnected)";
+ break;
+ case LIBUSB_ERROR_NOT_FOUND:
+ err = "Entity not found";
+ break;
+ case LIBUSB_ERROR_BUSY:
+ err = "Resource busy";
+ break;
+ case LIBUSB_ERROR_TIMEOUT:
+ err = "Operation timed out";
+ break;
+ case LIBUSB_ERROR_OVERFLOW:
+ err = "Overflow";
+ break;
+ case LIBUSB_ERROR_PIPE:
+ err = "Pipe error";
+ break;
+ case LIBUSB_ERROR_INTERRUPTED:
+ err = "System call interrupted (perhaps due to signal)";
+ break;
+ case LIBUSB_ERROR_NO_MEM:
+ err = "Insufficient memory";
+ break;
+ case LIBUSB_ERROR_NOT_SUPPORTED:
+ err = "Operation not supported or unimplemented on this platform";
+ break;
+ default:
+ err = "Unknown error";
+ break;
+ }
+ // convert err to const char* with help of c_str()
+ obj->Set(NODE_PSYMBOL("msg"), String::New(err.c_str()));
+ return e;
+ }
- // V8 getter
- static Handle<Value> BusNumberGetter(Local<String> property, const AccessorInfo &info);
- static Handle<Value> DeviceAddressGetter(Local<String> property, const AccessorInfo &info);
- // exposed to V8
- static Handle<Value> New(const Arguments& args);
- static Handle<Value> Close(const Arguments& args);
- static Handle<Value> Reset(const Arguments& args);
- static Handle<Value> GetConfigDescriptor(const Arguments& args);
- static Handle<Value> GetDeviceDescriptor(const Arguments& args);
- };
- class Interface : public EventEmitter {
- public:
- static void Initalize(Handle<Object> target);
- static Persistent<FunctionTemplate> constructor_template;
- Interface(libusb_device*, libusb_interface_descriptor*);
- ~Interface();
- protected:
- // members
- struct libusb_device *device;
- struct libusb_device_handle *handle;
- struct libusb_interface_descriptor *descriptor;
- // V8 getter
- static Handle<Value> IsKernelDriverActiveGetter(Local<String> property, const AccessorInfo &info);
- // exposed to V8
- static Handle<Value> New(const Arguments& args);
- };
class Callback {
public:
static void DispatchAsynchronousUsbTransfer(libusb_transfer *transfer);
};
- class Endpoint : public EventEmitter {
- public:
- static void Initalize(Handle<Object> target);
- static Persistent<FunctionTemplate> constructor_template;
- // Dispatcher / callback handler must be static
- Endpoint(libusb_device*, libusb_endpoint_descriptor*);
- ~Endpoint();
- protected:
- // members
- struct libusb_device *device;
- struct libusb_device_handle *handle;
- struct libusb_endpoint_descriptor *descriptor;
- int endpoint_type;
- int transfer_type;
-
- int FillTransferStructure(libusb_transfer *_transfer, unsigned char *_buffer, void *_user_data, uint32_t _timeout, unsigned int num_iso_packets = 0);
-
- // v8 getter
- static Handle<Value> EndpointTypeGetter(Local<String> property, const AccessorInfo &info);
- static Handle<Value> TransferTypeGetter(Local<String> property, const AccessorInfo &info);
- // exposed to V8
- static Handle<Value> New(const Arguments& args);
- static Handle<Value> Write(const Arguments& args);
-
- };
}
#endif
View
@@ -0,0 +1,202 @@
+#include "bindings.h"
+#include "device.h"
+#include "interface.h"
+#include "endpoint.h"
+
+namespace NodeUsb {
+ /** constructor template is needed for creating new Device objects from outside */
+ Persistent<FunctionTemplate> Device::constructor_template;
+
+ /**
+ * @param device.busNumber integer
+ * @param device.deviceAddress integer
+ */
+ void Device::Initalize(Handle<Object> target) {
+ DEBUG("Entering...")
+ HandleScope scope;
+ Local<FunctionTemplate> t = FunctionTemplate::New(Device::New);
+
+ // Constructor
+ t->InstanceTemplate()->SetInternalFieldCount(1);
+ t->SetClassName(String::NewSymbol("Device"));
+ Device::constructor_template = Persistent<FunctionTemplate>::New(t);
+
+ Local<ObjectTemplate> instance_template = t->InstanceTemplate();
+
+ // Constants
+ // no constants at the moment
+
+ // Properties
+ instance_template->SetAccessor(V8STR("deviceAddress"), Device::DeviceAddressGetter);
+ instance_template->SetAccessor(V8STR("busNumber"), Device::BusNumberGetter);
+
+ // Bindings to nodejs
+ NODE_SET_PROTOTYPE_METHOD(t, "reset", Device::Reset);
+ NODE_SET_PROTOTYPE_METHOD(t, "getDeviceDescriptor", Device::GetDeviceDescriptor);
+ NODE_SET_PROTOTYPE_METHOD(t, "getConfigDescriptor", Device::GetConfigDescriptor);
+
+ // Make it visible in JavaScript
+ target->Set(String::NewSymbol("Device"), t->GetFunction());
+ DEBUG("Leave")
+ }
+
+ Device::Device(libusb_device* _device) {
+ DEBUG("Assigning libusb_device structure to self")
+ device = _device;
+ config_descriptor = NULL;
+ }
+
+ Device::~Device() {
+ DEBUG("Device object destroyed")
+ }
+
+ Handle<Value> Device::New(const Arguments& args) {
+ HandleScope scope;
+ DEBUG("New Device object created")
+
+ // need libusb_device structure as first argument
+ if (args.Length() <= 0 || !args[0]->IsExternal()) {
+ THROW_BAD_ARGS("Device::New argument is invalid. Must be external!")
+ }
+
+ Local<External> refDevice = Local<External>::Cast(args[0]);
+
+ // cast local reference to local libusb_device structure
+ libusb_device *libusbDevice = static_cast<libusb_device*>(refDevice->Value());
+
+ // create new Device object
+ Device *device = new Device(libusbDevice);
+
+ // wrap created Device object to v8
+ device->Wrap(args.This());
+
+ return args.This();
+ }
+
+ /**
+ * @return integer
+ */
+ Handle<Value> Device::BusNumberGetter(Local<String> property, const AccessorInfo &info) {
+ LOCAL(Device, self, info.Holder())
+ uint8_t bus_number = libusb_get_bus_number(self->device);
+
+ return scope.Close(Integer::New(bus_number));
+ }
+
+ /**
+ * @return integer
+ */
+ Handle<Value> Device::DeviceAddressGetter(Local<String> property, const AccessorInfo &info) {
+ LOCAL(Device, self, info.Holder())
+ uint8_t address = libusb_get_device_address(self->device);
+
+ return scope.Close(Integer::New(address));
+ }
+
+ Handle<Value> Device::Reset(const Arguments& args) {
+ HandleScope scope;
+ THROW_NOT_YET
+ return scope.Close(True());
+ }
+
+
+// TODO: Read-Only
+#define LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(name) \
+ r->Set(V8STR(#name), Integer::New((*self->config_descriptor).name));
+
+ /**
+ * Returns configuration descriptor structure
+ */
+ Handle<Value> Device::GetConfigDescriptor(const Arguments& args) {
+ // make local value reference to first parameter
+ Local<External> refDevice = Local<External>::Cast(args[0]);
+
+ LOCAL(Device, self, args.This())
+ CHECK_USB(libusb_get_active_config_descriptor(self->device, &(self->config_descriptor)), scope)
+ Local<Object> r = Object::New();
+
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(bLength)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(bDescriptorType)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(wTotalLength)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(bNumInterfaces)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(bConfigurationValue)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(iConfiguration)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(bmAttributes)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(MaxPower)
+ LIBUSB_CONFIG_DESCRIPTOR_STRUCT_TO_V8(extra_length)
+
+ Local<Array> interfaces = Array::New();
+
+ // iterate interfaces
+ for (int i = 0; i < (*self->config_descriptor).bNumInterfaces; i++) {
+ libusb_interface interface_container = (*self->config_descriptor).interface[i];
+
+ for (int j = 0; j < interface_container.num_altsetting; j++) {
+ libusb_interface_descriptor interface_descriptor = interface_container.altsetting[j];
+
+ Local<Value> args_new_interface[2] = {
+ External::New(self->device),
+ External::New(&interface_descriptor),
+ };
+
+ // create new object instance of class NodeUsb::Interface
+ Persistent<Object> js_interface(Interface::constructor_template->GetFunction()->NewInstance(2, args_new_interface));
+ Local<Array> endpoints = Array::New();
+
+ // interate endpoints
+ for (int k = 0; k < interface_descriptor.bNumEndpoints; k++) {
+ libusb_endpoint_descriptor endpoint_descriptor = interface_descriptor.endpoint[k];
+
+ Local<Value> args_new_endpoint[2] = {
+ External::New(self->device),
+ External::New(&endpoint_descriptor),
+ };
+
+ // create new object instance of class NodeUsb::Endpoint
+ Persistent<Object> js_endpoint(Endpoint::constructor_template->GetFunction()->NewInstance(2, args_new_endpoint));
+ endpoints->Set(k, js_endpoint);
+ }
+
+ js_interface->Set(V8STR("endpoints"), endpoints);
+ interfaces->Set(i, js_interface);
+ }
+ }
+
+ r->Set(V8STR("interfaces"), interfaces);
+ // free it
+ libusb_free_config_descriptor(self->config_descriptor);
+
+ return scope.Close(r);
+ }
+
+// TODO: Read-Only
+#define LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(name) \
+ r->Set(V8STR(#name), Integer::New(self->device_descriptor.name));
+
+ /**
+ * Returns the device descriptor of current device
+ * @return object
+ */
+ Handle<Value> Device::GetDeviceDescriptor(const Arguments& args) {
+ LOCAL(Device, self, args.This())
+ CHECK_USB(libusb_get_device_descriptor(self->device, &(self->device_descriptor)), scope)
+ Local<Object> r = Object::New();
+
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bLength)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bDescriptorType)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bcdUSB)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bDeviceClass)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bDeviceSubClass)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bDeviceProtocol)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bMaxPacketSize0)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(idVendor)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(idProduct)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bcdDevice)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(iManufacturer)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(iProduct)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(iSerialNumber)
+ LIBUSB_DEVICE_DESCRIPTOR_STRUCT_TO_V8(bNumConfigurations)
+
+ return scope.Close(r);
+ }
+}
Oops, something went wrong.

0 comments on commit af227af

Please sign in to comment.