def initiate_call_when_a2dp_streaming_on(self):
        """Initiates HFP call when a2dp is streaming, then check for call is
        present or not.

        Disconnect a2dp profile and then connect HFP profile and
        answer the call from reference device.

        Returns:
            True if successful, False otherwise.
        """
        if not self.play_music_and_connect_wifi():
            return False

        if not initiate_call(self.log, self.pri_ad, self.re_phone_number):
            self.log.error("Failed to initiate call")
            return False
        if wait_for_dialing(self.log, self.pri_ad):
            self.pri_ad.droid.bluetoothDisconnectConnectedProfile(
                self.audio_receiver.mac_address,
                [BtEnum.BluetoothProfile.A2DP.value])
            if not connect_dev_to_headset(
                    self.pri_ad, self.audio_receiver.mac_address,
                [BtEnum.BluetoothProfile.HEADSET.value]):
                return False
        if not wait_and_answer_call(self.log, self.sec_ad):
            self.log.error("Failed to answer call in second device")
            return False
        time.sleep(self.iperf["duration"])
        if not hangup_call(self.log, self.pri_ad):
            self.log.error("Failed to hangup call")
            return False
        return True
 def setup_multi_call(self, caller0, caller1, callee):
     outgoing_num = get_phone_number(self.log, callee)
     if not initiate_call(self.log, caller0, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, callee):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     if not initiate_call(self.log, caller1, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, callee):
         self.log.error("Failed to answer call.")
         return False
     return True
示例#3
0
    def test_call_transfer_disconnect_connect(self):
        """
        Tests that after we connect when an active call is in progress,
        we show the call.

        Precondition:
        1. AG & HF are disconnected but paired.

        Steps:
        1. Make a call from AG role (since disconnected)
        2. Accept from RE role and transition the call to Active
        3. Connect AG & HF
        4. HF should transition into Active call state.

        Returns:
          Pass if True
          Fail if False

        Priority: 1
        """
        # make a call on AG
        if not initiate_call(self.log, self.ag, self.re_phone_number):
            self.ag.log.error("Failed to initiate call from ag.")
            return False
        if not wait_and_answer_call(self.log, self.re):
            self.re.log.error("Failed to accept call on re.")
            return False

        # Wait for AG, RE to go into an Active state.
        if not car_telecom_utils.wait_for_active(self.log, self.ag):
            self.ag.log.error("AG not in Active state.")
            return False
        if not car_telecom_utils.wait_for_active(self.log, self.re):
            self.re.log.error("RE not in Active state.")
            return False

        # Now connect the devices.
        if not bt_test_utils.connect_pri_to_sec(
                self.hf, self.ag,
                set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
            self.log.error("Could not connect HF and AG {} {}".format(
                self.hf.serial, self.ag.serial))
            return False

        # Check that HF is in active state
        if not car_telecom_utils.wait_for_active(self.log, self.hf):
            self.hf.log.error("HF not in Active state.")
            return False

        # Hangup the call and check all devices are clean
        self.hf.droid.telecomEndCall()
        ret = True
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf)
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag)
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re)

        return ret
示例#4
0
def initiate_disconnect_call_dut(pri_ad, sec_ad, duration, callee_number):
    """Initiates call and disconnect call on primary device.

    Steps:
    1. Initiate call from DUT.
    2. Wait for dialing state at DUT and wait for ringing at secondary device.
    3. Accepts call from secondary device.
    4. Wait for call active state at primary and secondary device.
    5. Sleeps until given duration.
    6. Disconnect call from primary device.
    7. Wait for call is not present state.

    Args:
        pri_ad: An android device to disconnect call.
        sec_ad: An android device accepting call.
        duration: Duration of call in seconds.
        callee_number: Secondary device's phone number.

    Returns:
        True if successful, False otherwise.
    """
    if not initiate_call(logging, pri_ad, callee_number):
        pri_ad.log.error("Failed to initiate call")
        return False
    time.sleep(2)

    flag = True
    flag &= wait_for_dialing(logging, pri_ad)
    flag &= wait_for_ringing(logging, sec_ad)
    if not flag:
        pri_ad.log.error("Outgoing call did not get established")
        return False

    if not wait_and_answer_call(logging, sec_ad):
        pri_ad.log.error("Failed to answer call in second device.")
        return False
    # Wait for AG, RE to go into an Active state.
    if not wait_for_active(logging, pri_ad):
        pri_ad.log.error("AG not in Active state.")
        return False
    if not wait_for_active(logging, sec_ad):
        pri_ad.log.error("RE not in Active state.")
        return False
    time.sleep(duration)
    if not hangup_call(logging, pri_ad):
        pri_ad.log.error("Failed to hangup call.")
        return False
    flag = True
    flag &= wait_for_not_in_call(logging, pri_ad)
    flag &= wait_for_not_in_call(logging, sec_ad)

    return flag
 def outgoing_multi_call_join_conference_call(self, pri_dut, sec_dut,
                                              ter_dut):
     self.log.info(
         "Test 2 outgoing calls scenario from phone then join the calls.")
     input("Press enter to execute this testcase...")
     outgoing_num = get_phone_number(self.log, sec_dut)
     if not initiate_call(self.log, pri_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, sec_dut):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     outgoing_num = get_phone_number(self.log, ter_dut)
     if not initiate_call(self.log, pri_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, ter_dut):
         self.log.error("Failed to answer call.")
         return False
     input("Press enter to join active calls...")
     calls = pri_dut.droid.telecomCallGetCallIds()
     pri_dut.droid.telecomCallJoinCallsInConf(calls[0], calls[1])
     time.sleep(WAIT_TIME_IN_CALL)
     if num_active_calls(self.log, pri_dut) != 4:
         self.log.error("Total number of call ids in {} is not 4.".format(
             pri_dut.serial))
         return False
     input("Press enter to hangup call 1...")
     if not hangup_call(self.log, sec_dut):
         self.log.error("Failed to hangup call")
         return False
     input("Press enter to hangup call 2...")
     if not hangup_call(self.log, ter_dut):
         self.log.error("Failed to hangup call")
         return False
     return True
示例#6
0
def initiate_disconnect_from_hf(audio_receiver, pri_ad, sec_ad, duration):
    """Initiates call and disconnect call on primary device.

    Steps:
    1. Initiate call from HF.
    2. Wait for dialing state at DUT and wait for ringing at secondary device.
    3. Accepts call from secondary device.
    4. Wait for call active state at primary and secondary device.
    5. Sleeps until given duration.
    6. Disconnect call from primary device.
    7. Wait for call is not present state.

    Args:
        audio_receiver: An relay device object.
        pri_ad: An android device to disconnect call.
        sec_ad: An android device accepting call.
        duration: Duration of call in seconds.

    Returns:
        True if successful, False otherwise.
    """
    audio_receiver.press_initiate_call()
    time.sleep(2)
    flag = True
    flag &= wait_for_dialing(logging, pri_ad)
    flag &= wait_for_ringing(logging, sec_ad)
    if not flag:
        pri_ad.log.error("Outgoing call did not get established")
        return False

    if not wait_and_answer_call(logging, sec_ad):
        pri_ad.log.error("Failed to answer call in second device.")
        return False
    if not wait_for_active(logging, pri_ad):
        pri_ad.log.error("AG not in Active state.")
        return False
    if not wait_for_active(logging, sec_ad):
        pri_ad.log.error("RE not in Active state.")
        return False
    time.sleep(duration)
    if not hangup_call(logging, pri_ad):
        pri_ad.log.error("Failed to hangup call.")
        return False
    flag = True
    flag &= wait_for_not_in_call(logging, pri_ad)
    flag &= wait_for_not_in_call(logging, sec_ad)
    return flag
 def incomming_call_unknown_contact(self, pri_dut, ter_dut):
     self.log.info(
         "Test incomming call scenario to phone from unknown contact")
     input("Press enter to execute this testcase...")
     outgoing_num = get_phone_number(self.log, pri_dut)
     if not initiate_call(self.log, ter_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, pri_dut):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     input("Press enter to hangup call...")
     if not hangup_call(self.log, ter_dut):
         self.log.error("Failed to hangup call")
         return False
     return True
 def outgoing_call_private_number(self, pri_dut, ter_dut):
     self.log.info(
         "Test outgoing call scenario from phone to private number")
     input("Press enter to execute this testcase...")
     outgoing_num = "*67" + get_phone_number(self.log, ter_dut)
     if not initiate_call(self.log, pri_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, ter_dut):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     input("Press enter to hangup call...")
     if not hangup_call(self.log, pri_dut):
         self.log.error("Failed to hangup call")
         return False
     return True
 def call_audio_routes(self, pri_dut, sec_dut):
     self.log.info("Test various audio routes scenario from phone.")
     input("Press enter to execute this testcase...")
     outgoing_num = get_phone_number(self.log, sec_dut)
     if not initiate_call(self.log, pri_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, sec_dut):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     call_id = pri_dut.droid.telecomCallGetCallIds()[0]
     pri_dut.droid.telecomCallPlayDtmfTone(call_id, "9")
     input("Press enter to switch to speaker...")
     self.log.info("Switching to speaker.")
     set_audio_route(self.log, pri_dut, AUDIO_ROUTE_SPEAKER)
     time.sleep(self.short_timeout)
     if get_audio_route(self.log, pri_dut) != AUDIO_ROUTE_SPEAKER:
         self.log.error(
             "Audio Route not set to {}".format(AUDIO_ROUTE_SPEAKER))
         return False
     input("Press enter to switch to earpiece...")
     self.log.info("Switching to earpiece.")
     set_audio_route(self.log, pri_dut, AUDIO_ROUTE_EARPIECE)
     time.sleep(self.short_timeout)
     if get_audio_route(self.log, pri_dut) != AUDIO_ROUTE_EARPIECE:
         self.log.error(
             "Audio Route not set to {}".format(AUDIO_ROUTE_EARPIECE))
         return False
     input("Press enter to switch to Bluetooth...")
     self.log.info("Switching to Bluetooth...")
     set_audio_route(self.log, pri_dut, AUDIO_ROUTE_BLUETOOTH)
     time.sleep(self.short_timeout)
     if get_audio_route(self.log, pri_dut) != AUDIO_ROUTE_BLUETOOTH:
         self.log.error(
             "Audio Route not set to {}".format(AUDIO_ROUTE_BLUETOOTH))
         return False
     input("Press enter to hangup call...")
     self.log.info("Hanging up call...")
     pri_dut.droid.telecomCallStopDtmfTone(call_id)
     if not hangup_call(self.log, pri_dut):
         self.log.error("Failed to hangup call")
         return False
     return True
 def outgoing_call_multiple_iterations(self, pri_dut, sec_dut):
     iteration_count = 3
     self.log.info(
         "Test outgoing call scenario from phone {} times from known contact"
         .format(iteration_count))
     input("Press enter to execute this testcase...")
     outgoing_num = get_phone_number(self.log, sec_dut)
     for _ in range(iteration_count):
         if not initiate_call(self.log, pri_dut, outgoing_num):
             self.log.error("Failed to initiate call")
             return False
         if not wait_and_answer_call(self.log, sec_dut):
             self.log.error("Failed to answer call.")
             return False
         time.sleep(self.short_timeout)
         if not hangup_call(self.log, pri_dut):
             self.log.error("Failed to hangup call")
             return False
     return True
 def sms_during_incomming_call(self, pri_dut, sec_dut):
     self.log.info(
         "Test incomming call scenario to phone from unknown contact")
     input("Press enter to execute this testcase...")
     outgoing_num = get_phone_number(self.log, pri_dut)
     if not initiate_call(self.log, sec_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, pri_dut):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     msg = [rand_ascii_str(10)]
     if not sms_send_receive_verify(self.log, sec_dut, pri_dut, msg):
         return False
     else:
         self.log.info("Successfully sent sms. Please verify on carkit.")
     input("Press enter to hangup call...")
     if not hangup_call(self.log, sec_dut):
         self.log.error("Failed to hangup call")
         return False
     return True
 def outgoing_call_a2dp_play_before_and_after(self, pri_dut, sec_dut):
     self.log.info(
         "Test outgoing call scenario while playing music. Music should resume after call."
     )
     pri_dut.adb.shell(KEYCODE_EVENT_PREVIOUS)
     input(
         "Press enter to execute this testcase when music is in a play state..."
     )
     outgoing_num = get_phone_number(self.log, sec_dut)
     if not initiate_call(self.log, pri_dut, outgoing_num):
         self.log.error("Failed to initiate call")
         return False
     if not wait_and_answer_call(self.log, sec_dut):
         self.log.error("Failed to answer call.")
         return False
     time.sleep(self.short_timeout)
     input("Press enter to hangup call...")
     if not hangup_call(self.log, pri_dut):
         self.log.error("Failed to hangup call")
         return False
     input("Press enter when music continues to play.")
     self.log.info("Pausing Music...")
     pri_dut.adb.shell(KEYCODE_EVENT_PLAY_PAUSE)
     return True
示例#13
0
    def test_call_transfer_connect_disconnect_connect(self):
        """
        Test that when we go from connect -> disconnect -> connect on an active
        call then the call is restored on HF.

        Precondition:
        1. AG & HF are paired

        Steps:
        0. Connect AG & HF
        1. Make a call from HF role
        2. Accept from RE role and transition the call to Active
        3. Disconnect AG & HF
        4. Verify that we don't have any calls on HF
        5. Connect AG & HF
        6. Verify that HF gets the call back.

        Returns:
          Pass if True
          Fail if False

        Priority: 1
        """
        # Now connect the devices.
        if not bt_test_utils.connect_pri_to_sec(
                self.hf, self.ag,
                set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
            self.log.error("Could not connect HF and AG {} {}".format(
                self.hf.serial, self.ag.serial))
            return False

        # make a call on HF
        if not car_telecom_utils.dial_number(self.log, self.hf,
                                             self.re_phone_number):
            self.hf.log.error("HF not in dialing state.")
            return False

        # Wait for HF, AG to be dialing and RE to be ringing
        ret = True
        ret &= car_telecom_utils.wait_for_dialing(self.log, self.hf)
        #uncomment once sl4a code has been merged.
        ret &= car_telecom_utils.wait_for_dialing(self.log, self.ag)
        ret &= car_telecom_utils.wait_for_ringing(self.log, self.re)

        if not ret:
            self.log.error("Outgoing call did not get established")
            return False

        # Accept call on RE.
        if not wait_and_answer_call(self.log, self.re):
            self.re.log.error("Failed to accept call on re.")
            return False

        ret &= car_telecom_utils.wait_for_active(self.log, self.hf)
        ret &= car_telecom_utils.wait_for_active(self.log, self.ag)
        ret &= car_telecom_utils.wait_for_active(self.log, self.re)

        if not ret:
            self.log.error("Outgoing call did not transition to active")
            return False

        # Disconnect HF & AG
        self.hf.droid.bluetoothDisconnectConnected(
            self.ag.droid.bluetoothGetLocalAddress())

        # We use the proxy of the Call going away as HF disconnected
        if not car_telecom_utils.wait_for_not_in_call(self.log, self.hf):
            self.hf.log.error("HF still in call after disconnection.")
            return False

        # Now connect the devices.
        if not bt_test_utils.connect_pri_to_sec(
                self.hf, self.ag,
                set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
            self.log.error("Could not connect HF and AG {} {}".format(
                self.hf.serial, self.ag.serial))
            # Additional profile connection check for b/
            if not bt_test_utils.is_hfp_client_device_connected(
                    self.hf, self.ag.droid.bluetoothGetLocalAddress()):
                self.hf.log.info(
                    "HFP Client connected even though connection state changed "
                    + " event not found")
                return False

        # Check that HF is in active state
        if not car_telecom_utils.wait_for_active(self.log, self.hf):
            self.hf.log.error("HF not in Active state.")
            return False

        # Hangup the call and check all devices are clean
        self.hf.droid.telecomEndCall()
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf)
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag)
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re)

        return ret
示例#14
0
    def test_call_transfer_off_on(self):
        """
        Tests that after we turn adapter on when an active call is in
        progress, we show the call.

        Precondition:
        1. AG & HF are disconnected but paired.
        2. HF's adapter is OFF

        Steps:
        1. Make a call from AG role (since disconnected)
        2. Accept from RE role and transition the call to Active
        3. Turn HF's adapter ON
        4. HF should transition into Active call state.

        Returns:
          Pass if True
          Fail if False

        Priority: 1
        """
        # Connect HF & AG
        if not bt_test_utils.connect_pri_to_sec(
                self.hf, self.ag,
                set([BtEnum.BluetoothProfile.HEADSET_CLIENT.value])):
            self.log.error("Could not connect HF and AG {} {}".format(
                self.hf.serial, self.ag.serial))
            return False

        # make a call on AG
        if not initiate_call(self.log, self.ag, self.re_phone_number):
            self.ag.log.error("Failed to initiate call from ag.")
            return False

        # Wait for all HF
        if not car_telecom_utils.wait_for_dialing(self.log, self.hf):
            self.hf.log.error("HF not in ringing state.")
            return False

        # Accept the call on RE
        if not wait_and_answer_call(self.log, self.re):
            self.re.log.error("Failed to accept call on re.")
            return False
        # Wait for all HF, AG, RE to go into an Active state.
        if not car_telecom_utils.wait_for_active(self.log, self.hf):
            self.hf.log.error("HF not in Active state.")
            return False
        if not car_telecom_utils.wait_for_active(self.log, self.ag):
            self.ag.log.error("AG not in Active state.")
            return False
        if not car_telecom_utils.wait_for_active(self.log, self.re):
            self.re.log.error("RE not in Active state.")
            return False

        # Turn the adapter OFF on HF
        if not bt_test_utils.disable_bluetooth(self.hf.droid):
            self.hf.log.error("Failed to turn BT off on HF.")
            return False

        # Turn adapter ON on HF
        if not bt_test_utils.enable_bluetooth(self.hf.droid, self.hf.ed):
            self.hf.log.error("Failed to turn BT ON after call on HF.")
            return False

        # Check that HF is in active state
        if not car_telecom_utils.wait_for_active(self.log, self.hf):
            self.hf.log.error("HF not in Active state.")
            return False

        # Hangup the call and check all devices are clean
        self.hf.droid.telecomEndCall()
        ret = True
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.hf)
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.ag)
        ret &= car_telecom_utils.wait_for_not_in_call(self.log, self.re)

        return ret
    def _telephony_monitor_test(self):
        """
        Steps -
        1. Reboot the phone
        2. Start Telephony Monitor using adb/developer options
        3. Verify if it is running
        4. Phone Call from A to B
        5. Answer on B
        6. Trigger ModemSSR on B
        7. There will be a call drop with Media Timeout/Server Unreachable
        8. Parse logcat to confirm that

        Expected Results:
            UI Notification is received by User

        Returns:
            True is pass, False if fail.
        """
        # Reboot
        ads = self.android_devices
        ads[0].adb.shell(
            "am start -n com.android.settings/.DevelopmentSettings",
            ignore_status=True)
        ads[0].log.info("reboot!")
        ads[0].reboot()
        ads[0].log.info("wait %d secs for radio up." % WAIT_TIME_AFTER_REBOOT)
        time.sleep(WAIT_TIME_AFTER_REBOOT)

        # Ensure apk is running
        if not ads[0].is_apk_running("com.google.telephonymonitor"):
            ads[0].log.info("TelephonyMonitor is not running, start it now")
            ads[0].adb.shell(
                'am broadcast -a '
                'com.google.gservices.intent.action.GSERVICES_OVERRIDE -e '
                '"ce.telephony_monitor_enable" "true"')

        # Setup Phone Call
        caller_number = ads[0].cfg['subscription'][get_outgoing_voice_sub_id(
            ads[0])]['phone_num']
        callee_number = ads[1].cfg['subscription'][get_incoming_voice_sub_id(
            ads[1])]['phone_num']
        tasks = [(phone_setup_voice_general, (self.log, ads[0])),
                 (phone_setup_voice_general, (self.log, ads[1]))]
        if not multithread_func(self.log, tasks):
            self.log.error("Phone Failed to Set Up Properly.")
            return False

        if not initiate_call(ads[0].log, ads[0], callee_number):
            ads[0].log.error("Phone was unable to initate a call")
            return False
        if not wait_and_answer_call(self.log, ads[1], caller_number):
            ads[0].log.error("wait_and_answer_call failed")
            return False

        # Modem SSR
        time.sleep(5)
        ads[1].log.info("Triggering ModemSSR")
        ads[1].adb.shell("echo restart > /sys/kernel/debug/msm_subsys/modem",
                         ignore_status=True)
        time.sleep(60)

        # Parse logcat for UI notification
        if ads[0].search_logcat("Bugreport notification title Call Drop:"):
            ads[0].log.info("User got the Call Drop Notification")
        else:
            ads[0].log.error("User didn't get Call Drop Notification in 1 min")
            return False
        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)