Ejemplo n.º 1
0
    def monitor_audio(self, loop_iteration):
        self._logger.debug(
            "RunAudioStreaming: Listening for silence on the PC line in.")
        audio_output_file = os.path.join(
            self.log_directory, "captured_audio_%d.mp3" % loop_iteration)
        self._logger.info(
            "RunAudioStreaming: Saving audio capture data to %s" %
            audio_output_file)

        #calculate how much time is left in the test run
        listen_time = self.runtime_seconds - (time.time() - self.start_time)
        #if greater than MONITORING_CHUNK_SIZE, then limit this chunk to that size
        if listen_time > self._pars.monitoring_chunk_size * 60:
            listen_time = self._pars.monitoring_chunk_size * 60
        #Use AudioUtilities function that records audio and checks for unexpected silence.  Use the
        #silence_threshold_seconds to account for expected breaks between songs, and silence_threshold to adjust for the noise floor.
        silence_offsets = audio_verification.verify_audio_input(
            output_file_path=audio_output_file,
            silence_threshold_seconds=10,
            silence_callback_func=self.debug_silence_thread,
            audio_resume_callback_func=None,
            listen_len_seconds=listen_time,
            silence_threshold=300)
        if len(silence_offsets) > 0:
            silence_offset_str = ""
            for offset_pair in silence_offsets:
                silence_begin_minutes = int(offset_pair[0] / 60)
                silence_begin_seconds = int(offset_pair[0] -
                                            (silence_begin_minutes * 60))
                silence_end_minutes = int(offset_pair[1] / 60)
                silence_end_seconds = int(offset_pair[1] -
                                          (silence_end_minutes * 60))
                silence_offset_str += "%d:%02d-%d:%02d, " % (
                    silence_begin_minutes, silence_begin_seconds,
                    silence_end_minutes, silence_end_seconds)
            # Remove the comma at the end
            silence_offset_str = silence_offset_str[:-2]
            self._logger.error(
                "RunAudioStreaming: Silence detected at offset " +
                silence_offset_str)
            self._logger.error(
                "RunAudioStreaming: FAILED -- detected excessive silence.")
            return False

        return True
Ejemplo n.º 2
0
    def run_test(self):
        """
        Execute the test
        """
        # Call LabAudioVcBase Run Test function
        LabAudioWcdmaVcBase.run_test(self)

        # Initiate a MO voice call
        if self._vc_type == "MO":

            # Dial using phone number
            self._logger.info("Calling %s ..." % self._phone_number)
            self._voicecall_api.dial(self._phone_number)

            # Check call status before callSetupTimeout (NS)
            self._vc_3g.check_call_connected(self._call_setup_time,
                                             blocking=False)

            # Check call status before callSetupTimeout (DUT)
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.ACTIVE,  # pylint: disable=E1101
                self._call_setup_time)

        else:
            # Initiate a MT voice call
            self._vc_3g.mt_originate_call()
            # pylint: disable=E1101
            # Check call status is incoming before callSetupTimeout
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.INCOMING,
                self._call_setup_time)

            # Answer incoming call
            self._voicecall_api.answer()

            # Check call status before callSetupTimeout (NS)
            self._vc_3g.check_call_connected(self._call_setup_time,
                                             blocking=False)

            # Check call status before callSetupTimeout (DUT)
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.ACTIVE,
                self._call_setup_time)

        start_time = time.localtime()

        # Configure Audio output to headset (jack)
        time.sleep(self._wait_btwn_cmd)
        self._phonesystem_api.switch_audio_output("headset")

        # Set Voice Call Volume
        self._system_api.adjust_specified_stream_volume(
            "VoiceCall", self._call_stream_volume_dut)

        if self._elapsed_time > 0:
            self._elapsed_time = 0

        self._logger.info(
            "Start verifying audio routing - Call duration = %d s" %
            self._call_duration)

        while self._elapsed_time < self._call_duration:

            # Scenario 1: The audio analyzer is an equipment (RS UPV here)
            if self._audio_analyzer_node.get_param_value("Model") in "RS_UPV":

                # Load UPV setup for DL path
                self._audio_analyzer.load_configuration(
                    self._name, str(self._ns_node.get_param_value("Model")),
                    self._aa_ref_file_path, self._codec_type, "DL")

                # Perform audio routing verification for DL path first
                self._logger.info("Verify audio routing in DL")
                self._audio_analyzer.start_single_measurement()

                # Wait for the measurement to end
                self._audio_analyzer.wait_for_sweep_state("sweep_waiting")

                # Transfer the result of the measurement to ACS host
                self._audio_analyzer.store_data_list(
                    self._aa_trace_file_path_dl, self._host_trace_file_path_dl,
                    "SWEep")

                # Get the dynamic range indicator for DL audio path
                res_dl = AudioUtil.get_rms_from_sweep(
                    AudioUtil.get_sweep_trace(self._host_trace_file_path_dl),
                    self._logger)

                # Load UPV setup for UL path
                self._audio_analyzer.load_configuration(
                    self._name, str(self._ns_node.get_param_value("Model")),
                    self._aa_ref_file_path, self._codec_type, "UL")

                # Perform audio routing verification for UL path
                self._logger.info("Verify audio routing in UL")
                self._audio_analyzer.start_single_measurement()

                # Wait for the measurement to end
                self._audio_analyzer.wait_for_sweep_state("sweep_waiting")

                # Transfer the result of the measurement to ACS host
                self._audio_analyzer.store_data_list(
                    self._aa_trace_file_path_ul, self._host_trace_file_path_ul,
                    "SWEep")

                # Get the dynamic range indicator for UL audio path
                res_ul = AudioUtil.get_rms_from_sweep(
                    AudioUtil.get_sweep_trace(self._host_trace_file_path_ul),
                    self._logger)

                if res_dl > self._dynamic_threshold and res_ul > self._dynamic_threshold:
                    self._error.Msg = "Audio correctly routed in both DL and UL - " + \
                                      "Dynamic indicator : DL = %f / UL = %f" % (res_dl, res_ul)
                    self._logger.info(self._error.Msg)
                    self._result_verdict = Global.SUCCESS
                elif res_dl < self._dynamic_threshold and res_ul > self._dynamic_threshold:
                    self._error.Msg = "Audio routing error in DL - " + \
                                      "Dynamic indicator : DL = %f / UL = %f" % (res_dl, res_ul)
                    self._logger.error(self._error.Msg)
                    self._result_verdict = Global.FAILURE
                elif res_ul < self._dynamic_threshold and res_dl > self._dynamic_threshold:
                    self._error.Msg = "Audio routing error in UL - " + \
                                      "Dynamic indicator : DL = %f / UL = %f" % (res_dl, res_ul)
                    self._logger.error(self._error.Msg)
                    self._result_verdict = Global.FAILURE
                else:
                    self._error.Msg = "Audio routing error in both DL and UL - " + \
                                      "Dynamic indicator : DL = %f / UL = %f" % (res_dl, res_ul)
                    self._logger.error(self._error.Msg)
                    self._result_verdict = Global.FAILURE

                if self._keep_record:
                    # Update the name of the trace file, in case of back-to-back and KEEP_RECORD = true
                    self._host_trace_file_path_dl = self._host_trace_file_path_dl.strip(self._host_trace_file_path_dl.split('_')[-1]) + \
                                                 str(self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 1) \
                                                 + ".trc"
                    self._host_trace_file_path_ul = self._host_trace_file_path_ul.strip(self._host_trace_file_path_ul.split('_')[-1]) + \
                                                 str(self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 1) \
                                                 + ".trc"
                else:
                    os.remove(self._host_trace_file_path_dl)
                    os.remove(self._host_trace_file_path_ul)

                self._tc_iteration_count -= 1

            # Scenario 2: The audio analyzer is an external python framework
            elif self._audio_analyzer_node.get_param_value(
                    "Model") in "AUDIO_FRAMEWORK":
                [self._result_verdict,
                 self._error.Msg] = AudioFramework.start_audio_routing(
                     self._audio_framework,
                     self._ref_file,
                     self._audio_framework_timeout,
                     wait_for_timeout=1)

            if self._result_verdict is Global.FAILURE:
                break

            # Wait for the next measurement to be made while checking the CSV call is still active
            self._vc_3g.is_voice_call_connected(self._wait_between_measure)

            # Get elapsed time since call establishment in s
            self._elapsed_time = self.__get_elapsed_time(
                start_time, time.localtime())
            self._logger.info(
                "Time elapsed since the beginning of the call: %d s" %
                self._elapsed_time)

        # Release the call
        self._vc_3g.voice_call_network_release()

        try:
            # Check call is released (NS)
            self._vc_3g.check_call_idle(self._registration_timeout,
                                        blocking=False)

            # Check call is released (CDK)
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.NOCALL,  # pylint: disable=E1101
                self._call_setup_time)

        except AcsBaseException as acs_exception:
            self._logger.warning("Call release fail:" + str(acs_exception))

        return self._result_verdict, self._error.Msg
Ejemplo n.º 3
0
    def run_test(self):
        """
        Execute the test
        """
        # Call LabAudioActivityBase run_test function
        LabAudioActivityBase.run_test(self)

        self._phone_calling.wait_for_state(
            self._uecmd_types.SIP_CALL_STATE.READY_TO_CALL,
            self._call_setup_time)

        # In case only 1 phone is used, no need to make verifications on reference phone (assuming MO call)
        if self._phone_receiving:
            self._phone_receiving.wait_for_state(
                self._uecmd_types.SIP_CALL_STATE.READY_TO_CALL,
                self._call_setup_time)

        # Dial using PHONE_NUMBER parameter
        if self._phone2 is not None:
            self._phone_calling.dial(self._calling_phone_number)
        else:
            self._phone_calling.dial(self._calling_phone_number,
                                     check_state=False)

        if self._phone_receiving:
            self._phone_receiving.wait_for_state(
                self._uecmd_types.SIP_CALL_STATE.INCOMING_CALL,
                self._call_setup_time)

            self._phone_receiving.answer()
            # Phone1 & 2 : Check voice call is active
        self._phone_calling.wait_for_state(
            self._uecmd_types.SIP_CALL_STATE.IN_CALL, self._call_setup_time)

        if self._phone_receiving:
            self._phone_receiving.wait_for_state(
                self._uecmd_types.SIP_CALL_STATE.IN_CALL,
                self._call_setup_time)

        # Configure Audio output to acc_type given with the test_case
        if self._acc_type == "EARPIECE":
            self._sip_call_api.switch_to_earpiece()
            if self._use_io_card:
                self._wired_headset.unplug_whs()
                self._wired_headset.unplug_headphone()
            time.sleep(self._wait_btwn_cmd)
        elif self._acc_type == "SPEAKER":
            self._sip_call_api.switch_to_speaker()
            time.sleep(self._wait_btwn_cmd)
        elif self._acc_type == "HEADSET":
            if self._use_io_card:
                self._sip_call_api.switch_to_earpiece()
                self._wired_headset.unplug_headphone()
                self._wired_headset.plug_whs()
        elif self._acc_type == "HEADPHONE":
            if self._use_io_card:
                self._sip_call_api.switch_to_earpiece()
                self._wired_headset.unplug_whs()
                self._wired_headset.plug_headphone()
        elif self._acc_type == "BLUETOOTHHSP" or self._acc_type == "BLUETOOTHHFP":
            self._sip_call_api.switch_to_bluetooth()
        elif self._acc_type == "BLUETOOTHA2DP":
            self._sip_call_api.switch_to_bluetooth_a2dp()
        else:
            self._logger.error("Unknown accessories")
            raise AcsConfigException(AcsConfigException.OPERATION_FAILED,
                                     "Unknown accessories")
        time.sleep(self._wait_btwn_cmd)

        if self._acc_type.find("BLUETOOTH") == -1:
            # Set Voice Call Volume
            self._system_api.adjust_specified_stream_volume(
                "VoiceCall", self._call_stream_volume_dut)
        else:
            # Set Voice Call Volume
            self._system_api.adjust_specified_stream_volume(
                "Bluetooth", self._call_stream_volume_dut)

        if self._phone_receiving:
            self._system_api2.adjust_specified_stream_volume(
                "VoiceCall", self._call_stream_volume_ref)

        # WAIT FOR CALL DURATION
        self._logger.info("Wait for call duration: %s s..." %
                          str(self._call_duration))
        time.sleep(self._call_duration)

        # STRESS WHS PLUG / UNPLUG
        if self._use_io_card:
            self._wired_headset.unplug_whs()
            time.sleep(2)
            self._wired_headset.plug_whs()
            time.sleep(2)
            self._wired_headset.unplug_whs()
            time.sleep(2)
            self._wired_headset.plug_whs()
            time.sleep(2)
            self._wired_headset.unplug_whs()
            time.sleep(2)
            self._wired_headset.plug_whs()
            time.sleep(2)
            self._wired_headset.unplug_whs()
            time.sleep(2)
            self._wired_headset.plug_whs()
            time.sleep(2)
            self._wired_headset.unplug_whs()
            time.sleep(2)
            self._wired_headset.plug_whs()
            time.sleep(2)
            self._wired_headset.unplug_whs()
            time.sleep(2)
            self._wired_headset.plug_whs()
            time.sleep(2)
        if self._audio_analyzer_node.get_param_value("Model") in "APx585":

            # Launch audio_quality test
            if self._signal_tested_direction in ["UL", "DL"]:
                audio_analyzer_result = self._audio_analyzer.run(
                    self._call_type, self._acc_type,
                    self._signal_tested_direction)

                # Compute test verdict and comment verdict
                LabAudioActivityBase.__compute_test_verdict__(
                    self, audio_analyzer_result)

            else:
                # Test both UL and DL audio output
                audio_analyzer_result_ul = self._audio_analyzer.run(
                    self._call_type, self._acc_type, "ul")

                audio_analyzer_result_dl = self._audio_analyzer.run(
                    self._call_type, self._acc_type, "dl")

                # Compute test verdict and comment verdict for UL
                LabAudioActivityBase.__compute_test_verdict__(
                    self, audio_analyzer_result_ul)

                if self._result_verdict is Global.SUCCESS:
                    tmp = self._verdict_comment

                    # Compute test verdict and comment verdict for DL
                    LabAudioActivityBase.__compute_test_verdict__(
                        self, audio_analyzer_result_dl)

                    if self._result_verdict is Global.SUCCESS:
                        self._verdict_comment += tmp

        elif self._audio_analyzer_node.get_param_value("Model") in "RS_UPV":

            # Perform audio routing verification for DL path first
            self._audio_analyzer.start_single_measurement()

            # Wait for the measurement to end
            time.sleep(12)

            # Transfer the result of the measurement to ACS host
            self._audio_analyzer.store_data_list(self._aa_trace_file_path,
                                                 self._host_trace_file_path,
                                                 "SWEep")

            # Get the dynamic range indicator for DL audio path
            res_dl = AudioUtil.get_rms_from_sweep(
                AudioUtil.get_sweep_trace(self._host_trace_file_path),
                self._logger)

            if res_dl > self._dynamic_threshold:
                self._verdict_comment = "Audio correctly routed - " + \
                                        "Dynamic indicator : %f" % res_dl
                self._logger.info(self._verdict_comment)
                self._result_verdict = Global.SUCCESS
            else:
                self._verdict_comment = "Audio routing error - " + \
                                        "Dynamic indicator : %f" % res_dl
                self._logger.error(self._verdict_comment)
                self._result_verdict = Global.FAILURE

            if self._keep_record and self._result_verdict < 0:
                # Update the name of the trace file, in case of back-to-back and KEEP_RECORD = true
                self._tc_iteration_count -= 1
                self._host_trace_file_path = self._host_trace_file_path.strip(
                    self._host_trace_file_path.split('_')[-1]) + \
                                             str(self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 1) \
                                             + ".trc"
            else:
                os.remove(self._host_trace_file_path)

        # RELEASE THE CALL
        # Phone1 & 2 : Check call is still active
        self._phone_calling.wait_for_state(
            self._uecmd_types.SIP_CALL_STATE.IN_CALL, self._call_setup_time)

        if self._phone_receiving:
            self._phone_receiving.wait_for_state(
                self._uecmd_types.SIP_CALL_STATE.IN_CALL,
                self._call_setup_time)

        self._phone_releasing.release()

        self._phone_releasing.wait_for_state(
            self._uecmd_types.SIP_CALL_STATE.READY_TO_CALL,
            self._call_setup_time)

        if self._phone_receiving:
            self._phone_receiving.wait_for_state(
                self._uecmd_types.SIP_CALL_STATE.READY_TO_CALL,
                self._call_setup_time)

        return self._result_verdict, self._verdict_comment
Ejemplo n.º 4
0
    def run_test(self):
        """
        Execute the test
        """
        # Call LabAudioVcBase Run Test function
        LabAudioWcdmaVcBase.run_test(self)

        # Initiate a MO voice call
        if self._vc_type == "MO":

            # Dial using phone number
            self._logger.info("Calling %s ..." % self._phone_number)
            self._voicecall_api.dial(self._phone_number)

            # Check call status before callSetupTimeout (NS)
            self._vc_3g.check_call_connected(self._call_setup_time,
                                             blocking=False)

            # Check call status before callSetupTimeout (DUT)
            self._voicecall_api.wait_for_state(self._uecmd_types.VOICE_CALL_STATE.ACTIVE,  # pylint: disable=E1101
                                               self._call_setup_time)

        else:
            # Initiate a MT voice call
            self._vc_3g.mt_originate_call()
            # pylint: disable=E1101
            # Check call status is incoming before callSetupTimeout
            self._voicecall_api.wait_for_state(self._uecmd_types.VOICE_CALL_STATE.INCOMING,
                                               self._call_setup_time)

            # Answer incoming call
            self._voicecall_api.answer()

            # Check call status before callSetupTimeout (NS)
            self._vc_3g.check_call_connected(self._call_setup_time,
                                             blocking=False)

            # Check call status before callSetupTimeout (DUT)
            self._voicecall_api.wait_for_state(self._uecmd_types.VOICE_CALL_STATE.ACTIVE,
                                               self._call_setup_time)

        # Set Voice Call Volume at 100%
        self._system_api.adjust_specified_stream_volume("VoiceCall", 100)

        # Set source input for the recording
        self._psi_recorder.set_source_input(self._rec_source)

        # Start recording the voice call
        self._psi_recorder.start()

        # Step 1: Start detecting recording tone with no speech in UPV uplink audio path
        self._logger.info("Step 1: Start detecting recording tone with no speech in UPV uplink audio path")

        if(AudioUtil.detect_recording_tone(self._em.get_audio_analyzer("AUDIO_ANALYZER"),
                                                               self._time_between_tones,
                                                               self._tone_frequency,
                                                               self._logger)):
            self._logger.info("Recording tone detected on the UL signal on the UPV without any speech")

            # Send an audio signal which contains speech
            self._audio_analyzer.load_waveform(self._aa_speech_file_path)

            # Step 2: Start detecting recording tone with speech in UPV uplink audio path
            self._logger.info("Step 2: Start detecting recording tone with speech in UPV uplink audio path")

            if(AudioUtil.detect_recording_tone(self._em.get_audio_analyzer("AUDIO_ANALYZER"),
                                                                           self._time_between_tones,
                                                                           self._tone_frequency,
                                                                           self._logger)):
                self._logger.info("Recording tone detected on the UL signal on the UPV with speech")

                # Send an audio signal which contains silence only
                self._audio_analyzer.load_waveform(self._aa_ref_file_path)

                # Step 3: Start detecting recording tone with no speech in UPV uplink audio path
                self._logger.info("Step 3: Start detecting recording tone with no speech in UPV uplink audio path")

                if(AudioUtil.detect_recording_tone(self._em.get_audio_analyzer("AUDIO_ANALYZER"),
                                                               self._time_between_tones,
                                                               self._tone_frequency,
                                                               self._logger)):
                    self._logger.info("Recording tone detected on the UL signal on the UPV without any speech")

                    # Stop recording the voice call
                    self._psi_recorder.stop()

                    # Step 4: Check that no recording tones are generated in UL
                    self._logger.info("Step 4: Check that no recording tones are generated in UL")
                    if(not AudioUtil.detect_recording_tone(self._em.get_audio_analyzer("AUDIO_ANALYZER"),
                                                               self._time_between_tones,
                                                               self._tone_frequency,
                                                               self._logger)):
                        self._logger.info("No recording tone detected while recorder is stopped")
                        self._verdict_comment = "Recording tone successfully detected during voice call"
                        self._result_verdict = Global.SUCCESS
                    else:
                        self._logger.error("Recording tone detected while recorder is stopped")
                else:
                    self._logger.error("Recording tone not detected in the UL signal")
                    # Stop recording the voice call
                    self._psi_recorder.stop()
            else:
                self._logger.error("Recording tone not detected in the UL signal")
                # Stop recording the voice call
                self._psi_recorder.stop()
        else:
            self._logger.error("Recording tone not detected in the UL signal")
            # Stop recording the voice call
            self._psi_recorder.stop()

        # Release the call
        self._vc_3g.voice_call_network_release()

        try:
            # Check call is released (NS)
            self._vc_3g.check_call_idle(self._registration_timeout,
                                        blocking=False)

            # Check call is released (DUT)
            self._voicecall_api.wait_for_state(self._uecmd_types.VOICE_CALL_STATE.NOCALL,  # pylint: disable=E1101
                                               self._call_setup_time)

        except AcsBaseException as acs_exception:
            self._logger.error("Call release fail:" + str(acs_exception))

        return self._result_verdict, self._verdict_comment
Ejemplo n.º 5
0
 def __init__(self, tc_conf, global_conf, ts_conf, factory):
     TestStepBase.__init__(self, tc_conf, global_conf, ts_conf, factory)
     self._audio_host_api = AudioUtils.AudioPlayer(self._logger)
Ejemplo n.º 6
0
    def audio_streaming_monitor_function(self):
        # Listen for silence
        # Do it again
        start_time = time.time()

        # Subtract 30 seconds from runtime because we generally have to wait some time to ensure audio playback has started.
        runtime_seconds = (self._pars.duration * 60) - 30
        loop_iteration = 0
        test_passed = True  # Start with True. Change to false on failure.

        while time.time() - start_time < runtime_seconds:
            loop_iteration += 1
            self._logger.info(self._pars.id + ": Loop %d" % loop_iteration)

            self._logger.debug(self._pars.id +
                               ": Listening for silence on the PC line in.")
            audio_output_file = os.path.join(
                self.report_path, "captured_audio_%d.mp3" % loop_iteration)
            self._logger.info(self._pars.id +
                              ": Saving audio capture data to %s" %
                              audio_output_file)
            # To keep from timing out in the app and to keep our wav files at a manageable size, limit listen_time to something less than 30 minutes.  Especially in longer test runs.
            listen_time = runtime_seconds - (time.time() - start_time)
            if listen_time > self._pars.listen_length * 60:
                listen_time = self._pars.listen_length * 60
            try:
                silence_offsets = audio_verification.verify_audio_input(
                    output_file_path=audio_output_file,
                    silence_threshold_seconds=self._pars.
                    silence_threshold_length,
                    silence_callback_func=self.debug_silence_in_new_thread,
                    audio_resume_callback_func=None,
                    listen_len_seconds=listen_time,
                    silence_threshold=self._pars.silence_threshold_raw)
            except IOError as e:
                self._logger.debug(
                    self._pars.id +
                    ": I/o error({0}) from verify_audio_input:  {1}".format(
                        e.errno, e.strerror))
                raise
            except:
                self._logger.debug(
                    self._pars.id +
                    ": Unexpected error occured from verify_audio_input\n" +
                    traceback.format_exc())
                raise
            if len(silence_offsets) > 0:
                silence_offset_str = ""
                for offset_pair in silence_offsets:
                    silence_begin_minutes = int(offset_pair[0] / 60)
                    silence_begin_seconds = int(offset_pair[0] -
                                                (silence_begin_minutes * 60))
                    silence_end_minutes = int(offset_pair[1] / 60)
                    silence_end_seconds = int(offset_pair[1] -
                                              (silence_end_minutes * 60))
                    silence_offset_str += "%d:%02d-%d:%02d, " % (
                        silence_begin_minutes, silence_begin_seconds,
                        silence_end_minutes, silence_end_seconds)
                # Remove the comma at the end
                silence_offset_str = silence_offset_str[:-2]
                self._logger.error(self._pars.id +
                                   ": Silence detected at offset " +
                                   silence_offset_str)
                self._logger.error(
                    self._pars.id +
                    ": Setting test result to FAIL due to silence detected.")
                test_passed = False
            self._logger.debug(self._pars.id + ": End of monitoring loop.")
        if test_passed:
            self._logger.info(self._pars.id + ": Monitoring loop passed!")
        else:
            self._logger.error(self._pars.id + ": Monitoring loop failed!!")
            self.ts_verdict_msg = self._pars.id + ":  Monitoring loop failed!!"
            raise DeviceException(
                DeviceException.OPERATION_FAILED,
                self._pars.id + ": Test has failed while monitoring audio!")
    def run_test(self):
        """
        Execute the test
        """

        # Call UseCaseBase Run Test function
        UseCaseBase.run_test(self)

        # Check registration status before registrationTimeout (CDK)
        self._modem_api.check_cdk_registration_bfor_timeout(
            self._registration_timeout * 2)

        # Data Connection State verification in 2G
        self._ns1_data.check_data_connection_state(
            self._expected_data_connection_state_2g, 30)

        # The flight mode activation can be iterative
        for i in range(int(self._flightmode_b2b_iteration)):

            # Activate flight mode
            self._networking_api.set_flight_mode("on")

            # The flight mode activation/disactivation can be either toggled, or separated by a timer
            if not self._toggle_flight_mode:
                # Wait 30s while airplane mode is enabled
                time.sleep(30)

                if self._ns1_cell_tech not in self._ns2_cell_tech:
                    self._logger.info("Switch to 3G cell")

                    # Disconnect network simulator
                    self._ns.release()

                    # Connect to cellular network simulator
                    self._ns.init()

                    # Set the equipment application format WCDMA
                    self._ns.switch_app_format("WCDMA")

                    # Perform Full Preset
                    self._ns.perform_full_preset()

                    # Set paging service to AMR VOICE
                    self._ns2_cell.set_cell_service(self._ns2_cell_service)

                    # Set cell off
                    self._ns2_cell.set_cell_off()

                    # Set Cell Band UARFCN (downlink) using Band and DlUarfcn
                    self._ns2_cell.set_band_and_dl_arfcn(
                        "BAND" + str(self._ns2_cell_band_name),
                        self._ns2_cell_arfcn)

                    # Set voice call output
                    self._ns2_vc.set_speech_configuration("SPEECH_OUTPUT")

                    # Set cell on
                    self._ns2_cell.set_cell_on()

            # Deactivate flight mode
            self._networking_api.set_flight_mode("off")

        if self._wait_for_registration:
            # Check registration status before registrationTimeout (CDK)
            self._modem_api.check_cdk_registration_bfor_timeout(
                self._registration_timeout * 2)

        # Data Connection State verification in 3G
        self._ns2_data.check_data_connection_state(
            self._expected_data_connection_state_3g, 30)

        # Initiate a MT voice call from the 3G cell
        self._ns2_vc.mt_originate_call()

        # Check call status before callSetupTimeout (DUT)
        self._voicecall_api.wait_for_state(
            self._uecmd_types.VOICE_CALL_STATE.INCOMING, self._call_setup_time)

        # Answer incoming call
        self._voicecall_api.answer()

        # Check call status before callSetupTimeout (NS)
        self._ns2_vc.check_call_connected(self._call_setup_time,
                                          blocking=False)

        # Check call status before callSetupTimeout (DUT)
        self._voicecall_api.wait_for_state(
            self._uecmd_types.VOICE_CALL_STATE.ACTIVE, self._call_setup_time)

        # Configure Audio output to headset (jack)
        time.sleep(self._wait_btwn_cmd)
        self._phonesystem_api.switch_audio_output("headset")

        # Set Voice Call Volume
        self._system_api.adjust_specified_stream_volume(
            "VoiceCall", self._call_stream_volume_dut)

        # Load setup on UPV
        self._audio_analyzer.load_configuration(
            self._name, str(self._ns_node.get_param_value("Model")), None,
            None, "DL")

        time.sleep(self._wait_btwn_cmd)

        # Perform audio routing verification for DL path first
        self._logger.info("Verify audio routing in DL")
        self._audio_analyzer.start_single_measurement()

        # Wait until the measurement ends
        self._audio_analyzer.wait_for_sweep_state("Sweep_Waiting")

        # Transfer the result of the measurement to ACS host
        self._audio_analyzer.store_data_list(self._aa_trace_file_path_dl_1,
                                             self._host_trace_file_path_dl_1,
                                             self._trace_type)

        # Get the dynamic range indicator for DL audio path
        res_dl_3g = AudioUtil.get_rms_from_sweep(
            AudioUtil.get_sweep_trace(self._host_trace_file_path_dl_1),
            self._logger)

        # Load UPV setup for UL path
        self._audio_analyzer.load_configuration(
            self._name, str(self._ns_node.get_param_value("Model")), None,
            None, "UL")

        # Perform audio routing verification for UL path
        self._logger.info("Verify audio routing in UL")
        self._audio_analyzer.start_single_measurement()

        # Wait until the measurement ends
        self._audio_analyzer.wait_for_sweep_state("Sweep_Waiting")

        # Transfer the result of the measurement to ACS host
        self._audio_analyzer.store_data_list(self._aa_trace_file_path_ul_1,
                                             self._host_trace_file_path_ul_1,
                                             self._trace_type)
        time.sleep(2)

        # Get the dynamic range indicator for UL audio path
        res_ul_3g = AudioUtil.get_rms_from_sweep(
            AudioUtil.get_sweep_trace(self._host_trace_file_path_ul_1),
            self._logger)

        try:
            # Release the call
            self._ns2_vc.voice_call_network_release()

            # Check call is released (NS)
            self._ns2_vc.check_call_idle(self._registration_timeout,
                                         blocking=False)
        except TestEquipmentException as e:
            self._error.Msg = \
                "CSV call dropped before the end"
            self._logger.error(e)
            raise TestEquipmentException(
                TestEquipmentException.OPERATION_FAILED, self._error.Msg)

        # Check call is released (CDK)
        self._voicecall_api.wait_for_state(
            self._uecmd_types.VOICE_CALL_STATE.NOCALL, self._call_setup_time)

        if res_dl_3g > self._dynamic_threshold and res_ul_3g > self._dynamic_threshold:
            self._error.Msg = "Audio correctly routed in both DL and UL - " + \
                              "Dynamic indicator : DL = %f / UL = %f" % (res_dl_3g, res_ul_3g)
            self._logger.info(self._error.Msg)
            self._result_verdict = Global.SUCCESS
        elif res_dl_3g < self._dynamic_threshold and res_ul_3g > self._dynamic_threshold:
            self._error.Msg = "Audio routing error in DL - " + \
                              "Dynamic indicator : DL = %f / UL = %f" % (res_dl_3g, res_ul_3g)
            self._logger.error(self._error.Msg)
            self._result_verdict = Global.FAILURE
        elif res_ul_3g < self._dynamic_threshold and res_dl_3g > self._dynamic_threshold:
            self._error.Msg = "Audio routing error in UL - " + \
                              "Dynamic indicator : DL = %f / UL = %f" % (res_dl_3g, res_ul_3g)
            self._logger.error(self._error.Msg)
            self._result_verdict = Global.FAILURE
        else:
            self._error.Msg = "Audio routing error in both DL and UL - " + \
                              "Dynamic indicator : DL = %f / UL = %f" % (res_dl_3g, res_ul_3g)
            self._logger.error(self._error.Msg)
            self._result_verdict = Global.FAILURE

        if self._ns1_cell_tech not in self._ns2_cell_tech:

            # Activate flight mode
            self._networking_api.set_flight_mode("on")

            # Wait 30s while airplane mode is enabled
            time.sleep(30)

            # Disconnect current equipment application of network simulator
            self._ns.release()

            # Connect to cellular network simulator
            self._ns.init()

            # Set the equipment application format back to 2G
            self._ns.switch_app_format("GSM/GPRS")

            # Set cell band using CELL_BAND parameter
            self._ns1_cell.set_band(self._ns1_cell_band_name)

            # Set cell off
            self._ns1_cell.set_cell_off()

            # Set cell service using CELL_SERVICE parameter
            self._ns1_cell.set_cell_service(self._ns1_cell_service)

            # Set cell on
            self._ns1_cell.set_cell_on()

            # Set voice call output
            self._ns1_vc.set_speech_configuration("SPEECH_OUTPUT")

            # Deactivate flight mode
            self._networking_api.set_flight_mode("off")

            # Check registration status before registrationTimeout (CDK)
            self._modem_api.check_cdk_registration_bfor_timeout(
                self._registration_timeout * 2)

            # Data Connection State verification in 2G
            self._ns1_data.check_data_connection_state(
                self._expected_data_connection_state_2g, 30)

            # Perform a MT voice call
            self._ns1_vc.mt_originate_call()

            # Check call status is incoming before callSetupTimeout
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.INCOMING,
                self._call_setup_time)

            # Answer incoming call
            self._voicecall_api.answer()

            # Check call status before callSetupTimeout (NS)
            self._ns1_vc.check_call_connected(self._call_setup_time,
                                              blocking=False)

            # Check call status before callSetupTimeout (DUT)
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.ACTIVE,
                self._call_setup_time)

            # Configure Audio output to headset (jack)
            time.sleep(self._wait_btwn_cmd)
            self._phonesystem_api.switch_audio_output("headset")

            # Set Voice Call Volume at 100%
            self._system_api.adjust_specified_stream_volume(
                "VoiceCall", self._call_stream_volume_dut)

            # Set Audio codec in 2G
            self._ns1_vc.set_audio_codec(self._ns1_cell_codec)

            # Load setup on UPV
            self._audio_analyzer.load_configuration(
                self._name, str(self._ns_node.get_param_value("Model")), None,
                None, "DL")

            # Perform audio routing verification for DL path first
            self._logger.info("Verify audio routing in DL")
            self._audio_analyzer.start_single_measurement()

            # Wait until the measurement ends
            self._audio_analyzer.wait_for_sweep_state("Sweep_Waiting")

            # Transfer the result of the measurement to ACS host
            self._audio_analyzer.store_data_list(
                self._aa_trace_file_path_dl_2, self._host_trace_file_path_dl_2,
                self._trace_type)

            # Get the dynamic range indicator for DL audio path
            res_dl_2g = AudioUtil.get_rms_from_sweep(
                AudioUtil.get_sweep_trace(self._host_trace_file_path_dl_2),
                self._logger)

            # Load UPV setup for UL path
            self._audio_analyzer.load_configuration(
                self._name, str(self._ns_node.get_param_value("Model")), None,
                None, "UL")

            # Perform audio routing verification for UL path
            self._logger.info("Verify audio routing in UL")
            self._audio_analyzer.start_single_measurement()

            # Wait until the measurement ends
            self._audio_analyzer.wait_for_sweep_state("Sweep_Waiting")

            # Transfer the result of the measurement to ACS host
            self._audio_analyzer.store_data_list(
                self._aa_trace_file_path_ul_2, self._host_trace_file_path_ul_2,
                self._trace_type)

            # Get the dynamic range indicator for UL audio path
            res_ul_2g = AudioUtil.get_rms_from_sweep(
                AudioUtil.get_sweep_trace(self._host_trace_file_path_ul_2),
                self._logger)
            try:
                # Release the call
                self._ns1_vc.voice_call_network_release()

                # Check call is released (NS)
                self._ns1_vc.check_call_idle(self._registration_timeout,
                                             blocking=False)
            except TestEquipmentException as e:
                self._error.Msg = \
                    "CSV call dropped before the end"
                self._logger.error(e)
                raise TestEquipmentException(
                    TestEquipmentException.OPERATION_FAILED, self._error.Msg)

            # Check call is released (CDK)
            self._voicecall_api.wait_for_state(
                self._uecmd_types.VOICE_CALL_STATE.NOCALL,
                self._call_setup_time)

            if res_dl_2g > self._dynamic_threshold and res_ul_2g > self._dynamic_threshold:
                self._logger.info("Audio correctly routed in both DL and UL while attached to 2G cell - " + \
                                  "Dynamic indicator : DL = %f / UL = %f" % (res_dl_2g, res_ul_2g))

                if self._result_verdict is Global.SUCCESS:
                    self._error.Msg = "Audio correctly routed in both DL and UL while attached to 2G and 3G cell - " + \
                                      "Dynamic indicator : 3G - DL = %f - UL = %f / 2G - DL = %f - UL = %f " % \
                                      (res_dl_3g, res_ul_3g, res_dl_2g, res_ul_2g)

            elif res_dl_2g < self._dynamic_threshold and res_ul_2g > self._dynamic_threshold:
                self._error.Msg = "Audio routing error in DL while attached to 2G cell - " + \
                                  "Dynamic indicator : DL = %f (3G) - %f (2G) / UL = %f (3G) - %f (2G)" % \
                                  (res_dl_3g, res_dl_2g, res_ul_3g, res_ul_2g)
                self._logger.error(self._error.Msg)
                if self._result_verdict is Global.SUCCESS:
                    self._result_verdict = Global.FAILURE
            elif res_ul_2g < self._dynamic_threshold and res_dl_2g > self._dynamic_threshold:
                self._error.Msg = "Audio routing error in UL while attached to 2G cell - " + \
                                  "Dynamic indicator : DL = %f (3G) - %f (2G) / UL = %f (3G) - %f (2G)" % \
                                  (res_dl_3g, res_dl_2g, res_ul_3g, res_ul_2g)
                self._logger.error(self._error.Msg)
                if self._result_verdict is Global.SUCCESS:
                    self._result_verdict = Global.FAILURE
            else:
                self._error.Msg = "Audio routing error in both DL and UL while attached to 2G cell - " + \
                                  "Dynamic indicator : DL = %f (3G) - %f (2G) / UL = %f (3G) - %f (2G)" % \
                                  (res_dl_3g, res_dl_2g, res_ul_3g, res_ul_2g)
                self._logger.error(self._error.Msg)
                if self._result_verdict is Global.SUCCESS:
                    self._result_verdict = Global.FAILURE

            if self._keep_record:
                # Update the name of the trace file, in case of back-to-back and KEEP_RECORD = true
                self._host_trace_file_path_dl_2 = self._host_trace_file_path_dl_2.strip(
                    self._host_trace_file_path_dl_2.split('_')[-1]) + \
                                                  str(
                                                      self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 2) + ".trc"

                self._host_trace_file_path_ul_2 = self._host_trace_file_path_ul_2.strip(
                    self._host_trace_file_path_ul_2.split('_')[-1]) + \
                                                  str(
                                                      self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 2) + ".trc"
            else:
                os.remove(self._host_trace_file_path_dl_2)
                os.remove(self._host_trace_file_path_ul_2)

        if self._keep_record:
            # Update the name of the trace file, in case of back-to-back and KEEP_RECORD = true
            self._host_trace_file_path_dl_1 = self._host_trace_file_path_dl_1.strip(
                self._host_trace_file_path_dl_1.split('_')[-1]) + \
                                              str(
                                                  self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 2) + ".trc"

            self._host_trace_file_path_ul_1 = self._host_trace_file_path_ul_1.strip(
                self._host_trace_file_path_ul_1.split('_')[-1]) + \
                                              str(
                                                  self._tc_parameters.get_b2b_iteration() - self._tc_iteration_count + 2) + ".trc"
        else:
            os.remove(self._host_trace_file_path_dl_1)
            os.remove(self._host_trace_file_path_ul_1)

        self._tc_iteration_count -= 1

        return self._result_verdict, self._error.Msg