ASR_BASE

Change-Id: Icf3719cc0afe3eeb3edc7fa80a2eb5199ca9dda1
diff --git a/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/tests/hwsim/remotehost.py b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/tests/hwsim/remotehost.py
new file mode 100644
index 0000000..9d7c657
--- /dev/null
+++ b/package/kernel/asr-wl/asr-hostapd/asr-hostapd-2023-06-22/tests/hwsim/remotehost.py
@@ -0,0 +1,259 @@
+# Host class
+# Copyright (c) 2016, Qualcomm Atheros, Inc.
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+
+import logging
+import subprocess
+import threading
+import tempfile
+import os
+import traceback
+import select
+
+logger = logging.getLogger()
+
+def remote_compatible(func):
+    func.remote_compatible = True
+    return func
+
+def execute_thread(command, reply):
+    cmd = ' '.join(command)
+    logger.debug("thread run: " + cmd)
+    err = tempfile.TemporaryFile()
+    try:
+        status = 0
+        buf = subprocess.check_output(command, stderr=err, bufsize=0).decode()
+    except subprocess.CalledProcessError as e:
+        status = e.returncode
+        err.seek(0)
+        buf = err.read()
+    err.close()
+
+    logger.debug("thread cmd: " + cmd)
+    logger.debug("thread exit status: " + str(status))
+    logger.debug("thread exit buf: " + str(buf))
+    reply.append(status)
+    reply.append(buf)
+
+def gen_reaper_file(conf):
+    fd, filename = tempfile.mkstemp(dir='/tmp', prefix=conf + '-')
+    f = os.fdopen(fd, 'w')
+
+    f.write("#!/bin/sh\n")
+    f.write("name=\"$(basename $0)\"\n")
+    f.write("echo $$ > /tmp/$name.pid\n")
+    f.write("exec \"$@\"\n");
+
+    return filename;
+
+class Host():
+    def __init__(self, host=None, ifname=None, port=None, name="", user="root"):
+        self.host = host
+        self.name = name
+        self.user = user
+        self.monitors = []
+        self.monitor_thread = None
+        self.logs = []
+        self.ifname = ifname
+        self.port = port
+        self.dev = None
+        self.monitor_params = []
+        if self.name == "" and host != None:
+            self.name = host
+
+    def local_execute(self, command):
+        logger.debug("execute: " + str(command))
+        err = tempfile.TemporaryFile()
+        try:
+            status = 0
+            buf = subprocess.check_output(command, stderr=err)
+        except subprocess.CalledProcessError as e:
+            status = e.returncode
+            err.seek(0)
+            buf = err.read()
+        err.close()
+
+        logger.debug("status: " + str(status))
+        logger.debug("buf: " + str(buf))
+        return status, buf.decode()
+
+    def execute(self, command):
+        if self.host is None:
+            return self.local_execute(command)
+
+        cmd = ["ssh", self.user + "@" + self.host, ' '.join(command)]
+        _cmd = self.name + " execute: " + ' '.join(cmd)
+        logger.debug(_cmd)
+        err = tempfile.TemporaryFile()
+        try:
+            status = 0
+            buf = subprocess.check_output(cmd, stderr=err)
+        except subprocess.CalledProcessError as e:
+            status = e.returncode
+            err.seek(0)
+            buf = err.read()
+        err.close()
+
+        logger.debug(self.name + " status: " + str(status))
+        logger.debug(self.name + " buf: " + str(buf))
+        return status, buf.decode()
+
+    # async execute
+    def thread_run(self, command, res, use_reaper=True):
+        if use_reaper:
+            filename = gen_reaper_file("reaper")
+            self.send_file(filename, filename)
+            self.execute(["chmod", "755", filename])
+            _command = [filename] + command
+        else:
+            filename = ""
+            _command = command
+
+        if self.host is None:
+            cmd = _command
+        else:
+            cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)]
+        _cmd = self.name + " thread_run: " + ' '.join(cmd)
+        logger.debug(_cmd)
+        t = threading.Thread(target=execute_thread, name=filename, args=(cmd, res))
+        t.start()
+        return t
+
+    def thread_stop(self, t):
+        if t.name.find("reaper") == -1:
+            raise Exception("use_reaper required")
+
+        pid_file = t.name + ".pid"
+
+        if t.is_alive():
+            cmd = ["kill `cat " + pid_file + "`"]
+            self.execute(cmd)
+
+        # try again
+        self.thread_wait(t, 5)
+        if t.is_alive():
+            cmd = ["kill `cat " + pid_file + "`"]
+            self.execute(cmd)
+
+        # try with -9
+        self.thread_wait(t, 5)
+        if t.is_alive():
+            cmd = ["kill -9 `cat " + pid_file + "`"]
+            self.execute(cmd)
+
+        self.thread_wait(t, 5)
+        if t.is_alive():
+            raise Exception("thread still alive")
+
+        self.execute(["rm", pid_file])
+        self.execute(["rm", t.name])
+        self.local_execute(["rm", t.name])
+
+    def thread_wait(self, t, wait=None):
+        if wait == None:
+            wait_str = "infinite"
+        else:
+            wait_str = str(wait) + "s"
+
+        logger.debug(self.name + " thread_wait(" + wait_str + "): ")
+        if t.is_alive():
+            t.join(wait)
+
+    def pending(self, s, timeout=0):
+        [r, w, e] = select.select([s], [], [], timeout)
+        if r:
+            return True
+        return False
+
+    def proc_run(self, command):
+        filename = gen_reaper_file("reaper")
+        self.send_file(filename, filename)
+        self.execute(["chmod", "755", filename])
+        _command = [filename] + command
+
+        if self.host:
+            cmd = ["ssh", self.user + "@" + self.host, ' '.join(_command)]
+        else:
+            cmd = _command
+
+        _cmd = self.name + " proc_run: " + ' '.join(cmd)
+        logger.debug(_cmd)
+        err = tempfile.TemporaryFile()
+        proc = subprocess.Popen(cmd, stdout=subprocess.PIPE, stderr=err,
+                                bufsize=0)
+        proc.reaper_file = filename
+        return proc
+
+    def proc_wait_event(self, proc, events, timeout=10):
+        if not isinstance(events, list):
+            raise Exception("proc_wait_event() events not a list")
+
+        logger.debug(self.name + " proc_wait_event: " + ' '.join(events) + " timeout: " + str(timeout))
+        start = os.times()[4]
+        try:
+            while True:
+                while self.pending(proc.stdout):
+                    line = proc.stdout.readline()
+                    if not line:
+                        return None
+                    line = line.decode()
+                    logger.debug(line.strip('\n'))
+                    for event in events:
+                        if event in line:
+                            return line
+                now = os.times()[4]
+                remaining = start + timeout - now
+                if remaining <= 0:
+                    break
+                if not self.pending(proc.stdout, timeout=remaining):
+                    break
+        except:
+            logger.debug(traceback.format_exc())
+            pass
+        return None
+
+    def proc_stop(self, proc):
+        if not proc:
+            return
+
+        self.execute(["kill `cat " + proc.reaper_file + ".pid`"])
+        self.execute(["rm", proc.reaper_file + ".pid"])
+        self.execute(["rm", proc.reaper_file])
+        self.local_execute(["rm", proc.reaper_file])
+        proc.kill()
+
+    def proc_dump(self, proc):
+        if not proc:
+            return ""
+        return proc.stdout.read()
+
+    def execute_and_wait_event(self, command, events, timeout=10):
+        proc = None
+        ev = None
+
+        try:
+            proc = self.proc_run(command)
+            ev = self.proc_wait_event(proc, events, timeout)
+        except:
+            pass
+
+        self.proc_stop(proc)
+        return ev
+
+    def add_log(self, log_file):
+        self.logs.append(log_file)
+
+    def get_logs(self, local_log_dir=None):
+        for log in self.logs:
+            if local_log_dir:
+                self.local_execute(["scp", self.user + "@[" + self.host + "]:" + log, local_log_dir])
+            self.execute(["rm", log])
+        del self.logs[:]
+
+    def send_file(self, src, dst):
+        if self.host is None:
+            return
+        self.local_execute(["scp", src,
+                            self.user + "@[" + self.host + "]:" + dst])