Beispiel #1
0
def orchestrate_and_verify_pan_connection(pan_dut, panu_dut):
    """Setups up a PAN conenction between two android devices.

    Args:
        pan_dut: the Android device providing tethering services
        panu_dut: the Android device using the internet connection from the
            pan_dut
    Returns:
        True if PAN connection and verification is successful,
        false if unsuccessful.
    """
    if not toggle_airplane_mode(log, panu_dut, True):
        log.error("Failed to toggle airplane mode on")
        return False
    if not bluetooth_enabled_check(panu_dut):
        return False
    pan_dut.droid.bluetoothPanSetBluetoothTethering(True)
    if not (pair_pri_to_sec(pan_dut.droid, panu_dut.droid)):
        return False
    if not pan_dut.droid.bluetoothPanIsTetheringOn():
        log.error("Failed to enable Bluetooth tethering.")
        return False
    # Magic sleep needed to give the stack time in between bonding and
    # connecting the PAN profile.
    time.sleep(MAGIC_PAN_CONNECT_TIMEOUT)
    panu_dut.droid.bluetoothConnectBonded(
        pan_dut.droid.bluetoothGetLocalAddress())
    if not verify_http_connection(log, panu_dut):
        log.error("Can't verify http connection on PANU device.")
        if not verify_http_connection(log, pan_dut):
            log.info("Can't verify http connection on PAN service device")
        return False
    return True
def tethering_check_internet_connection(log, provider, client_list,
                                        check_interval, check_iteration):
    """During tethering test, check client(s) and provider Internet connection.

    Do the following for <check_iteration> times:
        Delay <check_interval> seconds.
        Check Tethering provider's Internet connection.
        Check each client's Internet connection.

    Args:
        log: log object.
        provider: android object provide WiFi tethering.
        client_list: a list of clients using tethered WiFi.
        check_interval: delay time between each around of Internet connection check.
        check_iteration: check Internet connection for how many times in total.

    Returns:
        True if no error happened. False otherwise.
    """
    for i in range(1, check_iteration):
        time.sleep(check_interval)
        log.info(
            "Provider {} check Internet connection after {} seconds.".format(
                provider.serial, check_interval * i))
        if not verify_http_connection(log, provider):
            return False
        for client in client_list:
            log.info(
                "Client {} check Internet connection after {} seconds.".format(
                    client.serial, check_interval * i))
            if not verify_http_connection(log, client):
                return False
    return True
def airplane_mode_test(log, ad):
    """ Test airplane mode basic on Phone and Live SIM.

    Ensure phone attach, data on, WiFi off and verify Internet.
    Turn on airplane mode to make sure detach.
    Turn off airplane mode to make sure attach.
    Verify Internet connection.

    Args:
        log: log object.
        ad: android object.

    Returns:
        True if pass; False if fail.
    """
    if not ensure_phones_idle(log, [ad]):
        log.error("Failed to return phones to idle.")
        return False

    try:
        ad.droid.telephonyToggleDataConnection(True)
        WifiUtils.wifi_toggle_state(log, ad, False)

        log.info("Step1: ensure attach")
        if not toggle_airplane_mode(log, ad, False):
            log.error("Failed initial attach")
            return False
        if not verify_http_connection(log, ad):
            log.error("Data not available on cell.")
            return False

        log.info("Step2: enable airplane mode and ensure detach")
        if not toggle_airplane_mode(log, ad, True):
            log.error("Failed to enable Airplane Mode")
            return False
        if not wait_for_cell_data_connection(log, ad, False):
            log.error("Failed to disable cell data connection")
            return False
        if verify_http_connection(log, ad):
            log.error("Data available in airplane mode.")
            return False

        log.info("Step3: disable airplane mode and ensure attach")
        if not toggle_airplane_mode(log, ad, False):
            log.error("Failed to disable Airplane Mode")
            return False

        if not wait_for_cell_data_connection(log, ad, True):
            log.error("Failed to enable cell data connection")
            return False

        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)

        log.info("Step4 verify internet")
        return verify_http_connection(log, ad)
    finally:
        toggle_airplane_mode(log, ad, False)
Beispiel #4
0
    def test_wifi_cell_irat_stress_ping(self):
        """Test for data switch between WiFi and Cell. DUT go in and out WiFi
        coverage for multiple times.

        Steps:
        1. Set WiFi and Cellular signal to good (attenuation value to MIN).
        2. Make sure DUT get Cell data coverage (LTE) and WiFi connected.
        3. Set WiFi RSSI to MAX (WiFi attenuator value to MIN).
        4. Verify DUT report WiFi connected and Internet access OK.
        5. Set WiFi RSSI to MIN (WiFi attenuator value to MAX).
        6. Verify DUT report Cellular Data connected and Internet access OK.
        7. Repeat Step 3~6 for stress number.

        Expected Results:
        4. DUT report WiFi connected and Internet access OK.
        6. DUT report Cellular Data connected and Internet access OK.
        7. Stress test should pass.

        Returns:
        True if Pass. False if fail.
        """
        ad = self.android_devices[0]
        if not self._basic_connectivity_check():
            self.log.error("Basic Connectivity Check Failed")
            return False

        total_iteration = self.stress_test_number
        self.log.info("Stress test. Total iteration = %d.", total_iteration)
        current_iteration = 1
        while (current_iteration <= total_iteration):
            self.log.info(">----Current iteration = %d/%d----<",
                          current_iteration, total_iteration)

            self._atten_setup_wifi_cell()
            if (not wait_for_wifi_data_connection(self.log, ad, True)
                    or not verify_http_connection(self.log, ad)):
                ad.log.error("Data not on WiFi")
                break

            self._atten_setup_cell_only()
            if (not wait_for_cell_data_connection(self.log, ad, True)
                    or not verify_http_connection(self.log, ad)):
                ad.log.error("Data not on Cell")
                break
            self.log.info(">----Iteration : %d/%d succeed.----<",
                          current_iteration, total_iteration)
            current_iteration += 1
        if current_iteration <= total_iteration:
            self.log.info(">----Iteration : %d/%d failed.----<",
                          current_iteration, total_iteration)
            return False
        else:
            return True
Beispiel #5
0
    def test_lte_only_http_dl(self):
        """Test for 1GB file download on WiFi Only

        Steps:
        1. Set WiFi atten to MIN and Cellular to MAX
        2. Start downloading 1GB file from net
        3. Verify is the download is successfull

        Expected Results:
        1. File should download over WiFi

        Returns:
        True if Pass. False if fail.
        """
        ad = self.android_devices[0]
        if not self._basic_connectivity_check():
            self.log.error("Basic Connectivity Check Failed")
            return False
        self._atten_setup_lte_only()
        if (not wait_for_cell_data_connection(self.log, ad, True)
                or not verify_http_connection(self.log, ad)):
            ad.log.error("Data not on LTE")
            return False
        if not active_file_download_test(self.log, ad, "1GB"):
            ad.log.error("HTTP file download failed on LTE")
            return False
        return True
Beispiel #6
0
 def setup_class(self):
     """ Setup devices for tests and unpack params """
     self.dut = self.android_devices[0]
     wutils.wifi_toggle_state(self.dut, False)
     self.dut.droid.telephonyToggleDataConnection(True)
     wait_for_cell_data_connection(self.log, self.dut, True)
     asserts.assert_true(
         verify_http_connection(self.log, self.dut),
         "HTTP verification failed on cell data connection")
 def _check_lte_data(self):
     self.log.info("Check LTE data.")
     if not phone_setup_csfb(self.log, self.dut):
         self.log.error("Failed to setup LTE data.")
         return False
     if not verify_http_connection(self.log, self.dut):
         self.log.error("Data not available on cell.")
         return False
     return True
def verify_lte_data_and_tethering_supported(ad):
    """Verify if LTE data is enabled and tethering supported"""
    wutils.wifi_toggle_state(ad, False)
    ad.droid.telephonyToggleDataConnection(True)
    wait_for_cell_data_connection(ad.log, ad, True)
    asserts.assert_true(verify_http_connection(ad.log, ad),
                        "HTTP verification failed on cell data connection")
    asserts.assert_true(ad.droid.connectivityIsTetheringSupported(),
                        "Tethering is not supported for the provider")
    wutils.wifi_toggle_state(ad, True)
Beispiel #9
0
    def _wifi_cell_irat_task(self, ad, irat_wait_time=60):
        """
        Atten only WiFi to MIN and MAX
        WiFi --> Cellular
        """
        self._atten_setup_wifi_cell()
        if (not wait_for_wifi_data_connection(self.log, ad, True,
                                              irat_wait_time)
                or not verify_http_connection(self.log, ad)):
            ad.log.error("Data not on WiFi")
            return False

        ad.log.info("Triggering WiFi to Cellular IRAT")
        self._atten_setup_cell_only()
        if (not wait_for_cell_data_connection(self.log, ad, True,
                                              irat_wait_time)
                or not verify_http_connection(self.log, ad)):
            ad.log.error("Data not on Cell")
            return False
        return True
Beispiel #10
0
    def setup_class(self):
        """ Setup devices for tethering and unpack params """

        req_params = ("wifi_network", "download_file")
        self.unpack_userparams(req_params)

        for ad in self.android_devices:
            wutils.reset_wifi(ad)
            ad.droid.telephonyToggleDataConnection(True)
            wait_for_cell_data_connection(self.log, ad, True)
            asserts.assert_true(
                verify_http_connection(self.log, ad),
                "HTTP verification failed on cell data connection")
    def setup_class(self):
        """ Setup devices for tethering and unpack params """

        self.dut = self.android_devices[0]
        wutils.reset_wifi(self.dut)
        self.dut.droid.telephonyToggleDataConnection(True)
        wait_for_cell_data_connection(self.log, self.dut, True)
        asserts.assert_true(
            verify_http_connection(self.log, self.dut),
            "HTTP verification failed on cell data connection")
        req_params = ("wifi_network_with_dns_tls", "wifi_network_no_dns_tls",
                      "ping_hosts")
        self.unpack_userparams(req_params)
        self.tcpdump_pid = None
        self.tcpdump_file = None
Beispiel #12
0
 def test_check_environment(self):
     ad = self.android_devices[0]
     # Check WiFi environment.
     # 1. Connect to WiFi.
     # 2. Check WiFi have Internet access.
     toggle_airplane_mode(self.log, ad, False, strict_checking=False)
     try:
         if not ensure_wifi_connected(self.log, ad, self.wifi_network_ssid,
                                      self.wifi_network_pass):
             abort_all_tests(ad.log, "WiFi connect fail")
         if (not wait_for_wifi_data_connection(self.log, ad, True)
                 or not verify_http_connection(self.log, ad)):
             abort_all_tests(ad.log, "Data not available on WiFi")
     finally:
         wifi_toggle_state(self.log, ad, False)
     # TODO: add more environment check here.
     return True
 def _check_3g(self):
     self.log.info("Check 3G data and CS call")
     if not phone_setup_voice_3g(self.log, self.dut):
         self.log.error("Failed to setup 3G")
         return False
     if not verify_http_connection(self.log, self.dut):
         self.log.error("Data not available on cell.")
         return False
     if not call_setup_teardown(self.log, self.dut, self.ad_reference,
                                self.dut, is_phone_in_call_3g):
         self.log.error("WFC Call Failed.")
         return False
     if not sms_send_receive_verify(self.log, self.dut, self.ad_reference,
                                    [rand_ascii_str(50)]):
         self.log.error("SMS failed")
         return False
     return True
Beispiel #14
0
    def setup_class(self):
        """ Setup devices for tests and unpack params """
        self.dut = self.android_devices[0]
        self.tethered_devices = self.android_devices[1:]
        wutils.reset_wifi(self.dut)
        self.dut.droid.telephonyToggleDataConnection(True)
        wait_for_cell_data_connection(self.log, self.dut, True)
        asserts.assert_true(
            verify_http_connection(self.log, self.dut),
            "HTTP verification failed on cell data connection")

        # unpack user params
        req_params = ("wifi_network", "download_file", "file_size", "network")
        self.unpack_userparams(req_params)
        self.file_path = DOWNLOAD_PATH + self.download_file.split('/')[-1]
        self.file_size = int(self.file_size)
        self.sub_id = str(self.dut.droid.telephonyGetSubscriberId())
        self.android_os_uid = self.dut.droid.getUidForPackage(android_os_class)
        self.conn_test_uid = self.dut.droid.getUidForPackage(conn_test_class)
        for ad in self.android_devices:
            try:
                ad.adb.shell(instr_cmd)
            except adb.AdbError:
                self.log.warn("adb cmd %s failed on %s" %
                              (instr_cmd, ad.serial))

        # Set chrome browser start with no-first-run verification
        # Give permission to read from and write to storage
        commands = [
            "pm grant com.android.chrome "
            "android.permission.READ_EXTERNAL_STORAGE",
            "pm grant com.android.chrome "
            "android.permission.WRITE_EXTERNAL_STORAGE",
            "rm /data/local/chrome-command-line",
            "am set-debug-app --persistent com.android.chrome",
            'echo "chrome --no-default-browser-check --no-first-run '
            '--disable-fre" > /data/local/tmp/chrome-command-line'
        ]
        for cmd in commands:
            for dut in self.android_devices:
                try:
                    dut.adb.shell(cmd)
                except adb.AdbError:
                    self.log.warn("adb command %s failed on %s" %
                                  (cmd, dut.serial))
Beispiel #15
0
    def check_incall_data(self):
        if verify_internet_connection_by_ping(self.log, self.dut):
            self.internet_connection_check_method = verify_internet_connection_by_ping
        elif verify_http_connection(self.log, self.dut):
            self.internet_connection_check_method = verify_http_connection
        else:
            self.dut.log.error("Data test failed")
            raise signals.TestFailure("Data check failed")
        if self.single_phone_test:
            if not initiate_call(
                    self.log, self.dut,
                    self.call_server_number) and wait_for_in_call_active(
                        self.dut, 60, 3):
                self._take_bug_report(self.test_name, self.begin_time)
                raise signals.TestFailure("Unable to make phone call")
        else:
            if not call_setup_teardown(
                    self.log, self.dut, self.android_devices[1],
                    ad_hangup=None):
                self._take_bug_report(self.test_name, self.begin_time)
                raise signals.TestFailure("Unable to make phone call")
        voice_rat = self.dut.droid.telephonyGetCurrentVoiceNetworkType()
        data_rat = self.dut.droid.telephonyGetCurrentDataNetworkType()
        self.dut.log.info("Voice in RAT %s, Data in RAT %s", voice_rat,
                          data_rat)
        try:
            if is_rat_svd_capable(voice_rat.upper()) and is_rat_svd_capable(
                    data_rat.upper()):
                self.dut.log.info("Capable for simultaneous voice and data")

                if not self.internet_connection_check_method(
                        self.log, self.dut):
                    self.dut.log.error("Incall data check failed")
                    raise signals.TestFailure("Incall data check failed")
                else:
                    return True
            else:
                self.dut.log.info(
                    "Not capable for simultaneous voice and data")
                return False
            hangup_call(self.log, self.dut)
        finally:
            for ad in self.android_devices:
                if ad.droid.telecomIsInCall():
                    hangup_call(self.log, ad)
    def setup_class(self):
        """ Setup devices for tethering and unpack params """

        self.hotspot_device = self.android_devices[0]
        self.tethered_devices = self.android_devices[1:]
        req_params = ("network", "url", "open_network")
        self.unpack_userparams(req_params)
        self.new_ssid = "wifi_tethering_test2"

        wutils.wifi_toggle_state(self.hotspot_device, False)
        self.hotspot_device.droid.telephonyToggleDataConnection(True)
        wait_for_cell_data_connection(self.log, self.hotspot_device, True)
        asserts.assert_true(
            verify_http_connection(self.log, self.hotspot_device),
            "HTTP verification failed on cell data connection")
        asserts.assert_true(
            self.hotspot_device.droid.connectivityIsTetheringSupported(),
            "Tethering is not supported for the provider")
        for ad in self.tethered_devices:
            ad.droid.telephonyToggleDataConnection(False)
            wutils.wifi_test_device_init(ad)
def change_data_sim_and_verify_data(log, ad, sim_slot):
    """Change Data SIM and verify Data attach and Internet access

    Args:
        log: log object.
        ad: android device object.
        sim_slot: SIM slot index.

    Returns:
        Data SIM changed successfully, data attached and Internet access is OK.
    """
    sub_id = get_subid_from_slot_index(log, ad, sim_slot)
    log.info("Change Data to subId: {}, SIM slot: {}".format(sub_id, sim_slot))
    set_subid_for_data(ad, sub_id)
    if not wait_for_data_attach_for_subscription(log, ad, sub_id,
                                                 MAX_WAIT_TIME_NW_SELECTION):
        log.error("Failed to attach data on subId:{}".format(sub_id))
        return False
    if not verify_http_connection(log, ad):
        log.error("No Internet access after changing Data SIM.")
        return False
    return True
    def test_internet_access_during_video_call(self):
        """ Test Internet access during VT<->VT call.

        Make Sure PhoneA is in LTE mode (with Video Calling).
        Make Sure PhoneB is in LTE mode (with Video Calling).
        Call from PhoneA to PhoneB as Bi-Directional Video,
        Accept on PhoneB as video call.
        Verify PhoneA have Internet access.
        Hang up on PhoneA.

        Returns:
            True if pass; False if fail.
        """
        ads = self.android_devices
        tasks = [(phone_setup_video, (self.log, ads[0])),
                 (phone_setup_video, (self.log, ads[1]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            return False

        self.log.info("Step1: Make MO VT call.")
        if not video_call_setup_teardown(
                self.log,
                ads[0],
                ads[1],
                None,
                video_state=VT_STATE_BIDIRECTIONAL,
                verify_caller_func=is_phone_in_call_video_bidirectional,
                verify_callee_func=is_phone_in_call_video_bidirectional):
            self.log.error("Failed to setup+teardown a call")
            return False

        self.log.info("Step2: Verify Internet on PhoneA.")
        if not verify_http_connection(self.log, ads[0]):
            self.log.error("Verify Internet on PhoneA failed.")
            return False

        return hangup_call(self.log, ads[0])
Beispiel #19
0
    def test_pan_connection_then_disconnect(self):
        """Test bluetooth PAN connection then disconnect service

        Test basic PAN connection between two devices then disconnect
        service.

        Steps:
        1. Enable Airplane mode on PANU device. Enable Bluetooth only.
        2. Enable Bluetooth tethering on PAN Service device.
        3. Pair the PAN Service device to the PANU device.
        4. Verify that Bluetooth tethering is enabled on PAN Service device.
        5. Enable PAN profile from PANU device to PAN Service device.
        6. Verify HTTP connection on PANU device.
        7. Disable Bluetooth tethering on PAN Service device.
        8. Verify no HTTP connection on PANU device.

        Expected Result:
        PANU device does not have internet access.

        Returns:
          Pass if True
          Fail if False

        TAGS: Classic, PAN, tethering
        Priority: 1
        """
        if not orchestrate_and_verify_pan_connection(self.pan_dut,
                                                     self.panu_dut):
            self.log.error("Could not establish a PAN connection.")
            return False
        self.pan_dut.droid.bluetoothPanSetBluetoothTethering(False)
        if not verify_http_connection(self.log, self.panu_dut,
                                      expected_state=False):
            self.log.error("PANU device still has internet access.")
            return False
        self.log.info("PANU device has no internet access as expected.")
        return True
def wifi_cell_switching(log, ad, wifi_network_ssid, wifi_network_pass, nw_gen):
    """Test data connection network switching when phone on <nw_gen>.

    Ensure phone is on <nw_gen>
    Ensure WiFi can connect to live network,
    Airplane mode is off, data connection is on, WiFi is on.
    Turn off WiFi, verify data is on cell and browse to google.com is OK.
    Turn on WiFi, verify data is on WiFi and browse to google.com is OK.
    Turn off WiFi, verify data is on cell and browse to google.com is OK.

    Args:
        log: log object.
        ad: android object.
        wifi_network_ssid: ssid for live wifi network.
        wifi_network_pass: password for live wifi network.
        nw_gen: network generation the phone should be camped on.

    Returns:
        True if pass.
    """
    try:

        if not ensure_network_generation_for_subscription(
                log, ad, get_default_data_sub_id(ad), nw_gen,
                MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
            log.error("Device failed to register in {}".format(nw_gen))
            return False

        # Ensure WiFi can connect to live network
        log.info("Make sure phone can connect to live network by WIFI")
        if not ensure_wifi_connected(log, ad, wifi_network_ssid,
                                     wifi_network_pass):
            log.error("WiFi connect fail.")
            return False
        log.info("Phone connected to WIFI.")

        log.info("Step1 Airplane Off, WiFi On, Data On.")
        toggle_airplane_mode(log, ad, False)
        WifiUtils.wifi_toggle_state(log, ad, True)
        ad.droid.telephonyToggleDataConnection(True)
        if (not wait_for_wifi_data_connection(log, ad, True) or
                not verify_http_connection(log, ad)):
            log.error("Data is not on WiFi")
            return False

        log.info("Step2 WiFi is Off, Data is on Cell.")
        WifiUtils.wifi_toggle_state(log, ad, False)
        if (not wait_for_cell_data_connection(log, ad, True) or
                not verify_http_connection(log, ad)):
            log.error("Data did not return to cell")
            return False

        log.info("Step3 WiFi is On, Data is on WiFi.")
        WifiUtils.wifi_toggle_state(log, ad, True)
        if (not wait_for_wifi_data_connection(log, ad, True) or
                not verify_http_connection(log, ad)):
            log.error("Data did not return to WiFi")
            return False

        log.info("Step4 WiFi is Off, Data is on Cell.")
        WifiUtils.wifi_toggle_state(log, ad, False)
        if (not wait_for_cell_data_connection(log, ad, True) or
                not verify_http_connection(log, ad)):
            log.error("Data did not return to cell")
            return False
        return True

    finally:
        WifiUtils.wifi_toggle_state(log, ad, False)
Beispiel #21
0
    def test_smoke_3g_call_data_sms(self):
        try:
            ads = self.android_devices
            sms_idle_result = False
            sms_incall_result = False
            data_idle_result = False
            data_incall_result = False
            call_result = False

            self.log.info("--------start test_smoke_3g_call_data_sms--------")
            ensure_phones_default_state(self.log, ads)
            tasks = [(phone_setup_voice_3g, (self.log, ads[0])),
                     (phone_setup_voice_3g, (self.log, ads[1]))]
            if not multithread_func(self.log, tasks):
                self.log.error("Phone Failed to Set Up 3G.")
                return False
            self.log.info("1. SMS in 3G idle.")
            sms_idle_result = sms_send_receive_verify(self.log, ads[0], ads[1],
                                                      [rand_ascii_str(50)])

            self.log.info("2. Data in 3G idle.")
            if (wait_for_cell_data_connection(self.log, ads[0], True)
                    and verify_http_connection(self.log, ads[0])):
                data_idle_result = True

            self.log.info("3. Setup 3G Call.")
            if not call_setup_teardown(self.log,
                                       ads[0],
                                       ads[1],
                                       ad_hangup=None,
                                       verify_caller_func=is_phone_in_call_3g,
                                       verify_callee_func=is_phone_in_call_3g):
                self.log.error("Setup 3G Call Failed.")
                return False

            self.log.info("4. Verify SMS in call.")
            sms_incall_result = sms_send_receive_verify(
                self.log, ads[0], ads[1], [rand_ascii_str(51)])

            self.log.info("5. Verify Data in call.")
            if is_rat_svd_capable(
                    get_network_rat(self.log, ads[0], NETWORK_SERVICE_VOICE)):
                if (wait_for_cell_data_connection(self.log, ads[0], True)
                        and verify_http_connection(self.log, ads[0])):
                    data_incall_result = True
            else:
                self.log.info("Data in call not supported on current RAT."
                              "Skip Data verification.")
                data_incall_result = SKIP

            self.log.info("6. Verify Call not drop and hangup.")
            if (is_phone_in_call_3g(self.log, ads[0])
                    and is_phone_in_call_3g(self.log, ads[1])
                    and hangup_call(self.log, ads[0])):
                call_result = True

            return (sms_idle_result and data_idle_result and call_result
                    and sms_incall_result and ((data_incall_result is True) or
                                               (data_incall_result == SKIP)))
        finally:
            self.log.info(
                "Summary for test run. Testbed:<{}>. <3G> SMS idle: {}, "
                "Data idle: {}, SMS in call: {}, Data in call: {}, "
                "Voice Call: {}".format(
                    getattr(self, Config.ikey_testbed_name.value),
                    sms_idle_result, data_idle_result, sms_incall_result,
                    data_incall_result, call_result))
Beispiel #22
0
    def test_smoke_volte_call_data_sms(self):
        try:
            ads = self.android_devices
            sms_idle_result = False
            sms_incall_result = False
            data_idle_result = False
            data_incall_result = False
            call_result = False

            self.log.info(
                "--------start test_smoke_volte_call_data_sms--------")
            ensure_phones_default_state(self.log, ads)
            tasks = [(phone_setup_volte, (self.log, ads[0])),
                     (phone_setup_volte, (self.log, ads[1]))]
            if not multithread_func(self.log, tasks):
                self.log.error("Phone Failed to Set Up VoLTE.")
                return False

            # This is to reduce call fail in VoLTE mode.
            # TODO: b/26338170 remove sleep, use proper API to check DUT status.
            time.sleep(10)

            self.log.info("1. SMS in LTE idle.")
            sms_idle_result = sms_send_receive_verify(self.log, ads[0], ads[1],
                                                      [rand_ascii_str(50)])

            self.log.info("2. Data in LTE idle.")
            if (wait_for_cell_data_connection(self.log, ads[0], True)
                    and verify_http_connection(self.log, ads[0])):
                data_idle_result = True

            self.log.info("3. Setup VoLTE Call.")
            if not call_setup_teardown(
                    self.log,
                    ads[0],
                    ads[1],
                    ad_hangup=None,
                    verify_caller_func=is_phone_in_call_volte,
                    verify_callee_func=is_phone_in_call_volte,
                    wait_time_in_call=WAIT_TIME_IN_CALL_FOR_IMS):
                self.log.error("Setup VoLTE Call Failed.")
                return False

            self.log.info("4. Verify SMS in call.")
            sms_incall_result = sms_send_receive_verify(
                self.log, ads[0], ads[1], [rand_ascii_str(51)])

            self.log.info("5. Verify Data in call.")
            if (wait_for_cell_data_connection(self.log, ads[0], True)
                    and verify_http_connection(self.log, ads[0])):
                data_incall_result = True

            self.log.info("6. Verify Call not drop and hangup.")
            if (is_phone_in_call_volte(self.log, ads[0])
                    and is_phone_in_call_volte(self.log, ads[1])
                    and hangup_call(self.log, ads[0])):
                call_result = True

            return (sms_idle_result and data_idle_result and call_result
                    and sms_incall_result and data_incall_result)
        finally:
            self.log.info(
                "Summary for test run. Testbed:<{}>. <VoLTE> SMS idle: {}, "
                "Data idle: {}, SMS in call: {}, Data in call: {}, "
                "Voice Call: {}".format(
                    getattr(self, Config.ikey_testbed_name.value),
                    sms_idle_result, data_idle_result, sms_incall_result,
                    data_incall_result, call_result))
    def test_wifi_cell_switching_stress(self):
        """Test for data switch between WiFi and Cell. DUT go in and out WiFi
        coverage for multiple times.

        Steps:
        1. Set WiFi and Cellular signal to good (attenuation value to MIN).
        2. Make sure DUT get Cell data coverage (LTE) and WiFi connected.
        3. Set WiFi RSSI to MAX (WiFi attenuator value to MIN).
        4. Verify DUT report WiFi connected and Internet access OK.
        5. Set WiFi RSSI to MIN (WiFi attenuator value to MAX).
        6. Verify DUT report Cellular Data connected and Internet access OK.
        7. Repeat Step 3~6 for stress number.

        Expected Results:
        4. DUT report WiFi connected and Internet access OK.
        6. DUT report Cellular Data connected and Internet access OK.
        7. Stress test should pass.

        Returns:
        True if Pass. False if fail.
        """
        WIFI_RSSI_CHANGE_STEP_SIZE = 2
        WIFI_RSSI_CHANGE_DELAY_PER_STEP = 1
        # Set Attenuator Value for WiFi and Cell to 0.
        set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI], 0,
                 MAX_RSSI_RESERVED_VALUE)
        set_rssi(self.log, self.attens[ATTEN_NAME_FOR_CELL], 0,
                 MAX_RSSI_RESERVED_VALUE)

        # Make sure DUT get Cell Data coverage (LTE).
        toggle_airplane_mode(self.log, self.android_devices[0], False)
        if not ensure_network_generation(self.log, self.android_devices[0],
                                         GEN_4G, NETWORK_SERVICE_DATA):
            return False

        # Make sure DUT WiFi is connected.
        if not ensure_wifi_connected(self.log, self.android_devices[0],
                                     self.live_network_ssid,
                                     self.live_network_pwd):
            self.log.error("{} connect WiFI failed".format(
                self.android_devices[0].serial))
            return False

        total_iteration = self.stress_test_number
        self.log.info("Stress test. Total iteration = {}.".format(
            total_iteration))
        current_iteration = 1
        while (current_iteration <= total_iteration):
            self.log.info(">----Current iteration = {}/{}----<".format(
                current_iteration, total_iteration))

            # Set WiFi RSSI to MAX.
            set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI], 0,
                     MAX_RSSI_RESERVED_VALUE, WIFI_RSSI_CHANGE_STEP_SIZE,
                     WIFI_RSSI_CHANGE_DELAY_PER_STEP)
            # Wait for DUT report WiFi connected and Internet access OK.
            if (not wait_for_wifi_data_connection(
                    self.log, self.android_devices[0], True) or
                    not verify_http_connection(self.log,
                                               self.android_devices[0])):
                self.log.error("Data not on WiFi")
                break

            # Set WiFi RSSI to MIN (DUT lose WiFi coverage).
            set_rssi(self.log, self.attens[ATTEN_NAME_FOR_WIFI], 0,
                     MIN_RSSI_RESERVED_VALUE, WIFI_RSSI_CHANGE_STEP_SIZE,
                     WIFI_RSSI_CHANGE_DELAY_PER_STEP)
            # Wait for DUT report Cellular Data connected and Internet access OK.
            if (not wait_for_cell_data_connection(
                    self.log, self.android_devices[0], True) or
                    not verify_http_connection(self.log,
                                               self.android_devices[0])):
                self.log.error("Data not on Cell")
                break

            self.log.info(">----Iteration : {}/{} succeed.----<".format(
                current_iteration, total_iteration))
            current_iteration += 1
        if current_iteration <= total_iteration:
            self.log.info(">----Iteration : {}/{} failed.----<".format(
                current_iteration, total_iteration))
            return False
        else:
            return True
    def _test_msim_call_voice(self,
                              mo_slot,
                              mt_slot,
                              dds_slot,
                              mo_rat=["", ""],
                              mt_rat=["", ""],
                              call_direction="mo"):
        """Make MO/MT voice call at specific slot in specific RAT with DDS at
        specific slot.

        Test step:
        1. Get sub IDs of specific slots of both MO and MT devices.
        2. Switch DDS to specific slot.
        3. Check HTTP connection after DDS switch.
        4. Set up phones in desired RAT.
        5. Make voice call.

        Args:
            mo_slot: Slot making MO call (0 or 1)
            mt_slot: Slot receiving MT call (0 or 1)
            dds_slot: Preferred data slot
            mo_rat: RAT for both slots of MO device
            mt_rat: RAT for both slots of MT device
            call_direction: "mo" or "mt"

        Returns:
            TestFailure if failed.
        """
        ads = self.android_devices

        if call_direction == "mo":
            ad_mo = ads[0]
            ad_mt = ads[1]
        else:
            ad_mo = ads[1]
            ad_mt = ads[0]

        if mo_slot is not None:
            mo_sub_id = get_subid_from_slot_index(self.log, ad_mo, mo_slot)
            if mo_sub_id == INVALID_SUB_ID:
                ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
                return False
            mo_other_sub_id = get_subid_from_slot_index(
                self.log, ad_mo, 1 - mo_slot)
            set_incoming_voice_sub_id(ad_mo, mo_sub_id)
        else:
            _, mo_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
            if mo_sub_id == INVALID_SUB_ID:
                ad_mo.log.warning("Failed to get sub ID ar slot %s.", mo_slot)
                return False
            mo_slot = "auto"
            set_incoming_voice_sub_id(ad_mo, mo_sub_id)
        ad_mo.log.info("Sub ID for outgoing call at slot %s: %s", mo_slot,
                       get_outgoing_voice_sub_id(ad_mo))

        if mt_slot is not None:
            mt_sub_id = get_subid_from_slot_index(self.log, ad_mt, mt_slot)
            if mt_sub_id == INVALID_SUB_ID:
                ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
                return False
            mt_other_sub_id = get_subid_from_slot_index(
                self.log, ad_mt, 1 - mt_slot)
            set_incoming_voice_sub_id(ad_mt, mt_sub_id)
        else:
            _, mt_sub_id, _ = get_subid_on_same_network_of_host_ad(ads)
            if mt_sub_id == INVALID_SUB_ID:
                ad_mt.log.warning("Failed to get sub ID at slot %s.", mt_slot)
                return False
            mt_slot = "auto"
            set_incoming_voice_sub_id(ad_mt, mt_sub_id)
        ad_mt.log.info("Sub ID for incoming call at slot %s: %s", mt_slot,
                       get_incoming_voice_sub_id(ad_mt))

        self.log.info("Step 1: Switch DDS.")
        if dds_slot:
            if not set_dds_on_slot_1(ads[0]):
                ads[0].log.warning("Failed to set DDS at eSIM.")
                return False
        else:
            if not set_dds_on_slot_0(ads[0]):
                ads[0].log.warning("Failed to set DDS at pSIM.")
                return False

        self.log.info("Step 2: Check HTTP connection after DDS switch.")
        if not verify_http_connection(self.log,
                                      ads[0],
                                      url="https://www.google.com",
                                      retry=5,
                                      retry_interval=15,
                                      expected_state=True):

            self.log.error("Failed to verify http connection.")
            return False
        else:
            self.log.info("Verify http connection successfully.")

        if mo_rat[0] == "volte":
            mo_slot0_phone_setup_func = phone_setup_volte
            is_mo_slot0_in_call = is_phone_in_call_volte
        elif mo_rat[0] == "csfb":
            mo_slot0_phone_setup_func = phone_setup_csfb
            is_mo_slot0_in_call = is_phone_in_call_csfb
        elif mo_rat[0] == "3g":
            mo_slot0_phone_setup_func = phone_setup_voice_3g
            is_mo_slot0_in_call = is_phone_in_call_3g
        elif not mo_rat[0] or mo_rat[0] == "general":
            mo_slot0_phone_setup_func = phone_setup_voice_general
            is_mo_slot0_in_call = None

        if mo_rat[1] == "volte":
            mo_slot1_phone_setup_func = phone_setup_volte
            is_mo_slot1_in_call = is_phone_in_call_volte
        elif mo_rat[1] == "csfb":
            mo_slot1_phone_setup_func = phone_setup_csfb
            is_mo_slot1_in_call = is_phone_in_call_csfb
        elif mo_rat[1] == "3g":
            mo_slot1_phone_setup_func = phone_setup_voice_3g
            is_mo_slot1_in_call = is_phone_in_call_3g
        elif not mo_rat[1] or mo_rat[1] == "general":
            mo_slot1_phone_setup_func = phone_setup_voice_general
            is_mo_slot1_in_call = None

        if mt_rat[0] == "volte":
            mt_slot0_phone_setup_func = phone_setup_volte
            is_mt_slot0_in_call = is_phone_in_call_volte
        elif mt_rat[0] == "csfb":
            mt_slot0_phone_setup_func = phone_setup_csfb
            is_mt_slot0_in_call = is_phone_in_call_csfb
        elif mt_rat[0] == "3g":
            mt_slot0_phone_setup_func = phone_setup_voice_3g
            is_mt_slot0_in_call = is_phone_in_call_3g
        elif not mt_rat[0] or mt_rat[0] == "general":
            mt_slot0_phone_setup_func = phone_setup_voice_general
            is_mt_slot0_in_call = None

        if mt_rat[1] == "volte":
            mt_slot1_phone_setup_func = phone_setup_volte
            is_mt_slot1_in_call = is_phone_in_call_volte
        elif mt_rat[1] == "csfb":
            mt_slot1_phone_setup_func = phone_setup_csfb
            is_mt_slot1_in_call = is_phone_in_call_csfb
        elif mt_rat[1] == "3g":
            mt_slot1_phone_setup_func = phone_setup_voice_3g
            is_mt_slot1_in_call = is_phone_in_call_3g
        elif not mt_rat[1] or mt_rat[1] == "general":
            mt_slot1_phone_setup_func = phone_setup_voice_general
            is_mt_slot1_in_call = None

        if mo_slot == 1:
            mo_phone_setup_func = mo_slot1_phone_setup_func
            is_mo_in_call = is_mo_slot1_in_call
            if mo_rat[0] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mo,
                                                   mo_other_sub_id)
            elif mo_rat[0] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mo,
                                                  mo_other_sub_id)
            elif mo_rat[0] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mo,
                                                      mo_other_sub_id)
            elif not mo_rat[0] or mo_rat[0] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mo, mo_other_sub_id)
        elif mo_slot == 0:
            mo_phone_setup_func = mo_slot0_phone_setup_func
            is_mo_in_call = is_mo_slot0_in_call
            if mo_rat[1] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mo,
                                                   mo_other_sub_id)
            elif mo_rat[1] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mo,
                                                  mo_other_sub_id)
            elif mo_rat[1] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mo,
                                                      mo_other_sub_id)
            elif not mo_rat[1] or mo_rat[1] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mo, mo_other_sub_id)
        else:
            mo_phone_setup_func = phone_setup_voice_general
            is_mo_in_call = None

        if mt_slot == 1:
            mt_phone_setup_func = mt_slot1_phone_setup_func
            is_mt_in_call = is_mt_slot1_in_call
            if mt_rat[0] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mt,
                                                   mt_other_sub_id)
            elif mt_rat[0] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mt,
                                                  mt_other_sub_id)
            elif mt_rat[0] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mt,
                                                      mt_other_sub_id)
            elif not mt_rat[0] or mt_rat[0] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mt, mt_other_sub_id)
        elif mt_slot == 0:
            mt_phone_setup_func = mt_slot0_phone_setup_func
            is_mt_in_call = is_mt_slot0_in_call
            if mt_rat[1] == "volte":
                phone_setup_volte_for_subscription(self.log, ad_mt,
                                                   mt_other_sub_id)
            elif mt_rat[1] == "csfb":
                phone_setup_csfb_for_subscription(self.log, ad_mt,
                                                  mt_other_sub_id)
            elif mt_rat[1] == "3g":
                phone_setup_voice_3g_for_subscription(self.log, ad_mt,
                                                      mt_other_sub_id)
            elif not mt_rat[1] or mt_rat[1] == "general":
                phone_setup_voice_general_for_subscription(
                    self.log, ad_mt, mt_other_sub_id)
        else:
            mt_phone_setup_func = phone_setup_voice_general
            is_mt_in_call = None

        self.log.info("Step 3: Set up phones in desired RAT.")
        tasks = [(mo_phone_setup_func, (self.log, ad_mo)),
                 (mt_phone_setup_func, (self.log, ad_mt))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            self.tel_logger.set_result(CallResult("CALL_SETUP_FAILURE"))
            raise signals.TestFailure(
                "Failed",
                extras={"fail_reason": "Phone Failed to Set Up Properly."})

        self.log.info("Step 4: Make voice call.")
        result = two_phone_call_msim_for_slot(
            self.log, ad_mo,
            get_slot_index_from_subid(self.log, ad_mo,
                                      mo_sub_id), None, is_mo_in_call, ad_mt,
            get_slot_index_from_subid(self.log, ad_mt, mt_sub_id), None,
            is_mt_in_call)
        self.tel_logger.set_result(result.result_value)

        if not result:
            self.log.error(
                "Failed to make MO call from %s slot %s to %s slot %s",
                ad_mo.serial, mo_slot, ad_mt.serial, mt_slot)
            raise signals.TestFailure(
                "Failed", extras={"fail_reason": str(result.result_value)})
    def test_wfc_setup_timing(self):
        """ Measures the time delay in enabling WiFi calling

        Steps:
        1. Make sure DUT idle.
        2. Turn on Airplane Mode, Set WiFi Calling to WiFi_Preferred.
        3. Turn on WiFi, connect to WiFi AP and measure time delay.
        4. Wait for WiFi connected, verify Internet and measure time delay.
        5. Wait for rat to be reported as iwlan and measure time delay.
        6. Wait for ims registered and measure time delay.
        7. Wait for WiFi Calling feature bit to be True and measure time delay.

        Expected results:
        Time Delay in each step should be within pre-defined limit.

        Returns:
            Currently always return True.
        """
        # TODO: b/26338119 Set pass/fail criteria
        ad = self.android_devices[0]

        time_values = {
            'start': 0,
            'wifi_enabled': 0,
            'wifi_connected': 0,
            'wifi_data': 0,
            'iwlan_rat': 0,
            'ims_registered': 0,
            'wfc_enabled': 0,
            'mo_call_success': 0
        }

        WifiUtils.wifi_reset(self.log, ad)
        toggle_airplane_mode(self.log, ad, True)

        set_wfc_mode(self.log, ad, WFC_MODE_WIFI_PREFERRED)

        time_values['start'] = time.time()

        self.log.info("Start Time {}s".format(time_values['start']))

        WifiUtils.wifi_toggle_state(self.log, ad, True)
        time_values['wifi_enabled'] = time.time()
        self.log.info(
            "WiFi Enabled After {}s".format(time_values['wifi_enabled'] -
                                            time_values['start']))

        WifiUtils.wifi_connect(self.log, ad, self.wifi_network_ssid,
                               self.wifi_network_pass)

        ad.droid.wakeUpNow()

        if not wait_for_wifi_data_connection(self.log, ad, True,
                                             MAX_WAIT_TIME_WIFI_CONNECTION):
            self.log.error("Failed WiFi connection, aborting!")
            return False
        time_values['wifi_connected'] = time.time()

        self.log.info(
            "WiFi Connected After {}s".format(time_values['wifi_connected'] -
                                              time_values['wifi_enabled']))

        if not verify_http_connection(self.log, ad, 'http://www.google.com',
                                      100, .1):
            self.log.error("Failed to get user-plane traffic, aborting!")
            return False

        time_values['wifi_data'] = time.time()
        self.log.info(
            "WifiData After {}s".format(time_values['wifi_data'] -
                                        time_values['wifi_connected']))

        if not wait_for_network_rat(
                self.log, ad, RAT_FAMILY_WLAN,
                voice_or_data=NETWORK_SERVICE_DATA):
            self.log.error("Failed to set-up iwlan, aborting!")
            if is_droid_in_rat_family(self.log, ad, RAT_FAMILY_WLAN,
                                      NETWORK_SERVICE_DATA):
                self.log.error("Never received the event, but droid in iwlan")
            else:
                return False
        time_values['iwlan_rat'] = time.time()
        self.log.info(
            "iWLAN Reported After {}s".format(time_values['iwlan_rat'] -
                                              time_values['wifi_data']))

        if not wait_for_ims_registered(self.log, ad,
                                       MAX_WAIT_TIME_IMS_REGISTRATION):
            self.log.error("Never received IMS registered, aborting")
            return False
        time_values['ims_registered'] = time.time()
        self.log.info(
            "Ims Registered After {}s".format(time_values['ims_registered'] -
                                              time_values['iwlan_rat']))

        if not wait_for_wfc_enabled(self.log, ad, MAX_WAIT_TIME_WFC_ENABLED):
            self.log.error("Never received WFC feature, aborting")
            return False

        time_values['wfc_enabled'] = time.time()
        self.log.info("Wifi Calling Feature Enabled After {}s".format(
            time_values['wfc_enabled'] - time_values['ims_registered']))

        set_wfc_mode(self.log, ad, WFC_MODE_DISABLED)

        wait_for_not_network_rat(self.log,
                                 ad,
                                 RAT_FAMILY_WLAN,
                                 voice_or_data=NETWORK_SERVICE_DATA)

        self.log.info("\n\n------------------summary-----------------")
        self.log.info(
            "WiFi Enabled After {0:.2f} s".format(time_values['wifi_enabled'] -
                                                  time_values['start']))
        self.log.info("WiFi Connected After {0:.2f} s".format(
            time_values['wifi_connected'] - time_values['wifi_enabled']))
        self.log.info(
            "WifiData After {0:.2f} s".format(time_values['wifi_data'] -
                                              time_values['wifi_connected']))
        self.log.info(
            "iWLAN Reported After {0:.2f} s".format(time_values['iwlan_rat'] -
                                                    time_values['wifi_data']))
        self.log.info("Ims Registered After {0:.2f} s".format(
            time_values['ims_registered'] - time_values['iwlan_rat']))
        self.log.info("Wifi Calling Feature Enabled After {0:.2f} s".format(
            time_values['wfc_enabled'] - time_values['ims_registered']))
        self.log.info("\n\n")
        return True
def data_connectivity_single_bearer(log, ad, nw_gen):
    """Test data connection: single-bearer (no voice).

    Turn off airplane mode, enable Cellular Data.
    Ensure phone data generation is expected.
    Verify Internet.
    Disable Cellular Data, verify Internet is inaccessible.
    Enable Cellular Data, verify Internet.

    Args:
        log: log object.
        ad: android object.
        nw_gen: network generation the phone should on.

    Returns:
        True if success.
        False if failed.
    """
    ensure_phones_idle(log, [ad])

    if not ensure_network_generation_for_subscription(
            log, ad, get_default_data_sub_id(ad), nw_gen,
            MAX_WAIT_TIME_NW_SELECTION, NETWORK_SERVICE_DATA):
        log.error("Device failed to reselect in {}s.".format(
            MAX_WAIT_TIME_NW_SELECTION))
        return False

    try:
        log.info("Step1 Airplane Off, Data On.")
        toggle_airplane_mode(log, ad, False)
        ad.droid.telephonyToggleDataConnection(True)
        if not wait_for_cell_data_connection(log, ad, True):
            log.error("Failed to enable data connection.")
            return False

        log.info("Step2 Verify internet")
        if not verify_http_connection(log, ad):
            log.error("Data not available on cell.")
            return False

        log.info("Step3 Turn off data and verify not connected.")
        ad.droid.telephonyToggleDataConnection(False)
        if not wait_for_cell_data_connection(log, ad, False):
            log.error("Step3 Failed to disable data connection.")
            return False

        if verify_http_connection(log, ad):
            log.error("Step3 Data still available when disabled.")
            return False

        log.info("Step4 Re-enable data.")
        ad.droid.telephonyToggleDataConnection(True)
        if not wait_for_cell_data_connection(log, ad, True):
            log.error("Step4 failed to re-enable data.")
            return False
        if not verify_http_connection(log, ad):
            log.error("Data not available on cell.")
            return False

        if not is_droid_in_network_generation_for_subscription(
                log, ad, get_default_data_sub_id(ad), nw_gen,
                NETWORK_SERVICE_DATA):
            log.error("Failed: droid is no longer on correct network")
            log.info("Expected:{}, Current:{}".format(
                nw_gen, rat_generation_from_rat(
                    get_network_rat_for_subscription(
                        log, ad, get_default_data_sub_id(
                            ad), NETWORK_SERVICE_DATA))))
            return False
        return True
    finally:
        ad.droid.telephonyToggleDataConnection(True)
def wifi_tethering_setup_teardown(log,
                                  provider,
                                  client_list,
                                  ap_band=WifiUtils.WIFI_CONFIG_APBAND_2G,
                                  check_interval=30,
                                  check_iteration=4,
                                  do_cleanup=True,
                                  ssid=None,
                                  password=None):
    """Test WiFi Tethering.

    Turn off WiFi on clients.
    Turn off data and reset WiFi on clients.
    Verify no Internet access on clients.
    Turn on WiFi tethering on provider.
    Clients connect to provider's WiFI.
    Verify Internet on provider and clients.
    Tear down WiFi tethering setup and clean up.

    Args:
        log: log object.
        provider: android object provide WiFi tethering.
        client_list: a list of clients using tethered WiFi.
        ap_band: setup WiFi tethering on 2G or 5G.
            This is optional, default value is WifiUtils.WIFI_CONFIG_APBAND_2G
        check_interval: delay time between each around of Internet connection check.
            This is optional, default value is 30 (seconds).
        check_iteration: check Internet connection for how many times in total.
            This is optional, default value is 4 (4 times).
        do_cleanup: after WiFi tethering test, do clean up to tear down tethering
            setup or not. This is optional, default value is True.
        ssid: use this string as WiFi SSID to setup tethered WiFi network.
            This is optional. Default value is None.
            If it's None, a random string will be generated.
        password: use this string as WiFi password to setup tethered WiFi network.
            This is optional. Default value is None.
            If it's None, a random string will be generated.

    Returns:
        True if no error happened. False otherwise.
    """
    log.info("--->Start wifi_tethering_setup_teardown<---")
    log.info("Provider: {}".format(provider.serial))
    if not provider.droid.connectivityIsTetheringSupported():
        log.error("Provider does not support tethering. Stop tethering test.")
        return False

    if ssid is None:
        ssid = rand_ascii_str(10)
    if password is None:
        password = rand_ascii_str(8)

    # No password
    if password == "":
        password = None

    try:
        for client in client_list:
            log.info("Client: {}".format(client.serial))
            WifiUtils.wifi_toggle_state(log, client, False)
            client.droid.telephonyToggleDataConnection(False)
        log.info("WiFI Tethering: Verify client have no Internet access.")
        for client in client_list:
            if verify_http_connection(log, client):
                log.error("Turn off Data on client fail. {}".format(
                    client.serial))
                return False

        log.info(
            "WiFI Tethering: Turn on WiFi tethering on {}. SSID: {}, password: {}".format(
                provider.serial, ssid, password))

        if not WifiUtils.start_wifi_tethering(log, provider, ssid, password,
                                              ap_band):
            log.error("Provider start WiFi tethering failed.")
            return False
        time.sleep(WAIT_TIME_ANDROID_STATE_SETTLING)

        log.info("Provider {} check Internet connection.".format(
            provider.serial))
        if not verify_http_connection(log, provider):
            return False
        for client in client_list:
            log.info(
                "WiFI Tethering: {} connect to WiFi and verify AP band correct.".format(
                    client.serial))
            if not ensure_wifi_connected(log, client, ssid, password):
                log.error("Client connect to WiFi failed.")
                return False

            wifi_info = client.droid.wifiGetConnectionInfo()
            if ap_band == WifiUtils.WIFI_CONFIG_APBAND_5G:
                if wifi_info["is_24ghz"]:
                    log.error("Expected 5g network. WiFi Info: {}".format(
                        wifi_info))
                    return False
            else:
                if wifi_info["is_5ghz"]:
                    log.error("Expected 2g network. WiFi Info: {}".format(
                        wifi_info))
                    return False

            log.info("Client{} check Internet connection.".format(
                client.serial))
            if (not wait_for_wifi_data_connection(log, client, True) or
                    not verify_http_connection(log, client)):
                log.error("No WiFi Data on client: {}.".format(client.serial))
                return False

        if not tethering_check_internet_connection(
                log, provider, client_list, check_interval, check_iteration):
            return False

    finally:
        if (do_cleanup and
            (not wifi_tethering_cleanup(log, provider, client_list))):
            return False
    return True