Merge "New test cases and util related to data connection re-establish are added into class Nsa5gDSDSVoiceTest."
diff --git a/LICENSE b/LICENSE
new file mode 100644
index 0000000..7a4a3ea
--- /dev/null
+++ b/LICENSE
@@ -0,0 +1,202 @@
+
+                                 Apache License
+                           Version 2.0, January 2004
+                        http://www.apache.org/licenses/
+
+   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+   1. Definitions.
+
+      "License" shall mean the terms and conditions for use, reproduction,
+      and distribution as defined by Sections 1 through 9 of this document.
+
+      "Licensor" shall mean the copyright owner or entity authorized by
+      the copyright owner that is granting the License.
+
+      "Legal Entity" shall mean the union of the acting entity and all
+      other entities that control, are controlled by, or are under common
+      control with that entity. For the purposes of this definition,
+      "control" means (i) the power, direct or indirect, to cause the
+      direction or management of such entity, whether by contract or
+      otherwise, or (ii) ownership of fifty percent (50%) or more of the
+      outstanding shares, or (iii) beneficial ownership of such entity.
+
+      "You" (or "Your") shall mean an individual or Legal Entity
+      exercising permissions granted by this License.
+
+      "Source" form shall mean the preferred form for making modifications,
+      including but not limited to software source code, documentation
+      source, and configuration files.
+
+      "Object" form shall mean any form resulting from mechanical
+      transformation or translation of a Source form, including but
+      not limited to compiled object code, generated documentation,
+      and conversions to other media types.
+
+      "Work" shall mean the work of authorship, whether in Source or
+      Object form, made available under the License, as indicated by a
+      copyright notice that is included in or attached to the work
+      (an example is provided in the Appendix below).
+
+      "Derivative Works" shall mean any work, whether in Source or Object
+      form, that is based on (or derived from) the Work and for which the
+      editorial revisions, annotations, elaborations, or other modifications
+      represent, as a whole, an original work of authorship. For the purposes
+      of this License, Derivative Works shall not include works that remain
+      separable from, or merely link (or bind by name) to the interfaces of,
+      the Work and Derivative Works thereof.
+
+      "Contribution" shall mean any work of authorship, including
+      the original version of the Work and any modifications or additions
+      to that Work or Derivative Works thereof, that is intentionally
+      submitted to Licensor for inclusion in the Work by the copyright owner
+      or by an individual or Legal Entity authorized to submit on behalf of
+      the copyright owner. For the purposes of this definition, "submitted"
+      means any form of electronic, verbal, or written communication sent
+      to the Licensor or its representatives, including but not limited to
+      communication on electronic mailing lists, source code control systems,
+      and issue tracking systems that are managed by, or on behalf of, the
+      Licensor for the purpose of discussing and improving the Work, but
+      excluding communication that is conspicuously marked or otherwise
+      designated in writing by the copyright owner as "Not a Contribution."
+
+      "Contributor" shall mean Licensor and any individual or Legal Entity
+      on behalf of whom a Contribution has been received by Licensor and
+      subsequently incorporated within the Work.
+
+   2. Grant of Copyright License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      copyright license to reproduce, prepare Derivative Works of,
+      publicly display, publicly perform, sublicense, and distribute the
+      Work and such Derivative Works in Source or Object form.
+
+   3. Grant of Patent License. Subject to the terms and conditions of
+      this License, each Contributor hereby grants to You a perpetual,
+      worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+      (except as stated in this section) patent license to make, have made,
+      use, offer to sell, sell, import, and otherwise transfer the Work,
+      where such license applies only to those patent claims licensable
+      by such Contributor that are necessarily infringed by their
+      Contribution(s) alone or by combination of their Contribution(s)
+      with the Work to which such Contribution(s) was submitted. If You
+      institute patent litigation against any entity (including a
+      cross-claim or counterclaim in a lawsuit) alleging that the Work
+      or a Contribution incorporated within the Work constitutes direct
+      or contributory patent infringement, then any patent licenses
+      granted to You under this License for that Work shall terminate
+      as of the date such litigation is filed.
+
+   4. Redistribution. You may reproduce and distribute copies of the
+      Work or Derivative Works thereof in any medium, with or without
+      modifications, and in Source or Object form, provided that You
+      meet the following conditions:
+
+      (a) You must give any other recipients of the Work or
+          Derivative Works a copy of this License; and
+
+      (b) You must cause any modified files to carry prominent notices
+          stating that You changed the files; and
+
+      (c) You must retain, in the Source form of any Derivative Works
+          that You distribute, all copyright, patent, trademark, and
+          attribution notices from the Source form of the Work,
+          excluding those notices that do not pertain to any part of
+          the Derivative Works; and
+
+      (d) If the Work includes a "NOTICE" text file as part of its
+          distribution, then any Derivative Works that You distribute must
+          include a readable copy of the attribution notices contained
+          within such NOTICE file, excluding those notices that do not
+          pertain to any part of the Derivative Works, in at least one
+          of the following places: within a NOTICE text file distributed
+          as part of the Derivative Works; within the Source form or
+          documentation, if provided along with the Derivative Works; or,
+          within a display generated by the Derivative Works, if and
+          wherever such third-party notices normally appear. The contents
+          of the NOTICE file are for informational purposes only and
+          do not modify the License. You may add Your own attribution
+          notices within Derivative Works that You distribute, alongside
+          or as an addendum to the NOTICE text from the Work, provided
+          that such additional attribution notices cannot be construed
+          as modifying the License.
+
+      You may add Your own copyright statement to Your modifications and
+      may provide additional or different license terms and conditions
+      for use, reproduction, or distribution of Your modifications, or
+      for any such Derivative Works as a whole, provided Your use,
+      reproduction, and distribution of the Work otherwise complies with
+      the conditions stated in this License.
+
+   5. Submission of Contributions. Unless You explicitly state otherwise,
+      any Contribution intentionally submitted for inclusion in the Work
+      by You to the Licensor shall be under the terms and conditions of
+      this License, without any additional terms or conditions.
+      Notwithstanding the above, nothing herein shall supersede or modify
+      the terms of any separate license agreement you may have executed
+      with Licensor regarding such Contributions.
+
+   6. Trademarks. This License does not grant permission to use the trade
+      names, trademarks, service marks, or product names of the Licensor,
+      except as required for reasonable and customary use in describing the
+      origin of the Work and reproducing the content of the NOTICE file.
+
+   7. Disclaimer of Warranty. Unless required by applicable law or
+      agreed to in writing, Licensor provides the Work (and each
+      Contributor provides its Contributions) on an "AS IS" BASIS,
+      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+      implied, including, without limitation, any warranties or conditions
+      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+      PARTICULAR PURPOSE. You are solely responsible for determining the
+      appropriateness of using or redistributing the Work and assume any
+      risks associated with Your exercise of permissions under this License.
+
+   8. Limitation of Liability. In no event and under no legal theory,
+      whether in tort (including negligence), contract, or otherwise,
+      unless required by applicable law (such as deliberate and grossly
+      negligent acts) or agreed to in writing, shall any Contributor be
+      liable to You for damages, including any direct, indirect, special,
+      incidental, or consequential damages of any character arising as a
+      result of this License or out of the use or inability to use the
+      Work (including but not limited to damages for loss of goodwill,
+      work stoppage, computer failure or malfunction, or any and all
+      other commercial damages or losses), even if such Contributor
+      has been advised of the possibility of such damages.
+
+   9. Accepting Warranty or Additional Liability. While redistributing
+      the Work or Derivative Works thereof, You may choose to offer,
+      and charge a fee for, acceptance of support, warranty, indemnity,
+      or other liability obligations and/or rights consistent with this
+      License. However, in accepting such obligations, You may act only
+      on Your own behalf and on Your sole responsibility, not on behalf
+      of any other Contributor, and only if You agree to indemnify,
+      defend, and hold each Contributor harmless for any liability
+      incurred by, or claims asserted against, such Contributor by reason
+      of your accepting any such warranty or additional liability.
+
+   END OF TERMS AND CONDITIONS
+
+   APPENDIX: How to apply the Apache License to your work.
+
+      To apply the Apache License to your work, attach the following
+      boilerplate notice, with the fields enclosed by brackets "[]"
+      replaced with your own identifying information. (Don't include
+      the brackets!)  The text should be enclosed in the appropriate
+      comment syntax for the file format. We also recommend that a
+      file or class name and description of purpose be included on the
+      same "printed page" as the copyright notice for easier
+      identification within third-party archives.
+
+   Copyright [yyyy] [name of copyright owner]
+
+   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.
\ No newline at end of file
diff --git a/acts/framework/acts/controllers/access_point.py b/acts/framework/acts/controllers/access_point.py
index 21e26bb..a2f2840 100755
--- a/acts/framework/acts/controllers/access_point.py
+++ b/acts/framework/acts/controllers/access_point.py
@@ -185,15 +185,14 @@
         ssh_settings: The ssh settings being used by the ssh connection.
         dhcp_settings: The dhcp server settings being used.
     """
-
     def __init__(self, configs):
         """
         Args:
             configs: configs for the access point from config file.
         """
         self.ssh_settings = settings.from_config(configs['ssh_config'])
-        self.log = logger.create_logger(lambda msg: '[Access Point|%s] %s' % (
-            self.ssh_settings.hostname, msg))
+        self.log = logger.create_logger(lambda msg: '[Access Point|%s] %s' %
+                                        (self.ssh_settings.hostname, msg))
         self.device_pdu_config = configs.get('PduDevice', None)
         self.identifier = self.ssh_settings.hostname
 
@@ -429,11 +428,25 @@
     def get_dhcp_logs(self):
         """Get DHCP logs for this AP object.
 
-        This allows consumers of the access point objects validate DHCP
+        This allows consumers of the access point objects to validate DHCP
         behavior.
         """
         return self._dhcp.get_logs()
 
+    def get_hostapd_logs(self):
+        """Get hostapd logs for all interfaces on AP object.
+
+        This allows consumers of the access point objects to validate hostapd
+        behavior.
+
+        Returns: A dict with {interface: log} from hostapd instances.
+        """
+        hostapd_logs = dict()
+        for identifier in self._aps:
+            hostapd_logs[identifier] = self._aps.get(
+                identifier).hostapd.pull_logs()
+        return hostapd_logs
+
     def start_nat(self):
         """Start NAT on the AP.
 
diff --git a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py
index 1d202c6..d50f726 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/lib_controllers/wlan_controller.py
@@ -111,7 +111,12 @@
         net_ifaces = self.device.netstack_controller.list_interfaces()
         wlan_ifaces_by_role = {'client': {}, 'ap': {}}
         for iface in net_ifaces:
-            iface_mac = utils.mac_address_list_to_str(iface['mac'])
+            try:
+                # Some interfaces might not have a MAC
+                iface_mac = utils.mac_address_list_to_str(iface['mac'])
+            except Exception as e:
+                self.log.debug(f'Error {e} getting MAC for iface {iface}')
+                continue
             if iface_mac in wlan_ifaces_by_mac:
                 wlan_ifaces_by_mac[iface_mac]['netstack_id'] = iface['id']
 
diff --git a/acts/framework/acts/controllers/fuchsia_lib/session_manager_lib.py b/acts/framework/acts/controllers/fuchsia_lib/session_manager_lib.py
index 8c4bb55..2593dde 100644
--- a/acts/framework/acts/controllers/fuchsia_lib/session_manager_lib.py
+++ b/acts/framework/acts/controllers/fuchsia_lib/session_manager_lib.py
@@ -33,7 +33,7 @@
         """
         try:
             self.device.ffx_command(
-                "component bind /core/session-manager/session:session")
+                "component start /core/session-manager/session:session")
             return {'error': None, 'result': 'Success'}
         except Exception as e:
             return {'error': e, 'result': None}
diff --git a/acts/framework/acts/controllers/openwrt_lib/network_settings.py b/acts/framework/acts/controllers/openwrt_lib/network_settings.py
index cdf7c36..b3c1e4e 100644
--- a/acts/framework/acts/controllers/openwrt_lib/network_settings.py
+++ b/acts/framework/acts/controllers/openwrt_lib/network_settings.py
@@ -980,9 +980,11 @@
         return tcpdump_remote_path if pull_dir else None
 
     def clear_tcpdump(self):
-        self.ssh.run("killall tpcdump", ignore_status=True)
-        if self.ssh.run("pgrep tpcdump", ignore_status=True).stdout:
+        self.ssh.run("killall tcpdump", ignore_status=True)
+        if self.ssh.run("pgrep tcpdump", ignore_status=True).stdout:
             raise signals.TestFailure("Failed to clean up tcpdump process.")
+        if self.path_exists(TCPDUMP_DIR):
+            self.ssh.run("rm -f  %s/*" % TCPDUMP_DIR)
 
     def _get_tcpdump_pid(self, tcpdump_file_name):
         """Check tcpdump process on OpenWrt."""
diff --git a/acts/framework/tests/acts_utils_test.py b/acts/framework/tests/acts_utils_test.py
index 2c7c8ab..e662db8 100755
--- a/acts/framework/tests/acts_utils_test.py
+++ b/acts/framework/tests/acts_utils_test.py
@@ -72,74 +72,68 @@
 FUCHSIA_INTERFACES = {
     'id':
     '1',
-    'result': [{
-        'features':
-        4,
-        'filepath':
-        '[none]',
-        'id':
-        1,
-        'ipv4_addresses': [[127, 0, 0, 1]],
-        'ipv6_addresses': [[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1]],
-        'is_administrative_status_enabled':
-        True,
-        'is_physical_status_up':
-        True,
-        'mac': [0, 0, 0, 0, 0, 0],
-        'mtu':
-        65536,
-        'name':
-        'lo',
-        'topopath':
-        'loopback'
-    }, {
-        'features':
-        0,
-        'filepath':
-        '/dev/class/ethernet/000',
-        'id':
-        2,
-        'ipv4_addresses': [[100, 127, 110, 79]],
-        'ipv6_addresses':
-        [[254, 128, 0, 0, 0, 0, 0, 0, 198, 109, 60, 117, 44, 236, 29, 114],
-         [36, 1, 250, 0, 4, 128, 122, 0, 141, 79, 133, 255, 204, 92, 120, 126],
-         [36, 1, 250, 0, 4, 128, 122, 0, 4, 89, 185, 147, 252, 191, 20, 25]],
-        'is_administrative_status_enabled':
-        True,
-        'is_physical_status_up':
-        True,
-        'mac': [0, 224, 76, 5, 76, 229],
-        'mtu':
-        1514,
-        'name':
-        'eno1',
-        'topopath':
-        '@/dev/xhci/xhci/usb-bus/001/001/ifc-000/usb-cdc-ecm/ethernet'
-    }, {
-        'features':
-        1,
-        'filepath':
-        '/dev/class/ethernet/001',
-        'id':
-        3,
-        'ipv4_addresses': [],
-        'ipv6_addresses':
-        [[254, 128, 0, 0, 0, 0, 0, 0, 96, 255, 93, 96, 52, 253, 253, 243],
-         [254, 128, 0, 0, 0, 0, 0, 0, 70, 7, 11, 255, 254, 118, 126, 192]],
-        'is_administrative_status_enabled':
-        False,
-        'is_physical_status_up':
-        False,
-        'mac': [68, 7, 11, 118, 126, 192],
-        'mtu':
-        1500,
-        'name':
-        'wlanxc0',
-        'topopath':
-        '@/dev/wifi/wlanphy/wlanif-client/wlan-ethernet/ethernet'
-    }],
+    'result': [
+        {
+            'id': 1,
+            'name': 'lo',
+            'ipv4_addresses': [
+                [127, 0, 0, 1],
+            ],
+            'ipv6_addresses': [
+                [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1],
+            ],
+            'online': True,
+            'mac': [0, 0, 0, 0, 0, 0],
+        },
+        {
+            'id':
+            2,
+            'name':
+            'eno1',
+            'ipv4_addresses': [
+                [100, 127, 110, 79],
+            ],
+            'ipv6_addresses': [
+                [
+                    254, 128, 0, 0, 0, 0, 0, 0, 198, 109, 60, 117, 44, 236, 29,
+                    114
+                ],
+                [
+                    36, 1, 250, 0, 4, 128, 122, 0, 141, 79, 133, 255, 204, 92,
+                    120, 126
+                ],
+                [
+                    36, 1, 250, 0, 4, 128, 122, 0, 4, 89, 185, 147, 252, 191,
+                    20, 25
+                ],
+            ],
+            'online':
+            True,
+            'mac': [0, 224, 76, 5, 76, 229],
+        },
+        {
+            'id':
+            3,
+            'name':
+            'wlanxc0',
+            'ipv4_addresses': [],
+            'ipv6_addresses': [
+                [
+                    254, 128, 0, 0, 0, 0, 0, 0, 96, 255, 93, 96, 52, 253, 253,
+                    243
+                ],
+                [
+                    254, 128, 0, 0, 0, 0, 0, 0, 70, 7, 11, 255, 254, 118, 126,
+                    192
+                ],
+            ],
+            'online':
+            False,
+            'mac': [68, 7, 11, 118, 126, 192],
+        },
+    ],
     'error':
-    None
+    None,
 }
 
 CORRECT_FULL_IP_LIST = {
diff --git a/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py b/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py
index a39eeed..ba05a53 100644
--- a/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/abstract_devices/wlan_device_lib/AbstractDeviceWlanDeviceBaseTest.py
@@ -13,6 +13,9 @@
 #   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 os
+
+from acts import context
 from acts_contrib.test_utils.wifi.WifiBaseTest import WifiBaseTest
 
 from mobly import utils
@@ -54,3 +57,24 @@
 
         if device.hard_reboot_on_fail:
             device.reboot(reboot_type='hard', testbed_pdus=self.pdu_devices)
+
+    def download_ap_logs(self):
+        """Downloads the DHCP and hostapad logs from the access_point.
+
+        Using the current TestClassContext and TestCaseContext this method pulls
+        the DHCP and hostapd logs and outputs them to the correct path.
+        """
+        current_path = context.get_current_context().get_full_output_path()
+        dhcp_full_out_path = os.path.join(current_path, "dhcp_log.txt")
+
+        dhcp_log_file = open(dhcp_full_out_path, 'w')
+        dhcp_log_file.write(self.access_point.get_dhcp_logs())
+        dhcp_log_file.close()
+
+        hostapd_logs = self.access_point.get_hostapd_logs()
+        for interface in hostapd_logs:
+            out_name = interface + "_hostapd_log.txt"
+            hostapd_full_out_path = os.path.join(current_path, out_name)
+            hostapd_log_file = open(hostapd_full_out_path, 'w')
+            hostapd_log_file.write(hostapd_logs[interface])
+            hostapd_log_file.close()
diff --git a/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py b/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py
index 4ee6b16..9ff86be 100644
--- a/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/tel/GFTInOutBaseTest.py
@@ -126,7 +126,7 @@
                 adjust_gradually = self.user_params.get('adjust_gradually')
             if adjust_gradually:
                 self.log.info("adjust wifi signal set mini-circuits to %s" %(power))
-                self.adjust_atten_slowly(10, NO_SERVICE_AREA)
+                self.adjust_atten_slowly(10, NO_WIFI_AREA)
             else:
                 self.log.info("adjust wifi signal and set mini-circuits to %s" %(power))
                 self.attenuators[WIFI_PORT].set_atten(power)
@@ -175,7 +175,7 @@
         """adjust attenuator slowly
         Args:
             adjust_level: adjust power level for each cycle
-            move_to: no service area, in service area, wifi area
+            move_to: NO_SERVICE_AREA, IN_SERVICE_AREA , WIFI_AREA, NO_WIFI_AREA
             step: adjust attenuator how many time
             step_time: wait for how many sec for each loop
         Returns:
@@ -225,7 +225,7 @@
         return True
 
     def verify_device_status(self, ad, call_type=None, end_call=True,
-        talk_time=30, verify_data=True, verify_voice=True, retry=True, data_retries=2):
+        talk_time=30, verify_data=True, verify_voice=True, data_retries=2, voice_retries=2):
         """verfiy device status includes network service, data connection and voice call
         Args:
             ad: android device
@@ -234,37 +234,39 @@
             talk_time: in call duration in sec
             verify_data: flag to check data connection
             verify_voice: flag to check voice
+            data_retries: retry times for data verification
+            voice_retris:retry times for voice call
         Returns:
             return True if pass
         """
-        test_result = True
         tasks = [(check_network_service, (ad, )) for ad in self.android_devices]
         if not multithread_func(self.log, tasks):
             log_screen_shot(ad, "check_network_service_fail")
-            ad.log.info("check_network_service_fail")
-            test_result = False
-        if retry:
-            if call_type:
-                tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time, 3))
-                    for ad in self.android_devices]
-                test_result = multithread_func(self.log, tasks)
-        elif verify_data and test_result:
+            ad.log.info("check_network_service fail")
+            return False
+        else:
+            self.log.info("check_network_service pass")
+        if verify_data:
             tasks = [(verify_data_connection, (ad, data_retries ))
                 for ad in self.android_devices]
             if not multithread_func(self.log, tasks):
                 log_screen_shot(ad, "verify_data_connection_fail")
                 ad.log.info("verify_data_connection_fail")
-                test_result = False
-        elif verify_voice and test_result:
+                return False
+            else:
+                self.log.info("verify_data_connection pass")
+        if verify_voice:
             if call_type:
-                tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time))
-                    for ad in self.android_devices]
+                tasks = [(mo_voice_call, (self.log, ad, call_type, end_call, talk_time,
+                    voice_retries)) for ad in self.android_devices]
             if not multithread_func(self.log, tasks):
                 log_screen_shot(ad, "verify_voice_call_fail")
                 ad.log.info("verify_voice_call_fail")
-                test_result = False
-        return test_result
-
+                return False
+            else:
+                self.log.info("verify_voice_call pass")
+                return True
+        return True
 
     def _on_failure(self, error_msg="", assert_on_fail=True, test_result=False):
         """ operation on fail
@@ -279,3 +281,4 @@
         for ad in self.android_devices:
             log_screen_shot(ad, error_msg)
         self.log.info(error_msg)
+
diff --git a/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py b/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py
index 45edc1f..ca65cb8 100644
--- a/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py
+++ b/acts_tests/acts_contrib/test_utils/tel/TelephonyBaseTest.py
@@ -504,6 +504,9 @@
 
     def on_fail(self, test_name, begin_time):
         for ad in self.android_devices:
+            # open Phone information page
+            ad.adb.shell("am start -n com.android.phone/.settings.RadioInfo")
+            time.sleep(3)
             ad.screenshot(f"{ad.serial}_last_screen")
         self._take_bug_report(test_name, begin_time)
 
diff --git a/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py b/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py
index 58ee339..2e4cfd4 100644
--- a/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/gft_inout_utils.py
@@ -45,6 +45,7 @@
         Returns:
             True if pass; False if fail.
     """
+
     for i in range (timeout):
         service_state = get_service_state_by_adb(ad.log,ad)
         if service_state != SERVICE_STATE_IN_SERVICE:
@@ -301,7 +302,4 @@
             ad.log.info("Ping fail!")
             return False
     else:
-        ad.log.info("Successful to browse websites!")
-
-
-
+        ad.log.info("Successful to browse websites!")
\ No newline at end of file
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py
index 13838d2..0153087 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_5g_test_utils.py
@@ -65,19 +65,22 @@
     return True
 
 
-def provision_device_for_5g_nsa(log, ads, nr_type=None):
+def provision_device_for_5g_nsa(log, ads, sub_id = None, mmwave = None):
     """Provision Devices for 5G NSA
 
     Args:
         log: Log object.
         ads: android device object(s).
-        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
-                wave
+        sub_id: The target SIM for querying.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
 
     Returns:
         True: Device(s) are provisioned on 5G NSA
         False: Device(s) are not provisioned on 5G NSA
     """
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
     if isinstance(ads, list):
         # Mode Pref
         tasks = [(set_preferred_mode_for_5g, [ad]) for ad in ads]
@@ -85,7 +88,7 @@
             log.error("failed to set preferred network mode on 5g")
             return False
         # Attach
-        tasks = [(is_current_network_5g_nsa, [ad, nr_type]) for ad in ads]
+        tasks = [(is_current_network_5g_nsa, [ad, sub_id, mmwave]) for ad in ads]
         if not multithread_func(log, tasks):
             log.error("phone not on 5g")
             return False
@@ -95,7 +98,7 @@
         set_preferred_mode_for_5g(ads)
 
         # Attach nsa5g
-        if not is_current_network_5g_nsa(ads, nr_type):
+        if not is_current_network_5g_nsa(ads, sub_id, mmwave):
             ads.log.error("Phone not attached on 5g")
             return False
         return True
@@ -177,29 +180,35 @@
     return True
 
 
-def verify_5g_attach_for_both_devices(log, ads, nr_type=None):
+def verify_5g_attach_for_both_devices(log, ads, sub_id = None, nr_type = None,
+                                      mmwave = None):
     """Verify the network is attached
 
     Args:
         log: Log object.
         ads: android device object(s).
-        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
-                wave
+        sub_id: The target SIM for querying.
+        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone,
+            'mmwave' for 5G millimeter wave.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
 
     Returns:
         True: Device(s) are attached on 5G
         False: Device(s) are not attached on 5G NSA
     """
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
     if nr_type=='sa':
         # Attach
-        tasks = [(is_current_network_5g_sa, [ad]) for ad in ads]
+        tasks = [(is_current_network_5g_sa, [ad, sub_id, mmwave]) for ad in ads]
         if not multithread_func(log, tasks):
             log.error("phone not on 5g sa")
             return False
         return True
     else:
         # Attach
-        tasks = [(is_current_network_5g_nsa, [ad, nr_type]) for ad in ads]
+        tasks = [(is_current_network_5g_nsa, [ad, sub_id, mmwave]) for ad in ads]
         if not multithread_func(log, tasks):
             log.error("phone not on 5g nsa")
             return False
@@ -220,17 +229,22 @@
     return set_preferred_network_mode_pref(ad.log, ad, sub_id, mode)
 
 
-def provision_device_for_5g_sa(log, ads):
+def provision_device_for_5g_sa(log, ads, sub_id = None, mmwave = None):
     """Provision Devices for 5G SA
 
     Args:
         log: Log object.
         ads: android device object(s).
+        sub_id: The target SIM for querying.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
 
     Returns:
         True: Device(s) are provisioned on 5G SA
         False: Device(s) are not provisioned on 5G SA
     """
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
     if isinstance(ads, list):
         # Mode Pref
         tasks = [(set_preferred_mode_for_5g, [ad, None, NETWORK_MODE_NR_ONLY]) for ad in ads]
@@ -238,7 +252,7 @@
             log.error("failed to set preferred network mode on 5g SA")
             return False
 
-        tasks = [(is_current_network_5g_sa, [ad]) for ad in ads]
+        tasks = [(is_current_network_5g_sa, [ad, sub_id, mmwave]) for ad in ads]
         if not multithread_func(log, tasks):
             log.error("phone not on 5g SA")
             return False
@@ -247,46 +261,59 @@
         # Mode Pref
         set_preferred_mode_for_5g(ads, None, NETWORK_MODE_NR_ONLY)
 
-        if not is_current_network_5g_sa(ads):
+        if not is_current_network_5g_sa(ads, sub_id, mmwave):
             ads.log.error("Phone not attached on SA 5g")
             return False
         return True
 
 
-def check_current_network_5g(ad, timeout=30, nr_type=None):
+def check_current_network_5g(
+    ad, sub_id = None, nr_type = None, mmwave = None, timeout = 30):
     """Verifies data network type is on 5G
 
     Args:
         ad: android device object.
+        sub_id: The target SIM for querying.
         timeout: max time to wait for event
         nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
-                wave
+                wave.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
 
     Returns:
         True: if data is on 5g
         False: if data is not on 5g
     """
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
     if nr_type == 'sa':
-        if not is_current_network_5g_sa(ad):
+        if not is_current_network_5g_sa(ad, sub_id, mmwave=mmwave):
             return False
     else:
-        if not is_current_network_5g_nsa(ad, nr_type= nr_type, timeout=timeout):
+        if not is_current_network_5g_nsa(ad, sub_id, mmwave=mmwave,
+                                         timeout=timeout):
             return False
     return True
 
 
-def test_activation_by_condition(ad, from_3g=False, nr_type=None, precond_func=None):
+def test_activation_by_condition(ad, sub_id=None, from_3g=False, nr_type=None,
+                                 precond_func=None, mmwave=None):
     """Test 5G activation based on various pre-conditions.
 
     Args:
         ad: android device object.
+        sub_id: The target SIM for querying.
         from_3g: If true, test 5G activation from 3G attaching. Otherwise, starting from 5G attaching.
         nr_type: check the band of NR network. Default is to check sub-6.
         precond_func: A function to execute pre conditions before testing 5G activation.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
 
     Returns:
         If success, return true. Otherwise, return false.
     """
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
     wifi_toggle_state(ad.log, ad, False)
     toggle_airplane_mode(ad.log, ad, False)
     if not from_3g:
@@ -313,7 +340,7 @@
             ad.log.error("Fail to ensure initial data in 4G")
         # 5G attach
         ad.log.info("Waiting for 5g NSA attach for 60 secs")
-        if is_current_network_5g_nsa(ad, nr_type= nr_type, timeout=60):
+        if is_current_network_5g_nsa(ad, sub_id, mmwave=mmwave, timeout=60):
             ad.log.info("Success! attached on 5g NSA")
             return True
         else:
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py
index 58ce9ee..f35272e 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_5g_utils.py
@@ -19,140 +19,121 @@
 from acts_contrib.test_utils.tel.tel_defines import DisplayInfoContainer
 from acts_contrib.test_utils.tel.tel_defines import EventDisplayInfoChanged
 
-def is_current_network_5g_nsa(ad, nr_type=None, timeout=30):
+def is_current_network_5g_nsa(ad, sub_id = None, mmwave = None, timeout=30):
     """Verifies 5G NSA override network type
     Args:
         ad: android device object.
-        nr_type: 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
-                wave
+        sub_id: The target SIM for querying.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
         timeout: max time to wait for event.
 
     Returns:
         True: if data is on nsa5g NSA
         False: if data is not on nsa5g NSA
     """
-    ad.ed.clear_events(EventDisplayInfoChanged)
-    ad.droid.telephonyStartTrackingDisplayInfoChange()
-    if nr_type == 'mmwave':
-        nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE
-    elif nr_type == 'nsa':
-        nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
+    def _nsa_display_monitor(ad, sub_id, mmwave, timeout):
+        ad.ed.clear_events(EventDisplayInfoChanged)
+        ad.droid.telephonyStartTrackingDisplayInfoChangeForSubscription(sub_id)
+        if mmwave:
+            nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_MMWAVE
+        else:
+            nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA
+        try:
+            event = ad.ed.wait_for_event(
+                    EventDisplayInfoChanged,
+                    ad.ed.is_event_match,
+                    timeout=timeout,
+                    field=DisplayInfoContainer.OVERRIDE,
+                    value=nsa_band)
+            ad.log.info("Got expected event %s", event)
+            return True
+        except Empty:
+            ad.log.info("No event for display info change with <%s>", nsa_band)
+            ad.screenshot("5g_nsa_icon_checking")
+            return False
+        finally:
+            ad.droid.telephonyStopTrackingServiceStateChangeForSubscription(
+                sub_id)
+
+    if mmwave is None:
+        return _nsa_display_monitor(
+            ad, sub_id, mmwave=False, timeout=timeout) or _nsa_display_monitor(
+            ad, sub_id, mmwave=True, timeout=timeout)
     else:
-        nsa_band = OverrideNetworkContainer.OVERRIDE_NETWORK_TYPE_NR_NSA
-    try:
-        event = ad.ed.wait_for_event(
-                EventDisplayInfoChanged,
-                ad.ed.is_event_match,
-                timeout=timeout,
-                field=DisplayInfoContainer.OVERRIDE,
-                value=nsa_band)
-        ad.log.info("Got expected event %s", event)
-        return True
-    except Empty:
-        ad.log.info("No event for display info change")
-        ad.screenshot("5g_nsa_icon_checking")
-        return False
-    finally:
-        ad.droid.telephonyStopTrackingDisplayInfoChange()
-    return None
+        return _nsa_display_monitor(ad, sub_id, mmwave, timeout)
 
 
-def is_current_network_5g_nsa_for_subscription(ad, nr_type=None, timeout=30, sub_id=None):
-    """Verifies 5G NSA override network type for subscription id.
-    Args:
-        ad: android device object.
-        nr_type: 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter wave
-        timeout: max time to wait for event.
-        sub_id: subscription id.
-
-    Returns:
-        True: if data is on nsa5g NSA
-        False: if data is not on nsa5g NSA
-    """
-    if not sub_id:
-        return is_current_network_5g_nsa(ad, nr_type=nr_type)
-
-    voice_sub_id_changed = False
-    current_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
-    if current_sub_id != sub_id:
-        ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
-        voice_sub_id_changed = True
-
-    result = is_current_network_5g_nsa(ad, nr_type=nr_type)
-
-    if voice_sub_id_changed:
-        ad.droid.subscriptionSetDefaultVoiceSubId(current_sub_id)
-
-    return result
-
-
-def is_current_network_5g_sa(ad):
+def is_current_network_5g_sa(ad, sub_id = None, mmwave = None):
     """Verifies 5G SA override network type
 
     Args:
         ad: android device object.
+        sub_id: The target SIM for querying.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
 
     Returns:
         True: if data is on 5g SA
         False: if data is not on 5g SA
     """
-    network_connected = ad.droid.telephonyGetCurrentDataNetworkType()
-    if network_connected == 'NR':
-        ad.log.debug("Network is currently connected to %s", network_connected)
-        return True
-    else:
-        ad.log.error("Network is currently connected to %s, Expected on NR", network_connected)
-        ad.screenshot("5g_sa_icon_checking")
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+    current_rat = ad.droid.telephonyGetCurrentDataNetworkTypeForSubscription(
+        sub_id)
+    # TODO(richardwychang): check SA MMWAVE when function ready.
+    sa_type = ['NR',]
+    if mmwave is None:
+        if current_rat in sa_type:
+            ad.log.debug("Network is currently connected to %s", current_rat)
+            return True
+        else:
+            ad.log.error(
+                "Network is currently connected to %s, Expected on %s",
+                current_rat, sa_type)
+            ad.screenshot("5g_sa_icon_checking")
+            return False
+    elif mmwave:
+        ad.log.error("SA MMWAVE currently not support.")
         return False
+    else:
+        if current_rat == 'NR':
+            ad.log.debug("Network is currently connected to %s", current_rat)
+            return True
+        else:
+            ad.log.error(
+                "Network is currently connected to %s, Expected on NR",
+                current_rat)
+            ad.screenshot("5g_sa_icon_checking")
+            return False
 
 
-def is_current_network_5g(ad, nr_type=None, timeout=30):
+def is_current_network_5g(ad, sub_id = None, nr_type = None, mmwave = None,
+                          timeout = 30):
     """Verifies 5G override network type
 
     Args:
         ad: android device object
-        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
-                wave
+        sub_id: The target SIM for querying.
+        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone.
+        mmwave: True to detect 5G millimeter wave, False to detect sub-6,
+            None to detect both.
         timeout: max time to wait for event.
 
     Returns:
         True: if data is on 5G regardless of SA or NSA
         False: if data is not on 5G refardless of SA or NSA
     """
+    sub_id = sub_id if sub_id else ad.droid.subscriptionGetDefaultDataSubId()
+
     if nr_type == 'nsa':
-        return is_current_network_5g_nsa(ad, nr_type = 'nsa', timeout=timeout)
+        return is_current_network_5g_nsa(
+            ad, sub_id=sub_id, mmwave=mmwave, timeout=timeout)
     elif nr_type == 'sa':
-        return is_current_network_5g_sa(ad)
-    elif nr_type == 'mmwave':
-        return is_current_network_5g_nsa(ad, nr_type = 'mmwave', timeout=timeout)
+        return is_current_network_5g_sa(ad, sub_id=sub_id, mmwave=mmwave)
     else:
-        return is_current_network_5g_nsa(ad, nr_type=None) or is_current_network_5g_sa(ad)
-
-
-def is_current_network_5g_for_subscription(ad, sub_id=None, nr_type=None):
-    """Verifies 5G override network type for subscription id.
-    Args:
-        ad: android device object
-        sub_id: subscription id
-        nr_type: 'sa' for 5G standalone, 'nsa' for 5G non-standalone, 'mmwave' for 5G millimeter
-                wave
-
-    Returns:
-        True: if data is on 5G regardless of NSA or SA.
-        False: if data is not on 5G regardless of NSA or SA.
-    """
-    if not sub_id:
-        return is_current_network_5g(ad, nr_type=nr_type)
-
-    voice_sub_id_changed = False
-    current_sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
-    if current_sub_id != sub_id:
-        ad.droid.subscriptionSetDefaultVoiceSubId(sub_id)
-        voice_sub_id_changed = True
-
-    result = is_current_network_5g(ad, nr_type=nr_type)
-
-    if voice_sub_id_changed:
-        ad.droid.subscriptionSetDefaultVoiceSubId(current_sub_id)
-
-    return result
+        return is_current_network_5g_nsa(
+            ad, sub_id=sub_id, mmwave=mmwave,
+            timeout=timeout) or is_current_network_5g_sa(
+                ad, sub_id=sub_id, mmwave=mmwave)
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py
index 64f3b55..05808f9 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_data_utils.py
@@ -527,7 +527,7 @@
             return False
 
         if nw_gen == GEN_5G:
-            if not check_current_network_5g(ad, timeout=60, nr_type=nr_type):
+            if not check_current_network_5g(ad, nr_type=nr_type, timeout=60):
                 return False
         else:
             if not is_droid_in_network_generation_for_subscription(
@@ -876,7 +876,7 @@
     ensure_phones_idle(log, ad_list)
 
     if nw_gen == GEN_5G:
-        if not provision_device_for_5g(log, android_devices, nr_type= nr_type):
+        if not provision_device_for_5g(log, android_devices, nr_type=nr_type):
             return False
     elif nw_gen:
         if not ensure_network_generation_for_subscription(
@@ -1032,7 +1032,7 @@
     ensure_phones_idle(log, clients)
     wifi_toggle_state(log, provider, False)
     if network_generation == RAT_5G:
-        if not provision_device_for_5g(log, provider, nr_type= nr_type):
+        if not provision_device_for_5g(log, provider, nr_type=nr_type):
             return False
     elif network_generation:
         if not ensure_network_generation(
@@ -1102,7 +1102,7 @@
         return False
 
     if provider_setup_func == RAT_5G:
-        if not provision_device_for_5g(log, provider, nr_type= nr_type):
+        if not provision_device_for_5g(log, provider, nr_type=nr_type):
             return False
     try:
         log.info("1. Setup WiFi Tethering.")
@@ -1249,7 +1249,7 @@
                                    wait_time_in_call)
 
     if nw_gen == GEN_5G:
-        if not provision_device_for_5g(log, ads[0], nr_type= nr_type):
+        if not provision_device_for_5g(log, ads[0], nr_type=nr_type):
             return False
     elif nw_gen:
         if not ensure_network_generation(log, ads[0], nw_gen,
@@ -1304,7 +1304,8 @@
             return False
     # Disable airplane mode if test under apm on.
     toggle_airplane_mode(log, ads[0], False)
-    if nw_gen == GEN_5G and not check_current_network_5g(ads[0], nr_type= nr_type):
+    if nw_gen == GEN_5G and not check_current_network_5g(ads[0],
+                                                         nr_type=nr_type):
         ads[0].log.error("Phone not attached on 5G after call.")
         return False
     return True
@@ -1335,7 +1336,7 @@
         False if failed.
     """
     if nw_gen == GEN_5G:
-        if not provision_device_for_5g(log, ads[0], nr_type= nr_type):
+        if not provision_device_for_5g(log, ads[0], nr_type=nr_type):
             return False
     elif nw_gen:
         if not ensure_network_generation(log, ads[0], nw_gen,
@@ -1382,7 +1383,8 @@
     ad_download.force_stop_apk("com.google.android.youtube")
     # Disable airplane mode if test under apm on.
     toggle_airplane_mode(log, ads[0], False)
-    if nw_gen == GEN_5G and not check_current_network_5g(ads[0], nr_type= nr_type):
+    if nw_gen == GEN_5G and not check_current_network_5g(ads[0],
+                                                         nr_type=nr_type):
         ads[0].log.error("Phone not attached on 5G after call.")
         result = False
     return result
@@ -1452,7 +1454,8 @@
 
     time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)
 
-    if nw_gen == GEN_5G and not verify_5g_attach_for_both_devices(log, ads, nr_type= nr_type):
+    if nw_gen == GEN_5G and not verify_5g_attach_for_both_devices(
+        log, ads, nr_type=nr_type):
         log.error("Phone not attached on 5G after epdg call.")
         return False
 
@@ -1553,7 +1556,7 @@
                         ssid=None,
                         password=None,
                         pre_teardown_func=None,
-                        nr_type= None):
+                        nr_type=None):
     """WiFi Tethering test
     Args:
         log: log object.
@@ -1579,7 +1582,7 @@
         nr_type: NR network type e.g. NSA, SA, MMWAVE.
 
     """
-    if not test_setup_tethering(log, provider, clients, nw_gen, nr_type= nr_type):
+    if not test_setup_tethering(log, provider, clients, nw_gen, nr_type=nr_type):
         log.error("Verify %s Internet access failed.", nw_gen)
         return False
 
@@ -1880,7 +1883,7 @@
                                              provider,
                                              clients,
                                              new_gen=None,
-                                             nr_type= None):
+                                             nr_type=None):
     """Verify toggle Data network during WiFi Tethering.
     Args:
         log: log object.
@@ -1905,7 +1908,7 @@
                                    check_iteration=2,
                                    do_cleanup=False,
                                    ssid=ssid,
-                                   nr_type= nr_type):
+                                   nr_type=nr_type):
             log.error("WiFi Tethering failed.")
             return False
         if not provider.droid.wifiIsApEnabled():
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py
index fdfda44..1cb6bb5 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_logging_utils.py
@@ -118,6 +118,7 @@
 
 def stop_sdm_logger(ad):
     """Stop SDM logger."""
+    ad.sdm_log_path = DEFAULT_SDM_LOG_PATH
     cycle = 1
 
     ad.log.debug("stop sdm logging")
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py
index f9e1712..6077d9c 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_phone_setup_utils.py
@@ -50,7 +50,7 @@
 from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_ANDROID_STATE_SETTLING
 from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_DISABLED
 from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g_for_subscription
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
 from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
 from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte_for_subscription
 from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
@@ -753,8 +753,7 @@
         nr_type: NR network type e.g. NSA, SA, MMWAVE
     """
     if nw_gen == GEN_5G:
-        if not is_current_network_5g_for_subscription(ad, sub_id=sub_id,
-                                            nr_type=nr_type):
+        if not is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
             ad.log.error("Not in 5G coverage.")
             return False
     else:
@@ -839,7 +838,7 @@
         nw_gen: GEN_4G or GEN_5G
     """
     if nw_gen == GEN_5G:
-        if not is_current_network_5g_for_subscription(ad, sub_id=sub_id, nr_type=nr_type):
+        if not is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
             ad.log.error("Not in 5G coverage.")
             return False
     else:
@@ -1406,8 +1405,7 @@
         return True
 
     if (generation == GEN_5G) or (generation == RAT_5G):
-        if is_current_network_5g_for_subscription(ad, sub_id=sub_id,
-                                        nr_type=nr_type):
+        if is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
             ad.log.info("Current network type is 5G.")
             return True
         else:
@@ -1532,7 +1530,7 @@
         nr_type=None):
 
     if generation == GEN_5G:
-        if is_current_network_5g_for_subscription(ad, sub_id=sub_id, nr_type=nr_type):
+        if is_current_network_5g(ad, sub_id=sub_id, nr_type=nr_type):
             ad.log.info("Current network type is 5G.")
             return True
         else:
diff --git a/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py b/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
index b1b1626..ac6f1f9 100644
--- a/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
+++ b/acts_tests/acts_contrib/test_utils/tel/tel_voice_utils.py
@@ -64,7 +64,6 @@
 from acts_contrib.test_utils.tel.tel_defines import EventMessageWaitingIndicatorChanged
 from acts_contrib.test_utils.tel.tel_defines import CallStateContainer
 from acts_contrib.test_utils.tel.tel_defines import MessageWaitingIndicatorContainer
-from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
 from acts_contrib.test_utils.tel.tel_ims_utils import is_wfc_enabled
 from acts_contrib.test_utils.tel.tel_ims_utils import toggle_volte
 from acts_contrib.test_utils.tel.tel_ims_utils import toggle_wfc
@@ -351,15 +350,8 @@
                   ad,
                   callee_number,
                   emergency=False,
-                  timeout=MAX_WAIT_TIME_CALL_INITIATION,
-                  checking_interval=5,
                   incall_ui_display=INCALL_UI_DISPLAY_FOREGROUND,
-                  video=False,
-                  voice_type_init=None,
-                  call_stats_check=False,
-                  result_info=result_dict,
-                  nw_gen_5g=False,
-                  nr_type= None):
+                  video=False):
     """Make phone call from caller to callee.
 
     Args:
@@ -400,10 +392,6 @@
             ad.adb.shell("i2cset -fy 3 65 6 1 b", ignore_status=True)
         ad.droid.telephonyStopTrackingCallStateChangeForSubscription(sub_id)
 
-        if nw_gen_5g:
-            if not is_current_network_5g(ad, nr_type= nr_type):
-                ad.log.error("Phone is not attached on 5G")
-
         if incall_ui_display == INCALL_UI_DISPLAY_FOREGROUND:
             ad.droid.telecomShowInCallScreen()
         elif incall_ui_display == INCALL_UI_DISPLAY_BACKGROUND:
@@ -738,9 +726,7 @@
                         slot_id_callee=None,
                         voice_type_init=None,
                         call_stats_check=False,
-                        result_info=result_dict,
-                        nsa_5g_for_stress=False,
-                        nr_type= None):
+                        result_info=result_dict):
     """ Call process, including make a phone call from caller,
     accept from callee, and hang up. The call is on default voice subscription
 
@@ -779,8 +765,7 @@
         log, ad_caller, ad_callee, subid_caller, subid_callee, ad_hangup,
         verify_caller_func, verify_callee_func, wait_time_in_call,
         incall_ui_display, dialing_number_length, video_state,
-        voice_type_init, call_stats_check, result_info, nsa_5g_for_stress,
-        nr_type)
+        voice_type_init, call_stats_check, result_info)
 
 
 def call_setup_teardown_for_subscription(
@@ -798,9 +783,7 @@
         video_state=None,
         voice_type_init=None,
         call_stats_check=False,
-        result_info=result_dict,
-        nsa_5g_for_stress=False,
-        nr_type= None):
+        result_info=result_dict):
     """ Call process, including make a phone call from caller,
     accept from callee, and hang up. The call is on specified subscription
 
@@ -992,11 +975,6 @@
                 except Exception as e:
                     log.error(str(e))
 
-        if nsa_5g_for_stress:
-            for ad in (ad_caller, ad_callee):
-                if not is_current_network_5g(ad, nr_type):
-                    ad.log.error("Phone not attached on 5G")
-
         if ad_hangup or not tel_result_wrapper:
             for ad in (ad_caller, ad_callee):
                 if not wait_for_call_id_clearing(
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py
index 65f1c9a..962c1bf 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/VapeInteropTest.py
@@ -75,6 +75,7 @@
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
         self.dut.reset_wifi()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py
index fa4e13a..04adfab 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11ACTest.py
@@ -159,6 +159,7 @@
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
         self.dut.reset_wifi()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py
index 08b2cc6..ad0800f 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyCompliance11NTest.py
@@ -122,6 +122,7 @@
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
         self.dut.reset_wifi()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py
index 3dac3f9..2d17f4b 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanPhyComplianceABGTest.py
@@ -123,6 +123,7 @@
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
         self.dut.reset_wifi()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py
index 22bcfdc..a32c7c4 100644
--- a/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/compliance/WlanSecurityComplianceABGTest.py
@@ -201,6 +201,7 @@
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
         self.dut.reset_wifi()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py
index f99e610..a2a763b 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/BeaconLossTest.py
@@ -70,7 +70,7 @@
         else:
             # Default is an android device, just like the other tests
             self.dut = create_wlan_device(self.android_devices[0])
-        self.ap = self.access_points[0]
+        self.access_point = self.access_points[0]
         self.num_of_iterations = int(
             self.user_params.get("beacon_loss_test_iterations",
                                  self.num_of_iterations))
@@ -80,23 +80,25 @@
         self.dut.disconnect()
         self.dut.reset_wifi()
         # ensure radio is on, in case the test failed while the radio was off
-        self.ap.iwconfig.ap_iwconfig(self.in_use_interface, "txpower on")
-        self.ap.stop_all_aps()
+        self.access_point.iwconfig.ap_iwconfig(self.in_use_interface,
+                                               "txpower on")
+        self.download_ap_logs()
+        self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
         super().on_fail(test_name, begin_time)
-        self.ap.stop_all_aps()
+        self.access_point.stop_all_aps()
 
     def beacon_loss(self, channel):
-        setup_ap(access_point=self.ap,
+        setup_ap(access_point=self.access_point,
                  profile_name='whirlwind',
                  channel=channel,
                  ssid=self.ssid)
         time.sleep(self.wait_ap_startup_s)
         if channel > 14:
-            self.in_use_interface = self.ap.wlan_5g
+            self.in_use_interface = self.access_point.wlan_5g
         else:
-            self.in_use_interface = self.ap.wlan_2g
+            self.in_use_interface = self.access_point.wlan_2g
 
         # TODO(b/144505723): [ACTS] update BeaconLossTest.py to handle client
         # roaming, saved networks, etc.
@@ -110,7 +112,8 @@
         for _ in range(0, self.num_of_iterations):
             # Turn off AP radio
             self.log.info("turning off radio")
-            self.ap.iwconfig.ap_iwconfig(self.in_use_interface, "txpower off")
+            self.access_point.iwconfig.ap_iwconfig(self.in_use_interface,
+                                                   "txpower off")
             time.sleep(self.wait_after_ap_txoff_s)
 
             # Did we disconnect from AP?
@@ -119,7 +122,8 @@
 
             # Turn on AP radio
             self.log.info("turning on radio")
-            self.ap.iwconfig.ap_iwconfig(self.in_use_interface, "txpower on")
+            self.access_point.iwconfig.ap_iwconfig(self.in_use_interface,
+                                                   "txpower on")
             time.sleep(self.wait_to_connect_after_ap_txon_s)
 
             # Tell the client to connect
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py
index ccaa37a..be8e3ca 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/ChannelSwitchTest.py
@@ -57,14 +57,15 @@
         else:
             # Default is an android device, just like the other tests
             self.dut = create_wlan_device(self.android_devices[0])
-        self.ap = self.access_points[0]
+        self.access_point = self.access_points[0]
         self._stop_all_soft_aps()
         self.in_use_interface = None
 
     def teardown_test(self) -> None:
         self.dut.disconnect()
         self.dut.reset_wifi()
-        self.ap.stop_all_aps()
+        self.download_ap_logs()
+        self.access_point.stop_all_aps()
 
     # TODO(fxbug.dev/85738): Change band type to an enum.
     def channel_switch(self,
@@ -98,15 +99,15 @@
 
         self.current_channel_num = starting_channel
         if band == hostapd_constants.BAND_5G:
-            self.in_use_interface = self.ap.wlan_5g
+            self.in_use_interface = self.access_point.wlan_5g
         elif band == hostapd_constants.BAND_2G:
-            self.in_use_interface = self.ap.wlan_2g
+            self.in_use_interface = self.access_point.wlan_2g
         asserts.assert_true(
             self._channels_valid_for_band([self.current_channel_num], band),
             'starting channel {} not a valid channel for band {}'.format(
                 self.current_channel_num, band))
 
-        setup_ap(access_point=self.ap,
+        setup_ap(access_point=self.access_point,
                  profile_name='whirlwind',
                  channel=self.current_channel_num,
                  ssid=self.ssid)
@@ -128,8 +129,9 @@
                 continue
             self.log.info('channel switch: {} -> {}'.format(
                 self.current_channel_num, channel_num))
-            self.ap.channel_switch(self.in_use_interface, channel_num)
-            channel_num_after_switch = self.ap.get_current_channel(
+            self.access_point.channel_switch(self.in_use_interface,
+                                             channel_num)
+            channel_num_after_switch = self.access_point.get_current_channel(
                 self.in_use_interface)
             asserts.assert_true(channel_num_after_switch == channel_num,
                                 'AP failed to channel switch')
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py
index 640792a..64fc144 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/ConnectionStressTest.py
@@ -46,7 +46,7 @@
         self.ssid = rand_ascii_str(10)
         self.fd = self.fuchsia_devices[0]
         self.dut = create_wlan_device(self.fd)
-        self.ap = self.access_points[0]
+        self.access_point = self.access_points[0]
         self.num_of_iterations = int(
             self.user_params.get("connection_stress_test_iterations",
                                  self.num_of_iterations))
@@ -54,11 +54,12 @@
 
     def teardown_test(self):
         self.dut.reset_wifi()
-        self.ap.stop_all_aps()
+        self.download_ap_logs()
+        self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
         super().on_fail(test_name, begin_time)
-        self.ap.stop_all_aps()
+        self.access_point.stop_all_aps()
 
     def start_ap(self, profile, channel, security=None):
         """Starts an Access Point
@@ -68,7 +69,7 @@
             channel: Channel to operate on
         """
         self.log.info('Profile: %s, Channel: %d' % (profile, channel))
-        setup_ap(access_point=self.ap,
+        setup_ap(access_point=self.access_point,
                  profile_name=profile,
                  channel=channel,
                  ssid=self.ssid,
@@ -131,7 +132,7 @@
             time.sleep(1)
 
         # Stop AP
-        self.ap.stop_all_aps()
+        self.access_point.stop_all_aps()
         if failed:
             raise signals.TestFailure(
                 'One or more association attempt failed.')
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py
index 5027ddf..5ec6290 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/DownloadStressTest.py
@@ -56,12 +56,12 @@
         super().setup_class()
         self.ssid = rand_ascii_str(10)
         self.dut = create_wlan_device(self.fuchsia_devices[0])
-        self.ap = self.access_points[0]
+        self.access_point = self.access_points[0]
         self.num_of_iterations = int(
             self.user_params.get("download_stress_test_iterations",
                                  self.num_of_iterations))
 
-        setup_ap(access_point=self.ap,
+        setup_ap(access_point=self.access_point,
                  profile_name='whirlwind',
                  channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
                  ssid=self.ssid)
@@ -71,7 +71,8 @@
         self.download_threads_result.clear()
         self.dut.disconnect()
         self.dut.reset_wifi()
-        self.ap.stop_all_aps()
+        self.download_ap_logs()
+        self.access_point.stop_all_aps()
 
     def test_download_small(self):
         self.log.info("Downloading small file")
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py
index e7facd0..5f8addc 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/PingStressTest.py
@@ -48,8 +48,8 @@
 
         self.ssid = rand_ascii_str(10)
         self.dut = create_wlan_device(self.fuchsia_devices[0])
-        self.ap = self.access_points[0]
-        setup_ap(access_point=self.ap,
+        self.access_point = self.access_points[0]
+        setup_ap(access_point=self.access_point,
                  profile_name='whirlwind',
                  channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
                  ssid=self.ssid,
@@ -59,7 +59,8 @@
     def teardown_class(self):
         self.dut.disconnect()
         self.dut.reset_wifi()
-        self.ap.stop_all_aps()
+        self.download_ap_logs()
+        self.access_point.stop_all_aps()
 
     def send_ping(self,
                   dest_ip,
@@ -97,7 +98,7 @@
         return self.send_ping('127.0.0.1')
 
     def test_ping_AP(self):
-        return self.send_ping(self.ap.ssh_settings.hostname)
+        return self.send_ping(self.access_point.ssh_settings.hostname)
 
     def test_ping_with_params(self):
         return self.send_ping(self.google_dns_1,
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py
index 2a05579..ec74992 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/SoftApTest.py
@@ -208,6 +208,7 @@
             ad.droid.goToSleepNow()
         self.stop_all_soft_aps()
         if self.access_point:
+            self.download_ap_logs()
             self.access_point.stop_all_aps()
         self.dut.disconnect()
 
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py
index 7ffb5ef..8d365a7 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/WlanRebootTest.py
@@ -168,8 +168,14 @@
         self.ssid = utils.rand_ascii_str(hostapd_constants.AP_SSID_LENGTH_2G)
 
     def teardown_test(self):
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
         if self.router_adv_daemon:
+            output_path = context.get_current_context().get_base_output_path()
+            full_output_path = os.path.join(output_path, "radvd_log.txt")
+            radvd_log_file = open(full_output_path, 'w')
+            radvd_log_file.write(self.router_adv_daemon.pull_logs())
+            radvd_log_file.close()
             self.router_adv_daemon.stop()
             self.router_adv_daemon = None
         self.dut.disconnect()
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py
index 3a2e7f2..6133f0b 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/WlanScanTest.py
@@ -45,6 +45,7 @@
     def setup_class(self):
         super().setup_class()
 
+        self.access_point = self.access_points[0]
         self.start_access_point = False
         for fd in self.fuchsia_devices:
             fd.configure_wlan(association_mechanism='drivers')
@@ -84,14 +85,14 @@
                         security_mode=self.wpa2_network_5g["security"],
                         password=self.wpa2_network_5g["password"])))
             self.ap_2g = hostapd_ap_preset.create_ap_preset(
-                iface_wlan_2g=self.access_points[0].wlan_2g,
-                iface_wlan_5g=self.access_points[0].wlan_5g,
+                iface_wlan_2g=self.access_point.wlan_2g,
+                iface_wlan_5g=self.access_point.wlan_5g,
                 channel=hostapd_constants.AP_DEFAULT_CHANNEL_2G,
                 ssid=self.open_network_2g['SSID'],
                 bss_settings=bss_settings_2g)
             self.ap_5g = hostapd_ap_preset.create_ap_preset(
-                iface_wlan_2g=self.access_points[0].wlan_2g,
-                iface_wlan_5g=self.access_points[0].wlan_5g,
+                iface_wlan_2g=self.access_point.wlan_2g,
+                iface_wlan_5g=self.access_point.wlan_5g,
                 channel=hostapd_constants.AP_DEFAULT_CHANNEL_5G,
                 ssid=self.open_network_5g['SSID'],
                 bss_settings=bss_settings_5g)
@@ -133,10 +134,10 @@
         # previously saved ssid on the device.
         if self.start_access_point_2g:
             self.start_access_point = True
-            self.access_points[0].start_ap(hostapd_config=self.ap_2g)
+            self.access_point.start_ap(hostapd_config=self.ap_2g)
         if self.start_access_point_5g:
             self.start_access_point = True
-            self.access_points[0].start_ap(hostapd_config=self.ap_5g)
+            self.access_point.start_ap(hostapd_config=self.ap_5g)
 
     def setup_test(self):
         for fd in self.fuchsia_devices:
@@ -149,7 +150,8 @@
 
     def teardown_class(self):
         if self.start_access_point:
-            self.access_points[0].stop_all_aps()
+            self.download_ap_logs()
+            self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
         for fd in self.fuchsia_devices:
diff --git a/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py b/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py
index 0512b87..2debf65 100644
--- a/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/functional/WlanTargetSecurityTest.py
@@ -49,8 +49,9 @@
         self.dut.disconnect()
         self.access_point.stop_all_aps()
 
-    def setup_test(self):
+    def teardown_test(self):
         self.dut.disconnect()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py b/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py
index 842fa48..950015d 100644
--- a/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/misc/WlanMiscScenarioTest.py
@@ -50,8 +50,9 @@
         self.dut.disconnect()
         self.access_point.stop_all_aps()
 
-    def setup_test(self):
+    def teardown_test(self):
         self.dut.disconnect()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def on_fail(self, test_name, begin_time):
diff --git a/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py b/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py
index b687022..8ea7891 100644
--- a/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/performance/ChannelSweepTest.py
@@ -175,6 +175,7 @@
             ad.droid.goToSleepNow()
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def set_dut_country_code(self, country_code):
diff --git a/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py b/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py
index e640238..545bbc5 100644
--- a/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/performance/WlanRvrTest.py
@@ -13,6 +13,7 @@
 #   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 os
 import time
 
 from acts import asserts
@@ -226,6 +227,11 @@
         """
 
         if self.router_adv_daemon:
+            output_path = context.get_current_context().get_base_output_path()
+            full_output_path = os.path.join(output_path, "radvd_log.txt")
+            radvd_log_file = open(full_output_path, 'w')
+            radvd_log_file.write(self.router_adv_daemon.pull_logs())
+            radvd_log_file.close()
             self.router_adv_daemon.stop()
         if hasattr(self, "android_devices"):
             for ad in self.android_devices:
@@ -236,6 +242,7 @@
         self.dut.turn_location_off_and_scan_toggle_off()
         self.dut.disconnect()
         self.dut.reset_wifi()
+        self.download_ap_logs()
         self.access_point.stop_all_aps()
 
     def _wait_for_ipv4_addrs(self):
diff --git a/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py b/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py
index 3a3cd13..adbb5f6 100644
--- a/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py
+++ b/acts_tests/tests/google/fuchsia/wlan/performance/WlanWmmTest.py
@@ -190,6 +190,7 @@
                 tc.wlan_device.disconnect()
                 tc.wlan_device.reset_wifi()
             if tc.access_point:
+                self.download_ap_logs()
                 tc.access_point.stop_all_aps()
 
     def teardown_class(self):
diff --git a/acts_tests/tests/google/net/ApfCountersTest.py b/acts_tests/tests/google/net/ApfCountersTest.py
index 8fbfb22..d2eeff3 100755
--- a/acts_tests/tests/google/net/ApfCountersTest.py
+++ b/acts_tests/tests/google/net/ApfCountersTest.py
@@ -56,7 +56,7 @@
         self.dut = self.android_devices[0]
         wutils.wifi_test_device_init(self.dut)
         req_params = []
-        opt_param = ["reference_networks", ]
+        opt_param = ["reference_networks", "scapy"]
 
         self.unpack_userparams(
             req_param_names=req_params, opt_param_names=opt_param)
@@ -76,6 +76,8 @@
         current_dir = os.path.dirname(os.path.realpath(__file__))
         send_ra = os.path.join(current_dir, RA_SCRIPT)
         send_scapy = os.path.join(current_dir, SCAPY)
+        if hasattr(self, "scapy"):
+            send_scapy = self.scapy[0]
         self.access_points[0].install_scapy(send_scapy, send_ra)
         self.tcpdump_pid = None
 
diff --git a/acts_tests/tests/google/net/DhcpTest.py b/acts_tests/tests/google/net/DhcpTest.py
index a06b8fe..08aa983 100644
--- a/acts_tests/tests/google/net/DhcpTest.py
+++ b/acts_tests/tests/google/net/DhcpTest.py
@@ -50,11 +50,12 @@
                             "OpenWrt Wifi interface is not ready.")
 
     def teardown_class(self):
-        """Reset wifi to make sure VPN tears down cleanly."""
+        """Reset wifi and stop tcpdump cleanly."""
         wutils.reset_wifi(self.dut)
+        self.openwrt.network_setting.clear_tcpdump()
 
     def teardown_test(self):
-        """Reset wifi to make sure VPN tears down cleanly."""
+        """Reset wifi to make sure DUT tears down cleanly."""
         wutils.reset_wifi(self.dut)
 
     def _verify_ping(self, option="", dest=PING_ADDR):
diff --git a/acts_tests/tests/google/nr/cbr/CellBroadcastInitializationTest.py b/acts_tests/tests/google/nr/cbr/CellBroadcastInitializationTest.py
new file mode 100644
index 0000000..ed3ea6a
--- /dev/null
+++ b/acts_tests/tests/google/nr/cbr/CellBroadcastInitializationTest.py
@@ -0,0 +1,99 @@
+#!/usr/bin/env python3.4
+#
+#   Copyright 2022 - Google
+#
+#   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.
+"""
+    Test Script for CellBroadcast initialization Test
+"""
+
+import time
+import os
+
+
+from acts.logger import epoch_to_log_line_timestamp
+from acts.keys import Config
+from acts.base_test import BaseTestClass
+from acts.test_decorators import test_tracker_info
+from acts.utils import load_config
+from acts_contrib.test_utils.tel.TelephonyBaseTest import TelephonyBaseTest
+from acts_contrib.test_utils.tel.tel_test_utils import reboot_device
+from acts_contrib.test_utils.tel.tel_test_utils import get_device_epoch_time
+
+
+class CellBroadcastInitializationTest(BaseTestClass):
+    def setup_test(self):
+        super().setup_class()
+        self.number_of_devices = 1
+        self.cbr_init_iteration = self.user_params.get("cbr_init_iteration", 50)
+
+    def teardown_class(self):
+        super().teardown_class(self)
+
+    def _get_current_time_in_secs(self, ad):
+        try:
+            c_time = get_device_epoch_time(ad)
+            c_time = epoch_to_log_line_timestamp(c_time).split()[1].split('.')[0]
+            return self._convert_formatted_time_to_secs(c_time)
+        except Exception as e:
+            ad.log.error(e)
+
+    def _convert_formatted_time_to_secs(self, formatted_time):
+        try:
+            time_list = formatted_time.split(":")
+            return int(time_list[0]) * 3600 + int(time_list[1]) * 60 + int(time_list[2])
+        except Exception as e:
+            self.log.error(e)
+
+    def _verify_channel_config_4400(self, ad):
+        #TODO add all channel checks as constants in tel_defines
+        channel_4400__log = 'SmsBroadcastConfigInfo: Id \\[4400'
+        return ad.search_logcat(channel_4400__log)
+
+    @test_tracker_info(uuid="30f30fa4-f57a-40bd-a37a-141a8efb5a04")
+    @TelephonyBaseTest.tel_test_wrap
+    def test_reboot_stress(self):
+        """ Verifies channel 4400 is set correctly after device boot up
+        only applicable to US carriers
+        after every boot up, search logcat to verify channel 4400 is set
+        default iterations is 50
+        config param : cbr_init_iteration
+
+        """
+        ad = self.android_devices[0]
+
+        current_cbr_version = ad.get_apk_version('com.google.android.cellbroadcast')
+        ad.log.info("Current cbr apk version is %s.", current_cbr_version)
+
+        failure_count = 0
+        begin_time = self._get_current_time_in_secs(ad)
+        for iteration in range(1, self.cbr_init_iteration + 1):
+            msg = "Stress CBR reboot initialization test Iteration: <%s>/<%s>" % (iteration, self.cbr_init_iteration)
+            self.log.info(msg)
+            ad.reboot()
+            ad.wait_for_boot_completion()
+            self.log.info("Rebooted")
+            #TODO make sleep time a constant in tel_defines WAIT_TIME_CBR_INIT_AFTER_REBOOT
+            time.sleep(40)
+            if not self._verify_channel_config_4400(ad):
+                failure_count += 1
+                self.log.error('Iteration failed at %d ' % iteration)
+        end_time = self._get_current_time_in_secs(ad)
+        self.log.debug('Test completed from %s to %s' % (begin_time, end_time))
+        result = True
+        if failure_count > 0:
+            result = False
+            self.log.error('CBR reboot init stress test: <%s> failures in %s iterations',
+                           failure_count, self.cbr_init_iteration)
+        return result
+
diff --git a/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py b/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py
index 3dd5283..e7bcb5a 100755
--- a/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py
+++ b/acts_tests/tests/google/nr/nsa5g/Nsa5gMmsTest.py
@@ -25,11 +25,11 @@
 from acts_contrib.test_utils.tel.tel_defines import WFC_MODE_CELLULAR_PREFERRED
 from acts_contrib.test_utils.tel.tel_message_utils import message_test
 from acts_contrib.test_utils.tel.tel_phone_setup_utils import ensure_phones_idle
-from acts_contrib.test_utils.tel.tel_test_utils import active_file_download_task
+from acts_contrib.test_utils.tel.tel_phone_setup_utils import phone_setup_volte
+from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_task
 from acts_contrib.test_utils.tel.tel_test_utils import install_message_apk
 from acts_contrib.test_utils.tel.tel_test_utils import toggle_airplane_mode
 from acts_contrib.test_utils.tel.tel_test_utils import verify_internet_connection
-from acts_contrib.test_utils.tel.tel_voice_utils import phone_setup_volte
 from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
 from acts.libs.utils.multithread import run_multithread_func
 
diff --git a/acts_tests/tests/google/tel/lab/TelLabGFTDSDS.py b/acts_tests/tests/google/tel/lab/TelLabGFTDSDSTest.py
similarity index 100%
rename from acts_tests/tests/google/tel/lab/TelLabGFTDSDS.py
rename to acts_tests/tests/google/tel/lab/TelLabGFTDSDSTest.py
diff --git a/acts_tests/tests/google/tel/live/TelLiveStressTest.py b/acts_tests/tests/google/tel/live/TelLiveStressTest.py
index d1adcff..e04ba6a 100644
--- a/acts_tests/tests/google/tel/live/TelLiveStressTest.py
+++ b/acts_tests/tests/google/tel/live/TelLiveStressTest.py
@@ -47,6 +47,7 @@
 from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_MESSAGE_SUB_ID
 from acts_contrib.test_utils.tel.tel_defines import WAIT_TIME_CHANGE_VOICE_SUB_ID
 from acts_contrib.test_utils.tel.tel_5g_test_utils import provision_device_for_5g
+from acts_contrib.test_utils.tel.tel_5g_utils import is_current_network_5g
 from acts_contrib.test_utils.tel.tel_data_utils import active_file_download_test
 from acts_contrib.test_utils.tel.tel_ims_utils import set_wfc_mode
 from acts_contrib.test_utils.tel.tel_logging_utils import extract_test_log
@@ -477,9 +478,7 @@
                 incall_ui_display=INCALL_UI_DISPLAY_BACKGROUND,
                 call_stats_check=self.call_stats_check,
                 voice_type_init=voice_type_init,
-                result_info = self.result_info,
-                nw_gen_5g=self.nsa_5g_for_stress,
-                nr_type= self.nr_type
+                result_info = self.result_info
             ) and wait_for_in_call_active(self.dut, 60, 3)
         else:
             call_setup_result = call_setup_teardown(
@@ -494,9 +493,7 @@
                 slot_id_callee=slot_id_callee,
                 call_stats_check=self.call_stats_check,
                 voice_type_init=voice_type_init,
-                result_info = self.result_info,
-                nsa_5g_for_stress=self.nsa_5g_for_stress,
-                nr_type= self.nr_type)
+                result_info = self.result_info)
             self.result_collection[RESULTS_LIST[call_setup_result.result_value]] += 1
 
         if not call_setup_result:
@@ -563,6 +560,11 @@
         if not hangup_call(self.log, ads[0]):
             failure_reasons.add("Teardown")
             result = False
+        else:
+            if self.nsa_5g_for_stress:
+                for ad in (ads[0], ads[1]):
+                    if not is_current_network_5g(ad, self.nr_type):
+                        ad.log.error("Phone not attached on 5G")
         for ad in ads:
             if not wait_for_call_id_clearing(ad,
                                              []) or ad.droid.telecomIsInCall():