def setup_class(self):
        """Setup devices for tests and unpack params."""

        # unpack user params
        req_params = ("wifi_network",
                      "file_size",
                      "download_file_ipv4",
                      "download_file_ipv6",
                      "dbs_supported_models")
        self.unpack_userparams(req_params)
        self.file_path = DOWNLOAD_PATH + self.download_file_ipv4.split("/")[-1]
        self.file_size = float(self.file_size)

        for ad in self.android_devices:
            self.log.info("Operator on %s is %s" % \
                          (ad.serial, get_operator_name(self.log, ad)))
            ad.reboot()
            nutils.verify_lte_data_and_tethering_supported(ad)
            nutils.set_chrome_browser_permissions(ad)
            cutils.set_private_dns(ad, cconst.PRIVATE_DNS_MODE_OFF)
            try:
                ad.adb.shell(instr_cmd)
            except AdbError:
                self.log.warn("cmd %s failed on %s" % (instr_cmd, ad.serial))
        self.tcpdumps = []
        self.hs_enabled = []
 def setup_class(self):
     super().setup_class()
     self.dut = self.android_devices[0]
     if len(self.android_devices) > 1:
         self.ad_reference = self.android_devices[1]
         setattr(self.ad_reference, "qxdm_log", False)
     else:
         self.ad_reference = None
     setattr(self.dut, "qxdm_log", False)
     self.stress_test_number = int(
         self.user_params.get("stress_test_number", 5))
     self.skip_reset_between_cases = False
     self.dut_model = get_model_name(self.dut)
     self.dut_operator = get_operator_name(self.log, self.dut)
     self.dut_capabilities = set(
         device_capabilities.get(
             self.dut_model, device_capabilities["default"])) & set(
                 operator_capabilities.get(
                     self.dut_operator, operator_capabilities["default"]))
     self.dut.log.info("DUT capabilities: %s", self.dut_capabilities)
     self.user_params["check_crash"] = False
     self.skip_reset_between_cases = False
     self.path = self.user_params['account_util'][0]
     self.user_account = "commsteltest1"
     self.user_password = "******"
Пример #3
0
    def test_private_dns_mode_strict_connectivity_toggle_networks(self):
        """ Verify private DNS strict mode connectivity by toggling networks

        Steps:
            1. Set private DNS strict mode
            2. DUT is connected to mobile network
            3. Verify connectivity and DNS queries going to port 853
            4. Switch to wifi network
            5. Verify connectivity and DNS queries going to port 853
            6. Switch back to mobile network
            7. Verify connectivity and DNS queries going to port 853
            8. Repeat steps 1-7 for TMO, VZW and different private DNS servers
        """
        for ad in self.android_devices:
            self.log.info("Carrier is: %s" % get_operator_name(self.log, ad))
            for dns in self.private_dns_servers:
                self.log.info("Setting strict mode private dns: %s" % dns)
                # set private dns mode
                cutils.set_private_dns(ad, cconst.PRIVATE_DNS_MODE_STRICT, dns)

                # verify dns over tls on mobile network
                self._test_private_dns_mode(
                    self.dut, None, None, True, dns)


                # verify dns over tls on wifi network
                self._test_private_dns_mode(
                    self.dut, self.ipv4_ipv6_network, None, True, dns)

                # verify dns over tls on mobile network
                wutils.reset_wifi(self.dut)
                self._test_private_dns_mode(
                    self.dut, None, None, True, dns)
Пример #4
0
    def _supports_ipv6_tethering(self, dut):
        """ Check if provider supports IPv6 tethering.
            Currently, only Verizon supports IPv6 tethering

        Returns:
            True: if provider supports IPv6 tethering
            False: if not
        """
        # Currently only Verizon support IPv6 tethering
        carrier_supports_tethering = ["vzw"]
        operator = get_operator_name(self.log, dut)
        return operator in carrier_supports_tethering
Пример #5
0
    def _carrier_supports_ipv6(self, dut):
        """ Verify if carrier supports ipv6
            Currently, only verizon and t-mobile supports IPv6

        Returns:
            True: if carrier supports ipv6
            False: if not
        """
        carrier_supports_ipv6 = ["vzw", "tmo"]
        operator = get_operator_name(self.log, dut)
        self.log.info("Carrier is %s" % operator)
        return operator in carrier_supports_ipv6
def supports_ipv6_tethering(self, dut):
    """ Check if provider supports IPv6 tethering.

    Returns:
        True: if provider supports IPv6 tethering
        False: if not
    """
    carrier_supports_tethering = [
        "vzw", "tmo", "Far EasTone", "Chunghwa Telecom"
    ]
    operator = get_operator_name(self.log, dut)
    return operator in carrier_supports_tethering
def carrier_supports_ipv6(dut):
    """Verify if carrier supports ipv6.

    Args:
        dut: Android device that is being checked

    Returns:
        True: if carrier supports ipv6
        False: if not
    """

    carrier_supports_ipv6 = ["vzw", "tmo", "Far EasTone", "Chunghwa Telecom"]
    operator = get_operator_name("log", dut)
    return operator in carrier_supports_ipv6
    def __init__(self, controllers):
        TelephonyBaseTest.__init__(self, controllers)

        self.stress_test_number = self.get_stress_test_number()
        self.wifi_network_ssid = self.user_params["wifi_network_ssid"]

        try:
            self.wifi_network_pass = self.user_params["wifi_network_pass"]
        except KeyError:
            self.wifi_network_pass = None

        self.dut = self.android_devices[0]
        self.ad_reference = self.android_devices[1]
        self.dut_model = get_model_name(self.dut)
        self.dut_operator = get_operator_name(self.log, self.dut)
Пример #9
0
    def test_private_dns_mode_opportunistic_tmo_carrier(self):
        """ Verify private dns mode opportunistic on TMO network

        Steps:
            1. Set private dns mode opportunistic
            2. Connect to wifi network. TMP supports DNS/TLS
            3. Run HTTP ping to amazon.com, facebook.com, netflix.com
            4. Verify ping works to differnt hostnames
            5. Verify that all queries go to port 853 and encrypted
        """
        carrier = get_operator_name(self.log, self.dut)
        asserts.skip_if(carrier != "tmo", "Carrier is not T-mobile")
        self._test_private_dns_mode(self.dut,
                                    None,
                                    cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC,
                                    True)
Пример #10
0
    def test_private_dns_mode_opportunistic_vzw_carrier(self):
        """ Verify private dns mode opportunistic on VZW network

        Steps:
            1. Set private dns mode opportunistic
            2. Connect to wifi network. VZW doesn't support DNS/TLS
            3. Run HTTP ping to amazon.com, facebook.com, netflix.com
            4. Verify ping works to differnt hostnames
            5. Verify that all queries go to port 53
        """
        carrier = get_operator_name(self.log, self.dut_b)
        asserts.skip_if(carrier != "vzw", "Carrier is not Verizon")
        self._test_private_dns_mode(self.dut_b,
                                    None,
                                    cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC,
                                    False)
Пример #11
0
    def test_private_dns_mode_off_tmo_carrier(self):
        """ Verify private dns mode off on TMO network

        Steps:
            1. Set private dns to off mode
            2. Connect to wifi network. TMO supports DNS/TLS
            3. Run HTTP ping to amazon.com, facebook.com, netflix.com
            4. Verify ping works to differnt hostnames
            5. Verify that all queries go to port 53
        """
        carrier = get_operator_name(self.log, self.dut)
        asserts.skip_if(carrier != "tmo", "Carrier is not T-mobile")
        self._test_private_dns_mode(self.dut,
                                    None,
                                    cconst.PRIVATE_DNS_MODE_OFF,
                                    False)
Пример #12
0
    def test_private_dns_mode_strict_tmo_carrier(self):
        """ Verify private dns mode strict on TMO network

        Steps:
            1. Set private dns mode strict
            2. Connect to wifi network. TMO supports DNS/TLS
            3. Run HTTP ping to amazon.com, facebook.com, netflix.com
            4. Verify ping works to differnt hostnames
            5. Verify that all queries go to port 853 and encrypted
        """
        carrier = get_operator_name(self.log, self.dut)
        asserts.skip_if(carrier != "tmo", "Carrier is not T-mobile")
        for dns in self.private_dns_servers:
            self._test_private_dns_mode(self.dut,
                                        None,
                                        cconst.PRIVATE_DNS_MODE_STRICT,
                                        True,
                                        dns)
    def setup_class(self):
        TelephonyBaseTest.setup_class(self)
        self.user_params["enable_connectivity_metrics"] = False
        self.user_params["telephony_auto_rerun"] = 0
        self.consecutive_failure_limit = 5

        self.dut = self.android_devices[0]
        self.ad_reference = self.android_devices[1]
        self.dut_model = get_model_name(self.dut)
        self.dut_operator = get_operator_name(self.log, self.dut)
        self.dut_subID = get_outgoing_voice_sub_id(self.dut)
        self.dut_capabilities = self.dut.telephony["subscription"][self.dut_subID].get("capabilities", [])
        self.dut_wfc_modes = self.dut.telephony["subscription"][self.dut_subID].get("wfc_modes", [])
        self.ad_reference_subID = get_outgoing_voice_sub_id(self.ad_reference)
        self.reference_capabilities = self.ad_reference.telephony["subscription"][self.ad_reference_subID].get(
            "capabilities", [])
        self.dut.log.info("DUT capabilities: %s", self.dut_capabilities)
        self.skip_reset_between_cases = False
        self.user_params["telephony_auto_rerun"] = 0
        self.number_of_devices = 1
        self.call_drop_override_code = self.user_params.get(
            "call_drop_override_code", 373)
Пример #14
0
    def test_att_passpoint_network(self):
        """Add a AT&T Passpoint network and verify device connects to it.

        Steps:
            1. Install a AT&T Passpoint Profile.
            2. Verify the device connects to the required Passpoint SSID.
            3. Get the Passpoint configuration added above.
            4. Delete Passpoint configuration using its FQDN.
            5. Verify that we are disconnected from the Passpoint network.

        """
        carriers = ["att"]
        operator = get_operator_name(self.log, self.dut)
        asserts.skip_if(operator not in carriers,
                        "Device %s does not have a ATT sim" % self.dut.model)

        passpoint_config = self.passpoint_networks[ATT]
        self.install_passpoint_profile(passpoint_config)
        ssid = passpoint_config[WifiEnums.SSID_KEY]
        self.check_passpoint_connection(ssid)
        self.get_configured_passpoint_and_delete()
        wutils.wait_for_disconnect(self.dut)
Пример #15
0
 def setup_dut(self, ad):
     self.dut = ad
     output = self.dut.adb.shell("dumpsys carrier_config")
     self.default_settings = {}
     for setting in (IMS_FIRST, ALLOW_NON_EMERGENCY_CALL,
                     BLOCK_DURATION_CMD):
         values = re.findall(r"%s = (\S+)" % setting, output)
         if values:
             self.default_settings[setting] = values[-1]
         else:
             self.default_settings[setting] = ""
     self.dut.adb.shell(" ".join(
         [CARRIER_OVERRIDE_CMD, BLOCK_DURATION_CMD,
          "%s" % BLOCK_DURATION]))
     self.dut_operator = get_operator_name(self.log, ad)
     if self.dut_operator == "tmo":
         self.fake_emergency_number = "611"
     elif self.dut_operator == "vzw":
         self.fake_emergency_number = "922"
     elif self.dut_operator == "spt":
         self.fake_emergency_number = "526"
     if len(self.my_devices) > 1:
         self.android_devices.remove(ad)
         self.android_devices.insert(0, ad)
Пример #16
0
    def test_private_dns_mode_opportunistic_connectivity_toggle_networks(self):
        """ Verify private DNS opportunistic mode connectivity by toggling networks

        Steps:
            1. Set private DNS opportunistic mode
            2. DUT is connected to mobile network
            3. Verify connectivity and DNS queries going to port 853 for TMO
               and port 53 for VZW
            4. Switch to wifi network set with private DNS server
            5. Verify connectivity and DNS queries going to port 853
            6. Switch back to mobile network
            7. Verify connectivity and DNS queries going to port 853 for TMO
               and port 53 for VZW
            8. Repeat steps 1-7 for TMO, VZW and different private DNS servers
        """
        for ad in self.android_devices:
            carrier = get_operator_name(self.log, ad)
            self.log.info("Carrier is: %s" % carrier)
            use_tls = True if carrier == "tmo" else False
            for dns in self.private_dns_servers:
                self.log.info("Setting opportunistic private dns mode")
                # set private dns mode
                cutils.set_private_dns(ad, cconst.PRIVATE_DNS_MODE_OPPORTUNISTIC)

                # verify dns over tls on mobile network
                self._test_private_dns_mode(
                    self.dut, None, None, use_tls, dns)

                # verify dns over tls on wifi network
                self._test_private_dns_mode(
                    self.dut, self.ipv4_ipv6_network, None, True, dns)

                # verify dns over tls on mobile network
                wutils.reset_wifi(self.dut)
                self._test_private_dns_mode(
                    self.dut, None, None, use_tls, dns)
    def test_pre_flight_check(self):
        def droid_has_phone(log, ad):
            #check for sim and service
            subInfo = ad.droid.subscriptionGetAllSubInfoList()
            if not subInfo or len(subInfo) < 1:
                return False
            toggle_airplane_mode(log, ad, False)
            sub_id = ad.droid.subscriptionGetDefaultVoiceSubId()
            if not wait_for_voice_attach_for_subscription(
                    log, ad, sub_id, MAX_WAIT_TIME_NW_SELECTION):
                log.error("{} didn't find a cell network".format(ad.serial))
                return False
            return True

        def droid_has_provisioning(log, ad):
            if not ad.droid.imsIsVolteProvisionedOnDevice():
                log.error("{}: VoLTE Not Provisioned on the Platform".format(
                    ad.serial))
                return False
            else:
                log.info("{} VoLTE Provisioned".format(ad.serial))
            return True

        def droid_has_volte(log, ad):
            if not ad.droid.imsIsEnhanced4gLteModeSettingEnabledByPlatform():
                log.error("{}: VoLTE Not Enabled on the Platform".format(
                    ad.serial))
                return False
            else:
                log.info("{} VoLTE Enabled by platform".format(ad.serial))
            return True

        def droid_has_wifi_calling(log, ad):
            if not ad.droid.imsIsWfcEnabledByPlatform():
                log.error("{}: WFC Not Enabled on the Platform".format(
                    ad.serial))
                return False
            else:
                log.info("{} WFC Enabled by platform".format(ad.serial))
            return True

        def droid_has_vt(log, ad):
            if not ad.droid.imsIsVtEnabledByPlatform():
                log.error("{}: VT Not Enabled on the Platform".format(
                    ad.serial))
                return False
            else:
                log.info("{} VT Enabled by platform".format(ad.serial))
            return True

        try:
            for ad in self.android_devices:
                model = ad.model
                # Remove aosp prefix
                if model.startswith(AOSP_PREFIX):
                    model = model[len(AOSP_PREFIX):]

                # Special capability phone, needed to get SIM Operator
                if not CAPABILITY_PHONE in device_capabilities[model]:
                    self.log.info("Skipping {}:{}: not a phone".format(
                        ad.serial, model))
                    return True

                operator = get_operator_name(self.log, ad)
                self.log.info(
                    "Pre-flight check for <{}>, <{}:{}>, build<{}>".format(
                        operator, model, ad.serial, ad.droid.getBuildID()))

                if ("force_provisioning" in self.user_params
                        and CAPABILITY_OMADM in device_capabilities[model]
                        and CAPABILITY_OMADM in operator_capabilities[operator]
                        and not droid_has_provisioning(self.log, ad)):
                    self.log.info("{} not IMS Provisioned!!".format(ad.serial))
                    self.log.info("{} Forcing IMS Provisioning!".format(
                        ad.serial))
                    ad.droid.imsSetVolteProvisioning(True)
                    self.log.info("{} reboot!".format(ad.serial))
                    ad.reboot()
                    self.log.info("{} wait {}s for radio up.".format(
                        ad.serial, WAIT_TIME_AFTER_REBOOT))
                    # This sleep WAIT_TIME_AFTER_REBOOT seconds is waiting for
                    # radio to initiate after phone reboot.
                    time.sleep(WAIT_TIME_AFTER_REBOOT)

                active_capabilities = [
                    CAPABILITY_PHONE, CAPABILITY_OMADM, CAPABILITY_VOLTE,
                    CAPABILITY_WFC
                ]
                for capability in active_capabilities:
                    if (capability in device_capabilities[model]
                            and capability in operator_capabilities[operator]):
                        if not {
                                # TODO: b/26337715 make the check table global
                                CAPABILITY_PHONE: droid_has_phone,
                                CAPABILITY_OMADM: droid_has_provisioning,
                                CAPABILITY_VOLTE: droid_has_volte,
                                CAPABILITY_WFC: droid_has_wifi_calling,
                                CAPABILITY_VT: droid_has_vt
                        }[capability](self.log, ad):
                            abort_all(
                                "Pre-flight check FAILED for <{}>, <{}:{}>."
                                " Failed Check: <{}>".format(
                                    operator, model, ad.serial, capability))
        except Exception as e:
            abort_all("Pre-flight check exception: {}".format(e))
        return True
Пример #18
0
    def _setup_device(self, ad, sim_conf_file, qxdm_log_mask_cfg=None):
        if self.user_params.get("enable_connectivity_metrics", True):
            enable_connectivity_metrics(ad)
        if self.user_params.get("build_id_override", False):
            build_postfix = self.user_params.get("build_id_postfix", "TEST")
            build_id_override(ad,
                              new_build_id=self.user_params.get(
                                  "build_id_override_with", None),
                              postfix=build_postfix)
        if self.enable_radio_log_on:
            enable_radio_log_on(ad)
        if "sdm" in ad.model:
            if ad.adb.getprop("persist.radio.multisim.config") != "ssss":
                ad.adb.shell("setprop persist.radio.multisim.config ssss")
                reboot_device(ad)

        stop_qxdm_logger(ad)
        ad.qxdm_log = getattr(ad, "qxdm_log", self.qxdm_log)
        if ad.qxdm_log:
            qxdm_log_mask = getattr(ad, "qxdm_log_mask", None)
            if qxdm_log_mask_cfg:
                qxdm_mask_path = self.user_params.get("qxdm_log_path",
                                                      DEFAULT_QXDM_LOG_PATH)
                ad.adb.shell("mkdir %s" % qxdm_mask_path)
                ad.log.info("Push %s to %s", qxdm_log_mask_cfg, qxdm_mask_path)
                ad.adb.push("%s %s" % (qxdm_log_mask_cfg, qxdm_mask_path))
                mask_file_name = os.path.split(qxdm_log_mask_cfg)[-1]
                qxdm_log_mask = os.path.join(qxdm_mask_path, mask_file_name)
            set_qxdm_logger_command(ad, mask=qxdm_log_mask)
            start_qxdm_logger(ad, utils.get_current_epoch_time())
        else:
            disable_qxdm_logger(ad)
        if not unlock_sim(ad):
            raise signals.TestAbortClass("unable to unlock the SIM")

        if get_sim_state(ad) in (SIM_STATE_ABSENT, SIM_STATE_UNKNOWN):
            ad.log.info("Device has no or unknown SIM in it")
            ensure_phone_idle(self.log, ad)
        elif self.user_params.get("Attenuator"):
            ad.log.info("Device in chamber room")
            ensure_phone_idle(self.log, ad)
            setup_droid_properties(self.log, ad, sim_conf_file)
        else:
            if not wait_for_sim_ready_by_adb(self.log, ad):
                raise signals.TestAbortClass("unable to load the SIM")
            ensure_phone_default_state(self.log, ad)
            setup_droid_properties(self.log, ad, sim_conf_file)

        # Setup VoWiFi MDN for Verizon. b/33187374
        if get_operator_name(self.log, ad) == "vzw" and ad.is_apk_installed(
                "com.google.android.wfcactivation"):
            ad.log.info("setup VoWiFi MDN per b/33187374")
        ad.adb.shell("setprop dbg.vzw.force_wfc_nv_enabled true")
        ad.adb.shell("am start --ei EXTRA_LAUNCH_CARRIER_APP 0 -n "
                     "\"com.google.android.wfcactivation/"
                     ".VzwEmergencyAddressActivity\"")
        # Sub ID setup
        initial_set_up_for_subid_infomation(self.log, ad)

        # If device is setup already, skip the following setup procedures
        if getattr(ad, "telephony_test_setup", None):
            return True

        if "enable_wifi_verbose_logging" in self.user_params:
            ad.droid.wifiEnableVerboseLogging(WIFI_VERBOSE_LOGGING_ENABLED)

        # Disable Emergency alerts
        # Set chrome browser start with no-first-run verification and
        # disable-fre. Give permission to read from and write to storage.
        for cmd in ("pm disable com.android.cellbroadcastreceiver",
                    "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'):
            ad.adb.shell(cmd)

        # Curl for 2016/7 devices
        if not getattr(ad, "curl_capable", False):
            try:
                out = ad.adb.shell("/data/curl --version")
                if not out or "not found" in out:
                    if int(ad.adb.getprop("ro.product.first_api_level")) >= 25:
                        tel_data = self.user_params.get("tel_data", "tel_data")
                        if isinstance(tel_data, list):
                            tel_data = tel_data[0]
                        curl_file_path = os.path.join(tel_data, "curl")
                        if not os.path.isfile(curl_file_path):
                            curl_file_path = os.path.join(
                                self.user_params[Config.key_config_path],
                                curl_file_path)
                        if os.path.isfile(curl_file_path):
                            ad.log.info("Pushing Curl to /data dir")
                            ad.adb.push("%s /data" % (curl_file_path))
                            ad.adb.shell("chmod 777 /data/curl",
                                         ignore_status=True)
                else:
                    setattr(ad, "curl_capable", True)
            except Exception:
                ad.log.info("Failed to push curl on this device")

        # Ensure that a test class starts from a consistent state that
        # improves chances of valid network selection and facilitates
        # logging.
        try:
            if not set_phone_screen_on(self.log, ad):
                self.log.error("Failed to set phone screen-on time.")
                return False
            if not set_phone_silent_mode(self.log, ad):
                self.log.error("Failed to set phone silent mode.")
                return False
            ad.droid.telephonyAdjustPreciseCallStateListenLevel(
                PRECISE_CALL_STATE_LISTEN_LEVEL_FOREGROUND, True)
            ad.droid.telephonyAdjustPreciseCallStateListenLevel(
                PRECISE_CALL_STATE_LISTEN_LEVEL_RINGING, True)
            ad.droid.telephonyAdjustPreciseCallStateListenLevel(
                PRECISE_CALL_STATE_LISTEN_LEVEL_BACKGROUND, True)
        except Exception as e:
            self.log.error("Failure with %s", e)
        setattr(ad, "telephony_test_setup", True)
        return True
    def _cbrs_call_sequence(
            self, ads, mo_mt, cbrs_phone_setup_func,
            verify_cbrs_initial_idle_func, verify_data_initial_func,
            verify_cbrs_in_call_state_func, verify_data_in_call_func,
            incall_cbrs_setting_check_func, verify_data_final_func,
            verify_cbrs_final_func, expected_result):
        """_cbrs_call_sequence

        Args:
            ads: list of android devices. This list should have 2 ad.
            mo_mt: indicating this call sequence is MO or MT.
                Valid input: DIRECTION_MOBILE_ORIGINATED and
                DIRECTION_MOBILE_TERMINATED.

        Returns:
            if expected_result is True,
                Return True if call sequence finish without exception.
            if expected_result is string,
                Return True if expected exception happened. Otherwise False.

        """
        class _CBRSCallSequenceException(Exception):
            pass

        if (len(ads) != 2) or (mo_mt not in [
                DIRECTION_MOBILE_ORIGINATED, DIRECTION_MOBILE_TERMINATED
        ]):
            self.log.error("Invalid parameters.")
            return False

        self.cbrs_subid, self.default_subid = get_cbrs_and_default_sub_id(
            ads[0])

        if mo_mt == DIRECTION_MOBILE_ORIGINATED:
            ad_caller = ads[0]
            ad_callee = ads[1]
            caller_number = get_phone_number(self.log, ad_caller)
            callee_number = get_phone_number(self.log, ad_callee)
            mo_operator = get_operator_name(ads[0].log, ads[0])
            mt_operator = get_operator_name(ads[1].log, ads[1])
        else:
            ad_caller = ads[1]
            ad_callee = ads[0]
            caller_number = get_phone_number(self.log, ad_caller)
            callee_number = get_phone_number(self.log, ad_callee)
            mt_operator = get_operator_name(ads[0].log, ads[0])
            mo_operator = get_operator_name(ads[1].log, ads[1])

        self.log.info("-->Begin cbrs_call_sequence: %s to %s<--",
                      caller_number, callee_number)
        self.log.info("--> %s to %s <--", mo_operator, mt_operator)

        try:
            # Setup
            if cbrs_phone_setup_func and not cbrs_phone_setup_func():
                raise _CBRSCallSequenceException("cbrs_phone_setup_func fail.")
            if not phone_setup_voice_general(self.log, ads[1]):
                raise _CBRSCallSequenceException(
                    "phone_setup_voice_general fail.")
            time.sleep(WAIT_TIME_BETWEEN_REG_AND_CALL)

            # Ensure idle status correct
            if verify_cbrs_initial_idle_func and not \
                verify_cbrs_initial_idle_func():
                raise _CBRSCallSequenceException(
                    "verify_cbrs_initial_idle_func fail.")

            # Ensure data checks are performed
            if verify_data_initial_func and not \
                verify_data_initial_func():
                raise _CBRSCallSequenceException(
                    "verify_data_initial_func fail.")

            # Make MO/MT call.
            if not initiate_call(self.log, ad_caller, callee_number):
                raise _CBRSCallSequenceException("initiate_call fail.")
            if not wait_and_answer_call(self.log, ad_callee, caller_number):
                raise _CBRSCallSequenceException("wait_and_answer_call fail.")
            time.sleep(WAIT_TIME_FOR_CBRS_DATA_SWITCH)

            # Check state, wait 30 seconds, check again.
            if (verify_cbrs_in_call_state_func
                    and not verify_cbrs_in_call_state_func()):
                raise _CBRSCallSequenceException(
                    "verify_cbrs_in_call_state_func fail.")

            if is_phone_not_in_call(self.log, ads[1]):
                raise _CBRSCallSequenceException("PhoneB not in call.")

            # Ensure data checks are performed
            if verify_data_in_call_func and not \
                verify_data_in_call_func():
                raise _CBRSCallSequenceException(
                    "verify_data_in_call_func fail.")

            time.sleep(WAIT_TIME_IN_CALL)

            if (verify_cbrs_in_call_state_func
                    and not verify_cbrs_in_call_state_func()):
                raise _CBRSCallSequenceException(
                    "verify_cbrs_in_call_state_func fail after 30 seconds.")
            if is_phone_not_in_call(self.log, ads[1]):
                raise _CBRSCallSequenceException(
                    "PhoneB not in call after 30 seconds.")

            # in call change setting and check
            if (incall_cbrs_setting_check_func
                    and not incall_cbrs_setting_check_func()):
                raise _CBRSCallSequenceException(
                    "incall_cbrs_setting_check_func fail.")

            # Hangup call
            if is_phone_in_call(self.log, ads[0]):
                if not hangup_call(self.log, ads[0]):
                    raise _CBRSCallSequenceException("hangup_call fail.")
            else:
                if incall_cbrs_setting_check_func is None:
                    raise _CBRSCallSequenceException("Unexpected call drop.")

            time.sleep(WAIT_TIME_FOR_CBRS_DATA_SWITCH)

            # Ensure data checks are performed
            if verify_data_final_func and not \
                verify_data_final_func():
                raise _CBRSCallSequenceException(
                    "verify_data_final_func fail.")

            # Ensure data checks are performed
            if verify_cbrs_final_func and not \
                verify_cbrs_final_func():
                raise _CBRSCallSequenceException(
                    "verify_cbrs_final_func fail.")

        except _CBRSCallSequenceException as e:
            if str(e) == expected_result:
                self.log.info("Expected exception: <%s>, return True.", e)
                return True
            else:
                self.log.info("Unexpected exception: <%s>, return False.", e)
                return False
        finally:
            for ad in ads:
                if ad.droid.telecomIsInCall():
                    hangup_call_by_adb(ad)
        self.log.info("cbrs_call_sequence finished, return %s",
                      expected_result is True)
        return (expected_result is True)