summaryrefslogtreecommitdiffstats
path: root/vpp-api/python/vpp_papi/pneum_wrap.c
blob: 09d972d447c48d6dea220ed5bf55853039e81ee8 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
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);
}