ASR_BASE
Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/Makefile b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/Makefile
new file mode 100644
index 0000000..6f720a9
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/Makefile
@@ -0,0 +1,15 @@
+all: build
+
+SRC=wpaspy.c
+
+.PHONY: build
+build: $(SRC) setup.py
+ python setup.py build
+
+install:
+ python setup.py install
+
+clean:
+ python setup.py clean
+ rm -f *~
+ rm -rf build
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/setup.py b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/setup.py
new file mode 100644
index 0000000..4dbf765
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/setup.py
@@ -0,0 +1,22 @@
+#!/usr/bin/python
+#
+# Python bindings for wpa_ctrl (wpa_supplicant/hostapd control interface)
+# Copyright (c) 2013, Jouni Malinen <j@w1.fi>
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+from distutils.core import setup, Extension
+
+ext = Extension(name = 'wpaspy',
+ sources = ['../src/common/wpa_ctrl.c',
+ '../src/utils/os_unix.c',
+ 'wpaspy.c'],
+ extra_compile_args = ["-I../src/common",
+ "-I../src/utils",
+ "-DCONFIG_CTRL_IFACE",
+ "-DCONFIG_CTRL_IFACE_UNIX"])
+
+setup(name = 'wpaspy',
+ ext_modules = [ext],
+ description = 'Python bindings for wpa_ctrl (wpa_supplicant/hostapd)')
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/test.py b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/test.py
new file mode 100644
index 0000000..5e18fb2
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/test.py
@@ -0,0 +1,82 @@
+#!/usr/bin/python
+#
+# Test script for wpaspy
+# Copyright (c) 2013, Jouni Malinen <j@w1.fi>
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import os
+import sys
+import time
+import wpaspy
+
+wpas_ctrl = '/var/run/wpa_supplicant'
+
+def wpas_connect(host=None, port=9877):
+ ifaces = []
+
+ if host != None:
+ try:
+ wpas = wpaspy.Ctrl(host, port)
+ return wpas
+ except:
+ print("Could not connect to host: ", host)
+ return None
+
+ if os.path.isdir(wpas_ctrl):
+ try:
+ ifaces = [os.path.join(wpas_ctrl, i) for i in os.listdir(wpas_ctrl)]
+ except OSError as error:
+ print("Could not find wpa_supplicant: ", error)
+ return None
+
+ if len(ifaces) < 1:
+ print("No wpa_supplicant control interface found")
+ return None
+
+ for ctrl in ifaces:
+ try:
+ wpas = wpaspy.Ctrl(ctrl)
+ return wpas
+ except Exception as e:
+ pass
+ return None
+
+
+def main(host=None, port=9877):
+ print("Testing wpa_supplicant control interface connection")
+ wpas = wpas_connect(host, port)
+ if wpas is None:
+ return
+ print("Connected to wpa_supplicant")
+ print(wpas.request('PING'))
+
+ mon = wpas_connect(host, port)
+ if mon is None:
+ print("Could not open event monitor connection")
+ return
+
+ mon.attach()
+ print("Scan")
+ print(wpas.request('SCAN'))
+
+ count = 0
+ while count < 10:
+ count += 1
+ time.sleep(1)
+ while mon.pending():
+ ev = mon.recv()
+ print(ev)
+ if 'CTRL-EVENT-SCAN-RESULTS' in ev:
+ print('Scan completed')
+ print(wpas.request('SCAN_RESULTS'))
+ count = 10
+ pass
+
+
+if __name__ == "__main__":
+ if len(sys.argv) > 2:
+ main(host=sys.argv[1], port=int(sys.argv[2]))
+ else:
+ main()
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/wpaspy.c b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/wpaspy.c
new file mode 100644
index 0000000..4d4c2a4
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/wpaspy.c
@@ -0,0 +1,245 @@
+/*
+ * Python bindings for wpa_ctrl (wpa_supplicant/hostapd control interface)
+ * Copyright (c) 2013, Jouni Malinen <j@w1.fi>
+ *
+ * This software may be distributed under the terms of the BSD license.
+ * See README for more details.
+ */
+
+#include <Python.h>
+#include <structmember.h>
+
+#include "wpa_ctrl.h"
+
+
+struct wpaspy_obj {
+ PyObject_HEAD
+ struct wpa_ctrl *ctrl;
+ int attached;
+};
+
+static PyObject *wpaspy_error;
+
+
+static int wpaspy_open(struct wpaspy_obj *self, PyObject *args)
+{
+ const char *path;
+
+ if (!PyArg_ParseTuple(args, "s", &path))
+ return -1;
+ self->ctrl = wpa_ctrl_open(path);
+ if (self->ctrl == NULL)
+ return -1;
+ self->attached = 0;
+ return 0;
+}
+
+
+static void wpaspy_close(struct wpaspy_obj *self)
+{
+ if (self->ctrl) {
+ if (self->attached)
+ wpa_ctrl_detach(self->ctrl);
+ wpa_ctrl_close(self->ctrl);
+ self->ctrl = NULL;
+ }
+
+ PyObject_Del(self);
+}
+
+
+static PyObject * wpaspy_request(struct wpaspy_obj *self, PyObject *args)
+{
+ const char *cmd;
+ char buf[4096];
+ size_t buflen;
+ int ret;
+
+ if (!PyArg_ParseTuple(args, "s", &cmd))
+ return NULL;
+
+ buflen = sizeof(buf) - 1;
+ ret = wpa_ctrl_request(self->ctrl, cmd, strlen(cmd), buf, &buflen,
+ NULL);
+ if (ret == -2) {
+ PyErr_SetString(wpaspy_error, "Request timed out");
+ return NULL;
+ }
+ if (ret) {
+ PyErr_SetString(wpaspy_error, "Request failed");
+ return NULL;
+ }
+
+ buf[buflen] = '\0';
+ return Py_BuildValue("s", buf);
+}
+
+
+static PyObject * wpaspy_attach(struct wpaspy_obj *self)
+{
+ int ret;
+
+ if (self->attached)
+ Py_RETURN_NONE;
+
+ ret = wpa_ctrl_attach(self->ctrl);
+ if (ret) {
+ PyErr_SetString(wpaspy_error, "Attach failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+
+static PyObject * wpaspy_detach(struct wpaspy_obj *self)
+{
+ int ret;
+
+ if (!self->attached)
+ Py_RETURN_NONE;
+
+ ret = wpa_ctrl_detach(self->ctrl);
+ if (ret) {
+ PyErr_SetString(wpaspy_error, "Detach failed");
+ return NULL;
+ }
+ Py_RETURN_NONE;
+}
+
+
+static PyObject * wpaspy_pending(struct wpaspy_obj *self)
+{
+ switch (wpa_ctrl_pending(self->ctrl)) {
+ case 1:
+ Py_RETURN_TRUE;
+ case 0:
+ Py_RETURN_FALSE;
+ default:
+ PyErr_SetString(wpaspy_error, "wpa_ctrl_pending failed");
+ break;
+ }
+
+ return NULL;
+}
+
+
+static PyObject * wpaspy_recv(struct wpaspy_obj *self)
+{
+ int ret;
+ char buf[4096];
+ size_t buflen;
+
+ buflen = sizeof(buf) - 1;
+ Py_BEGIN_ALLOW_THREADS
+ ret = wpa_ctrl_recv(self->ctrl, buf, &buflen);
+ Py_END_ALLOW_THREADS
+
+ if (ret) {
+ PyErr_SetString(wpaspy_error, "wpa_ctrl_recv failed");
+ return NULL;
+ }
+
+ buf[buflen] = '\0';
+ return Py_BuildValue("s", buf);
+}
+
+
+static PyMethodDef wpaspy_methods[] = {
+ {
+ "request", (PyCFunction) wpaspy_request, METH_VARARGS,
+ "Send a control interface command and return response"
+ },
+ {
+ "attach", (PyCFunction) wpaspy_attach, METH_NOARGS,
+ "Attach as an event monitor"
+ },
+ {
+ "detach", (PyCFunction) wpaspy_detach, METH_NOARGS,
+ "Detach an event monitor"
+ },
+ {
+ "pending", (PyCFunction) wpaspy_pending, METH_NOARGS,
+ "Check whether any events are pending"
+ },
+ {
+ "recv", (PyCFunction) wpaspy_recv, METH_NOARGS,
+ "Received pending event"
+ },
+ { NULL, NULL, 0, NULL }
+};
+
+static PyMemberDef wpaspy_members[] = {
+ {
+ "attached", T_INT, offsetof(struct wpaspy_obj, attached),
+ READONLY,
+ "Whether instance is attached as event monitor"
+ },
+ { NULL }
+};
+
+static PyTypeObject wpaspy_ctrl = {
+ PyObject_HEAD_INIT(NULL)
+ .tp_name = "wpaspy.Ctrl",
+ .tp_basicsize = sizeof(struct wpaspy_obj),
+ .tp_getattro = PyObject_GenericGetAttr,
+ .tp_setattro = PyObject_GenericSetAttr,
+ .tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_BASETYPE,
+ .tp_methods = wpaspy_methods,
+ .tp_members = wpaspy_members,
+ .tp_init = (initproc) wpaspy_open,
+ .tp_dealloc = (destructor) wpaspy_close,
+ .tp_new = PyType_GenericNew,
+};
+
+
+#if PY_MAJOR_VERSION < 3
+static PyMethodDef module_methods[] = {
+ { NULL, NULL, 0, NULL }
+};
+
+
+PyMODINIT_FUNC initwpaspy(void)
+{
+ PyObject *mod;
+
+ PyType_Ready(&wpaspy_ctrl);
+ mod = Py_InitModule("wpaspy", module_methods);
+ wpaspy_error = PyErr_NewException("wpaspy.error", NULL, NULL);
+
+ Py_INCREF(&wpaspy_ctrl);
+ Py_INCREF(wpaspy_error);
+
+ PyModule_AddObject(mod, "Ctrl", (PyObject *) &wpaspy_ctrl);
+ PyModule_AddObject(mod, "error", wpaspy_error);
+}
+#else
+static struct PyModuleDef wpaspy_def = {
+ PyModuleDef_HEAD_INIT,
+ "wpaspy",
+};
+
+
+PyMODINIT_FUNC initwpaspy(void)
+{
+ PyObject *mod;
+
+ mod = PyModule_Create(&wpaspy_def);
+ if (!mod)
+ return NULL;
+
+ wpaspy_error = PyErr_NewException("wpaspy.error", NULL, NULL);
+
+ Py_INCREF(&wpaspy_ctrl);
+ Py_INCREF(wpaspy_error);
+
+ if (PyModule_AddObject(mod, "Ctrl", (PyObject *) &wpaspy_ctrl) < 0 ||
+ PyModule_AddObject(mod, "error", wpaspy_error) < 0) {
+ Py_DECREF(&wpaspy_ctrl);
+ Py_DECREF(wpaspy_error);
+ Py_DECREF(mod);
+ mod = NULL;
+ }
+
+ return mod;
+}
+#endif
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/wpaspy.py b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/wpaspy.py
new file mode 100644
index 0000000..5b8140b
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/wpaspy/wpaspy.py
@@ -0,0 +1,149 @@
+#!/usr/bin/python
+#
+# wpa_supplicant/hostapd control interface using Python
+# Copyright (c) 2013, Jouni Malinen <j@w1.fi>
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import os
+import stat
+import socket
+import select
+
+counter = 0
+
+class Ctrl:
+ def __init__(self, path, port=9877):
+ global counter
+ self.started = False
+ self.attached = False
+ self.path = path
+ self.port = port
+
+ self.udp = False
+ if not path.startswith('/'):
+ try:
+ mode = os.stat(path).st_mode
+ if not stat.S_ISSOCK(mode):
+ self.udp = True
+ except:
+ self.udp = True
+
+ if not self.udp:
+ self.s = socket.socket(socket.AF_UNIX, socket.SOCK_DGRAM)
+ self.dest = path
+ self.local = "/tmp/wpa_ctrl_" + str(os.getpid()) + '-' + str(counter)
+ counter += 1
+ self.s.bind(self.local)
+ try:
+ self.s.connect(self.dest)
+ except Exception as e:
+ self.s.close()
+ os.unlink(self.local)
+ raise
+ else:
+ try:
+ self.s = None
+ ai_list = socket.getaddrinfo(path, port, socket.AF_INET,
+ socket.SOCK_DGRAM)
+ for af, socktype, proto, cn, sockaddr in ai_list:
+ self.sockaddr = sockaddr
+ break
+ self.s = socket.socket(af, socktype)
+ self.s.settimeout(5)
+ self.s.sendto(b"GET_COOKIE", sockaddr)
+ reply, server = self.s.recvfrom(4096)
+ self.cookie = reply
+ self.port = port
+ except:
+ print("connect exception ", path, str(port))
+ if self.s != None:
+ self.s.close()
+ raise
+ self.started = True
+
+ def __del__(self):
+ self.close()
+
+ def close(self):
+ if self.attached:
+ try:
+ self.detach()
+ except Exception as e:
+ # Need to ignore this allow the socket to be closed
+ self.attached = False
+ pass
+ if self.started:
+ self.s.close()
+ if not self.udp:
+ os.unlink(self.local)
+ self.started = False
+
+ def request(self, cmd, timeout=10):
+ if type(cmd) == str:
+ try:
+ cmd2 = cmd.encode()
+ cmd = cmd2
+ except UnicodeDecodeError as e:
+ pass
+ if self.udp:
+ self.s.sendto(self.cookie + cmd, self.sockaddr)
+ else:
+ self.s.send(cmd)
+ [r, w, e] = select.select([self.s], [], [], timeout)
+ if r:
+ res = self.s.recv(4096).decode()
+ try:
+ r = str(res)
+ except UnicodeDecodeError as e:
+ r = res
+ return r
+ raise Exception("Timeout on waiting response")
+
+ def attach(self):
+ if self.attached:
+ return None
+ res = self.request("ATTACH")
+ if "OK" in res:
+ self.attached = True
+ return None
+ raise Exception("ATTACH failed")
+
+ def detach(self):
+ if not self.attached:
+ return None
+ if self.s.fileno() == -1:
+ self.attached = False
+ return None
+ while self.pending():
+ ev = self.recv()
+ res = self.request("DETACH")
+ if "FAIL" not in res:
+ self.attached = False
+ return None
+ raise Exception("DETACH failed")
+
+ def terminate(self):
+ if self.attached:
+ try:
+ self.detach()
+ except Exception as e:
+ # Need to ignore this to allow the socket to be closed
+ self.attached = False
+ self.request("TERMINATE")
+ self.close()
+
+ def pending(self, timeout=0):
+ [r, w, e] = select.select([self.s], [], [], timeout)
+ if r:
+ return True
+ return False
+
+ def recv(self):
+ res = self.s.recv(4096).decode()
+ try:
+ r = str(res)
+ except UnicodeDecodeError as e:
+ r = res
+ return r