diff --git a/tests/hwsim/remotehost.py b/tests/hwsim/remotehost.py
index cab2045..f5e88ae 100644
--- a/tests/hwsim/remotehost.py
+++ b/tests/hwsim/remotehost.py
@@ -32,6 +32,9 @@ class Host():
         self.host = host
         self.name = name
         self.user = user
+        self.monitors = []
+        self.monitor_thread = None
+        self.logs = []
         self.ifname = ifname
         self.port = port
         if self.name == "" and host != None:
@@ -97,3 +100,10 @@ class Host():
         logger.debug(self.name + " wait_execute_complete(" + wait_str + "): ")
         if t.isAlive():
             t.join(wait)
+
+    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[:]
diff --git a/tests/remote/config.py b/tests/remote/config.py
index 89de0fe..44efd2f 100644
--- a/tests/remote/config.py
+++ b/tests/remote/config.py
@@ -33,6 +33,7 @@ setup_params = {"setup_hw" : "./tests/setup_hw.sh",
 #devices = [{"hostname": "192.168.254.58", "ifname" : "wlan0", "port": "9877", "name" : "t2-ath9k", "flags" : "AP_HT40 STA_HT40"},
 #           {"hostname": "192.168.254.58", "ifname" : "wlan1", "port": "9877", "name" : "t2-ath10k", "flags" : "AP_VHT80"},
 #           {"hostname": "192.168.254.58", "ifname" : "wlan3", "port": "9877", "name" : "t2-intel7260", "flags" : "STA_VHT80"},
+#           {"hostname": "192.168.254.55", "ifname" : "wlan0, wlan1, wlan2", "port": "", "name" : "t3-monitor"},
 #           {"hostname": "192.168.254.50", "ifname" : "wlan0", "port": "9877", "name" : "t1-ath9k"},
 #           {"hostname": "192.168.254.50", "ifname" : "wlan1", "port": "9877", "name" : "t1-ath10k"}]
 
diff --git a/tests/remote/monitor.py b/tests/remote/monitor.py
new file mode 100644
index 0000000..b25e8d7
--- /dev/null
+++ b/tests/remote/monitor.py
@@ -0,0 +1,177 @@
+#
+# Monitor support
+# Copyright (c) 2016, Tieto Corporation
+#
+# This software may be distributed under the terms of the BSD license.
+# See README for more details.
+import time
+from remotehost import Host
+import config
+import re
+import traceback
+import logging
+logger = logging.getLogger()
+import hostapd
+
+# standalone monitor with multi iface support
+def create(devices, setup_params, refs, duts, monitors):
+    mons= []
+    mhosts = []
+    hosts = duts + refs
+
+    # choose only standalone monitors
+    for monitor in monitors:
+        if monitor not in hosts and monitor != "all":
+            mons.append(monitor)
+
+    for mon in mons:
+        dev = config.get_device(devices, mon)
+        if dev is None:
+            continue
+
+        host = Host(host = dev['hostname'],
+                    ifname = dev['ifname'],
+                    port = dev['port'],
+                    name = dev['name'])
+
+        try:
+            host.execute("iw reg set " + setup_params['country'])
+            setup_hw = setup_params['setup_hw']
+            for iface in ifaces:
+                host.execute(setup_hw + " -I " + iface + " -R 1")
+        except:
+            pass
+        mhosts.append(host)
+
+    return mhosts
+
+def destroy(devices, hosts):
+    for host in hosts:
+        stop(host)
+        for monitor in host.monitors:
+            host.execute("ifconfig " + monitor + " down")
+
+def setup(host, monitor_params):
+    if host is None:
+        return
+
+    ifaces = re.split('; | |, ', host.ifname)
+    count = 0
+    for param in monitor_params:
+        try:
+            iface = ifaces[count]
+        except:
+            logger.debug(traceback.format_exc())
+            break
+        host.execute("ifconfig " + iface + " down")
+        host.execute("iw " + iface + " set type monitor")
+        host.execute("ifconfig " + iface + " up")
+        status, buf = host.execute("iw " + iface + " set freq " + param['freq'] +
+                                   " " + param['bw'] + " " + param['center_freq1'] +
+                                   " " + param['center_freq2'])
+        if status != 0:
+            logger.debug("Could not setup monitor interface: " + buf)
+            continue
+        host.monitors.append(iface)
+        count = count + 1
+
+def run(host, setup_params):
+    monitor_res = []
+    log_monitor = ""
+    if host is None:
+        return None
+    if len(host.monitors) == 0:
+        return None
+    try:
+        log_dir = setup_params['log_dir']
+        tc_name = setup_params['tc_name']
+    except:
+        return None
+
+    tshark = "tshark"
+    for monitor in host.monitors:
+        host.execute("ifconfig " + monitor + " up")
+        tshark = tshark + " -i " + monitor
+        log_monitor = log_monitor + "_" + monitor
+
+    log = log_dir + tc_name + "_" + host.name + log_monitor + ".pcap"
+    host.logs.append(log)
+    thread = host.execute_run(tshark + " -w " + log, monitor_res)
+    host.thread = thread
+
+
+def stop(host):
+    if host is None:
+        return
+    if len(host.monitors) == 0:
+        return
+    if host.thread is None:
+        return
+
+    host.execute("killall -s INT tshark")
+    host.wait_execute_complete(host.thread, 5)
+    if host.thread.isAlive():
+       raise Exception("tshark still alive")
+    host.thread = None
+
+# Add monitor to existing interface
+def add(host, monitors):
+    if host is None:
+        return
+
+    for monitor in monitors:
+        if monitor != "all" and monitor != host.name:
+            continue
+        mon = "mon_" + host.ifname
+        status, buf = host.execute("iw " + host.ifname + " interface add " + mon + " type monitor")
+        if status == 0:
+            host.monitors.append(mon)
+            host.execute("ifconfig " + mon + " up")
+        else:
+            logger.debug("Could not add monitor for " + host.name)
+
+def remove(host):
+    stop(host)
+    for monitor in host.monitors:
+        host.execute("iw " + monitor + " del")
+        host.monitors.remove(monitor)
+
+
+# get monitor params from hostapd
+def get_monitor_params(hapd):
+    freq = hapd.get_status_field("freq")
+    bw = "20"
+    center_freq1=""
+    center_freq2=""
+
+    vht_oper_chwidth = hapd.get_status_field("vht_oper_chwidth")
+    secondary_channel = hapd.get_status_field("secondary_channel")
+    vht_oper_centr_freq_seg0_idx = hapd.get_status_field("vht_oper_centr_freq_seg0_idx")
+    vht_oper_centr_freq_seg1_idx = hapd.get_status_field("vht_oper_centr_freq_seg1_idx")
+    if vht_oper_chwidth == "0" or vht_oper_chwidth is None:
+        if secondary_channel == "1":
+            bw = "40"
+            center_freq1 = str(int(freq) + 10)
+        elif secondary_channel == "-1":
+            center_freq1 = str(int(freq) - 10)
+        else:
+            pass
+    elif vht_oper_chwidth == "1":
+        bw = "80"
+        center_freq1 = str(int(vht_oper_centr_freq_seg0_idx) * 5 + 5000)
+    elif vht_oper_chwidth == "2":
+        bw = "160"
+        center_freq1 = str(int(vht_oper_centr_freq_seg0_idx) * 5 + 5000)
+    elif vht_oper_chwidth == "3":
+        bw = "80+80"
+        center_freq1 = str(int(vht_oper_centr_freq_seg0_idx) * 5 + 5000)
+        center_freq2 = str(int(vht_oper_centr_freq_seg1_idx) * 5 + 5000)
+    else:
+        pass
+
+    monitor_params = { "freq" : freq,
+                       "bw" : bw,
+                       "center_freq1" : center_freq1,
+                       "center_freq2" : center_freq2 }
+
+    return monitor_params
