2 * Python bindings for wpa_ctrl (wpa_supplicant/hostapd control interface)
3 * Copyright (c) 2013, Jouni Malinen <j@w1.fi>
5 * This software may be distributed under the terms of the BSD license.
6 * See README for more details.
10 #include <structmember.h>
17 struct wpa_ctrl *ctrl;
21 static PyObject *wpaspy_error;
24 static int wpaspy_open(struct wpaspy_obj *self, PyObject *args)
28 if (!PyArg_ParseTuple(args, "s", &path))
30 self->ctrl = wpa_ctrl_open(path);
31 if (self->ctrl == NULL)
38 static void wpaspy_close(struct wpaspy_obj *self)
42 wpa_ctrl_detach(self->ctrl);
43 wpa_ctrl_close(self->ctrl);
48 self->ob_type->tp_free((PyObject *) self);
52 static PyObject * wpaspy_request(struct wpaspy_obj *self, PyObject *args)
59 if (!PyArg_ParseTuple(args, "s", &cmd))
62 buflen = sizeof(buf) - 1;
63 ret = wpa_ctrl_request(self->ctrl, cmd, strlen(cmd), buf, &buflen,
66 PyErr_SetString(wpaspy_error, "Request timed out");
70 PyErr_SetString(wpaspy_error, "Request failed");
75 return Py_BuildValue("s", buf);
79 static PyObject * wpaspy_attach(struct wpaspy_obj *self)
86 ret = wpa_ctrl_attach(self->ctrl);
88 PyErr_SetString(wpaspy_error, "Attach failed");
95 static PyObject * wpaspy_detach(struct wpaspy_obj *self)
102 ret = wpa_ctrl_detach(self->ctrl);
104 PyErr_SetString(wpaspy_error, "Detach failed");
111 static PyObject * wpaspy_pending(struct wpaspy_obj *self)
113 switch (wpa_ctrl_pending(self->ctrl)) {
119 PyErr_SetString(wpaspy_error, "wpa_ctrl_pending failed");
127 static PyObject * wpaspy_recv(struct wpaspy_obj *self)
133 buflen = sizeof(buf) - 1;
134 Py_BEGIN_ALLOW_THREADS
135 ret = wpa_ctrl_recv(self->ctrl, buf, &buflen);
139 PyErr_SetString(wpaspy_error, "wpa_ctrl_recv failed");
144 return Py_BuildValue("s", buf);
148 static PyMethodDef wpaspy_methods[] = {
150 "request", (PyCFunction) wpaspy_request, METH_VARARGS,
151 "Send a control interface command and return response"
154 "attach", (PyCFunction) wpaspy_attach, METH_NOARGS,
155 "Attach as an event monitor"
158 "detach", (PyCFunction) wpaspy_detach, METH_NOARGS,
159 "Detach an event monitor"
162 "pending", (PyCFunction) wpaspy_pending, METH_NOARGS,
163 "Check whether any events are pending"
166 "recv", (PyCFunction) wpaspy_recv, METH_NOARGS,
167 "Received pending event"
169 { NULL, NULL, 0, NULL }
172 static PyMemberDef wpaspy_members[] = {
174 "attached", T_INT, offsetof(struct wpaspy_obj, attached),
176 "Whether instance is attached as event monitor"
181 static PyTypeObject wpaspy_ctrl = {
182 PyObject_HEAD_INIT(NULL)
183 .tp_name = "wpaspy.Ctrl",
184 .tp_basicsize = sizeof(struct wpaspy_obj),
185 .tp_getattro = PyObject_GenericGetAttr,
186 .tp_setattro = PyObject_GenericSetAttr,
187 .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
188 .tp_methods = wpaspy_methods,
189 .tp_members = wpaspy_members,
190 .tp_init = (initproc) wpaspy_open,
191 .tp_dealloc = (destructor) wpaspy_close,
192 .tp_new = PyType_GenericNew,
196 static PyMethodDef module_methods[] = {
197 { NULL, NULL, 0, NULL }
201 PyMODINIT_FUNC initwpaspy(void)
205 PyType_Ready(&wpaspy_ctrl);
206 mod = Py_InitModule("wpaspy", module_methods);
207 wpaspy_error = PyErr_NewException("wpaspy.error", NULL, NULL);
209 Py_INCREF(&wpaspy_ctrl);
210 Py_INCREF(wpaspy_error);
212 PyModule_AddObject(mod, "Ctrl", (PyObject *) &wpaspy_ctrl);
213 PyModule_AddObject(mod, "error", wpaspy_error);