2009-04-22 20:04:28 +02:00

2150 lines
52 KiB
C

/*
* PyUSB - Python module for USB Access
*
* Copyright 2005 - 2007 Wander Lairson Costa
*/
#if _MSC_VER >= 1400 /* Visual C++ 8.00 */
#define _CRT_SECURE_NO_DEPRECATE
#endif /* _MSC_VER */
#include "pyusb.h"
#include <stdlib.h>
#include <stdio.h>
#define DEFAULT_TIMEOUT 100
/*
* Necessary to compile successfully in python 2.3
* Thanks to Mark Rages for the patch
*/
#ifndef Py_RETURN_NONE
#define Py_RETURN_NONE return Py_INCREF(Py_None), Py_None
#endif
// PYUSB_STATIC char cvsid[] = "$Id: pyusb.c,v 1.24 2007/05/15 21:20:55 wander Exp $";
/*
* USBError
*/
PYUSB_STATIC PyObject *PyExc_USBError;
#define PyUSB_Error() PyErr_SetString(PyExc_USBError, usb_strerror())
#define SUPPORT_NUMBER_PROTOCOL(_Arg) \
(PyNumber_Check(_Arg) || PyString_Check(_Arg) || PyUnicode_Check(_Arg))
#if !defined(NDEBUG)
#define DUMP_PARAMS 1
#else
#define DUMP_PARAMS 0
#endif /* NDEBUG */
#ifndef NDEBUG
/*
* Print a buffer of data
*/
PYUSB_STATIC void printBuffer(
const char *buffer,
int size
)
{
int i;
if (!buffer) {
fputs("NULL\n", stderr);
return;
}
for (i = 0; i < size; ++i) {
fprintf(stderr, "%2x ", buffer[i]);
if (i && !(i % 20)) fputc('\n', stderr);
}
fputc('\n', stderr);
}
#endif /* NDEBUG */
/*
* Converts a object with number procotol to int type
*/
PYUSB_STATIC int py_NumberAsInt(
PyObject *obj
)
{
PyObject *number = PyNumber_Int(obj);
if (number) {
int ret = PyInt_AS_LONG(number);
Py_DECREF(number);
return ret;
} else {
return 0;
}
}
/*
* Gets a byte from a PyObject
* If the obj is a number, returns the number casted to a byte
* If it is a sequence, returns the first byte representation of the sequence
* If it is a mapping, returns the first byte representation of the first obj.values()
*/
PYUSB_STATIC u_int8_t getByte(
PyObject *obj
)
{
u_int8_t byte;
if (PyNumber_Check(obj)) {
byte = (u_int8_t) py_NumberAsInt(obj);
} else if (PyString_Check(obj) || PyUnicode_Check(obj)) {
return (u_int8_t) PyString_AsString(obj)[0];
} else if (PySequence_Check(obj)) {
PyObject *el0;
el0 = PySequence_GetItem(obj, 0);
if (!el0) return 0;
byte = getByte(el0);
Py_DECREF(el0);
} else if (PyMapping_Check(obj)) {
PyObject *vals;
vals = PyMapping_Values(obj);
if (!vals) return 0;
byte = getByte(vals);
Py_DECREF(vals);
} else {
byte = 0;
PyErr_BadArgument();
}
return byte;
}
/*
* Gets a unsigned byte * representation of the obj
* If the obj is a sequence, returns the elements as a c byte array representation
* If it is a mapping, returns the c byte array representations of the obj.values()
*/
PYUSB_STATIC char *getBuffer(
PyObject *obj,
int *size
)
{
char *p = NULL;
/*
* When the obj is a sequence type, we take the first byte from
* the each element of the sequence
*/
/* ok, string is a sequence too, but let us optimize it */
if (PyString_Check(obj) || PyUnicode_Check(obj)) {
char *tmp;
if (-1 != PyString_AsStringAndSize(obj, &tmp, size)) {
p = (char *) PyMem_Malloc(*size);
if (p) memcpy(p, tmp, *size);
}
} else if (PySequence_Check(obj)) {
u_int32_t i, sz;
PyObject *el;
sz = PySequence_Size(obj);
p = (char *) PyMem_Malloc(sz);
for (i = 0; i < sz; ++i) {
el = PySequence_GetItem(obj, i);
p[i] = getByte(el);
Py_DECREF(el);
if (!p[i] && PyErr_Occurred()) {
PyMem_Free(p);
return NULL;
}
}
*size = sz;
} else if (PyMapping_Check(obj)) {
PyObject *values;
values = PyMapping_Values(obj);
if (!values) return NULL;
p = getBuffer(values, size);
Py_DECREF(values);
} else if (obj == Py_None) {
*size = 0;
return NULL;
} else {
PyErr_BadArgument();
return NULL;
}
return p;
}
/*
* Build a numeric tuple from the buffer values
*/
PYUSB_STATIC PyObject *buildTuple(
char *buffer,
int size
)
{
PyObject *ret;
int i;
ret = PyTuple_New(size);
if (ret) {
for (i = 0; i < size; ++i) {
PyTuple_SET_ITEM(ret, i, PyInt_FromLong((u_int8_t) buffer[i]));
}
}
return ret;
}
/*
* Add a numeric constant to the dictionary
*/
PYUSB_STATIC void addConstant(
PyObject *dict,
const char *name,
long value)
{
PyObject *val;
val = PyInt_FromLong(value);
if (val) {
PyDict_SetItemString(dict, name, val);
Py_DECREF(val);
}
}
/*
* Add the module constants to the module dictionary
*/
PYUSB_STATIC void installModuleConstants(
PyObject *module
)
{
PyObject *dict;
dict = PyModule_GetDict(module);
addConstant(dict, "CLASS_PER_INTERFACE", USB_CLASS_PER_INTERFACE);
addConstant(dict, "CLASS_AUDIO", USB_CLASS_AUDIO);
addConstant(dict, "CLASS_COMM", USB_CLASS_COMM);
addConstant(dict, "CLASS_HID", USB_CLASS_HID);
addConstant(dict, "CLASS_PRINTER", USB_CLASS_PRINTER);
addConstant(dict, "CLASS_MASS_STORAGE", USB_CLASS_MASS_STORAGE);
addConstant(dict, "CLASS_HUB", USB_CLASS_HUB);
addConstant(dict, "CLASS_DATA", USB_CLASS_DATA);
addConstant(dict, "CLASS_VENDOR_SPEC", USB_CLASS_VENDOR_SPEC);
addConstant(dict, "DT_DEVICE", USB_DT_DEVICE);
addConstant(dict, "DT_CONFIG", USB_DT_CONFIG);
addConstant(dict, "DT_STRING", USB_DT_STRING);
addConstant(dict, "DT_INTERFACE", USB_DT_INTERFACE);
addConstant(dict, "DT_ENDPOINT", USB_DT_ENDPOINT);
addConstant(dict, "DT_HID", USB_DT_HID);
addConstant(dict, "DT_REPORT", USB_DT_REPORT);
addConstant(dict, "DT_PHYSICAL", USB_DT_PHYSICAL);
addConstant(dict, "DT_HUB", USB_DT_HUB);
addConstant(dict, "DT_DEVICE_SIZE", USB_DT_DEVICE_SIZE);
addConstant(dict, "DT_CONFIG_SIZE", USB_DT_CONFIG_SIZE);
addConstant(dict, "DT_INTERFACE_SIZE", USB_DT_INTERFACE_SIZE);
addConstant(dict, "DT_ENDPOINT_SIZE", USB_DT_ENDPOINT_SIZE);
addConstant(dict, "DT_ENDPOINT_AUDIO_SIZE", USB_DT_ENDPOINT_AUDIO_SIZE);
addConstant(dict, "DT_HUB_NONVAR_SIZE", USB_DT_HUB_NONVAR_SIZE);
addConstant(dict, "MAXENDPOINTS", USB_MAXENDPOINTS);
addConstant(dict, "ENDPOINT_ADDRESS_MASK", USB_ENDPOINT_ADDRESS_MASK);
addConstant(dict, "ENDPOINT_DIR_MASK", USB_ENDPOINT_DIR_MASK);
addConstant(dict, "ENDPOINT_TYPE_MASK", USB_ENDPOINT_TYPE_MASK);
addConstant(dict, "ENDPOINT_TYPE_CONTROL", USB_ENDPOINT_TYPE_CONTROL);
addConstant(dict, "ENDPOINT_TYPE_ISOCHRONOUS", USB_ENDPOINT_TYPE_ISOCHRONOUS);
addConstant(dict, "ENDPOINT_TYPE_BULK", USB_ENDPOINT_TYPE_BULK);
addConstant(dict, "ENDPOINT_TYPE_INTERRUPT", USB_ENDPOINT_TYPE_INTERRUPT);
addConstant(dict, "MAXINTERFACES", USB_MAXINTERFACES);
addConstant(dict, "MAXALTSETTING", USB_MAXALTSETTING);
addConstant(dict, "MAXCONFIG", USB_MAXCONFIG);
addConstant(dict, "REQ_GET_STATUS", USB_REQ_GET_STATUS);
addConstant(dict, "REQ_CLEAR_FEATURE", USB_REQ_CLEAR_FEATURE);
addConstant(dict, "REQ_SET_FEATURE", USB_REQ_SET_FEATURE);
addConstant(dict, "REQ_SET_ADDRESS", USB_REQ_SET_ADDRESS);
addConstant(dict, "REQ_GET_DESCRIPTOR", USB_REQ_GET_DESCRIPTOR);
addConstant(dict, "REQ_SET_DESCRIPTOR", USB_REQ_SET_DESCRIPTOR);
addConstant(dict, "REQ_GET_CONFIGURATION", USB_REQ_GET_CONFIGURATION);
addConstant(dict, "REQ_SET_CONFIGURATION", USB_REQ_SET_CONFIGURATION);
addConstant(dict, "REQ_GET_INTERFACE", USB_REQ_GET_INTERFACE);
addConstant(dict, "REQ_SET_INTERFACE", USB_REQ_SET_INTERFACE);
addConstant(dict, "REQ_SYNCH_FRAME", USB_REQ_SYNCH_FRAME);
addConstant(dict, "TYPE_STANDARD", USB_TYPE_STANDARD);
addConstant(dict, "TYPE_CLASS", USB_TYPE_CLASS);
addConstant(dict, "TYPE_VENDOR", USB_TYPE_VENDOR);
addConstant(dict, "TYPE_RESERVED", USB_TYPE_RESERVED);
addConstant(dict, "RECIP_DEVICE", USB_RECIP_DEVICE);
addConstant(dict, "RECIP_INTERFACE", USB_RECIP_INTERFACE);
addConstant(dict, "RECIP_ENDPOINT", USB_RECIP_ENDPOINT);
addConstant(dict, "RECIP_OTHER", USB_RECIP_OTHER);
addConstant(dict, "ENDPOINT_IN", USB_ENDPOINT_IN);
addConstant(dict, "ENDPOINT_OUT", USB_ENDPOINT_OUT);
addConstant(dict, "ERROR_BEGIN", USB_ERROR_BEGIN);
}
/*
* Earlier versions of the PyUSB separate direction bit and
* endpoint address with direction and address fields...
* Windows version of the libusb does need direction
* bit in endpoint address to works fine.
* Thanks to Ray Schumacher.
*/
PYUSB_STATIC PyMemberDef Py_usb_Endpoint_Members[] = {
{"address",
T_UBYTE,
offsetof(Py_usb_Endpoint, address),
READONLY,
"Contains the endpoint address."},
{"type",
T_UBYTE,
offsetof(Py_usb_Endpoint, type),
READONLY,
"It contains one of the following values, \n"
"indicating the endpoint transfer type:\n"
"\tENDPOINT_TYPE_CONTROL\n"
"\tENDPOINT_TYPE_ISOCHRONOUS\n"
"\tENDPOINT_TYPE_BULK\n"
"\tENDPOINT_TYPE_INTERRUPT\n"},
{"maxPacketSize",
T_USHORT,
offsetof(Py_usb_Endpoint, maxPacketSize),
READONLY,
"The maximum number of data bytes the endpoint\n"
"can transfer in a transaction."},
{"interval",
T_UBYTE,
offsetof(Py_usb_Endpoint, interval),
READONLY,
"The maximum latency for polling interrupt endpoints, or\n"
"the interval for polling isochronous endpoints, or the maximum NAK\n"
"rate for high-speed bulk OUT or control endpoints."},
{NULL}
};
PYUSB_STATIC PyMethodDef Py_usb_Endpoint_Methods[] = {
{NULL, NULL}
};
PYUSB_STATIC PyTypeObject Py_usb_Endpoint_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"usb.Endpoint", /*tp_name*/
sizeof(Py_usb_Endpoint), /*tp_basicsize*/
0, /*tp_itemsize*/
0, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Endpoint descriptor object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Py_usb_Endpoint_Methods, /* tp_methods */
Py_usb_Endpoint_Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0,
0,
0,
0,
0,
0,
0,
0, /* destructor */
};
PYUSB_STATIC void set_Endpoint_fields(
Py_usb_Endpoint *endpoint,
struct usb_endpoint_descriptor *ep
)
{
endpoint->address = ep->bEndpointAddress;
endpoint->type = ep->bmAttributes & 3;
endpoint->maxPacketSize = ep->wMaxPacketSize;
endpoint->interval = ep->bInterval;
endpoint->refresh = ep->bRefresh;
// endpoint->synchAddress - ep->bSynchAddress;
}
PYUSB_STATIC Py_usb_Endpoint *new_Endpoint(
struct usb_endpoint_descriptor *ep
)
{
Py_usb_Endpoint *endpoint;
endpoint = PyObject_New(Py_usb_Endpoint,
&Py_usb_Endpoint_Type);
if (endpoint && ep)
set_Endpoint_fields(endpoint, ep);
return endpoint;
}
PYUSB_STATIC PyMemberDef Py_usb_Interface_Members[] = {
{"interfaceNumber",
T_UBYTE,
offsetof(Py_usb_Interface, interfaceNumber),
READONLY,
"Identifies the interface."},
{"alternateSetting",
T_UBYTE,
offsetof(Py_usb_Interface, alternateSetting),
READONLY,
"Alternate setting number."},
{"interfaceClass",
T_UBYTE,
offsetof(Py_usb_Interface, interfaceClass),
READONLY,
"Similar to DeviceClass in the device descriptor, but\n"
"for devices with a class specified by the interface."},
{"interfaceSubClass",
T_UBYTE,
offsetof(Py_usb_Interface, interfaceSubClass),
READONLY,
"Similar to bDeviceSubClass in the device\n"
"descriptor, but for devices with a class defined by the interface."},
{"interfaceProtocol",
T_UBYTE,
offsetof(Py_usb_Interface, interfaceProtocol),
READONLY,
"Similar to bDeviceProtocol in the device\n"
"descriptor, but for devices whose class is defined by the interface."},
{"endpoints",
T_OBJECT,
offsetof(Py_usb_Interface, endpoints),
READONLY,
"Tuple with interface endpoints."},
{NULL}
};
PYUSB_STATIC void Py_usb_Interface_del(
PyObject *self
)
{
Py_XDECREF((PyObject *) ((Py_usb_Interface *) self)->endpoints);
PyObject_Del(self);
}
PYUSB_STATIC PyMethodDef Py_usb_Interface_Methods[] = {
{NULL}
};
PYUSB_STATIC PyTypeObject Py_usb_Interface_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"usb.Interface", /*tp_name*/
sizeof(Py_usb_Interface), /*tp_basicsize*/
0, /*tp_itemsize*/
Py_usb_Interface_del, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Interface descriptor object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Py_usb_Interface_Methods, /* tp_methods */
Py_usb_Interface_Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0,
0,
0,
0,
0,
0,
0,
0 /* destructor */
};
PYUSB_STATIC void set_Interface_fields(
Py_usb_Interface *interface,
struct usb_interface_descriptor *i
)
{
u_int8_t index;
interface->interfaceNumber = i->bInterfaceNumber;
interface->alternateSetting = i->bAlternateSetting;
interface->interfaceClass = i->bInterfaceClass;
interface->interfaceSubClass = i->bInterfaceSubClass;
interface->interfaceProtocol = i->bInterfaceProtocol;
interface->iInterface = i->iInterface;
interface->endpoints = PyTuple_New(i->bNumEndpoints);
if (!interface->endpoints) {
return;
}
for (index = 0; index < i->bNumEndpoints; ++index)
PyTuple_SET_ITEM(interface->endpoints, index,
(PyObject *) new_Endpoint(i->endpoint+index));
}
PYUSB_STATIC Py_usb_Interface *new_Interface(
struct usb_interface_descriptor *i
)
{
Py_usb_Interface *interface;
interface = PyObject_NEW(Py_usb_Interface, &Py_usb_Interface_Type);
if (interface) {
set_Interface_fields(interface, i);
if (PyErr_Occurred()) {
Py_XDECREF((PyObject *) interface);
return NULL;
}
}
return interface;
}
PYUSB_STATIC PyMemberDef Py_usb_Configuration_Members[] = {
{"totalLength",
T_USHORT,
offsetof(Py_usb_Configuration, totalLength),
READONLY,
"The number of data bytes that the device returns,\n"
"including the bytes for all of the configuration's interfaces and\n"
"endpoints."},
{"value",
T_UBYTE,
offsetof(Py_usb_Configuration, value),
READONLY,
"Identifies the configuration."},
{"selfPowered",
T_UBYTE,
offsetof(Py_usb_Configuration, selfPowered),
READONLY,
"True if the device is self powered."},
{"remoteWakeup",
T_UBYTE,
offsetof(Py_usb_Configuration, remoteWakeup),
READONLY,
"True if the device supports remote wakeup feature."},
{"maxPower",
T_UBYTE,
offsetof(Py_usb_Configuration, maxPower),
READONLY,
"Specifies the device current. This is the absolute value,\n"
"already multiplied by 2"},
{"interfaces",
T_OBJECT,
offsetof(Py_usb_Configuration, interfaces),
READONLY,
"Tuple with a tuple of the configuration interfaces.\n"
"Each element represents a sequence of the\n"
"alternate settings for each interface."},
{"iConfiguration",
T_UBYTE,
offsetof(Py_usb_Configuration, iConfiguration),
RO,
"Index to a string that describes the\n"
"configuration."},
{NULL}
};
PYUSB_STATIC PyMethodDef Py_usb_Configuration_Methods[] = {
{NULL, NULL}
};
PYUSB_STATIC void Py_usb_Configuration_del(
PyObject *self
)
{
Py_XDECREF((PyObject *) ((Py_usb_Configuration *) self)->interfaces);
PyObject_Del(self);;
}
PYUSB_STATIC PyTypeObject Py_usb_Configuration_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"usb.Configuration", /*tp_name*/
sizeof(Py_usb_Configuration), /*tp_basicsize*/
0, /*tp_itemsize*/
Py_usb_Configuration_del, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Configuration descriptor object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Py_usb_Configuration_Methods, /* tp_methods */
Py_usb_Configuration_Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0,
0,
0,
0,
0,
0,
0,
0 /* destructor */
};
PYUSB_STATIC void set_Configuration_fields(
Py_usb_Configuration *configuration,
struct usb_config_descriptor *config
)
{
u_int8_t i, j, k;
PyObject *t1;
configuration->totalLength = config->wTotalLength;
configuration->value = config->bConfigurationValue;
configuration->iConfiguration = config->iConfiguration;
configuration->selfPowered = (config->bmAttributes >> 6) & 1;
configuration->remoteWakeup = (config->bmAttributes >> 5) & 1;
configuration->maxPower = config->MaxPower << 2;
configuration->interfaces = PyTuple_New(config->bNumInterfaces);
if (!configuration->interfaces) return;
for (i = 0; i < config->bNumInterfaces; ++i) {
k = config->interface[i].num_altsetting;
t1 = PyTuple_New(k);
if (!t1) return;
for (j = 0; j < k; ++j)
PyTuple_SET_ITEM(t1, j,
(PyObject *) new_Interface(config->interface[i].altsetting+j));
PyTuple_SET_ITEM(configuration->interfaces, i, t1);
}
}
PYUSB_STATIC Py_usb_Configuration *new_Configuration(
struct usb_config_descriptor *conf
)
{
Py_usb_Configuration *configuration;
configuration = PyObject_NEW(Py_usb_Configuration, &Py_usb_Configuration_Type);
if (configuration) {
set_Configuration_fields(configuration, conf);
if (PyErr_Occurred()) {
Py_DECREF((PyObject *) configuration);
return NULL;
}
}
return configuration;
}
PYUSB_STATIC PyMemberDef Py_usb_Device_Members[] = {
{"usbVersion",
T_STRING_INPLACE,
offsetof(Py_usb_Device, usbVersion),
READONLY,
"String containing the USB specification number that\n"
"the device and its descriptors comply with."},
{"deviceClass",
T_UBYTE,
offsetof(Py_usb_Device, deviceClass),
READONLY,
"For devices that belong to a class, this field may\n"
"name the class."},
{"deviceSubClass",
T_UBYTE,
offsetof(Py_usb_Device, deviceSubClass),
READONLY,
"For devices that belong to a class, this field may\n"
"specify a subclass within the class."},
{"deviceProtocol",
T_UBYTE,
offsetof(Py_usb_Device, deviceProtocol),
READONLY,
"This field may specify a protocol defined by the\n"
"selected class or subclass."},
{"maxPacketSize",
T_UBYTE,
offsetof(Py_usb_Device, maxPacketSize),
READONLY,
"The maximum packet size for Endpoint 0."},
{"idVendor",
T_USHORT,
offsetof(Py_usb_Device, idVendor),
READONLY,
"Unique vendor identifier."},
{"idProduct",
T_USHORT,
offsetof(Py_usb_Device, idProduct),
READONLY,
"The manufacturer assigns a Product ID to identify the\n"
"device."},
{"deviceVersion",
T_STRING_INPLACE,
offsetof(Py_usb_Device, deviceVersion),
READONLY,
"String containing the device's release number."},
{"filename",
T_STRING_INPLACE,
offsetof(Py_usb_Device, filename),
READONLY,
""},
{"configurations",
T_OBJECT,
offsetof(Py_usb_Device, configurations),
READONLY,
"Tuple with the device configurations."},
{"iManufacturer",
T_UBYTE,
offsetof(Py_usb_Device, iManufacturer),
RO,
"An index that points to a string describing the\n"
"manufacturer."},
{"iProduct",
T_UBYTE,
offsetof(Py_usb_Device, iProduct),
RO,
"An index that points to a string describing the product."},
{"iSerialNumber",
T_UBYTE,
offsetof(Py_usb_Device, iSerialNumber),
RO,
"An index that points to a string containing the\n"
"device's serial number."},
{NULL}
};
PYUSB_STATIC PyObject *Py_usb_Device_open(
PyObject *self,
PyObject *args
)
{
return (PyObject *) new_DeviceHandle((Py_usb_Device *) self);
}
PYUSB_STATIC PyMethodDef Py_usb_Device_Methods[] = {
{"open",
Py_usb_Device_open,
METH_NOARGS,
"open() -> DeviceHandle\n\n"
"Open the device for use.\n"
"Returns a DeviceHandle object."},
{NULL, NULL}
};
PYUSB_STATIC void Py_usb_Device_del(
PyObject *self
)
{
Py_XDECREF(((Py_usb_Device *) self)->configurations);
PyObject_Del(self);;
}
PYUSB_STATIC PyTypeObject Py_usb_Device_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"usb.Device", /*tp_name*/
sizeof(Py_usb_Device), /*tp_basicsize*/
0, /*tp_itemsize*/
Py_usb_Device_del, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Device descriptor object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Py_usb_Device_Methods, /* tp_methods */
Py_usb_Device_Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0,
0,
0,
0,
0,
0,
0,
0 /* destructor */
};
PYUSB_STATIC void set_Device_fields(
Py_usb_Device *device,
struct usb_device *dev
)
{
struct usb_device_descriptor *desc = &dev->descriptor;
u_int8_t i;
device->usbVersion[0] = ((desc->bcdUSB >> 12) & 0xf) + '0';
device->usbVersion[1] = ((desc->bcdUSB >> 8) & 0xf) + '0';
device->usbVersion[2] = '.';
device->usbVersion[3] = ((desc->bcdUSB >> 4) & 0xf) + '0';
device->usbVersion[4] = (desc->bcdUSB & 0xf) + '0';
device->usbVersion[5] = '\0';
device->deviceVersion[0] = ((desc->bcdDevice >> 12) & 0xf) + '0';
device->deviceVersion[1] = ((desc->bcdDevice >> 8) & 0xf) + '0';
device->deviceVersion[2] = '.';
device->deviceVersion[3] = ((desc->bcdDevice >> 4) & 0xf) + '0';
device->deviceVersion[4] = (desc->bcdDevice & 0xf) + '0';
device->deviceVersion[5] = '\0';
device->deviceClass = desc->bDeviceClass;
device->deviceSubClass = desc->bDeviceSubClass;
device->deviceProtocol = desc->bDeviceProtocol;
device->maxPacketSize = desc->bMaxPacketSize0;
device->idVendor = desc->idVendor;
device->idProduct = desc->idProduct;
device->iManufacturer = desc->iManufacturer;
device->iProduct = desc->iProduct;
device->iSerialNumber = desc->iSerialNumber;
strcpy(device->filename, dev->filename);
device->dev = dev;
if (!dev->config) {
device->configurations = PyTuple_New(0);
return;
}
device->configurations = PyTuple_New(desc->bNumConfigurations);
if (!device->configurations) return;
for (i = 0; i < desc->bNumConfigurations; ++i)
PyTuple_SET_ITEM(device->configurations, i, (PyObject *) new_Configuration(dev->config+i));
}
PYUSB_STATIC Py_usb_Device *new_Device(
struct usb_device *dev
)
{
Py_usb_Device *device;
device = PyObject_NEW(Py_usb_Device, &Py_usb_Device_Type);
if (device) {
set_Device_fields(device, dev);
if (PyErr_Occurred()) {
Py_DECREF((PyObject *) device);
return NULL;
}
}
return device;
}
PYUSB_STATIC PyMemberDef Py_usb_Bus_Members[] = {
{"dirname",
T_STRING_INPLACE,
offsetof(Py_usb_Bus, dirname),
READONLY,
""},
{"location",
T_UINT,
offsetof(Py_usb_Bus, location),
READONLY,
""},
{"devices",
T_OBJECT,
offsetof(Py_usb_Bus, devices),
READONLY,
"Tuple with the bus devices"},
{NULL}
};
PYUSB_STATIC PyMethodDef Py_usb_Bus_Methods[] = {
{NULL, NULL}
};
PYUSB_STATIC void Py_usb_Bus_del(
PyObject *self
)
{
Py_XDECREF(((Py_usb_Bus *) self)->devices);
PyObject_Del(self);
}
PYUSB_STATIC PyTypeObject Py_usb_Bus_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"usb.Bus", /*tp_name*/
sizeof(Py_usb_Bus), /*tp_basicsize*/
0, /*tp_itemsize*/
Py_usb_Bus_del, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"Bus object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Py_usb_Bus_Methods, /* tp_methods */
Py_usb_Bus_Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0,
0,
0,
0,
0,
0,
0,
0 /* destructor */
};
PYUSB_STATIC Py_usb_Bus *new_Bus(
struct usb_bus *b
)
{
Py_usb_Bus *bus;
u_int32_t i;
struct usb_device *dev;
bus = PyObject_NEW(Py_usb_Bus, &Py_usb_Bus_Type);
if (bus) {
bus->location = b->location;
strcpy(bus->dirname, b->dirname);
for(dev = b->devices, i = 0; dev; dev = dev->next) ++i;
bus->devices = PyTuple_New(i);
if(!bus->devices) {
Py_DECREF((PyObject *) bus);
return NULL;
}
for(dev = b->devices, i=0; dev; dev = dev->next, ++i)
PyTuple_SET_ITEM(bus->devices, i, (PyObject *) new_Device(dev));
if (PyErr_Occurred()) {
Py_DECREF((PyObject *) bus);
bus = NULL;
}
}
return bus;
}
PYUSB_STATIC PyMemberDef Py_usb_DeviceHandle_Members[] = {
{NULL}
};
/*
* def controlMsg(requestType, request, buffer, value = 0, index = 0, timeout = 100)
*/
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_controlMsg(
PyObject *self,
PyObject *args,
PyObject *kwds
)
{
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
int requestType;
int request;
int value = 0;
int index = 0;
char *bytes;
PyObject *data;
int size;
int timeout = DEFAULT_TIMEOUT;
int ret;
int as_read = 0;
static char *kwlist[] = {
"requestType",
"request",
"buffer",
"value",
"index",
"timeout",
NULL
};
if (!PyArg_ParseTupleAndKeywords(args,
kwds,
"iiO|iii",
kwlist,
&requestType,
&request,
&data,
&value,
&index,
&timeout)) {
return NULL;
}
/*
* If is a number, should be a read operation...
*/
if (PyNumber_Check(data)) {
size = py_NumberAsInt(data);
if (PyErr_Occurred()) return NULL;
bytes = (char *) PyMem_Malloc(size);
if (!bytes) return NULL;
as_read = 1;
} else {
bytes = (char *) getBuffer(data, &size);
if (PyErr_Occurred()) return NULL;
}
#if DUMP_PARAMS
fprintf(stderr, "controlMsg params:\n"
"\trequestType: %d\n"
"\trequest: %d\n"
"\tvalue: %d\n"
"\tindex: %d\n"
"\ttimeout: %d\n",
requestType,
request,
value,
index,
timeout);
if (as_read) {
fprintf(stderr, "\tbuffer: %d\n", size);
} else {
fprintf(stderr, "controlMsg buffer param:\n");
printBuffer(bytes, size);
}
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_control_msg(_self->deviceHandle,
requestType,
request,
value,
index,
bytes,
size,
timeout);
Py_END_ALLOW_THREADS
if (ret < 0) {
PyMem_Free(bytes);
PyUSB_Error();
return NULL;
} else if (as_read) {
PyObject *retObj = buildTuple(bytes, ret);
PyMem_Free(bytes);
return retObj;
} else {
PyMem_Free(bytes);
return PyInt_FromLong(ret);
}
}
/*
* def setConfiguration(configuration)
*/
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_setConfiguration(
PyObject *self,
PyObject *args
)
{
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
int configuration;
int ret;
if (SUPPORT_NUMBER_PROTOCOL(args)) {
configuration = (int) PyInt_AS_LONG(args);
} else if (PyObject_TypeCheck(args, &Py_usb_Configuration_Type)) {
configuration = ((Py_usb_Configuration *) args)->value;
} else {
PyErr_BadArgument();
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"setConfiguration params:\n\tconfiguration: %d\n",
configuration);
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_set_configuration(_self->deviceHandle, configuration);
Py_END_ALLOW_THREADS
if (ret < 0) {
PyUSB_Error();
return NULL;
} else {
Py_RETURN_NONE;
}
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_claimInterface(
PyObject *self,
PyObject *args
)
{
int interfaceNumber;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (SUPPORT_NUMBER_PROTOCOL(args)) {
interfaceNumber = py_NumberAsInt(args);
if (PyErr_Occurred()) return NULL;
} else if (PyObject_TypeCheck(args, &Py_usb_Interface_Type)) {
interfaceNumber = ((Py_usb_Interface *) args)->interfaceNumber;
} else {
PyErr_BadArgument();
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"claimInterface params:\n\tinterfaceNumber: %d\n",
interfaceNumber);
#endif /* DUMP_PARAMS */
if (usb_claim_interface(_self->deviceHandle, interfaceNumber)) {
PyUSB_Error();
return NULL;
} else {
_self->interfaceClaimed = interfaceNumber;
}
Py_RETURN_NONE;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_detachKernelDriver(
PyObject *self,
PyObject *args
)
{
int interfaceNumber;
int ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (SUPPORT_NUMBER_PROTOCOL(args)) {
interfaceNumber = py_NumberAsInt(args);
if (PyErr_Occurred()) return NULL;
} else if (PyObject_TypeCheck(args, &Py_usb_Interface_Type)) {
interfaceNumber = ((Py_usb_Interface *) args)->interfaceNumber;
} else {
PyErr_BadArgument();
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"detachKernelDriver params:\n\tinterfaceNumber: %d\n",
interfaceNumber);
#endif /* DUMP_PARAMS */
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
Py_BEGIN_ALLOW_THREADS
ret = usb_detach_kernel_driver_np(_self->deviceHandle, interfaceNumber);
Py_END_ALLOW_THREADS
if (ret) {
PyUSB_Error();
return NULL;
}
#endif
Py_RETURN_NONE;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_releaseInterface(
PyObject *self,
PyObject *args
)
{
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (-1 != _self->interfaceClaimed) {
int ret;
Py_BEGIN_ALLOW_THREADS
ret = usb_release_interface(_self->deviceHandle, _self->interfaceClaimed);
Py_END_ALLOW_THREADS
if (ret) {
PyUSB_Error();
return NULL;
} else {
_self->interfaceClaimed = -1;
}
} else {
PyErr_SetString(PyExc_ValueError, "No interface claimed");
return NULL;
}
Py_RETURN_NONE;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_setAltInterface(
PyObject *self,
PyObject *args
)
{
int altInterface, ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (SUPPORT_NUMBER_PROTOCOL(args)) {
altInterface = (int) py_NumberAsInt(args);
if (PyErr_Occurred()) return NULL;
} else if (PyObject_TypeCheck(args, &Py_usb_Interface_Type)) {
altInterface = ((Py_usb_Interface *) args)->alternateSetting;
} else {
PyErr_BadArgument();
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"setAltInterface params:\n\taltInterface: %d\n",
altInterface);
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_set_altinterface(_self->deviceHandle, altInterface);
Py_END_ALLOW_THREADS
if (ret < 0) {
PyUSB_Error();
return NULL;
} else {
Py_RETURN_NONE;
}
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_bulkWrite(
PyObject *self,
PyObject *args
)
{
int endpoint;
int timeout = DEFAULT_TIMEOUT;
char *data;
int size;
PyObject *bytes;
int ret;
PyObject *retObj;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (!PyArg_ParseTuple(args,
"iO|i",
&endpoint,
&bytes,
&timeout)) {
return NULL;
}
data = getBuffer(bytes, &size);
if (PyErr_Occurred()) return NULL;
#if DUMP_PARAMS
fprintf(stderr,
"bulkWrite params:\n"
"\tendpoint: %d\n"
"\ttimeout: %d\n",
endpoint,
timeout);
fprintf(stderr, "bulkWrite buffer param:\n");
printBuffer(data, size);
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_bulk_write(_self->deviceHandle, endpoint, data, size, timeout);
Py_END_ALLOW_THREADS
PyMem_Free(data);
if (ret < 0) {
PyUSB_Error();
return NULL;
} else {
retObj = PyInt_FromLong(ret);
}
return retObj;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_bulkRead(
PyObject *self,
PyObject *args
)
{
int endpoint;
int timeout = DEFAULT_TIMEOUT;
char *buffer;
int size;
PyObject *ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (!PyArg_ParseTuple(args,
"ii|i",
&endpoint,
&size,
&timeout)) {
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"bulkRead params:\n"
"\tendpoint: %d\n"
"\tsize: %d\n"
"\ttimeout: %d\n",
endpoint,
size,
timeout);
#endif /* DUMP_PARAMS */
buffer = (char *) PyMem_Malloc(size);
if (!buffer) return NULL;
Py_BEGIN_ALLOW_THREADS
size = usb_bulk_read(_self->deviceHandle, endpoint, buffer, size, timeout);
Py_END_ALLOW_THREADS
if (size < 0) {
PyMem_Free(buffer);
PyUSB_Error();
return NULL;
} else {
ret = buildTuple(buffer, size);
PyMem_Free(buffer);
}
return ret;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_interruptWrite(
PyObject *self,
PyObject *args
)
{
int endpoint;
int timeout = DEFAULT_TIMEOUT;
char *data;
int size;
PyObject *bytes;
int ret;
PyObject *retObj;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (!PyArg_ParseTuple(args,
"iO|i",
&endpoint,
&bytes,
&timeout)) {
return NULL;
}
data = getBuffer(bytes, &size);
if (PyErr_Occurred()) return NULL;
#if DUMP_PARAMS
fprintf(stderr,
"interruptWrite params:\n"
"\tendpoint: %d\n"
"\ttimeout: %d\n",
endpoint,
timeout);
fprintf(stderr, "interruptWrite buffer param:\n");
printBuffer(data, size);
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_interrupt_write(_self->deviceHandle, endpoint, data, size, timeout);
Py_END_ALLOW_THREADS
PyMem_Free(data);
if (ret < 0) {
PyUSB_Error();
return NULL;
} else {
retObj = PyInt_FromLong(ret);
}
return retObj;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_interruptRead(
PyObject *self,
PyObject *args
)
{
int endpoint;
int timeout = DEFAULT_TIMEOUT;
char *buffer;
int size;
PyObject *ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (!PyArg_ParseTuple(args,
"ii|i",
&endpoint,
&size,
&timeout)) {
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"interruptRead params:\n"
"\tendpoint: %d\n"
"\tsize: %d\n"
"\ttimeout: %d\n",
endpoint,
size,
timeout);
#endif /* DUMP_PARAMS */
buffer = (char *) PyMem_Malloc(size);
if (!buffer) return NULL;
Py_BEGIN_ALLOW_THREADS
size = usb_interrupt_read(_self->deviceHandle, endpoint, buffer, size, timeout);
Py_END_ALLOW_THREADS
if (size < 0) {
PyMem_Free(buffer);
PyUSB_Error();
return NULL;
} else {
ret = buildTuple(buffer, size);
PyMem_Free(buffer);
}
return ret;
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_resetEndpoint(
PyObject *self,
PyObject *args
)
{
int endpoint, ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
endpoint = py_NumberAsInt(args);
if (PyErr_Occurred()) return NULL;
#if DUMP_PARAMS
fprintf(stderr,
"resetEndpoint params:\n"
"\tendpoint: %d\n",
endpoint);
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_resetep(_self->deviceHandle, endpoint);
Py_END_ALLOW_THREADS
if (ret) {
PyUSB_Error();
return NULL;
} else {
Py_RETURN_NONE;
}
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_reset(
PyObject *self,
PyObject *args
)
{
int ret;
Py_BEGIN_ALLOW_THREADS
ret = usb_reset(((Py_usb_DeviceHandle *) self)->deviceHandle);
Py_END_ALLOW_THREADS
if (ret) {
PyUSB_Error();
return NULL;
} else {
Py_RETURN_NONE;
}
}
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_clearHalt(
PyObject *self,
PyObject *args
)
{
int endpoint, ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
endpoint = py_NumberAsInt(args);
if (PyErr_Occurred()) return NULL;
#if DUMP_PARAMS
fprintf(stderr,
"clearHalt params:\n"
"\tendpoint: %d\n",
endpoint);
#endif /* DUMP_PARAMS */
Py_BEGIN_ALLOW_THREADS
ret = usb_clear_halt(_self->deviceHandle, endpoint);
Py_END_ALLOW_THREADS
if (ret) {
PyUSB_Error();
return NULL;
} else {
Py_RETURN_NONE;
}
}
/*
* def getString(index, len, langid = -1)
*/
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_getString(
PyObject *self,
PyObject *args
)
{
int langid=-1, index;
unsigned long len;
PyObject *retStr;
char *buffer;
int ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (!PyArg_ParseTuple(args,
"ik|i",
&index,
&len,
&langid)) {
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"getString params:\n"
"\tindex: %d\n"
"\tlen: %lu\n"
"\tlangid: %d\n",
index,
len,
langid);
#endif /* DUMP_PARAMS */
++len; /* for NULL termination */
buffer = (char *) PyMem_Malloc(len);
if (!buffer) return NULL;
Py_BEGIN_ALLOW_THREADS
if (-1 == langid) {
ret = usb_get_string_simple(_self->deviceHandle, index, buffer, len);
} else {
ret = usb_get_string(_self->deviceHandle, index, langid, buffer, len);
}
Py_END_ALLOW_THREADS
if (ret < 0) {
PyMem_Free(buffer);
PyUSB_Error();
return NULL;
}
retStr = PyString_FromStringAndSize(buffer, ret);
PyMem_Free(buffer);
return retStr;
}
/*
* def getDescriptor(type, index, len, endpoint = -1)
*/
PYUSB_STATIC PyObject *Py_usb_DeviceHandle_getDescriptor(
PyObject *self,
PyObject *args
)
{
int endpoint=-1, type, index;
int len;
PyObject *retSeq;
char *buffer;
int ret;
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
if (!PyArg_ParseTuple(args,
"iii|i",
&type,
&index,
&len,
&endpoint)) {
return NULL;
}
#if DUMP_PARAMS
fprintf(stderr,
"getDescriptor params:\n"
"ttype: %d\n"
"\tindex: %d\n"
"\tlen: %d\n"
"\tendpoint: %d\n",
type,
index,
len,
endpoint);
#endif /* DUMP_PARAMS */
buffer = (char *) PyMem_Malloc(len);
if (!buffer) return NULL;
Py_BEGIN_ALLOW_THREADS
if (-1 == endpoint) {
ret = usb_get_descriptor(_self->deviceHandle, type, index, buffer, len);
} else {
ret = usb_get_descriptor_by_endpoint(_self->deviceHandle, endpoint, type, index, buffer, len);
}
Py_END_ALLOW_THREADS
if (ret < 0) {
PyMem_Free(buffer);
PyUSB_Error();
return NULL;
}
retSeq = buildTuple(buffer, ret);
PyMem_Free(buffer);
return retSeq;
}
PYUSB_STATIC PyMethodDef Py_usb_DeviceHandle_Methods[] = {
{"controlMsg",
(PyCFunction) Py_usb_DeviceHandle_controlMsg,
METH_VARARGS | METH_KEYWORDS,
"controlMsg(requestType, request, buffer, value=0, index=0, timeout=100) -> bytesWritten|buffer\n\n"
"Performs a control request to the default control pipe on a device.\n"
"Arguments:\n"
"\trequestType: specifies the direction of data flow, the type\n"
"\t of request, and the recipient.\n"
"\trequest: specifies the request.\n"
"\tbuffer: if the transfer is a write transfer, buffer is a sequence \n"
"\t with the transfer data, otherwise, buffer is the number of\n"
"\t bytes to read.\n"
"\tvalue: specific information to pass to the device. (default: 0)\n"
"\tindex: specific information to pass to the device. (default: 0)\n"
"\ttimeout: operation timeout in miliseconds. (default: 100)\n"
"Returns the number of bytes written."},
{"setConfiguration",
Py_usb_DeviceHandle_setConfiguration,
METH_O,
"setConfiguration(configuration) -> None\n\n"
"Sets the active configuration of a device.\n"
"Arguments:\n"
"\tconfiguration: a configuration value or a Configuration object."},
{"claimInterface",
Py_usb_DeviceHandle_claimInterface,
METH_O,
"claimInterface(interface) -> None\n\n"
"Claims the interface with the Operating System.\n"
"Arguments:\n"
"\tinterface: interface number or an Interface object."},
{"detachKernelDriver",
Py_usb_DeviceHandle_detachKernelDriver,
METH_O,
"detachKernelDriver(interface) -> None\n\n"
"Detaches a kernel driver from the interface (if one is attached,\n"
"we have permission and the operation is supported by the OS)\n"
"Arguments:\n"
"\tinterface: interface number or an Interface object."},
{"releaseInterface",
Py_usb_DeviceHandle_releaseInterface,
METH_NOARGS,
"releaseInterface() -> None\n\n"
"Releases an interface previously claimed with claimInterface."},
{"setAltInterface",
Py_usb_DeviceHandle_setAltInterface,
METH_O,
"setAltInterface(alternate) -> None\n\n"
"Sets the active alternate setting of the current interface.\n"
"Arguments:\n"
"\talternate: an alternate setting number or an Interface object."},
{"bulkWrite",
Py_usb_DeviceHandle_bulkWrite,
METH_VARARGS,
"bulkWrite(endpoint, buffer, timeout=100) -> bytesWritten\n\n"
"Performs a bulk write request to the endpoint specified.\n"
"Arguments:\n"
"\tendpoint: endpoint number.\n"
"\tbuffer: sequence data buffer to write.\n"
"\t This parameter can be any sequence type\n"
"\ttimeout: operation timeout in miliseconds. (default: 100)\n"
"Returns the number of bytes written."},
{"bulkRead",
Py_usb_DeviceHandle_bulkRead,
METH_VARARGS,
"bulkRead(endpoint, size, timeout=100) -> buffer\n\n"
"Performs a bulk read request to the endpoint specified.\n"
"Arguments:\n"
"\tendpoint: endpoint number.\n"
"\tsize: number of bytes to read.\n"
"\ttimeout: operation timeout in miliseconds. (default: 100)\n"
"Returns a tuple with the data read."},
{"interruptWrite",
Py_usb_DeviceHandle_interruptWrite,
METH_VARARGS,
"interruptWrite(endpoint, buffer, timeout=100) -> bytesWritten\n\n"
"Performs a interrupt write request to the endpoint specified.\n"
"Arguments:\n"
"\tendpoint: endpoint number.\n"
"\tbuffer: sequence data buffer to write.\n"
"\t This parameter can be any sequence type\n"
"\ttimeout: operation timeout in miliseconds. (default: 100)\n"
"Returns the number of bytes written."},
{"interruptRead",
Py_usb_DeviceHandle_interruptRead,
METH_VARARGS,
"interruptRead(endpoint, size, timeout=100) -> buffer\n\n"
"Performs a interrupt read request to the endpoint specified.\n"
"Arguments:\n"
"\tendpoint: endpoint number.\n"
"\tsize: number of bytes to read.\n"
"\ttimeout: operation timeout in miliseconds. (default: 100)\n"
"Returns a tuple with the data read."},
{"resetEndpoint",
Py_usb_DeviceHandle_resetEndpoint,
METH_O,
"resetEndpoint(endpoint) -> None\n\n"
"Resets all state (like toggles) for the specified endpoint.\n"
"Arguments:\n"
"\tendpoint: endpoint number.\n"},
{"reset",
Py_usb_DeviceHandle_reset,
METH_NOARGS,
"reset() -> None\n\n"
"Resets the specified device by sending a RESET\n"
"down the port it is connected to.\n"},
{"clearHalt",
Py_usb_DeviceHandle_clearHalt,
METH_O,
"clearHalt(endpoint) -> None\n\n"
"Clears any halt status on the specified endpoint.\n"
"Arguments:\n"
"\tendpoint: endpoint number.\n"},
{"getString",
Py_usb_DeviceHandle_getString,
METH_VARARGS,
"getString(index, len, langid = -1) -> string\n\n"
"Retrieves the string descriptor specified by index\n"
"and langid from a device.\n"
"Arguments:\n"
"\tindex: index of descriptor in the device.\n"
"\tlen: number of bytes of the string\n"
"\tlangid: Language ID. If it is omittedi, will be\n"
"\t used the first language.\n"},
{"getDescriptor",
Py_usb_DeviceHandle_getDescriptor,
METH_VARARGS,
"getDescriptor(type, index, len, endpoint = -1) -> descriptor\n\n"
"Retrieves a descriptor from the device identified by the type\n"
"and index of the descriptor.\n"
"Arguments:\n"
"\ttype: descriptor type.\n"
"\tindex: index of the descriptor.\n"
"\tlen: descriptor length.\n"
"\tendpoint: endpoint number from descriptor is read. If it is\n"
"\t omitted, the descriptor is read from default control pipe.\n"},
{NULL, NULL}
};
PYUSB_STATIC void Py_usb_DeviceHandle_del(
PyObject *self
)
{
Py_usb_DeviceHandle *_self = (Py_usb_DeviceHandle *) self;
struct usb_dev_handle *h = _self->deviceHandle;
if (h) {
if (-1 != _self->interfaceClaimed) {
usb_release_interface(_self->deviceHandle,
_self->interfaceClaimed);
}
usb_close(_self->deviceHandle);
}
PyObject_Del(self);
}
PYUSB_STATIC PyTypeObject Py_usb_DeviceHandle_Type = {
PyObject_HEAD_INIT(NULL)
0, /*ob_size*/
"usb.DeviceHandle", /*tp_name*/
sizeof(Py_usb_DeviceHandle), /*tp_basicsize*/
0, /*tp_itemsize*/
Py_usb_DeviceHandle_del, /*tp_dealloc*/
0, /*tp_print*/
0, /*tp_getattr*/
0, /*tp_setattr*/
0, /*tp_compare*/
0, /*tp_repr*/
0, /*tp_as_number*/
0, /*tp_as_sequence*/
0, /*tp_as_mapping*/
0, /*tp_hash */
0, /*tp_call*/
0, /*tp_str*/
0, /*tp_getattro*/
0, /*tp_setattro*/
0, /*tp_as_buffer*/
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE, /*tp_flags*/
"DeviceHandle object", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
0, /* tp_richcompare */
0, /* tp_weaklistoffset */
0, /* tp_iter */
0, /* tp_iternext */
Py_usb_DeviceHandle_Methods, /* tp_methods */
Py_usb_DeviceHandle_Members, /* tp_members */
0, /* tp_getset */
0, /* tp_base */
0, /* tp_dict */
0, /* tp_descr_get */
0, /* tp_descr_set */
0, /* tp_dictoffset */
0, /* tp_init */
0, /* tp_alloc */
PyType_GenericNew, /* tp_new */
0,
0,
0,
0,
0,
0,
0,
0 /* destructor */
};
PYUSB_STATIC Py_usb_DeviceHandle *new_DeviceHandle(
Py_usb_Device *device
)
{
Py_usb_DeviceHandle *dh;
struct usb_dev_handle *h;
dh = PyObject_NEW(Py_usb_DeviceHandle, &Py_usb_DeviceHandle_Type);
if (dh) {
h = usb_open(device->dev);
if (!h) {
PyUSB_Error();
Py_DECREF((PyObject *) dh);
return NULL;
}
dh->deviceHandle = h;
dh->interfaceClaimed = -1;
}
return dh;
}
/*
* Global functions
*/
PYUSB_STATIC PyObject *busses(
PyObject *self,
PyObject *args
)
{
PyObject *tuple;
struct usb_bus *bus, *b;
u_int32_t i;
if (usb_find_busses() < 0) {
PyUSB_Error();
return NULL;
}
if (usb_find_devices() < 0) {
PyUSB_Error();
return NULL;
}
bus = usb_get_busses();
if (!bus) {
PyUSB_Error();
return NULL;
}
for(i=0,b=bus;b;b=b->next) ++i;
tuple = PyTuple_New(i);
if (!tuple) return NULL;
for(b=bus,i=0;b;++i,b=b->next)
PyTuple_SET_ITEM(tuple, i, (PyObject *) new_Bus(b));
if (PyErr_Occurred()) {
Py_DECREF(tuple);
return NULL;
}
return tuple;
}
PYUSB_STATIC PyMethodDef usb_Methods[] = {
{"busses", busses, METH_NOARGS, "Returns a tuple with the usb busses"},
{NULL, NULL}
};
#ifndef PyMODINIT_FUNC
#define PyMODINIT_FUNC void
#endif /* PyMODINIT_FUNC */
/*
* Entry point for the module
*/
PyMODINIT_FUNC initusb(void)
{
PyObject *module;
module = Py_InitModule3("usb", usb_Methods,"USB access module");
if (!module) return;
PyExc_USBError = PyErr_NewException("usb.USBError", PyExc_IOError, NULL);
if (!PyExc_USBError) return;
PyModule_AddObject(module, "USBError", PyExc_USBError);
Py_INCREF(PyExc_USBError);
if (PyType_Ready(&Py_usb_Endpoint_Type) < 0) return;
Py_INCREF(&Py_usb_Endpoint_Type);
PyModule_AddObject(module, "Endpoint", (PyObject *) &Py_usb_Endpoint_Type);
if (PyType_Ready(&Py_usb_Interface_Type) < 0) return;
Py_INCREF(&Py_usb_Interface_Type);
PyModule_AddObject(module, "Interface", (PyObject *) &Py_usb_Interface_Type);
if (PyType_Ready(&Py_usb_Configuration_Type) < 0) return;
Py_INCREF(&Py_usb_Configuration_Type);
PyModule_AddObject(module, "Configuration", (PyObject *) &Py_usb_Configuration_Type);
if (PyType_Ready(&Py_usb_Device_Type) < 0) return;
Py_INCREF(&Py_usb_Device_Type);
PyModule_AddObject(module, "Device", (PyObject *) &Py_usb_Device_Type);
if (PyType_Ready(&Py_usb_Bus_Type) < 0) return;
Py_INCREF(&Py_usb_Bus_Type);
PyModule_AddObject(module, "Bus", (PyObject *) &Py_usb_Bus_Type);
if (PyType_Ready(&Py_usb_DeviceHandle_Type) < 0) return;
Py_INCREF(&Py_usb_DeviceHandle_Type);
PyModule_AddObject(module, "DeviceHandle", (PyObject *) &Py_usb_DeviceHandle_Type);
installModuleConstants(module);
usb_init();
}
/*
* vim:ts=4
*/