예제 #1
0
        private int iterationResult; // Stores result of iteration

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Class constructor
        /// </summary>
        /// <param name="_iterationResult"></param>
        /// <param name="_category"></param>
        /// <param name="_callerData"></param>
        /// <param name="_calleeData"></param>
        /// <param name="_spResult"></param>
        private IterationResult(int _iterationResult, CallerIterationInfo _callerData, CalleeIterationInfo _calleeData, SpeechRecognizerResult _callerSpResult, SpeechRecognizerResult _calleeSpResult)
        {
            iterationResult = _iterationResult;
            callerData = _callerData;
            calleeData = _calleeData;
            callerSpeechResult = _callerSpResult;
            calleeSpeechResult = _calleeSpResult;

            audioPowerResult = AudioVolume.NOT_ATTENUATED;
            audioVolConf = AudioVolumeConfidence.GOOD_CONFIDENCE;

            // determine the classification (category) for IterationResult
            if (iterationResult == ValidationErrors.NO_ERROR)
                category = TestIterationCategory.PASSED;
            else
                if (conditionExists(iterationResult, ValidationErrors.FAILED_CALL) || conditionExists(iterationResult, ValidationErrors.MISSING_HANGUP) ||
                    conditionExists(iterationResult, ValidationErrors.ECHO_DETECTED) || conditionExists(iterationResult, ValidationErrors.CALLER_NOISE_DETECTED) ||
                    conditionExists(iterationResult, ValidationErrors.CALLEE_NOISE_DETECTED) || conditionExists(iterationResult, ValidationErrors.CALLEE_NOT_HEARD) ||
                    conditionExists(iterationResult, ValidationErrors.CALLER_NOT_HEARD))
                    category = TestIterationCategory.FAILED;

            //if(iterationResult == ValidationErrors.FAILED_CALL || iterationResult == ValidationErrors.NOISE_DETECTED || iterationResult == ValidationErrors.ECHO_DETECTED)
                //    category = TestIterationCategory.FAILED;
                else
                {
                    // Use invalid for all others errors such as callee could not play prompt, execution error etc
                    category = TestIterationCategory.INVALID;
                }
        }
예제 #2
0
        /// <summary>
        /// Method that applies various validation rules to interpret the result of the iteration
        /// </summary>
        /// <param name="callerInfo"></param>
        /// <param name="calleeInfo"></param>
        /// <returns></returns>
        public IterationResult applyValidationRules(CallerIterationInfo callerInfo, CalleeIterationInfo calleeInfo)
        {
            IterationResult result = null;
            SpeechRecognizerResult callerSpeechResult = null;
            SpeechRecognizerResult calleeSpeechResult = null;
            callerData = callerInfo;
            calleeData = calleeInfo;

            int hangupRuleOutcome = ValidationErrors.NO_ERROR;
            int timestampRuleOutcome = ValidationErrors.NO_ERROR;
            int latencyRuleResult = ValidationErrors.NO_ERROR;
            int speechRecoRuleResult = ValidationErrors.NO_ERROR;

            NextRule rule = NextRule.None;

            // First rule - check if call was completed end to end between caller and callee.
            // If not, fail the iteration and return the result
            if (applyCallFailureValidationRule() == ValidationErrors.FAILED_CALL)
            {
                result = IterationResult.getInstance(ValidationErrors.FAILED_CALL, callerData, calleeData, null, null);
                return result;
            }

            hangupRuleOutcome = applyHangupValidationRule();
            timestampRuleOutcome = applyTimeStampValidationRule(out rule);

            // Next apply timestamp validation rule and if we encounter a failure in that, and, we find that we don't need
            // to apply another rule, return result.
            if (rule == NextRule.None)
            {
                result = IterationResult.getInstance(hangupRuleOutcome | timestampRuleOutcome, callerData, calleeData, null, null);
                return result;
            }

            latencyRuleResult = applyLatencyValidationRule();

            speechRecoRuleResult = applySpeechRecognitionRule(out calleeSpeechResult, out callerSpeechResult);

            result = IterationResult.getInstance(hangupRuleOutcome | timestampRuleOutcome | latencyRuleResult | speechRecoRuleResult, callerData,
                                                    calleeData,
                                                    callerSpeechResult, calleeSpeechResult);

            return result;
        }
예제 #3
0
 /// <summary>
 /// Method to create an instance of IterationResult.
 /// </summary>
 /// <param name="_iterationResult"></param>
 /// <param name="_category"></param>
 /// <param name="_callerData"></param>
 /// <param name="_calleeData"></param>
 /// <param name="_spResult"></param>
 /// <returns></returns>
 public static IterationResult getInstance(int _iterationResult, CallerIterationInfo _callerData, CalleeIterationInfo _calleeData, SpeechRecognizerResult _callerSpResult, SpeechRecognizerResult _calleeSpResult)
 {
     try
     {
         return new IterationResult(_iterationResult, _callerData, _calleeData, _callerSpResult, _calleeSpResult);
     }
     catch (Exception e)
     {
         return null;
     }
 }
예제 #4
0
        /// <summary>
        /// Method that places a call to the callee and sets caller state to dialing
        /// <returns>true if call has been attempted, false otherwise</returns>
        /// </summary>
        public bool placeCall()
        {
            int nextCallIter; // Local temp variable
            /**
             * Place a call only if no other call was in progress and caller is ready.
             */

            CurrentState localState = getState();

            if (localState == CurrentState.READY)
            {
                lock (this)
                {
                   numRemainingIter--;
                   nextCallIter = ++numCallsPlaced;
                }

                conn = null;

                /**
                 * Create a new instance of caller iteration info while attempting to place a call.
                 */
                callerData = null;
                callerData = new CallerIterationInfo();

                display("Starting iteration " + nextCallIter);

                phone.MakeCall("SIP:" + inputParam.remoteExtension + "@" + inputParam.sipServerIP);
                // Store the current time
                callerData.makeCallMethodTime = DateTime.Now;

                setState(CurrentState.DIALING);
                return true;
            }
            else
                return false;
        }
예제 #5
0
        /// <summary>
        /// This method is fired when call is hungup.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="args"></param>
        void phone_ConnectionCleared(object sender, ConnectionClearedEventArgs args)
        {
            DateTime callReleaseTimeStamp = DateTime.Now;
            Connection droppedConn = args.DroppedConnection;

            /**
             * If connection cleared was received in response to active or dialing connection, take appropriate action
             * or else do nothing.
             */
            if (conn != null && conn.Equals(droppedConn) == true)
            {
                conn = args.DroppedConnection;

                // Store the timestamp when call was disconnected with callerData
                callerData.callReleaseTime = callReleaseTimeStamp;

                // Disable all timers to prevent them from accidentally firing in next iteration
                callDurationTimer.Enabled = false;
                bargeTimer.Enabled = false;

                try
                {
                    if (ll != null)
                        ll.Stop();
                    if (recorder != null)
                        recorder.Stop();
                }
                catch (Exception e)
                {
                    Trace.TraceError("Exception in phone_ConnectionCleared. Message: " + e.Message + "Current time = " + DateTime.Now + "\r\nStack Trace : \r\n" + e.StackTrace, "Warning");
                }

                // After processing a connection cleared, send the notification of call state for the caller to the observer.
                // Make sure to set the callerData to null - this is a safety mechanism to prevent same iteration being logged
                // multiple times (if multiple connection cleared) are received in response to makecall
                if (OnIterationCompleted != null && callerData != null)
                {
                    OnIterationCompleted(this, callerData);
                    callerData = null;
                }

                int temp;

                lock (this)
                {
                    temp = numRemainingIter;
                }
                if (temp > 0)
                {
                    setState(CurrentState.READY);
                    display("Enabling inter-call wait timer");
                    // Start the timer to place the next call
                    interCallTimer.Enabled = true;
                }
                else
                {
                    setState(CurrentState.EXECUTION_COMPLETED);
                }
            }
            else
            {
                /**
                 * If connection cleared was ignored, print out the time that happened, and also the reason.
                 * If conn was null say that. If conn was not equivalent to dropped connection, say that, otherwise
                 * set the reason as "Unknown".
                 */
                StringBuilder message = new StringBuilder();
                message.Append("Ignoring connection cleared event at time = " + DateTime.Now + " Reason: ");

                if (conn == null)
                {
                    message.Append("Preserved connection was null");
                }
                else
                {
                    message.Append("Preserved connection is not equivalent to dropped connection");
                }

                display(message.ToString());
            }
        }
예제 #6
0
        /// <summary>
        /// Method that reads the corresponding callee and caller log files and finds out which lines of caller
        /// and callee belong to same call and processes them
        /// </summary>
        public void generateResults()
        {
            string callerLine;
            string calleeLine;
            CallerIterationInfo callerInfo = null;      // Caller's iteration info
            CalleeIterationInfo calleeInfo = null;      // Callee's iteration info
            int returnCode;
            bool calleeFileEmpty = false;

            while (true)
            {
                // If callerInfo is null, read the next line and create a callerInfo from it.
                // If callerFile is empty or exception in creating callerInfo, break.
                if (callerInfo == null)
                {
                    callerLine = callerFileReader.ReadLine();
                    currentCallerLineNum++;

                    if (callerLine == null)
                    {
                        break;
                    }
                    else
                    {
                        try
                        {
                            callerInfo = new CallerIterationInfo(callerLine);
                        }
                        catch(Exception e)
                        {
                            Console.WriteLine("Error in Analyer.generateResults. Could not create CallerIterationInfo instance. Terminating reading of input logs");
                            Trace.TraceError("Exception while creating callerInfo: " + e.Message + "\r\nStack Trace : " + e.StackTrace);
                            break;
                        }
                    }
                }

                // If calleeInfo is null, read the next line and create a calleeInfo from it.
                // If calleeFile is empty then create a dummy callee object. Exception in creating calleeInfo, break.
                if (calleeInfo == null)
                {
                    calleeLine = calleeFileReader.ReadLine();
                    currentCalleeLineNum++;

                    if (calleeLine == null)
                    {
                        calleeFileEmpty = true;
                        calleeInfo = new CalleeIterationInfo();
                    }
                    else
                    {
                        try
                        {
                            calleeInfo = new CalleeIterationInfo(calleeLine);
                        }
                        catch(Exception e2)
                        {
                            Console.WriteLine("Error in Analyer.generateResults. Could not create CalleeIterationInfo instance. Terminating reading of input logs");
                            Trace.TraceError("Exception while creating calleeInfo: " + e2.Message + "\r\nStack Trace : " + e2.StackTrace);
                            break;
                        }
                    }
                }

                if (!calleeFileEmpty)
                {
                    returnCode = causalOrderBetweenCallerAndCallee(callerInfo, calleeInfo);

                    switch (returnCode)
                    {
                        case 0: // both belong to same call
                        case -3: // both have uninitialized connect timestamps
                            processTokens(callerInfo, calleeInfo, true);
                            callerInfo = null;
                            calleeInfo = null;
                            break;

                        case 1: // caller's current call after callee's call
                        case -2: // callee's current call had uninitialized connection timestamp
                            // discard calleeInfo as it could not be matched with caller
                            // continue to store callerInfo
                            calleeInfo = null;
                            break;

                        case 2: // callee's current call after caller's call
                        case -1: // caller's current call had uninitialized conneciton timestamp
                            // processTokens with callerInfo and dummy calleeInfo
                            // and discard callerInfo
                            processTokens(callerInfo, new CalleeIterationInfo(), false);
                            callerInfo = null;
                            break;
                    }
                }
                else
                {
                    processTokens(callerInfo, new CalleeIterationInfo(), false);
                    callerInfo = null;
                }
            }
            aggResult.displayResult(resultDir + "\\GatewayTestResults.txt");
        }
예제 #7
0
        /// <summary>
        /// Private method that applies the token validation rules and generates iteration result instances
        /// </summary>
        /// <param name="callerInfo"></param>
        /// <param name="calleeInfo"></param>
        private void processTokens(CallerIterationInfo callerInfo, CalleeIterationInfo calleeInfo, bool matchRecordedWav)
        {
            IterationResult result = null;

            /**
             * If the current objects indeed belong to a same call, we can locate corresponding wav files and rename them
             * to ensure that the file from caller and the callee can be correlated.
             */
            if (matchRecordedWav == true)
            {
                string callerFile = resultDir + "\\Caller_RecordedWav_" + currentCallerLineNum + ".wav";
                string calleeFile = resultDir + "\\Callee_RecordedWav_" + currentCalleeLineNum + ".wav";
                string newCallerFile = resultDir + "\\Caller_RecordedWav_" + currentCallerLineNum + "_matched.wav";
                string newCalleeFile = resultDir + "\\Callee_RecordedWav_" + currentCallerLineNum + "_matched.wav";

                try
                {
                    if (File.Exists(callerFile) && File.Exists(calleeFile))
                    {
                        File.Move(callerFile, newCallerFile);
                        File.Move(calleeFile, newCalleeFile);
                    }
                }
                catch (Exception e)
                {
                    Console.WriteLine("Exception encountered in matching " + callerFile + " with " + calleeFile + ". Message:\n" + e.Message);
                    Trace.TraceError("Exception occurred. Message : " + e.Message + "\r\nStack Trace : " + e.StackTrace);
                }
            }

            result = ri.applyValidationRules(callerInfo, calleeInfo);

            Console.WriteLine("\nIteration = " + ++iterationNum + "\n" + result.ToString());
            aggResult.addIterationResult(result);
        }
예제 #8
0
 /// <summary>
 /// Method to determine causal ordering between caller and callee's current call
 /// </summary>
 /// <param name="callerInfo"></param>
 /// <param name="calleeInfo"></param>
 /// <returns></returns>
 private int causalOrderBetweenCallerAndCallee(CallerIterationInfo callerInfo, CalleeIterationInfo calleeInfo)
 {
     DateTime uninitDate = new DateTime(); // Uninitialized date
     int result = -1;
     /**
      * If either caller or callee did not have valid connection time, return -1 to indicate that no matching is possible
      * with this caller callee pair
      */
     if (callerInfo.callConnectTime == uninitDate && calleeInfo.callConnectTime == uninitDate)
     {
         return -3;
     }
     else
     if(callerInfo.callConnectTime == uninitDate)
     {
         result = -1;
     }
     else
     if (calleeInfo.callConnectTime == uninitDate)
     {
         result = -2;
     }
     else
         if ((callerInfo.callConnectTime <= calleeInfo.callConnectTime && calleeInfo.callConnectTime < callerInfo.callReleaseTime) ||
             (calleeInfo.callConnectTime <= callerInfo.callConnectTime && callerInfo.callConnectTime < calleeInfo.callReleaseTime))
         {
             /**
              * If caller and callee belong to same call return 0
              */
             result = 0;
         }
         else
             if (calleeInfo.callConnectTime >= callerInfo.callReleaseTime)
             {
                 /**
                  * If callee's current call is causally after caller's current call, return 2.
                  */
                 result = 2;
             }
             else
                 if (calleeInfo.callReleaseTime <= callerInfo.callConnectTime)
                 {
                     /**
                      * If caller's current call is causally before caller's current call, return 2
                      */
                     result = 1;
                 }
     return result;
 }
예제 #9
0
        private WavFileInfo wInfo; // WavFileInfo instance

        #endregion Fields

        #region Constructors

        /// <summary>
        /// Class constructor
        /// </summary>
        public ResultInterpreter(WavFileInfo _wInfo)
        {
            wInfo = _wInfo;
            callerData = null;
            calleeData = null;
        }