Python-API: Inital commit of Python bindings for the VPP API.
See: https://wiki.fd.io/view/VPP/Python_API
Change-Id: If135fc32208c7031787e1935b399d930e0e1ea1f
Signed-off-by: Ole Troan <ot@cisco.com>
diff --git a/vpp-api/python/vpp_papi/__init__.py b/vpp-api/python/vpp_papi/__init__.py
new file mode 100644
index 0000000..8be644d
--- /dev/null
+++ b/vpp-api/python/vpp_papi/__init__.py
@@ -0,0 +1,2 @@
+__import__('pkg_resources').declare_namespace(__name__)
+from .vpp_papi import *
diff --git a/vpp-api/python/vpp_papi/pneum_wrap.c b/vpp-api/python/vpp_papi/pneum_wrap.c
new file mode 100644
index 0000000..09d972d
--- /dev/null
+++ b/vpp-api/python/vpp_papi/pneum_wrap.c
@@ -0,0 +1,120 @@
+#include <Python.h>
+#include "pneum.h"
+
+static PyObject *pneum_callback = NULL;
+
+int
+wrap_pneum_callback (char *data, int len)
+{
+ PyGILState_STATE gstate;
+ PyObject *result;//, *arglist;
+
+ gstate = PyGILState_Ensure();
+
+ /* Time to call the callback */
+ result = PyObject_CallFunction(pneum_callback, "y#", data, len);
+ if (result)
+ Py_DECREF(result);
+ else
+ PyErr_Print();
+
+ PyGILState_Release(gstate);
+ return (0);
+}
+
+static PyObject *
+wrap_connect (PyObject *self, PyObject *args)
+{
+ char *name;
+ int rv;
+ PyObject *temp;
+
+ if (!PyArg_ParseTuple(args, "sO:set_callback", &name, &temp))
+ return (NULL);
+
+ if (!PyCallable_Check(temp)) {
+ PyErr_SetString(PyExc_TypeError, "parameter must be callable");
+ return NULL;
+ }
+
+ Py_XINCREF(temp); /* Add a reference to new callback */
+ Py_XDECREF(pneum_callback); /* Dispose of previous callback */
+ pneum_callback = temp; /* Remember new callback */
+
+ Py_BEGIN_ALLOW_THREADS
+ rv = pneum_connect(name);
+ Py_END_ALLOW_THREADS
+ return PyLong_FromLong(rv);
+}
+
+static PyObject *
+wrap_disconnect (PyObject *self, PyObject *args)
+{
+ int rv;
+ Py_BEGIN_ALLOW_THREADS
+ rv = pneum_disconnect();
+ Py_END_ALLOW_THREADS
+ return PyLong_FromLong(rv);
+}
+static PyObject *
+wrap_write (PyObject *self, PyObject *args)
+{
+ char *data;
+ int len, rv;
+
+ if (!PyArg_ParseTuple(args, "s#", &data, &len))
+ return NULL;
+ Py_BEGIN_ALLOW_THREADS
+ rv = pneum_write(data, len);
+ Py_END_ALLOW_THREADS
+
+ return PyLong_FromLong(rv);
+}
+
+void vl_msg_api_free(void *);
+
+static PyObject *
+wrap_read (PyObject *self, PyObject *args)
+{
+ char *data;
+ int len, rv;
+
+ Py_BEGIN_ALLOW_THREADS
+ rv = pneum_read(&data, &len);
+ Py_END_ALLOW_THREADS
+
+ if (rv != 0) { Py_RETURN_NONE; }
+
+ PyObject *ret = Py_BuildValue("y#", data, len);
+ if (!ret) { Py_RETURN_NONE; }
+
+ vl_msg_api_free(data);
+ return ret;
+}
+
+static PyMethodDef vpp_api_Methods[] = {
+ {"connect", wrap_connect, METH_VARARGS, "Connect to the VPP API."},
+ {"disconnect", wrap_disconnect, METH_VARARGS, "Disconnect from the VPP API."},
+ {"write", wrap_write, METH_VARARGS, "Write data to the VPP API."},
+ {"read", wrap_read, METH_VARARGS, "Read data from the VPP API."},
+ {NULL, NULL, 0, NULL} /* Sentinel */
+};
+
+static struct PyModuleDef vpp_api_module = {
+ PyModuleDef_HEAD_INIT,
+ "vpp_api", /* name of module */
+ NULL, /* module documentation, may be NULL */
+ -1, /* size of per-interpreter state of the module,
+ or -1 if the module keeps state in global variables. */
+ vpp_api_Methods
+};
+
+PyMODINIT_FUNC
+PyInit_vpp_api (void)
+{
+ /* Ensure threading is initialised */
+ if (!PyEval_ThreadsInitialized()) {
+ PyEval_InitThreads();
+ }
+ return PyModule_Create(&vpp_api_module);
+}