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
);