Merge "Remove connect bonded api in pairing."
diff --git a/acts/framework/acts/controllers/__init__.py b/acts/framework/acts/controllers/__init__.py
index 2cc6f43..41e48df 100644
--- a/acts/framework/acts/controllers/__init__.py
+++ b/acts/framework/acts/controllers/__init__.py
@@ -25,5 +25,5 @@
 """This is a list of all the top level controller modules"""
 __all__ = [
     "android_device", "attenuator", "monsoon", "access_point", "iperf_server",
-    "packet_sender"
+    "packet_sender", "arduino_wifi_dongle"
 ]
diff --git a/acts/framework/acts/controllers/access_point.py b/acts/framework/acts/controllers/access_point.py
index 71624bf..1d58498 100755
--- a/acts/framework/acts/controllers/access_point.py
+++ b/acts/framework/acts/controllers/access_point.py
@@ -1,4 +1,4 @@
-#!/usr/bin/env python3.4
+#!/usr/bin/env python3
 #
 #   Copyright 2016 - Google, Inc.
 #
@@ -16,16 +16,18 @@
 
 import collections
 import ipaddress
+import logging
 import time
 
-from acts import logger
 from acts.controllers.ap_lib import ap_get_interface
 from acts.controllers.ap_lib import bridge_interface
 from acts.controllers.ap_lib import dhcp_config
 from acts.controllers.ap_lib import dhcp_server
 from acts.controllers.ap_lib import hostapd
+from acts.controllers.ap_lib import hostapd_config
 from acts.controllers.utils_lib.commands import ip
 from acts.controllers.utils_lib.commands import route
+from acts.controllers.utils_lib.commands import shell
 from acts.controllers.utils_lib.ssh import connection
 from acts.controllers.utils_lib.ssh import settings
 from acts.libs.proc import job
@@ -104,12 +106,6 @@
             configs: configs for the access point from config file.
         """
         self.ssh_settings = settings.from_config(configs['ssh_config'])
-        self.ssh = connection.SshConnection(self.ssh_settings)
-        self.log = logger.create_logger(lambda msg: '[Access Point|%s] %s' % (
-            self.ssh_settings.hostname, msg))
-
-        self.check_state()
-
         if 'ap_subnet' in configs:
             self._AP_2G_SUBNET_STR = configs['ap_subnet']['2g']
             self._AP_5G_SUBNET_STR = configs['ap_subnet']['5g']
@@ -122,6 +118,8 @@
         self._AP_5G_SUBNET = dhcp_config.Subnet(
             ipaddress.ip_network(self._AP_5G_SUBNET_STR))
 
+        self.ssh = connection.SshConnection(self.ssh_settings)
+
         # Singleton utilities for running various commands.
         self._ip_cmd = ip.LinuxIpCommand(self.ssh)
         self._route_cmd = route.LinuxRouteCommand(self.ssh)
@@ -132,7 +130,7 @@
         self.bridge = bridge_interface.BridgeInterface(self)
         self.interfaces = ap_get_interface.ApInterfaces(self)
 
-        # Get needed interface names and initialize the unnecessary ones.
+        # Get needed interface names and initialize the unneccessary ones.
         self.wan = self.interfaces.get_wan_interface()
         self.wlan = self.interfaces.get_wlan_interface()
         self.wlan_2g = self.wlan[0]
@@ -140,30 +138,6 @@
         self.lan = self.interfaces.get_lan_interface()
         self.__initial_ap()
 
-    def check_state(self):
-        """Check what state the AP is in and reboot if required.
-
-        Check if the AP already has stale interfaces from the previous run.
-        If "yes", then reboot the AP and continue AP initialization.
-
-        """
-        self.log.debug("Checking AP state")
-        self.interfaces = ap_get_interface.ApInterfaces(self)
-        # Check if the AP has any virtual interfaces created.
-        interfaces = self.ssh.run('iw dev | grep -i "type ap" || true')
-        self.log.debug("AP interfaces = %s" % interfaces)
-        # The virtual interface will be of type "AP".
-        if 'AP' in interfaces.stdout:
-            self.log.debug("Found AP in stale state. Rebooting.")
-            try:
-                self.ssh.run('reboot')
-                # Wait for AP to shut down.
-                time.sleep(10)
-                self.ssh.run('echo connected', timeout=300)
-            except Exception as e:
-                self.log.exception("Error in rebooting AP: %s", e)
-                raise
-
     def __initial_ap(self):
         """Initial AP interfaces.
 
@@ -265,8 +239,9 @@
             counter = 1
             for bss in hostapd_config.bss_lookup:
                 if interface_mac_orig:
-                    hostapd_config.bss_lookup[bss].bssid = (
-                            interface_mac_orig.stdout[:-1] + str(counter))
+                    hostapd_config.bss_lookup[
+                        bss].bssid = interface_mac_orig.stdout[:-1] + str(
+                            counter)
                 self._route_cmd.clear_routes(net_interface=str(bss))
                 if interface is self.wlan_2g:
                     starting_ip_range = self._AP_2G_SUBNET_STR
diff --git a/acts/framework/acts/controllers/arduino_wifi_dongle.py b/acts/framework/acts/controllers/arduino_wifi_dongle.py
new file mode 100644
index 0000000..18423b7
--- /dev/null
+++ b/acts/framework/acts/controllers/arduino_wifi_dongle.py
@@ -0,0 +1,332 @@
+#!/usr/bin/env python3
+#
+#   Copyright 2018 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+import logging
+import os
+import re
+import serial
+import subprocess
+import threading
+import time
+
+from acts import logger
+from acts import signals
+from acts import tracelogger
+from acts import utils
+
+from datetime import datetime
+
+ACTS_CONTROLLER_CONFIG_NAME = "ArduinoWifiDongle"
+ACTS_CONTROLLER_REFERENCE_NAME = "arduino_wifi_dongles"
+
+WIFI_DONGLE_EMPTY_CONFIG_MSG = "Configuration is empty, abort!"
+WIFI_DONGLE_NOT_LIST_CONFIG_MSG = "Configuration should be a list, abort!"
+
+DEV = "/dev/"
+IP = "IP: "
+STATUS = "STATUS: "
+SSID = "SSID: "
+RSSI = "RSSI: "
+SCAN_BEGIN = "Scan Begin"
+SCAN_END = "Scan End"
+READ_TIMEOUT = 10
+BAUD_RATE = 9600
+
+
+class ArduinoWifiDongleError(signals.ControllerError):
+    pass
+
+class DoesNotExistError(ArduinoWifiDongleError):
+    """Raised when something that does not exist is referenced."""
+
+def create(configs):
+    """Creates ArduinoWifiDongle objects.
+
+    Args:
+        configs: A list of dicts or a list of serial numbers, each representing
+                 a configuration of a arduino wifi dongle.
+
+    Returns:
+        A list of Wifi dongle objects.
+    """
+    wcs = []
+    if not configs:
+        raise ArduinoWifiDongleError(WIFI_DONGLE_EMPTY_CONFIG_MSG)
+    elif not isinstance(configs, list):
+        raise ArduinoWifiDongleError(WIFI_DONGLE_NOT_LIST_CONFIG_MSG)
+    elif isinstance(configs[0], str):
+        # Configs is a list of serials.
+        wcs = get_instances(configs)
+    else:
+        # Configs is a list of dicts.
+        wcs = get_instances_with_configs(configs)
+
+    return wcs
+
+def destroy(wcs):
+    for wc in wcs:
+        wc.clean_up()
+
+def get_instances(configs):
+    wcs = []
+    for s in configs:
+        wcs.append(ArduinoWifiDongle(s))
+    return wcs
+
+def get_instances_with_configs(configs):
+    wcs = []
+    for c in configs:
+        try:
+            s = c.pop("serial")
+        except KeyError:
+            raise ArduinoWifiDongleError(
+                "'serial' is missing for ArduinoWifiDongle config %s." % c)
+        wcs.append(ArduinoWifiDongle(s))
+    return wcs
+
+class ArduinoWifiDongle(object):
+    """Class representing an arduino wifi dongle.
+
+    Each object of this class represents one wifi dongle in ACTS.
+
+    Attribtues:
+        serial: Short serial number of the wifi dongle in string.
+        port: The terminal port the dongle is connected to in string.
+        log: A logger adapted from root logger with added token specific to an
+             ArduinoWifiDongle instance.
+        log_file_fd: File handle of the log file.
+        set_logging: Logging for the dongle is enabled when this param is set
+        lock: Lock to acquire and release set_logging variable
+        ssid: SSID of the wifi network the dongle is connected to.
+        ip_addr: IP address on the wifi interface.
+        scan_results: Most recent scan results.
+    """
+    def __init__(self, serial=''):
+        """Initializes the ArduinoWifiDongle object."""
+        self.serial = serial
+        self.port = self._get_serial_port()
+        self.log = logger.create_tagged_trace_logger(
+            "ArduinoWifiDongle|%s" % self.serial)
+        log_path_base = getattr(logging, "log_path", "/tmp/logs")
+        self.log_file_path = os.path.join(
+            log_path_base, "ArduinoWifiDongle_%s_serial_log.txt" % self.serial)
+        self.log_file_fd = open(self.log_file_path, "a")
+
+        self.set_logging = True
+        self.lock = threading.Lock()
+        self.start_controller_log()
+
+        self.ssid = None
+        self.ip_addr = None
+        self.status = 0
+        self.scan_results = []
+        self.scanning = False
+
+    def clean_up(self):
+        """Cleans up the ArduinoifiDongle object and releases any resources it
+        claimed.
+        """
+        self.stop_controller_log()
+        self.log_file_fd.close()
+
+    def _get_serial_port(self):
+        """Get the serial port for a given ArduinoWifiDongle serial number.
+
+        Returns:
+            Serial port in string if the dongle is attached.
+        """
+        if not self.serial:
+            raise ArduinoWifiDongleError(
+                "Wifi dongle's serial should not be empty")
+        cmd = "ls %s" % DEV
+        serial_ports = utils.exe_cmd(cmd).decode("utf-8", "ignore").split("\n")
+        for port in serial_ports:
+            if "USB" not in port:
+                continue
+            tty_port = "%s%s" % (DEV, port)
+            cmd = "udevadm info %s" % tty_port
+            udev_output = utils.exe_cmd(cmd).decode("utf-8", "ignore")
+            result = re.search("ID_SERIAL_SHORT=(.*)\n", udev_output)
+            if self.serial == result.group(1):
+                logging.info("Found wifi dongle %s at serial port %s" %
+                             (self.serial, tty_port))
+                return tty_port
+        raise ArduinoWifiDongleError("Wifi dongle %s is specified in config"
+                                    " but is not attached." % self.serial)
+
+    def write(self, arduino, file_path):
+        """Write an ino file to the arduino wifi dongle.
+
+        Args:
+            arduino: path of the arduino executable.
+            file_path: path of the ino flash to flash onto the dongle.
+
+        Returns:
+            True: if the write is sucessful.
+            False: if not.
+        """
+        return_result = True
+        self.stop_controller_log("Flashing %s\n" % file_path)
+        cmd = arduino + file_path + " --upload --port " + self.port
+        self.log.info("Command is %s" % cmd)
+        proc = subprocess.Popen(cmd,
+            stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
+        out, err = proc.communicate()
+        return_code = proc.returncode
+        if return_code != 0:
+            self.log.error("Failed to write file %s" % return_code)
+            return_result = False
+        self.start_controller_log("Flashing complete\n")
+        return return_result
+
+    def start_controller_log(self, msg=None):
+        """Reads the serial port and writes the data to ACTS log file.
+
+        This method depends on the logging enabled in the .ino files. The logs
+        are read from the serial port and are written to the ACTS log after
+        adding a timestamp to the data.
+
+        Args:
+            msg: Optional param to write to the log file.
+        """
+        if msg:
+            curr_time = str(datetime.now())
+            self.log_file_fd.write(curr_time + " INFO: " + msg)
+        t = threading.Thread(target=self._start_log)
+        t.daemon = True
+        t.start()
+
+    def stop_controller_log(self, msg=None):
+        """Stop the controller log.
+
+        Args:
+            msg: Optional param to write to the log file.
+        """
+        with self.lock:
+            self.set_logging = False
+        if msg:
+            curr_time = str(datetime.now())
+            self.log_file_fd.write(curr_time + " INFO: " + msg)
+
+    def _start_log(self):
+        """Target method called by start_controller_log().
+
+        This method is called as a daemon thread, which continously reads the
+        serial port. Stops when set_logging is set to False or when the test
+        ends.
+        """
+        self.set_logging = True
+        ser = serial.Serial(self.port, BAUD_RATE)
+        while True:
+            curr_time = str(datetime.now())
+            data = ser.readline().decode("utf-8", "ignore")
+            self._set_vars(data)
+            with self.lock:
+                if not self.set_logging:
+                    break
+            self.log_file_fd.write(curr_time + " " + data)
+
+    def _set_vars(self, data):
+        """Sets the variables by reading from the serial port.
+
+        Wifi dongle data such as wifi status, ip address, scan results
+        are read from the serial port and saved inside the class.
+
+        Args:
+            data: New line from the serial port.
+        """
+        # 'data' represents each line retrieved from the device's serial port.
+        # since we depend on the serial port logs to get the attributes of the
+        # dongle, every line has the format of {ino_file: method: param: value}.
+        # We look for the attribute in the log and retrieve its value.
+        # Ex: data = "connect_wifi: loop(): STATUS: 3" then val = "3"
+        # Similarly, we check when the scan has begun and ended and get all the
+        # scan results in between.
+        if data.count(":") != 3:
+            return
+        val = data.split(":")[-1].lstrip().rstrip()
+        if SCAN_BEGIN in data:
+            self.scan_results = []
+            self.scanning = True
+        elif SCAN_END in data:
+            self.scanning = False
+        elif self.scanning:
+            self.scan_results.append(data)
+        elif IP in data:
+            self.ip_addr = None if val == "0.0.0.0" else val
+        elif SSID in data:
+            self.ssid = val
+        elif STATUS in data:
+            self.status = int(val)
+
+    def ip_address(self, exp_result=True, timeout=READ_TIMEOUT):
+        """Get the ip address of the wifi dongle.
+
+        Args:
+            exp_result: True if IP address is expected (wifi connected).
+            timeout: Optional param that specifies the wait time for the IP
+                     address to come up on the dongle.
+
+        Returns:
+            IP: addr in string, if wifi connected.
+                None if not connected.
+        """
+        curr_time = time.time()
+        while time.time() < curr_time + timeout:
+            if (exp_result and self.ip_addr) or \
+                (not exp_result and not self.ip_addr):
+                  break
+            time.sleep(1)
+        return self.ip_addr
+
+    def wifi_status(self):
+        """Get wifi status on the dongle.
+
+        Returns:
+            True: if wifi is connected.
+            False: if not connected.
+        """
+        return self.status == 3
+
+    def wifi_scan(self, exp_result=True, timeout=READ_TIMEOUT):
+        """Get the wifi scan results.
+
+        Args:
+            exp_result: True if scan results are expected.
+            timeout: Optional param that specifies the wait time for the scan
+                     results to come up on the dongle.
+
+        Returns:
+            list of dictionaries each with SSID and RSSI of the network
+            found in the scan.
+        """
+        scan_networks = []
+        d = {}
+        curr_time = time.time()
+        while time.time() < curr_time + timeout:
+            if (exp_result and self.scan_results) or \
+                (not exp_result and not self.scan_results):
+                  break
+            time.sleep(1)
+        for i in range(len(self.scan_results)):
+            if SSID in self.scan_results[i]:
+                d = {}
+                d[SSID] = self.scan_results[i].split(":")[-1].rstrip()
+            elif RSSI in self.scan_results[i]:
+                d[RSSI] = self.scan_results[i].split(":")[-1].rstrip()
+                scan_networks.append(d)
+
+        return scan_networks
diff --git a/acts/framework/acts/keys.py b/acts/framework/acts/keys.py
index cb95f65..f5a6999 100644
--- a/acts/framework/acts/keys.py
+++ b/acts/framework/acts/keys.py
@@ -51,6 +51,7 @@
     key_packet_sender = "PacketSender"
     key_monsoon = "Monsoon"
     key_sniffer = "Sniffer"
+    key_arduino_wifi_dongle = "ArduinoWifiDongle"
     # Internal keys, used internally, not exposed to user's config files.
     ikey_user_param = "user_params"
     ikey_testbed_name = "testbed_name"
@@ -69,6 +70,7 @@
     m_key_iperf_client = "iperf_client"
     m_key_packet_sender = "packet_sender"
     m_key_sniffer = "sniffer"
+    m_key_arduino_wifi_dongle = "arduino_wifi_dongle"
 
     # A list of keys whose values in configs should not be passed to test
     # classes without unpacking first.
@@ -87,6 +89,7 @@
         key_monsoon,
         key_sniffer,
         key_chameleon_device,
+        key_arduino_wifi_dongle,
     ]
 
     # Keys that are file or folder paths.
diff --git a/acts/framework/acts/test_utils/bt/gattc_lib.py b/acts/framework/acts/test_utils/bt/gattc_lib.py
index a5a75d8..349c9ee 100644
--- a/acts/framework/acts/test_utils/bt/gattc_lib.py
+++ b/acts/framework/acts/test_utils/bt/gattc_lib.py
@@ -17,6 +17,8 @@
 GATT Client Libraries
 """
 
+from acts.test_utils.bt.bt_constants import default_le_connection_interval_ms
+from acts.test_utils.bt.bt_constants import default_bluetooth_socket_timeout_ms
 from acts.test_utils.bt.bt_gatt_utils import disconnect_gatt_connection
 from acts.test_utils.bt.bt_gatt_utils import setup_gatt_connection
 from acts.test_utils.bt.bt_gatt_utils import setup_gatt_mtu
@@ -25,6 +27,8 @@
 from acts.test_utils.bt.bt_constants import gatt_char_desc_uuids
 from acts.test_utils.bt.bt_constants import gatt_descriptor
 from acts.test_utils.bt.bt_constants import gatt_transport
+from acts.test_utils.bt.bt_constants import le_default_supervision_timeout
+from acts.test_utils.bt.bt_constants import le_connection_interval_time_step_ms
 from acts.test_utils.bt.bt_constants import scan_result
 from acts.test_utils.bt.bt_gatt_utils import log_gatt_server_uuids
 
@@ -329,15 +333,6 @@
         self._setup_discovered_services_index()
         services_count = self.dut.droid.gattClientGetDiscoveredServicesCount(
             self.discovered_services_index)
-        """
-        self.log.info(
-            CMD_LOG.format(
-                cmd,
-                self.dut.droid.gattClientWriteDescriptorByInstanceId(
-                    self.bluetooth_gatt, self.discovered_services_index,
-                    int(instance_id, 16),
-                    gatt_descriptor['enable_notification_value'])))
-        """
         for i in range(services_count):
             characteristic_uuids = (
                 self.dut.droid.gattClientGetDiscoveredCharacteristicUuids(
@@ -365,6 +360,39 @@
                             self.bluetooth_gatt,
                             self.discovered_services_index, i, j, True)
 
+    def enable_indication_desc_by_instance_id(self, line):
+        """GATT Client Enable indication on Descriptor by instance ID"""
+        instance_id = line
+        self._setup_discovered_services_index()
+        services_count = self.dut.droid.gattClientGetDiscoveredServicesCount(
+            self.discovered_services_index)
+        for i in range(services_count):
+            characteristic_uuids = (
+                self.dut.droid.gattClientGetDiscoveredCharacteristicUuids(
+                    self.discovered_services_index, i))
+            for j in range(len(characteristic_uuids)):
+                descriptor_uuids = (
+                    self.dut.droid.
+                    gattClientGetDiscoveredDescriptorUuidsByIndex(
+                        self.discovered_services_index, i, j))
+                for k in range(len(descriptor_uuids)):
+                    desc_inst_id = self.dut.droid.gattClientGetDescriptorInstanceId(
+                        self.bluetooth_gatt, self.discovered_services_index, i,
+                        j, k)
+                    if desc_inst_id == int(instance_id, 16):
+                        self.dut.droid.gattClientDescriptorSetValueByIndex(
+                            self.bluetooth_gatt,
+                            self.discovered_services_index, i, j, k,
+                            gatt_descriptor['enable_indication_value'])
+                        time.sleep(2)  #Necessary for PTS
+                        self.dut.droid.gattClientWriteDescriptorByIndex(
+                            self.bluetooth_gatt,
+                            self.discovered_services_index, i, j, k)
+                        time.sleep(2)  #Necessary for PTS
+                        self.dut.droid.gattClientSetCharacteristicNotificationByIndex(
+                            self.bluetooth_gatt,
+                            self.discovered_services_index, i, j, True)
+
     def char_enable_all_notifications(self):
         self._setup_discovered_services_index()
         services_count = self.dut.droid.gattClientGetDiscoveredServicesCount(
@@ -519,3 +547,30 @@
             uuid = self.generic_uuid.format(line)
         self.dut.droid.gattClientDiscoverServiceByUuid(self.bluetooth_gatt,
                                                        uuid)
+
+    def request_le_connection_parameters(self):
+        le_min_ce_len = 0
+        le_max_ce_len = 0
+        le_connection_interval = 0
+        minInterval = default_le_connection_interval_ms / le_connection_interval_time_step_ms
+        maxInterval = default_le_connection_interval_ms / le_connection_interval_time_step_ms
+        return_status = self.dut.droid.gattClientRequestLeConnectionParameters(
+            self.bluetooth_gatt, minInterval, maxInterval, 0,
+            le_default_supervision_timeout, le_min_ce_len, le_max_ce_len)
+        self.log.info(
+            "Result of request le connection param: {}".format(return_status))
+
+    def socket_conn_begin_connect_thread_psm(self, line):
+        args = line.split()
+        is_ble = bool(int(args[0]))
+        secured_conn = bool(int(args[1]))
+        psm_value = int(args[2])  # 1
+        self.dut.droid.bluetoothSocketConnBeginConnectThreadPsm(
+            self.target_mac_addr, is_ble, psm_value, secured_conn)
+
+    def socket_conn_begin_accept_thread_psm(self, line):
+        accept_timeout_ms = default_bluetooth_socket_timeout_ms
+        is_ble = True
+        secured_conn = False
+        self.dut.droid.bluetoothSocketConnBeginAcceptThreadPsm(
+            accept_timeout_ms, is_ble, secured_conn)
diff --git a/acts/framework/acts/test_utils/bt/gatts_lib.py b/acts/framework/acts/test_utils/bt/gatts_lib.py
index 7916a92..cbffb18 100644
--- a/acts/framework/acts/test_utils/bt/gatts_lib.py
+++ b/acts/framework/acts/test_utils/bt/gatts_lib.py
@@ -117,12 +117,15 @@
             self.gatt_server_callback)
         char_read = gatt_event['char_read_req']['evt'].format(
             self.gatt_server_callback)
+        char_write_req = gatt_event['char_write_req']['evt'].format(
+            self.gatt_server_callback)
         char_write = gatt_event['char_write']['evt'].format(
             self.gatt_server_callback)
         execute_write = gatt_event['exec_write']['evt'].format(
             self.gatt_server_callback)
-        regex = "({}|{}|{}|{}|{})".format(desc_read, desc_write, char_read,
-                                          char_write, execute_write)
+        regex = "({}|{}|{}|{}|{}|{})".format(desc_read, desc_write, char_read,
+                                             char_write, execute_write,
+                                             char_write_req)
         events = self.dut.ed.pop_events(regex, 5, small_timeout)
         status = 0
         if user_input:
@@ -147,7 +150,8 @@
                 continue
             offset = event['data']['offset']
             instance_id = event['data']['instanceId']
-            if (event['name'] == desc_write or event['name'] == char_write):
+            if (event['name'] == desc_write or event['name'] == char_write
+                    or event['name'] == char_write_req):
                 if ('preparedWrite' in event['data']
                         and event['data']['preparedWrite'] == True):
                     value = event['data']['value']
diff --git a/acts/framework/acts/test_utils/tel/tel_test_utils.py b/acts/framework/acts/test_utils/tel/tel_test_utils.py
index 1639bcc..dc9c45c 100644
--- a/acts/framework/acts/test_utils/tel/tel_test_utils.py
+++ b/acts/framework/acts/test_utils/tel/tel_test_utils.py
@@ -3351,7 +3351,10 @@
         return False
 
 
-def wait_for_in_call_active(ad, timeout=5, interval=1, call_id=None):
+def wait_for_in_call_active(ad,
+                            timeout=MAX_WAIT_TIME_ACCEPT_CALL_TO_OFFHOOK_EVENT,
+                            interval=WAIT_TIME_BETWEEN_STATE_CHECK,
+                            call_id=None):
     """Wait for call reach active state.
 
     Args:
@@ -4851,6 +4854,11 @@
                 ad.log.error("Failed to end call")
         ad.droid.telephonyFactoryReset()
         ad.droid.imsFactoryReset()
+        if ad.adb.shell(
+                "settings get global device_provisioning_mobile_data") != "1":
+            ad.log.warning("mobile data is not ON")
+            ad.adb.shell(
+                "settings put global device_provisioning_mobile_data 1")
         data_roaming = getattr(ad, 'roaming', False)
         if get_cell_data_roaming_state_by_adb(ad) != data_roaming:
             set_cell_data_roaming_state_by_adb(ad, data_roaming)
@@ -5228,9 +5236,7 @@
     ad.droid.setMediaVolume(0)
     ad.droid.setVoiceCallVolume(0)
     ad.droid.setAlarmVolume(0)
-    out = ad.adb.shell("settings list system | grep volume")
-    for attr in re.findall(r"(volume_.*)=\d+", out):
-        ad.adb.shell("settings put system %s 0" % attr)
+    ad.adb.shell("setprop ro.audio.silent 1", ignore_status=True)
     return silent_mode == ad.droid.checkRingerSilentMode()
 
 
@@ -5931,6 +5937,7 @@
     if ad.skip_sl4a: return status
     bring_up_sl4a(ad)
     synchronize_device_time(ad)
+    set_phone_silent_mode(ad.log, ad)
     return status
 
 
diff --git a/acts/tests/google/bt/pts/cmd_input.py b/acts/tests/google/bt/pts/cmd_input.py
index 1185976..7cf7f20 100644
--- a/acts/tests/google/bt/pts/cmd_input.py
+++ b/acts/tests/google/bt/pts/cmd_input.py
@@ -90,6 +90,27 @@
 
     """Begin GATT Client wrappers"""
 
+    def do_gattc_socket_conn_begin_connect_thread_psm(self, line):
+        cmd = ""
+        try:
+            self.pri_dut.gattc.socket_conn_begin_connect_thread_psm(line)
+        except Exception as err:
+            self.log.info(FAILURE.format(cmd, err))
+
+    def do_gattc_socket_conn_begin_accept_thread_psm(self, line):
+        cmd = ""
+        try:
+            self.pri_dut.gattc.socket_conn_begin_accept_thread_psm(line)
+        except Exception as err:
+            self.log.info(FAILURE.format(cmd, err))
+
+    def do_gattc_request_le_connection_parameters(self, line):
+        cmd = ""
+        try:
+            self.pri_dut.gattc.request_le_connection_parameters()
+        except Exception as err:
+            self.log.info(FAILURE.format(cmd, err))
+
     def do_gattc_connect_over_le(self, line):
         """Perform GATT connection over LE"""
         cmd = "Gatt connect over LE"
@@ -280,6 +301,14 @@
         except Exception as err:
             self.log.info(FAILURE.format(cmd, err))
 
+    def do_gattc_enable_indication_desc_by_instance_id(self, line):
+        """GATT Client Enable Indication on Descriptor by instance ID"""
+        cmd = "GATT Client Enable Indication on Descriptor by instance ID"
+        try:
+            self.pri_dut.gattc.enable_indication_desc_by_instance_id(line)
+        except Exception as err:
+            self.log.info(FAILURE.format(cmd, err))
+
     def do_gattc_char_enable_all_notifications(self, line):
         """GATT Client enable all notifications"""
         cmd = "GATT Client enable all notifications"
@@ -473,7 +502,7 @@
             value = []
             for i in range(size):
                 value.append(i % 256)
-            self.pri_dut.gatts.gatt_server_characteristic_set_value_by_instance_id(
+            self.pri_dut.gatts.characteristic_set_value_by_instance_id(
                 instance_id, value)
         except Exception as err:
             self.log.info(FAILURE.format(cmd, err))
diff --git a/acts/tests/google/bt/pts/instructions/GATT_PTS_INSTRUCTIONS b/acts/tests/google/bt/pts/instructions/GATT_PTS_INSTRUCTIONS
index 3d0f67f..49540b4 100644
--- a/acts/tests/google/bt/pts/instructions/GATT_PTS_INSTRUCTIONS
+++ b/acts/tests/google/bt/pts/instructions/GATT_PTS_INSTRUCTIONS
@@ -17,6 +17,11 @@
 Note: Bug in PTS forces GATT operations to be over BR/EDR. To run tests over
 LE disable BR/EDR in ICS when running tests.
 
+Note: As of PTS version 7.2.1 GATT server tests now performs scans appropriately. Change IXIT value for TSPX_iut_device_name_in_adv_packet_for_random_address to "CMD LINE Test" and make sure you have a connectable advertisement with that local name:
+  ble_adv_data_include_local_name true
+  ble_start_generic_connectable_advertisement
+
+
 TC_CL_GAC_BV_01_C
   gattc_connect_over_le
   gattc_request_mtu 23
@@ -48,6 +53,7 @@
   gattc_disconnect
 
 TC_CL_GAD_BV_02_C
+  Note: Values of UUIDS sometimes changes.
   gattc_connect_over_le
   gattc_discover_service_by_uuid 1800
   [PTS Interaction] Verify Values
@@ -79,84 +85,101 @@
 
 TC_CL_GAD_BV_03_C
   gattc_connect_over_le
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
 
 TC_CL_GAD_BV_04_C
   gattc_connect_over_le
-  gattc_list_all_uuids
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
-  gattc_list_all_uuids
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
-  gattc_list_all_uuids
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
-  gattc_list_all_uuids
+  gattc_refresh
   [PTS Interation]
   gattc_disconnect
 
 TC_CL_GAD_BV_05_C
   gattc_connect_over_le
+  gattc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gttc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refesh
+  gattc_list_all_uuids
+  gattc_refesh
+  [PTS Interation]
+  gattc_disconnect
+  gattc_connect_over_le
+  gattc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
-  gattc_list_all_uuids
-  [PTS Interation]
-  gattc_disconnect
-  gattc_connect_over_le
+  gattc_refesh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
 
 TC_CL_GAD_BV_06_C
   gattc_connect_over_le
+  gattc_refresh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refresh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refresh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
   gattc_connect_over_le
+  gattc_refresh
   gattc_list_all_uuids
   [PTS Interation]
   gattc_disconnect
@@ -220,6 +243,36 @@
   [PTS Interaction]
   bta_unbond
 
+TC_CL_GAR_BV_03_C
+  gattc_connect_over_le
+  gattc_read_char_by_uuid [Input UUID]
+  [PTS Interaction] Verify values
+  gattc_read_char_by_uuid 000055f2-0000-0000-0123-456789abcdef
+
+TC_CL_GAR_BI_06_C
+  gattc_connect_over_le
+  gattc_read_char_by_uuid [Input UUID]
+  gattc_disconnect
+  [PTS Interaction] Verify values
+
+TC_CL_GAR_BI_07_C
+  gattc_connect_over_le
+  gattc_read_char_by_uuid [Input UUID]
+  gattc_disconnect
+  [PTS Interaction] Verify values
+
+TC_CL_GAR_BI_10_C
+  gattc_connect_over_le
+  gattc_read_char_by_uuid [Input UUID]
+  gattc_disconnect
+  [PTS Interaction] Verify values
+
+TC_CL_GAR_BI_11_C
+  gattc_connect_over_le
+  gattc_read_char_by_uuid [Input UUID]
+  gattc_disconnect
+  [PTS Interaction] Verify values
+
 TC_CL_GAR_BV_04_C
   gattc_connect_over_le
   gattc_mod_read_char_by_instance_id [handle]
@@ -437,7 +490,7 @@
 
 TC_CL_GAW_BI_08_C
   gattc_connect_over_le
-  do_gattc_mod_write_char_by_instance_id [handle] 43
+  gattc_mod_write_char_by_instance_id [handle] 43
   [PTS Interaction]
   gattc_disconnect
 
@@ -622,6 +675,15 @@
   gattc_execute_reliable_write
   gattc_disconnect
 
+TC_CL_GAW_BI_32_C - Alternate method
+  gattc_connect_over_le
+  gattc_write_invalid_char_by_instance_id 0029 1
+  gattc_write_invalid_char_by_instance_id 0029 21
+  gattc_write_invalid_char_by_instance_id 0029 21
+  gattc_write_invalid_char_by_instance_id 0029 21
+  gattc_disconnect
+
+
 TC_CL_GAW_BI_33_C
   gattc_connect_over_le
   gattc_write_char_by_instance_id [handle] [size]
@@ -652,11 +714,12 @@
   [PTS Interaction]
   gattc_disconnect
 
-TC_CL_GAN_BV_01_C
-  gatts_setup_database TEST_DB_5
-  ble_start_generic_connectable_advertisement
-  gatts_list_all_uuids
-  gatts_notify_characteristic_changed [instance id from previous command of only characteristic.] true
+TC_CL_GAI_BV_01_C
+  gattc_connect_over_le
+  gattc_enable_indication_desc_by_instance_id 0113
+  [PTS Interaction]
+  gattc_disconnect
+
 
 TC_CL_GAS_BV_01_C
   gattc_connect_over_le
@@ -729,7 +792,8 @@
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
   ble_start_generic_connectable_advertisement
-  gatts_send_response GATT_INVALID_PDU
+  [PTS Interaction] Enter handle of uuid 2a30 after running the command gatts_list_all_uuids
+  gatts_send_response GATT_FAILURE
 
 TC_SR_GAR_BI_03_C
   gatts_setup_database TEST_DB_1
@@ -763,8 +827,11 @@
 
 TC_SR_GAR_BI_08_C
   Note: Static Address OK
+  bta_start_pairing_helper
   gatts_setup_database TEST_DB_1
   ble_start_generic_connectable_advertisement
+  [PTS Interaction] Enter pin from PTS to phone
+  gatts_send_response GATT_FAILURE
 
 TC_SR_GAR_BI_09_C
   gatts_setup_database TEST_DB_1
@@ -806,6 +873,14 @@
   gatts_send_response GATT_SUCCESS 24
   gatts_send_response GATT_INVALID_OFFSET
 
+TC_SR_GAR_BI_13_C (on PTS 7.2.1)
+  gatts_setup_database LARGE_1
+  # Have a logcat going as such: adb logcat | grep GattServer11onCharacteristicReadRequest
+  # Every time the offset is > 23:
+    gatts_send_response GATT_INVALID_OFFSET
+  # Every time the offset is < 23:
+    gatts_send_response GATT_SUCCESS 24
+
 TC_SR_GAR_BI_14_C
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
@@ -828,13 +903,23 @@
   gatts_send_response GATT_0C_ERR
   gatts_send_response GATT_0C_ERR
 
-TC_SR_GAR_BV_05_C
+TC_SR_GAR_BV_05_C - Deprecated
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
   ble_start_generic_connectable_advertisement
   [PTS Interaction] Enter 002a
   gatts_send_response GATT_READ_NOT_PERMITTED
 
+TC_SR_GAR_BV_05_C - PTS 7.2.1
+  gatts_setup_database TEST_DB_3
+  bta_start_pairing_helper
+  ble_adv_data_include_local_name true
+  ble_start_generic_connectable_advertisement
+  [PTS Interaction] Enter PIN fro PTS to phone
+  gatts_send_response GATT_SUCCESS
+  gatts_send_response GATT_SUCCESS
+  [PTS Interaction] Verify values
+
 TC_SR_GAR_BI_18_C
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
@@ -1006,6 +1091,8 @@
   gatts_send_response GATT_SUCCESS
   gatts_send_response GATT_SUCCESS
   gatts_send_response GATT_SUCCESS
+  atts_send_response GATT_SUCCESS
+  atts_send_response GATT_SUCCESS
 
 TC_SR_GAW_BI_02_C
   Note: Static Address OK
@@ -1056,7 +1143,7 @@
   [PTS Interaction] Enter 002a
   gatts_send_response GATT_WRITE_NOT_PERMITTED
 
-TC_SR_GAW_BI_09_C
+TC_SR_GAW_BI_09_C - Deprecated
   Note: Static Address OK
   gatts_setup_database PTS_TEST
   ble_start_generic_connectable_advertisement
@@ -1066,6 +1153,20 @@
     gatts_send_response GATT_SUCCESS
   gatts_send_response GATT_INVALID_OFFSET
 
+TC_SR_GAW_BI_09_C - NEW INSTRUCTIONS
+  Note: This test is a little tricky. Need to monitor logcat as such: adb logcat | grep offset.
+  gatts_setup_database LARGE_DB_3
+  ble_adv_data_include_local_name true
+  ble_start_generic_connectable_advertisement
+  # Whenever offset is <=23
+    gatts_send_response GATT_SUCCESS 24
+  # Whenever offset is > 23
+    # If preparedWrite value is True
+      gatts_send_response GATT_SUCCESS 24
+      gatts_send_response GATT_INVALID_OFFSET
+    # If preparedWrite value is False
+      gatts_send_response GATT_INVALID_OFFSET
+
 TC_SR_GAW_BI_11_C
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
@@ -1097,9 +1198,9 @@
 TC_SR_GAW_BV_10_C
   Note: Static Address OK
   Note: Make sure MTU is set to 23 on PTS
-  gatts_setup_database PTS_TEST
+  gatts_setup_database LARGE_DB_3
   ble_start_generic_connectable_advertisement
-  Whenever PTS prompts: "Discover All Characteristics of Service Request completed successfully" run this cmd:
+  Whenever PTS prompts: "Discover All Characteristics of Service Request completed successfully" in the Output Tool Window run this cmd:
     gatts_send_response GATT_SUCCESS 24
   Otherwise always respond with:
     gatts_send_response GATT_SUCCESS
@@ -1195,7 +1296,7 @@
   gatts_send_response GATT_0C_ERR
   gatts_send_response GATT_0C_ERR
 
-TC_SR_GAW_BV_09_C
+TC_SR_GAW_BV_09_C - DEPRECATED
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
   ble_start_generic_connectable_advertisement
@@ -1209,6 +1310,13 @@
   gatts_send_response GATT_SUCCESS
   gatts_send_response GATT_SUCCESS
 
+TC_SR_GAW_BV_09_C - New Instructions
+  Note: Static Address OK
+  gatts_setup_database LARGE_DB_1
+  ble_start_generic_connectable_advertisement
+  # Repeat below cmd until success
+  gatts_send_response GATT_SUCCESS
+
 TC_SR_GAW_BI_25_C
   Note: Static Address OK
   gatts_setup_database TEST_DB_3
@@ -1274,6 +1382,7 @@
 
 TC_SR_GAW_BI_33_C
   Note: Static Address OK
+  Note: This testcase is tricky as the order randomises a bit each time...
   gatts_setup_database LARGE_DB_3
   ble_start_generic_connectable_advertisement
   gatts_send_response GATT_SUCCESS 24
@@ -1318,18 +1427,22 @@
   gatts_notify_characteristic_changed [Handle from PTS] false 10
 
 TC_SR_GAI_BV_01_C
-  gattc_connect_over_le
-  gattc_write_desc_notification_by_instance_id 00f3 2
+  gatts_setup_database DB_TEST
+  ble_adv_data_include_local_name true
+  ble_start_generic_connectable_advertisement
   [PTS Interaction] Verify value and click yes
-  gattc_disconnect
+  gatts_notify_characteristic_changed 002a false 10
+  gatts_notify_characteristic_changed 002a true 10
+
 
 TC_SR_GAS_BV_01_C
   gatts_setup_database DB_TEST
   ble_start_generic_connectable_advertisement
+  [PTS Interaction] Click ok
+  gatts_notify_characteristic_changed 002a false 10
   gatts_setup_database TEST_DB_3
-  Wait 60 seconds for PTS to process
 
-TC_SR_GAT_BV_01_C
+TC_SR_GAT_BV_01_C - Deprecated
   gatts_setup_database LARGE_DB_3
   ble_start_generic_connectable_advertisement
   gatts_send_response GATT_SUCCESS
@@ -1337,3 +1450,22 @@
   gatts_send_response GATT_SUCCESS
   gatts_setup_database TEST_DB_3
   Wait 30 seconds for PTS to process
+
+TC_SR_GAT_BV_01_C - Deprecated
+  gatts_setup_database Test_DB_5
+  ble_adv_data_include_local_name true
+  ble_start_generic_connectable_advertisement
+  gatts_notify_characteristic_changed 0013 true
+  gatts_notify_characteristic_changed 002a true
+  gatts_send_response GATT_SUCCESS
+  gatts_send_response GATT_SUCCESS
+  gatts_send_response GATT_SUCCESS
+  gatts_notify_characteristic_changed 0003 true
+  gatts_setup_database TEST_DB_1
+  [PTS WAIT] 30 seconds to timeout to occur
+
+TC_SR_UNS_BI_02_C
+  bta_start_pairing_helper
+  ble_adv_data_include_local_name true
+  ble_start_generic_connectable_advertisement
+  [PTS Interaction] Enter pin from PTS to phone
\ No newline at end of file
diff --git a/acts/tests/google/bt/pts/instructions/L2CAP_PTS_INSTRUCTIONS b/acts/tests/google/bt/pts/instructions/L2CAP_PTS_INSTRUCTIONS
index a865f45..d41872f 100644
--- a/acts/tests/google/bt/pts/instructions/L2CAP_PTS_INSTRUCTIONS
+++ b/acts/tests/google/bt/pts/instructions/L2CAP_PTS_INSTRUCTIONS
@@ -101,6 +101,49 @@
 TC_L2CAP_COS_ECH_BV_01_C
   bta_enable
 
+TC_L2CP_COS_CFC_BV_01_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  rfcomm_write 10
+  [PTS Interaction] Verify value
+  rfcomm_stop
+  gattc_disconnect
+  bta_disable
+  bta_enable
+
+TC_L2CP_COS_CFC_BV_02_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  rfcomm_write 10
+  [PTS Interaction] Verify value
+  rfcomm_stop
+  gattc_disconnect
+
+TC_L2CP_COS_CFC_BV_03_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  rfcomm_write 10
+  [PTS Interaction] Verify value
+  rfcomm_stop
+  gattc_disconnect
+
+TC_L2CP_COS_CFC_BV_04_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify value
+  rfcomm_stop
+  gattc_disconnect
+
+TC_L2CP_COS_CFC_BV_05_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify value
+  rfcomm_stop
+  gattc_disconnect
+  bta_disable
+  bta_enable
+
 TC_L2CAP_EXF_BV_01_C
   bta_set_scan_mode connectable
 
@@ -119,6 +162,10 @@
 TC_L2CAP_CMC_BV_10_C
   rfcomm_connect
   rfcomm_stop
+  rfcomm_connect
+  rfcomm_stop
+  rfcomm_connect
+  rfcomm_stop
   [Wait up to 10-15 seconds]
 
 TC_L2CAP_CMC_BV_11_C
@@ -138,7 +185,7 @@
   [PTS Interaction] Yes
 
 TC_L2CAP_CMC_BI_05_C
-  rfcomm_accept
+  rfcomm_connect
   [Wait up to 10-15 seconds]
 
 TC_L2CAP_CMC_BI_06_C
@@ -161,9 +208,80 @@
   gattc_connect_over_le
   gattc_disconnect
 
+TC_L2CAP_LE_CFC_BI_01_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
+TC_L2CAP_LE_CFC_BV_01_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
+TC_L2CAP_LE_CFC_BV_02_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
+TC_L2CAP_LE_CFC_BV_03_C
+  TBD
+
+TC_L2CAP_LE_CFC_BV_04_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 241
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
 TC_L2CAP_LE_CFC_BV_05_C
   gattc_connect_over_le
   gattc_disconnect
   bta_disable
   bta_enable
   gattc_connect_over_le
+
+TC_L2CAP_LE_CFC_BV_06_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  rfcomm_write 10
+  rfcomm_write 10
+  rfcomm_write 10
+  gattc_disconnect
+  bta_disable
+  bta_enable
+
+TC_L2CAP_LE_CFC_BV_07_C
+  TBD
+
+TC_L2CAP_LE_CFC_BV_09_C
+  TBD
+
+TC_L2CAP_LE_CFC_BV_16_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
+TC_L2CAP_LE_CFC_BV_18_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
+TC_L2CAP_LE_CFC_BV_19_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
+TC_L2CAP_LE_CFC_BV_20_C
+  TBD
+
+TC_L2CAP_LE_CFC_BV_21_C
+  gattc_connect_over_le
+  gattc_socket_conn_begin_connect_thread_psm 1 0 1
+  [PTS Interaction] Verify values
+  gattc_disconnect
+
diff --git a/acts/tests/google/net/arduino/connect_wifi/connect_wifi.ino b/acts/tests/google/net/arduino/connect_wifi/connect_wifi.ino
new file mode 100644
index 0000000..803e5c1
--- /dev/null
+++ b/acts/tests/google/net/arduino/connect_wifi/connect_wifi.ino
@@ -0,0 +1,93 @@
+#include <ESP8266WiFi.h>
+#include <ESP8266Ping.h>
+#include <WiFiUdp.h>
+
+const char* ssid = "wifi_tethering_test";
+const char* password = "password";
+
+unsigned int localPort = 8888;
+char packetBuffer[UDP_TX_PACKET_MAX_SIZE];
+WiFiUDP Udp;
+
+
+void setup() {
+    delay(1000); // wait for a second to read from serial port after flashing
+    Serial.begin(9600);
+    Serial.println("connect: setup(): CALL: Setup Begin");
+    Serial.println("connect: setup(): INFO: Setting baud rate to 9600");
+
+    wifiStatus();
+    connectWifi();
+
+    Udp.begin(localPort);
+    Serial.println("connect: setup(): CALL: Setup End");
+}
+
+void loop() {
+    wifiStatus();
+    udpPackets();
+}
+
+void connectWifi() {
+    Serial.println("connect: connectWifi(): CALL: Connect Begin");
+    WiFi.begin(ssid, password);
+    while (WiFi.status() != WL_CONNECTED) {
+        Serial.println("connect: setup(): INFO: WiFi disconnected");
+        delay(1000);
+    }
+    Serial.println("connect: connectWifi(): CALL: Connect End");
+}
+
+void wifiStatus() {
+    Serial.println("connect: wifiStatus(): CALL: Status Begin");
+    Serial.println("connect: wifiStatus(): INFO: WiFi connected");
+    Serial.print("connect: wifiStatus(): STATUS: ");
+    Serial.println(WiFi.status());
+    Serial.print("connect: wifiStatus(): IP: ");
+    Serial.println(WiFi.localIP());
+    Serial.print("connect: wifiStatus(): SSID: ");
+    Serial.println(WiFi.SSID());
+    bool ret = Ping.ping("www.google.com", 3);
+    Serial.print("connect: wifiStatus(): PING: ");
+    if (ret) {
+        Serial.println("1");
+    } else {
+        Serial.println("0");
+    }
+
+    delay(1000);
+    Serial.println("connect: wifiStatus(): CALL: Status End");
+}
+
+void udpPackets() {
+    Serial.println("connect: udpPackets(): CALL: UDP Begin");
+    int packetSize = Udp.parsePacket();
+    while(packetSize) {
+        Serial.print("connect: udpPackets(): PKTSZ: ");
+        Serial.println(packetSize);
+        Serial.print("connect: udpPackets(): REMOTEIP: ");
+        IPAddress remote = Udp.remoteIP();
+        for (int i =0; i < 4; i++) {
+            Serial.print(remote[i], DEC);
+            if (i < 3) {
+                Serial.print(".");
+            }
+        }
+        Serial.println("");
+        Serial.print("connect: udpPackets(): REMOTEPORT: ");
+        Serial.println(Udp.remotePort());
+
+        // read the packet into packetBufffer
+        Udp.read(packetBuffer,UDP_TX_PACKET_MAX_SIZE);
+        Serial.print("connect: udpPackets(): RECV: ");
+        Serial.println(packetBuffer);
+
+        // send the same message back
+        Udp.beginPacket(Udp.remoteIP(), Udp.remotePort());
+        Udp.write(packetBuffer);
+        Udp.endPacket();
+
+        packetSize = Udp.parsePacket();
+    }
+    Serial.println("connect: udpPackets(): CALL: UDP End");
+}
diff --git a/acts/tests/google/net/arduino/disconnect_wifi/disconnect_wifi.ino b/acts/tests/google/net/arduino/disconnect_wifi/disconnect_wifi.ino
new file mode 100644
index 0000000..cacef95
--- /dev/null
+++ b/acts/tests/google/net/arduino/disconnect_wifi/disconnect_wifi.ino
@@ -0,0 +1,64 @@
+#include <ESP8266WiFi.h>
+
+void setup() {
+    delay(1000); // wait for a second to read from serial port after flashing
+    Serial.begin(9600);
+    Serial.println("disconnect: setup(): CALL: Setup Begin");
+    Serial.println("disconnect: setup(): INFO: Setting baud rate to 9600");
+
+    wifiStatus();
+    disconnectWifi();
+
+    Serial.println("disconnect: setup(): CALL: Setup End");
+}
+
+void loop() {
+    wifiStatus();
+    scanNetworks();
+}
+
+void disconnectWifi() {
+    Serial.println("disconnect: setup(): CALL: Disconnect Begin");
+    WiFi.disconnect();
+    while (WiFi.status() == WL_CONNECTED) {
+        Serial.println("disconnect: setup(): INFO: WiFi connected");
+        delay(1000);
+    }
+    Serial.println("disconnect: setup(): CALL: Disconnect End");
+}
+
+void wifiStatus() {
+    Serial.println("disconnect: wifiStatus(): CALL: Status Begin");
+    Serial.println("disconnect: loop(): INFO: WiFi disconnected");
+    Serial.print("disconnect: wifiStatus(): STATUS: ");
+    Serial.println(WiFi.status());
+    Serial.print("disconnect: wifiStatus(): IP: ");
+    Serial.println(WiFi.localIP());
+    Serial.print("disconnect: wifiStatus(): SSID: ");
+    Serial.println(WiFi.SSID());
+    delay(1000);
+    Serial.println("disconnect: wifiStatus(): CALL: Status End");
+}
+
+void scanNetworks() {
+    Serial.println("disconnect: scanNetworks(): CALL: Scan Begin");
+    int n = WiFi.scanNetworks();
+    if (n == 0) {
+        Serial.println("disconnect: scanNetworks(): INFO: No networks found");
+        Serial.println("disconnect: scanNetworks(): COUNT: 0");
+    } else {
+        Serial.println("disconnect: scanNetworks(): INFO: WiFi Networks Found");
+        Serial.print("COUNT: ");
+        Serial.println(n);
+
+        for (int i = 0; i < n; ++i) {
+            Serial.print("SSID: ");
+            Serial.println(WiFi.SSID(i));
+            Serial.print("RSSI: ");
+            Serial.println(WiFi.RSSI(i));
+        }
+    }
+
+    delay(5000); // Wait a bit before scanning again
+    Serial.println("disconnect: scanNetworks(): CALL: Scan End");
+}
diff --git a/acts/tests/google/tel/live/TelLiveProjectFiTest.py b/acts/tests/google/tel/live/TelLiveProjectFiTest.py
index bba8d54..65f02d0 100644
--- a/acts/tests/google/tel/live/TelLiveProjectFiTest.py
+++ b/acts/tests/google/tel/live/TelLiveProjectFiTest.py
@@ -34,6 +34,7 @@
 from acts.test_utils.tel.tel_test_utils import reboot_device
 from acts.test_utils.tel.tel_test_utils import refresh_droid_config
 from acts.test_utils.tel.tel_test_utils import send_dialer_secret_code
+from acts.test_utils.tel.tel_test_utils import toggle_airplane_mode_by_adb
 from acts.test_utils.tel.tel_test_utils import wait_for_state
 
 CARRIER_AUTO = "auto"
@@ -67,6 +68,11 @@
     "-e tycho.enable_ample_logging true"
 ]
 
+_TYCHO_SERVER_LAB_OVERRIDE_CMD = (
+    "am broadcast -a com.google.gservices.intent.action.GSERVICES_OVERRIDE -e "
+    "url:tycho_server_endpoint https://android.googleapis.com/nova/nfe/ rewrite"
+    "https://android.googleapis.com/lab/nova/nfe/")
+
 
 class TychoClassId(object):
     """Tycho Activity/Service Classnames."""
@@ -88,7 +94,7 @@
 
 class TelLiveProjectFiTest(TelephonyBaseTest):
     def setup_class(self):
-        self.activation_attemps = self.user_params.get("activation_attemps", 2)
+        self.activation_attemps = self.user_params.get("activation_attemps", 3)
 
     def _add_google_account(self, ad, retries=3):
         for _ in range(3):
@@ -117,7 +123,7 @@
             ad.log.error(
                 "com.google.android.tradefed.account is not installed")
             return False
-        for _ in range(3):
+        for _ in range(retries):
             ad.ensure_screen_on()
             output = ad.adb.shell(
                 'am instrument -w '
@@ -142,6 +148,7 @@
         return True
 
     def _account_registration(self, ad):
+        toggle_airplane_mode_by_adb(self.log, ad, new_state=False)
         for cmd in _TYCHO_VERBOSE_LOGGING_CMDS:
             ad.adb.shell(cmd)
         if hasattr(ad, "user_account"):
@@ -175,6 +182,7 @@
                 (ad.user_account, ad.user_password))
             ad.log.info("Enable and activate tycho apk")
             ad.adb.shell('pm enable %s' % _TYCHO_PKG)
+            #ad.adb.shell(_TYCHO_SERVER_LAB_OVERRIDE_CMD)
             for i in range(1, self.activation_attemps + 1):
                 if i == self.activation_attemps:
                     ad.log.info("Reboot and try Fi activation again")
@@ -250,6 +258,11 @@
             time.sleep(1)
             current_window = ad.get_my_current_focus_window()
             log_screen_shot(ad, self.test_name)
+            if ad.adb.shell(
+                    "settings get global device_provisioning_mobile_data"
+            ) != "1":
+                ad.adb.shell(
+                    "settings put global device_provisioning_mobile_data 1")
             if 'SwitchConfirmDialogActivity' in current_window:
                 ad.log.info("In Switch Confirmation Dialog")
                 if ad.adb.getprop("ro.build.version.release")[0] not in ("8",
diff --git a/acts/tests/google/tel/live/TelLiveStressTest.py b/acts/tests/google/tel/live/TelLiveStressTest.py
index e8a021f..575946c 100644
--- a/acts/tests/google/tel/live/TelLiveStressTest.py
+++ b/acts/tests/google/tel/live/TelLiveStressTest.py
@@ -30,6 +30,8 @@
 from acts.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
 from acts.test_utils.tel.tel_defines import CAPABILITY_VOLTE
 from acts.test_utils.tel.tel_defines import CAPABILITY_WFC
+from acts.test_utils.tel.tel_defines import GEN_3G
+from acts.test_utils.tel.tel_defines import GEN_4G
 from acts.test_utils.tel.tel_defines import INCALL_UI_DISPLAY_BACKGROUND
 from acts.test_utils.tel.tel_defines import MAX_WAIT_TIME_SMS_RECEIVE
 from acts.test_utils.tel.tel_defines import NETWORK_MODE_WCDMA_ONLY
@@ -46,6 +48,7 @@
 from acts.test_utils.tel.tel_test_utils import active_file_download_test
 from acts.test_utils.tel.tel_test_utils import is_phone_in_call
 from acts.test_utils.tel.tel_test_utils import call_setup_teardown
+from acts.test_utils.tel.tel_test_utils import ensure_network_generation_for_subscription
 from acts.test_utils.tel.tel_test_utils import ensure_wifi_connected
 from acts.test_utils.tel.tel_test_utils import get_device_epoch_time
 from acts.test_utils.tel.tel_test_utils import hangup_call
@@ -61,6 +64,7 @@
 from acts.test_utils.tel.tel_test_utils import set_preferred_network_mode_pref
 from acts.test_utils.tel.tel_test_utils import verify_internet_connection
 from acts.test_utils.tel.tel_test_utils import wait_for_call_id_clearing
+from acts.test_utils.tel.tel_test_utils import wait_for_data_connection
 from acts.test_utils.tel.tel_test_utils import wait_for_in_call_active
 from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_3g
 from acts.test_utils.tel.tel_voice_utils import is_phone_in_call_2g
@@ -103,6 +107,8 @@
                 self.file_download_method = "curl"
         else:
             self.android_devices = self.android_devices[:2]
+        for ad in self.android_devices:
+            ad.adb.shell("setprop nfc.debug_enable 1")
         self.user_params["telephony_auto_rerun"] = 0
         self.phone_call_iteration = int(
             self.user_params.get("phone_call_iteration", 500))
@@ -629,6 +635,73 @@
         else:
             return True
 
+    def _check_data(self):
+        self.result_info["Data Connection Check Total"] += 1
+        if not wait_for_data_connection(self.log, self.dut, True):
+            self.result_info["Data Connection Setup Failure"] += 1
+            return False
+        if not verify_internet_connection(self.log, self.dut):
+            rat = self.dut.adb.getprop("gsm.network.type")
+            self.dut.log.info("Network in RAT %s", rat)
+            self.result_info["Internet Connection Check Failure"] += 1
+            return False
+        return True
+
+    def _data_call_test(self, sub_id, generation):
+        self.dut.log.info(dict(self.result_info))
+        begin_time = get_device_epoch_time(self.dut)
+        start_qxdm_loggers(self.log, self.android_devices)
+        test_name = "%s_data_call_test_iter_%s" % (
+            self.test_name,
+            self.result_info["Network Preference Change Total"] + 1)
+        log_msg = "[Test Case] %s" % test_name
+        self.log.info(log_msg)
+        self.dut.droid.logI("%s begin" % log_msg)
+        if not ensure_network_generation_for_subscription(
+                self.log, self.dut, sub_id, generation):
+            self.result_info["Network Change Failure"] += 1
+            try:
+                self._take_bug_report(test_name, begin_time)
+            except Exception as e:
+                self.log.warning(e)
+            return False
+        elif not self._check_data():
+            try:
+                self._take_bug_report(test_name, begin_time)
+            except Exception as e:
+                self.log.warning(e)
+            return False
+        self.dut.log.info("Toggling data connection")
+        self.dut.droid.telephonyToggleDataConnectionForSubscription(
+            sub_id, False)
+        time.sleep(3)
+        self.dut.droid.telephonyToggleDataConnectionForSubscription(
+            sub_id, True)
+        if not self._check_data():
+            self.dut.droid.logI("%s end" % log_msg)
+            self.dut.log.info("%s end", log_msg)
+            try:
+                self._take_bug_report(test_name, begin_time)
+            except Exception as e:
+                self.log.warning(e)
+            return False
+
+    def data_call_stress_test(self):
+        result = True
+        sub_id = self.dut.droid.subscriptionGetDefaultSubId()
+        while time.time() < self.finishing_time:
+            for generation in (GEN_4G, GEN_3G):
+                try:
+                    if not self._data_call_test(sub_id, generation):
+                        result = False
+                except Exception as e:
+                    self.log.error("Exception error %s", str(e))
+                    self.result_info["Exception Errors"] += 1
+            if self.result_info["Exception Errors"] >= EXCEPTION_TOLERANCE:
+                self.log.error("Too many exception errors, quit test")
+                return False
+        return result
+
     def check_incall_data(self):
         if self.single_phone_test:
             if not initiate_call(
@@ -830,4 +903,18 @@
         return self.parallel_with_network_change_tests(
             setup_func=self._setup_lte_volte_enabled)
 
+    @test_tracker_info(uuid="10e34247-5fd3-4f87-81bf-3c17a6b71ab2")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_data_call_stress(self):
+        """ Default state stress test"""
+        self.finishing_time = time.time() + self.max_run_time
+        results = run_multithread_func(self.log,
+                                       [(self.data_call_stress_test, []),
+                                        (self.crash_check_test, [])])
+        result_message = self._get_result_message()
+        self.log.info(result_message)
+        self._update_perf_json()
+        self.result_detail = result_message
+        return all(results)
+
     """ Tests End """
diff --git a/acts/tests/google/wifi/WifiIOTtpeTest.py b/acts/tests/google/wifi/WifiIOTtpeTest.py
new file mode 100644
index 0000000..ef2d6ec
--- /dev/null
+++ b/acts/tests/google/wifi/WifiIOTtpeTest.py
@@ -0,0 +1,218 @@
+#!/usr/bin/env python3.4
+#
+#   Copyright 2017 - The Android Open Source Project
+#
+#   Licensed under the Apache License, Version 2.0 (the "License");
+#   you may not use this file except in compliance with the License.
+#   You may obtain a copy of the License at
+#
+#       http://www.apache.org/licenses/LICENSE-2.0
+#
+#   Unless required by applicable law or agreed to in writing, software
+#   distributed under the License is distributed on an "AS IS" BASIS,
+#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+#   See the License for the specific language governing permissions and
+#   limitations under the License.
+
+import itertools
+import pprint
+import time
+
+import acts.signals
+import acts.test_utils.wifi.wifi_test_utils as wutils
+
+from acts import asserts
+from acts.test_decorators import test_tracker_info
+from acts.test_utils.wifi.WifiBaseTest import WifiBaseTest
+
+WifiEnums = wutils.WifiEnums
+
+
+class WifiIOTtpeTest(WifiBaseTest):
+    """ Tests for wifi IOT
+
+        Test Bed Requirement:
+          * One Android device
+          * Wi-Fi IOT networks visible to the device
+    """
+
+    def __init__(self, controllers):
+        self.attenuators = None
+        WifiBaseTest.__init__(self, controllers)
+
+    def setup_class(self):
+        self.dut = self.android_devices[0]
+        wutils.wifi_test_device_init(self.dut)
+
+        req_params = [ "iot_networks", ]
+        opt_params = [ "open_network", "iperf_server_address" ]
+        self.unpack_userparams(req_param_names=req_params,
+                               opt_param_names=opt_params)
+
+        asserts.assert_true(
+            len(self.iot_networks) > 0,
+            "Need at least one iot network with psk.")
+
+        if getattr(self, 'open_network', False):
+            self.iot_networks.append(self.open_network)
+
+        wutils.wifi_toggle_state(self.dut, True)
+        if "iperf_server_address" in self.user_params:
+            self.iperf_server = self.iperf_servers[0]
+            self.iperf_server.start()
+
+        # create hashmap for testcase name and SSIDs
+        self.iot_test_prefix = "test_iot_connection_to_"
+        self.ssid_map = {}
+        for network in self.iot_networks:
+            SSID = network['SSID'].replace('-','_')
+            self.ssid_map[SSID] = network
+
+    def setup_test(self):
+        self.dut.droid.wakeLockAcquireBright()
+        self.dut.droid.wakeUpNow()
+
+    def teardown_test(self):
+        self.dut.droid.wakeLockRelease()
+        self.dut.droid.goToSleepNow()
+        wutils.reset_wifi(self.dut)
+
+    def teardown_class(self):
+        if "iperf_server_address" in self.user_params:
+            self.iperf_server.stop()
+
+    def on_fail(self, test_name, begin_time):
+        self.dut.take_bug_report(test_name, begin_time)
+        self.dut.cat_adb_log(test_name, begin_time)
+
+    """Helper Functions"""
+
+    def connect_to_wifi_network(self, network):
+        """Connection logic for open and psk wifi networks.
+
+        Args:
+            params: Dictionary with network info.
+        """
+        SSID = network[WifiEnums.SSID_KEY]
+        self.dut.ed.clear_all_events()
+        wutils.start_wifi_connection_scan(self.dut)
+        scan_results = self.dut.droid.wifiGetScanResults()
+        wutils.assert_network_in_list({WifiEnums.SSID_KEY: SSID}, scan_results)
+        wutils.wifi_connect(self.dut, network, num_of_tries=3)
+
+    def run_iperf_client(self, network):
+        """Run iperf traffic after connection.
+
+        Args:
+            params: Dictionary with network info.
+        """
+        if "iperf_server_address" in self.user_params:
+            wait_time = 5
+            SSID = network[WifiEnums.SSID_KEY]
+            self.log.info("Starting iperf traffic through {}".format(SSID))
+            time.sleep(wait_time)
+            port_arg = "-p {}".format(self.iperf_server.port)
+            success, data = self.dut.run_iperf_client(self.iperf_server_address,
+                                                      port_arg)
+            self.log.debug(pprint.pformat(data))
+            asserts.assert_true(success, "Error occurred in iPerf traffic.")
+
+    def connect_to_wifi_network_and_run_iperf(self, network):
+        """Connection logic for open and psk wifi networks.
+
+        Logic steps are
+        1. Connect to the network.
+        2. Run iperf traffic.
+
+        Args:
+            params: A dictionary with network info.
+        """
+        self.connect_to_wifi_network(network)
+        self.run_iperf_client(network)
+
+    """Tests"""
+
+    @test_tracker_info(uuid="0e4ad6ed-595c-4629-a4c9-c6be9c3c58e0")
+    def test_iot_connection_to_ASUS_RT_AC68U_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="a76d8acc-808e-4a5d-a52b-5ba07d07b810")
+    def test_iot_connection_to_ASUS_RT_AC68U_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="659a3e5e-07eb-4905-9cda-92e959c7b674")
+    def test_iot_connection_to_D_Link_DIR_868L_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="6bcfd736-30fc-48a8-b4fb-723d1d113f3c")
+    def test_iot_connection_to_D_Link_DIR_868L_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="c9da945a-2c4a-44e1-881d-adf307b39b21")
+    def test_iot_connection_to_TP_LINK_WR940N_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="db0d224d-df81-401f-bf35-08ad02e41a71")
+    def test_iot_connection_to_ASUS_RT_N66U_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="845ff1d6-618d-40f3-81c3-6ed3a0751fde")
+    def test_iot_connection_to_ASUS_RT_N66U_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="6908039b-ccc9-4777-a0f1-3494ce642014)
+    def test_iot_connection_to_ASUS_RT_AC54U_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="2647c15f-2aad-47d7-8dee-b2ee1ac4cef6")
+    def test_iot_connection_to_ASUS_RT_AC54U_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="99678f66-ddf1-454d-87e4-e55177ec380d")
+    def test_iot_connection_to_ASUS_RT_N56U_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="4dd75e81-9a8e-44fd-9449-09f5ab8a63c3")
+    def test_iot_connection_to_ASUS_RT_N56U_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="315397ce-50d5-4abf-a11c-1abcaef832d3")
+    def test_iot_connection_to_BELKIN_F9K1002v1_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="05ba464a-b1ef-4ac1-a32f-c919ec4aa1dd")
+    def test_iot_connection_to_CISCO_E1200_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="04912868-4a47-40ce-877e-4e4c89849557")
+    def test_iot_connection_to_TP_LINK_C2_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="53517a21-3802-4185-b8bb-6eaace063a42")
+    def test_iot_connection_to_TP_LINK_C2_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="71c08c1c-415d-4da4-a151-feef43fb6ad8")
+    def test_iot_connection_to_ASUS_RT_AC66U_2G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])
+
+    @test_tracker_info(uuid="2322c155-07d1-47c9-bd21-2e358e3df6ee")
+    def test_iot_connection_to_ASUS_RT_AC66U_5G(self):
+        ssid_key = self.current_test_name.replace(self.iot_test_prefix, "")
+        self.connect_to_wifi_network_and_run_iperf(self.ssid_map[ssid_key])