예제 #1
0
        /// <summary>
        /// User put call on hold or retrieve
        /// </summary>
        /// <param name="session">session identification</param>
        public void onUserHoldRetrieve(int session)
        {
            // check Hold or Retrieve
            CAbstractState state = this[session].getState();

            if (state.StateId == EStateId.ACTIVE)
            {
                this.getCall(session).getState().holdCall(session);
            }
            else if (state.StateId == EStateId.HOLDING)
            {
                // execute retrieve
                // check if any ACTIVE calls
                if (this.getNoCallsInState(EStateId.ACTIVE) > 0)
                {
                    // get 1st and put it on hold
                    CStateMachine sm = ((List <CStateMachine>)enumCallsInState(EStateId.ACTIVE))[0];
                    if (null != sm)
                    {
                        sm.getState().holdCall(sm.Session);
                    }

                    // set Retrieve event pending for HoldConfirm
                    _pendingAction = new PendingAction(EPendingActions.EUserHold, session);
                    return;
                }

                this[session].getState().retrieveCall(session);
            }
            else
            {
                // illegal
            }
        }
예제 #2
0
 private void OnCallNotification(int callId, ECallNotification notFlag, string text)
 {
     if (notFlag == ECallNotification.CN_HOLDCONFIRM)
     {
         CStateMachine sm = this.getCall(callId);
         if (sm != null)
         {
             sm.getState().onHoldConfirm();
         }
     }
 }
예제 #3
0
        ////////////////////////////////////////////////////////////////////////////////////////
        /// <summary>
        ///
        /// </summary>
        /// <param name="callId"></param>
        /// <param name="callState"></param>
        private void OnCallStateChanged(int callId, int callState, string info)
        {
            //    PJSIP_INV_STATE_NULL,	    /**< Before INVITE is sent or received  */
            //    PJSIP_INV_STATE_CALLING,	    /**< After INVITE is sent		    */
            //    PJSIP_INV_STATE_INCOMING,	    /**< After INVITE is received.	    */
            //    PJSIP_INV_STATE_EARLY,	    /**< After response with To tag.	    */
            //    PJSIP_INV_STATE_CONNECTING,	    /**< After 2xx is sent/received.	    */
            //    PJSIP_INV_STATE_CONFIRMED,	    /**< After ACK is sent/received.	    */
            //    PJSIP_INV_STATE_DISCONNECTED,   /**< Session is terminated.		    */
            //if (callState == 2) return 0;

            CStateMachine sm = getCall(callId);

            if (sm == null)
            {
                return;
            }

            switch (callState)
            {
            case 1:
                //sm.getState().onCalling();
                break;

            case 2:
                //sm.getState().incomingCall("4444");
                break;

            case 3:
                sm.getState().onAlerting();
                break;

            case 4:
                sm.getState().onConnect();
                break;

            case 6:
                sm.getState().onReleased();
                break;
            }
        }
예제 #4
0
 /// <summary>
 ///
 /// </summary>
 /// <param name="session"></param>
 public void onUserConference(int session)
 {
     // check preconditions: 1 call active, other held
     // 1st if current call is held -> search if any active -> execute retrieve
     if ((getNoCallsInState(EStateId.ACTIVE) == 1) && (getNoCallsInState(EStateId.HOLDING) >= 1))
     {
         CStateMachine call = getCallInState(EStateId.HOLDING);
         call.getState().retrieveCall(call.Session);
         // set conference flag
         return;
     }
 }
예제 #5
0
        /// <summary>
        /// User accepts call for a given session
        /// In case of multi call put current active call to Hold
        /// </summary>
        /// <param name="session">session identification</param>
        public void onUserAnswer(int session)
        {
            List <CStateMachine> list = (List <CStateMachine>) this.enumCallsInState(EStateId.ACTIVE);

            // should not be more than 1 call active
            if (list.Count > 0)
            {
                // put it on hold
                CStateMachine sm = list[0];
                if (null != sm)
                {
                    sm.getState().holdCall(sm.Session);
                }

                // set ANSWER event pending for HoldConfirm
                // TODO
                _pendingAction = new PendingAction(EPendingActions.EUserAnswer, session);
                return;
            }
            this[session].getState().acceptCall(session);
        }
예제 #6
0
        /// <summary>
        /// Handler for outgoing calls (sessionId is not known yet).
        /// </summary>
        /// <param name="number">Number to call</param>
        /// <param name="accountId">Specified account Id </param>
        public CStateMachine createOutboundCall(string number, int accountId)
        {
            // check if current call automatons allow session creation.
            if (this.getNoCallsInStates((int)(EStateId.CONNECTING | EStateId.ALERTING)) > 0)
            {
                // new call not allowed!
                return(null);
            }
            // if at least 1 connected try to put it on hold
            if (this.getNoCallsInState(EStateId.ACTIVE) == 0)
            {
                // create state machine
                // TODO check max calls!!!!
                CStateMachine call = new CStateMachine(this);

                // make call request (stack provides new sessionId)
                int newsession = call.getState().makeCall(number, accountId);
                if (newsession == -1)
                {
                    return(null);
                }
                // update call table
                // TODO catch argument exception (same key)!!!!
                call.Session = newsession;
                _calls.Add(newsession, call);
                return(call);
            }
            else // we have at least one ACTIVE call
            {
                // put connected call on hold
                // TODO pending action
                _pendingAction = new PendingAction(EPendingActions.ECreateSession, number, accountId);
                CStateMachine call = getCallInState(EStateId.ACTIVE);
                call.getState().holdCall(call.Session);
            }
            return(null);
        }
예제 #7
0
        public void testStateMachineEventHandlingOutgoing()
        {
            CStateMachine sm1 = new CStateMachine(_manager);
              sm1.getState().makeCall("1234", 0);
              Assert.AreEqual(EStateId.CONNECTING, sm1.getStateId());
              Assert.AreEqual(false, sm1.Incoming);
              Assert.AreEqual("1234", sm1.CallingNo);
              Assert.AreEqual(sm1.RuntimeDuration, TimeSpan.Zero);

              sm1.getState().onAlerting();
              Assert.AreEqual(EStateId.ALERTING, sm1.getStateId());
              Assert.AreEqual(false, sm1.Counting);
              Assert.AreEqual(sm1.RuntimeDuration, TimeSpan.Zero);

              sm1.getState().onConnect();
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);
              //Assert.AreNotEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());

              sm1.getState().onReleased();
              Assert.AreEqual(EStateId.RELEASED, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);
              //Assert.AreNotEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());
        }
예제 #8
0
        public void testStateMachineEventHandlingIncoming()
        {
            CStateMachine sm1 = new CStateMachine(_manager);

              sm1.getState().incomingCall("1234","");
              Assert.AreEqual(EStateId.INCOMING, sm1.getStateId());
              Assert.AreEqual(true, sm1.Incoming);
              Assert.AreEqual("1234", sm1.CallingNo);
              Assert.AreEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());

              sm1.getState().acceptCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);
              //Assert.AreNotEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());

              sm1.getState().onReleased();
              Assert.AreEqual(EStateId.RELEASED, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);
              //Assert.AreNotEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());
        }
예제 #9
0
        public void testCallFeaturesCallWaiting()
        {
            // out call
              CStateMachine sm2 = new CStateMachine(_manager);

              sm2.getState().makeCall("4444", 0);
              Assert.AreEqual(EStateId.CONNECTING, sm2.getStateId());
              Assert.AreEqual(false, sm2.Incoming);
              Assert.AreEqual("4444", sm2.CallingNo);

              sm2.getState().onAlerting();
              Assert.AreEqual(EStateId.ALERTING, sm2.getStateId());
              Assert.AreEqual(false, sm2.Counting);

              sm2.getState().onConnect();
              Assert.AreEqual(EStateId.ACTIVE, sm2.getStateId());
              Assert.AreEqual(true, sm2.Counting);

              // inc call
              CStateMachine sm1 = new CStateMachine(_manager);

              sm1.getState().incomingCall("1234","");
              Assert.AreEqual(EStateId.INCOMING, sm1.getStateId());
              Assert.AreEqual(true, sm1.Incoming);
              Assert.AreEqual("1234", sm1.CallingNo);
              Assert.AreEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());

              // check what happens here?
              sm1.getState().acceptCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);
              // this should be done automatically by call manager
              // Here we do not test call manager
              //Assert.AreEqual(EStateId.HOLDING, sm2.getStateId());

              sm1.getState().endCall(sm1.Session);
              sm2.getState().endCall(sm2.Session);
              Assert.AreEqual(EStateId.IDLE, sm1.getStateId());
              Assert.AreEqual(EStateId.IDLE, sm2.getStateId());
              sm1.getState().onReleased();
              sm2.getState().onReleased();
              Assert.AreEqual(EStateId.IDLE, sm1.getStateId());
              Assert.AreEqual(EStateId.IDLE, sm2.getStateId());
        }
예제 #10
0
        public void testCallFeaturesCallHoldMultiple()
        {
            CStateMachine sm1 = new CStateMachine(_manager);

              sm1.getState().incomingCall("1234","");
              Assert.AreEqual(EStateId.INCOMING, sm1.getStateId());
              Assert.AreEqual(true, sm1.Incoming);
              Assert.AreEqual("1234", sm1.CallingNo);
              Assert.AreEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());

              sm1.getState().acceptCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);

              sm1.getState().holdCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId()); // still ACTIVE (waiting confirmation)
              sm1.getState().onHoldConfirm();
              Assert.AreEqual(EStateId.HOLDING, sm1.getStateId());

              // next call
              CStateMachine sm2 = new CStateMachine(_manager);

              sm2.getState().makeCall("4444", 0);
              Assert.AreEqual(EStateId.CONNECTING, sm2.getStateId());
              Assert.AreEqual(false, sm2.Incoming);
              Assert.AreEqual("4444", sm2.CallingNo);

              sm2.getState().onAlerting();
              Assert.AreEqual(EStateId.ALERTING, sm2.getStateId());
              Assert.AreEqual(false, sm2.Counting);

              sm2.getState().onConnect();
              Assert.AreEqual(EStateId.ACTIVE, sm2.getStateId());
              Assert.AreEqual(true, sm2.Counting);

              sm2.getState().holdCall(sm2.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm2.getStateId()); // still ACTIVE (waiting confirmation)
              sm2.getState().onHoldConfirm();
              Assert.AreEqual(EStateId.HOLDING, sm2.getStateId());

              // release first
              sm1.getState().onReleased();
              Assert.AreEqual(EStateId.RELEASED, sm1.getStateId());
              sm2.getState().onHoldConfirm();
              Assert.AreEqual(EStateId.HOLDING, sm2.getStateId());

              sm2.getState().endCall(sm2.Session);
              Assert.AreEqual(EStateId.IDLE, sm2.getStateId());
              sm2.getState().onReleased();
              Assert.AreEqual(EStateId.IDLE, sm2.getStateId());
        }
예제 #11
0
        public void testCallFeaturesCallHold()
        {
            CStateMachine sm1 = new CStateMachine(_manager);

              sm1.getState().incomingCall("1234","");
              Assert.AreEqual(EStateId.INCOMING, sm1.getStateId());
              Assert.AreEqual(true, sm1.Incoming);
              Assert.AreEqual("1234", sm1.CallingNo);
              Assert.AreEqual(sm1.RuntimeDuration.ToString(), TimeSpan.Zero.ToString());

              sm1.getState().acceptCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId());
              Assert.AreEqual(true, sm1.Counting);

              sm1.getState().holdCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId()); // still ACTIVE (waiting confirmation)
              sm1.getState().onHoldConfirm();
              Assert.AreEqual(EStateId.HOLDING, sm1.getStateId());
              // check twice hold
              sm1.getState().holdCall(sm1.Session);
              Assert.AreEqual(EStateId.HOLDING, sm1.getStateId());

              sm1.getState().retrieveCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId());

              sm1.getState().holdCall(sm1.Session);
              Assert.AreEqual(EStateId.ACTIVE, sm1.getStateId()); // still ACTIVE (waiting confirmation)
              sm1.getState().onHoldConfirm();
              Assert.AreEqual(EStateId.HOLDING, sm1.getStateId());

              sm1.destroy();
              Assert.AreEqual(EStateId.IDLE, sm1.getStateId());
        }
예제 #12
0
        /// <summary>
        /// Handler for outgoing calls (sessionId is not known yet).
        /// </summary>
        /// <param name="number">Number to call</param>
        /// <param name="accountId">Specified account Id </param>
        public CStateMachine createOutboundCall(string number, int accountId)
        {
            // check if current call automatons allow session creation.
              if (this.getNoCallsInStates((int)(EStateId.CONNECTING | EStateId.ALERTING)) > 0)
              {
            // new call not allowed!
            return null;
              }
              // if at least 1 connected try to put it on hold
              if (this.getNoCallsInState(EStateId.ACTIVE) == 0)
              {
            // create state machine
            // TODO check max calls!!!!
            CStateMachine call = new CStateMachine(this);

            // make call request (stack provides new sessionId)
            int newsession = call.getState().makeCall(number, accountId);
            if (newsession == -1)
            {
              return null;
            }
            // update call table
            // TODO catch argument exception (same key)!!!!
            call.Session = newsession;
            _calls.Add(newsession, call);
            return call;
              }
              else // we have at least one ACTIVE call
              {
            // put connected call on hold
            // TODO pending action
            _pendingAction = new PendingAction(EPendingActions.ECreateSession, number, accountId);
            CStateMachine call = getCallInState(EStateId.ACTIVE);
            call.getState().holdCall(call.Session);
              }
              return null;
        }
예제 #13
0
        /// <summary>
        ///
        /// </summary>
        /// <param name="callId"></param>
        /// <param name="number"></param>
        /// <param name="info"></param>
        private void OnIncomingCall(int callId, string number, string info)
        {
            CStateMachine sm = createSession(callId, number);

            sm.getState().incomingCall(number, info);
        }