Skip to content

Commit

Permalink
vdp: python bindings, USB filter stuff done
Browse files Browse the repository at this point in the history
  • Loading branch information
Sheph committed Mar 12, 2017
1 parent 74bcba9 commit 804b43f
Show file tree
Hide file tree
Showing 3 changed files with 233 additions and 29 deletions.
7 changes: 7 additions & 0 deletions bindings/python/vdp/usb/vdp_py_usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,11 @@ PyMODINIT_FUNC initusb(void)
PyModule_AddIntConstant(module, "SPEED_FULL", vdp_usb_speed_full);
PyModule_AddIntConstant(module, "SPEED_HIGH", vdp_usb_speed_high);

PyModule_AddIntConstant(module, "EVENT_NONE", vdp_usb_event_none);
PyModule_AddIntConstant(module, "EVENT_SIGNAL", vdp_usb_event_signal);
PyModule_AddIntConstant(module, "EVENT_URB", vdp_usb_event_urb);
PyModule_AddIntConstant(module, "EVENT_UNLINK_URB", vdp_usb_event_unlink_urb);

PyModule_AddIntConstant(module, "SIGNAL_RESET_START", vdp_usb_signal_reset_start);
PyModule_AddIntConstant(module, "SIGNAL_RESET_END", vdp_usb_signal_reset_end);
PyModule_AddIntConstant(module, "SIGNAL_POWER_ON", vdp_usb_signal_power_on);
Expand Down Expand Up @@ -152,6 +157,8 @@ PyMODINIT_FUNC initusb(void)
PyModule_AddIntConstant(module, "HID_DT_REPORT", VDP_USB_HID_DT_REPORT);
PyModule_AddIntConstant(module, "HID_DT_PHYSICAL", VDP_USB_HID_DT_PHYSICAL);

PyModule_AddIntConstant(module, "URB_ZERO_PACKET", VDP_USB_URB_ZERO_PACKET);

vdp_py_usb_error_init(module);
vdp_py_usb_context_init(module);
vdp_py_usb_urb_init(module);
Expand Down
115 changes: 110 additions & 5 deletions bindings/python/vdp/usb/vdp_py_usb_filter.c
Original file line number Diff line number Diff line change
Expand Up @@ -427,66 +427,171 @@ static vdp_usb_urb_status vdp_py_usb_filter_get_status(void* user_data,
vdp_u8 recipient, vdp_u8 index, vdp_u16* status)
{
struct vdp_py_usb_filter* self = user_data;
PyObject* ret;
int ret_urb_status, ret_status = 0;

if (!self->fn_get_status) {
PyErr_Format(PyExc_AttributeError, "'%s' not found", "get_status");
return vdp_usb_urb_status_stall;
}

return vdp_usb_urb_status_stall;
ret = PyObject_CallFunction(self->fn_get_status, "ii", (int)recipient, (int)index);

if (!ret) {
return vdp_usb_urb_status_stall;
}

if (PyInt_Check(ret)) {
return ret_to_status("get_status", ret);
}

if (!PyTuple_Check(ret)) {
Py_DECREF(ret);
PyErr_Format(PyExc_TypeError, "%s: value not a tuple", "get_status");
return vdp_usb_urb_status_stall;
}

if (!PyArg_ParseTuple(ret, "i|i:get_status", &ret_urb_status, &ret_status)) {
Py_DECREF(ret);
return vdp_usb_urb_status_stall;
}

if (!vdp_usb_urb_status_validate(ret_urb_status)) {
Py_DECREF(ret);
PyErr_Format(PyExc_ValueError, "%s: invalid status value", "get_status");
return vdp_usb_urb_status_stall;
}

*status = ret_status;

Py_DECREF(ret);

return ret_urb_status;
}

static vdp_usb_urb_status vdp_py_usb_filter_enable_feature(void* user_data,
vdp_u8 recipient, vdp_u8 index, vdp_u16 feature, int enable)
{
struct vdp_py_usb_filter* self = user_data;
PyObject* ret;

if (!self->fn_enable_feature) {
PyErr_Format(PyExc_AttributeError, "'%s' not found", "enable_feature");
return vdp_usb_urb_status_stall;
}

return vdp_usb_urb_status_stall;
ret = PyObject_CallFunction(self->fn_enable_feature, "iiii", (int)recipient, (int)index, (int)feature, (int)enable);

if (!ret) {
return vdp_usb_urb_status_stall;
}

if (!PyInt_Check(ret)) {
PyErr_SetString(PyExc_TypeError, "value is not numeric");
Py_DECREF(ret);
return vdp_usb_urb_status_stall;
}

return ret_to_status("enable_feature", ret);
}

static vdp_usb_urb_status vdp_py_usb_filter_get_interface(void* user_data,
vdp_u8 interface, vdp_u8* alt_setting)
{
struct vdp_py_usb_filter* self = user_data;
PyObject* ret;
int ret_urb_status, ret_alt_setting = 0;

if (!self->fn_get_interface) {
PyErr_Format(PyExc_AttributeError, "'%s' not found", "get_interface");
return vdp_usb_urb_status_stall;
}

return vdp_usb_urb_status_stall;
ret = PyObject_CallFunction(self->fn_get_interface, "i", (int)interface);

if (!ret) {
return vdp_usb_urb_status_stall;
}

if (PyInt_Check(ret)) {
return ret_to_status("get_interface", ret);
}

if (!PyTuple_Check(ret)) {
Py_DECREF(ret);
PyErr_Format(PyExc_TypeError, "%s: value not a tuple", "get_interface");
return vdp_usb_urb_status_stall;
}

if (!PyArg_ParseTuple(ret, "i|i:get_interface", &ret_urb_status, &ret_alt_setting)) {
Py_DECREF(ret);
return vdp_usb_urb_status_stall;
}

if (!vdp_usb_urb_status_validate(ret_urb_status)) {
Py_DECREF(ret);
PyErr_Format(PyExc_ValueError, "%s: invalid status value", "get_interface");
return vdp_usb_urb_status_stall;
}

*alt_setting = ret_alt_setting;

Py_DECREF(ret);

return ret_urb_status;
}

static vdp_usb_urb_status vdp_py_usb_filter_set_interface(void* user_data,
vdp_u8 interface, vdp_u8 alt_setting)
{
struct vdp_py_usb_filter* self = user_data;
PyObject* ret;

if (!self->fn_set_interface) {
PyErr_Format(PyExc_AttributeError, "'%s' not found", "set_interface");
return vdp_usb_urb_status_stall;
}

return vdp_usb_urb_status_stall;
ret = PyObject_CallFunction(self->fn_set_interface, "ii", (int)interface, (int)alt_setting);

if (!ret) {
return vdp_usb_urb_status_stall;
}

if (!PyInt_Check(ret)) {
PyErr_SetString(PyExc_TypeError, "value is not numeric");
Py_DECREF(ret);
return vdp_usb_urb_status_stall;
}

return ret_to_status("set_interface", ret);
}

static vdp_usb_urb_status vdp_py_usb_filter_set_descriptor(void* user_data,
vdp_u16 value, vdp_u16 index, const vdp_byte* data,
vdp_u32 len)
{
struct vdp_py_usb_filter* self = user_data;
PyObject* ret;

if (!self->fn_set_descriptor) {
PyErr_Format(PyExc_AttributeError, "'%s' not found", "set_descriptor");
return vdp_usb_urb_status_stall;
}

return vdp_usb_urb_status_stall;
ret = PyObject_CallFunction(self->fn_set_descriptor, "iis#", (int)value, (int)index, data, (int)len);

if (!ret) {
return vdp_usb_urb_status_stall;
}

if (!PyInt_Check(ret)) {
PyErr_SetString(PyExc_TypeError, "value is not numeric");
Py_DECREF(ret);
return vdp_usb_urb_status_stall;
}

return ret_to_status("set_descriptor", ret);
}

static struct vdp_usb_filter_ops vdp_py_usb_filter_ops =
Expand Down
140 changes: 116 additions & 24 deletions bindings/python/vdp/usb/vdp_py_usb_urb.c
Original file line number Diff line number Diff line change
Expand Up @@ -259,19 +259,6 @@ static PyObject* vdp_py_usb_urb_get_transfer_length(struct vdp_py_usb_urb* self,
return PyLong_FromLong(urb_wrapper->urb->transfer_length);
}

static int vdp_py_usb_urb_set_transfer_length(struct vdp_py_usb_urb* self, PyObject* value, void* closure)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
(struct vdp_py_usb_urb_wrapper*)self->urb_wrapper;

if (value && PyInt_Check(value)) {
urb_wrapper->urb->transfer_length = PyInt_AsLong(value);
return 0;
}
PyErr_SetString(PyExc_TypeError, "value is not numeric");
return -1;
}

static PyObject* vdp_py_usb_urb_get_actual_length(struct vdp_py_usb_urb* self, void* closure)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
Expand Down Expand Up @@ -301,27 +288,41 @@ static PyObject* vdp_py_usb_urb_get_interval(struct vdp_py_usb_urb* self, void*
return PyLong_FromLong(urb_wrapper->urb->interval);
}

static int vdp_py_usb_urb_set_interval(struct vdp_py_usb_urb* self, PyObject* value, void* closure)
static PyObject* vdp_py_usb_urb_get_flags(struct vdp_py_usb_urb* self, void* closure)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
(struct vdp_py_usb_urb_wrapper*)self->urb_wrapper;

if (value && PyInt_Check(value)) {
urb_wrapper->urb->interval = PyInt_AsLong(value);
return 0;
}
PyErr_SetString(PyExc_TypeError, "value is not numeric");
return -1;
return PyLong_FromLong(urb_wrapper->urb->flags);
}

static PyObject* vdp_py_usb_urb_get_endpoint_address(struct vdp_py_usb_urb* self, void* closure)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
(struct vdp_py_usb_urb_wrapper*)self->urb_wrapper;

return PyLong_FromLong(urb_wrapper->urb->endpoint_address);
}

static PyObject* vdp_py_usb_urb_get_number_of_packets(struct vdp_py_usb_urb* self, void* closure)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
(struct vdp_py_usb_urb_wrapper*)self->urb_wrapper;

return PyLong_FromLong(urb_wrapper->urb->number_of_packets);
}

static PyGetSetDef vdp_py_usb_urb_getset[] =
{
{ "id", (getter)vdp_py_usb_urb_get_id, NULL, "sequence id" },
{ "type", (getter)vdp_py_usb_urb_get_type, NULL, "type" },
{ "status", (getter)vdp_py_usb_urb_get_status, (setter)vdp_py_usb_urb_set_status, "status" },
{ "transfer_length", (getter)vdp_py_usb_urb_get_transfer_length, (setter)vdp_py_usb_urb_set_transfer_length, "transfer_length" },
{ "transfer_length", (getter)vdp_py_usb_urb_get_transfer_length, NULL, "transfer_length" },
{ "actual_length", (getter)vdp_py_usb_urb_get_actual_length, (setter)vdp_py_usb_urb_set_actual_length, "actual_length" },
{ "interval", (getter)vdp_py_usb_urb_get_interval, (setter)vdp_py_usb_urb_set_interval, "interval" },
{ "interval", (getter)vdp_py_usb_urb_get_interval, NULL, "interval" },
{ "flags", (getter)vdp_py_usb_urb_get_flags, NULL, "flags" },
{ "endpoint_address", (getter)vdp_py_usb_urb_get_endpoint_address, NULL, "endpoint_address" },
{ "number_of_packets", (getter)vdp_py_usb_urb_get_number_of_packets, NULL, "number_of_packets" },
{ NULL }
};

Expand Down Expand Up @@ -427,6 +428,75 @@ static PyTypeObject vdp_py_usb_control_setuptype =
vdp_py_usb_control_setup_getset, /* tp_getset */
};

static Py_ssize_t vdp_py_usb_iso_packet_getreadbuf(struct vdp_py_usb_iso_packet* self, Py_ssize_t index, const void** ptr)
{
if (index != 0) {
PyErr_SetString(PyExc_SystemError, "accessing non-existent segment");
return -1;
}

*ptr = self->iso_packet->buffer;
return self->iso_packet->length;
}

static Py_ssize_t vdp_py_usb_iso_packet_getwritebuf(struct vdp_py_usb_iso_packet* self, Py_ssize_t index, const void** ptr)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
(struct vdp_py_usb_urb_wrapper*)self->urb_wrapper;

if (index != 0) {
PyErr_SetString(PyExc_SystemError, "accessing non-existent segment");
return -1;
}

if (VDP_USB_URB_ENDPOINT_OUT(urb_wrapper->urb->endpoint_address)) {
return -1;
}

*ptr = self->iso_packet->buffer;
return self->iso_packet->length;
}

static Py_ssize_t vdp_py_usb_iso_packet_getsegcount(struct vdp_py_usb_iso_packet* self, Py_ssize_t* lenp)
{
if (lenp) {
*lenp = self->iso_packet->length;
}

return 1;
}

static Py_ssize_t vdp_py_usb_iso_packet_getcharbuffer(struct vdp_py_usb_iso_packet* self, Py_ssize_t index, const void **ptr)
{
if (index != 0) {
PyErr_SetString(PyExc_SystemError, "accessing non-existent segment");
return -1;
}

*ptr = self->iso_packet->buffer;
return self->iso_packet->length;
}

static int vdp_py_usb_iso_packet_getbuffer(struct vdp_py_usb_iso_packet* self, Py_buffer* view, int flags)
{
struct vdp_py_usb_urb_wrapper* urb_wrapper =
(struct vdp_py_usb_urb_wrapper*)self->urb_wrapper;

return PyBuffer_FillInfo(view, (PyObject*)self,
self->iso_packet->buffer, self->iso_packet->length,
VDP_USB_URB_ENDPOINT_OUT(urb_wrapper->urb->endpoint_address), flags);
}

static PyBufferProcs vdp_py_usb_iso_packet_as_buffer =
{
(readbufferproc)vdp_py_usb_iso_packet_getreadbuf,
(writebufferproc)vdp_py_usb_iso_packet_getwritebuf,
(segcountproc)vdp_py_usb_iso_packet_getsegcount,
(charbufferproc)vdp_py_usb_iso_packet_getcharbuffer,
(getbufferproc)vdp_py_usb_iso_packet_getbuffer,
0,
};

static void vdp_py_usb_iso_packet_dealloc(struct vdp_py_usb_iso_packet* self)
{
Py_DECREF(self->urb_wrapper);
Expand Down Expand Up @@ -457,9 +527,31 @@ static int vdp_py_usb_iso_packet_set_status(struct vdp_py_usb_iso_packet* self,
return -1;
}

static PyObject* vdp_py_usb_iso_packet_get_actual_length(struct vdp_py_usb_iso_packet* self, void* closure)
{
return PyLong_FromLong(self->iso_packet->actual_length);
}

static int vdp_py_usb_iso_packet_set_actual_length(struct vdp_py_usb_iso_packet* self, PyObject* value, void* closure)
{
if (value && PyInt_Check(value)) {
self->iso_packet->actual_length = PyInt_AsLong(value);
return 0;
}
PyErr_SetString(PyExc_TypeError, "value is not numeric");
return -1;
}

static PyObject* vdp_py_usb_iso_packet_get_length(struct vdp_py_usb_iso_packet* self, void* closure)
{
return PyLong_FromLong(self->iso_packet->length);
}

static PyGetSetDef vdp_py_usb_iso_packet_getset[] =
{
{ "status", (getter)vdp_py_usb_iso_packet_get_status, (setter)vdp_py_usb_iso_packet_set_status, "status" },
{ "actual_length", (getter)vdp_py_usb_iso_packet_get_actual_length, (setter)vdp_py_usb_iso_packet_set_actual_length, "actual_length" },
{ "length", (getter)vdp_py_usb_iso_packet_get_length, NULL, "length" },
{ NULL }
};

Expand All @@ -483,8 +575,8 @@ static PyTypeObject vdp_py_usb_iso_packettype =
0, /* tp_str */
0, /* tp_getattro */
0, /* tp_setattro */
0, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT, /* tp_flags */
&vdp_py_usb_iso_packet_as_buffer, /* tp_as_buffer */
Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_NEWBUFFER, /* tp_flags */
"vdpusb ISOPacket", /* tp_doc */
0, /* tp_traverse */
0, /* tp_clear */
Expand Down

0 comments on commit 804b43f

Please sign in to comment.