예제 #1
0
        private void SendBye(SipAbstractDialog dialog)
        {
            var byeRequest = dialog.CreateRequest(SipMethods.Bye);
            var ctx        = SipProvider.CreateClientTransaction(byeRequest);

            dialog.SendRequest(ctx);
        }
예제 #2
0
파일: Server.cs 프로젝트: HNeukermans/Hallo
        private void _btnStart_Click(object sender, EventArgs e)
        {
            var ipEndPoint = SipUtil.ParseIpEndPoint(_txtLocalIPAddress.Text);

            _stack = new SipStack();
            var listeningPoint = _stack.CreateUdpListeningPoint(ipEndPoint);
            _sipProvider = _stack.CreateSipProvider(listeningPoint);
            _sipProvider.AddSipListener(this);
            _stack.Start();
            _tmrDiagnostics.Start();
        }
예제 #3
0
 protected override void  Given()
 {
     _contextSource = new FakeSipContextSource();
     _sipStack      = new SipStack();
     _provider      = new SipProvider(_sipStack, _contextSource);
     _inviteRequest = CreateInviteRequest();
     BeforeCreateInviteTransaction();
     _inviteTransaction = _provider.CreateClientTransaction(_inviteRequest).As <SipInviteClientTransaction>();
     _dialog            = _provider.CreateClientDialog(_inviteTransaction);
     _inviteTransaction.SendRequest();
     GivenOverride();
 }
예제 #4
0
파일: Server.cs 프로젝트: goupviet/Hallo
        private void _btnStart_Click(object sender, EventArgs e)
        {
            var ipEndPoint = SipUtil.ParseIpEndPoint(_txtLocalIPAddress.Text);

            _stack = new SipStack();
            var listeningPoint = _stack.CreateUdpListeningPoint(ipEndPoint);

            _sipProvider = _stack.CreateSipProvider(listeningPoint);
            _sipProvider.AddSipListener(this);
            _stack.Start();
            _tmrDiagnostics.Start();
        }
예제 #5
0
        private void Invite()
        {
            FormHelper.ValidateCondition(SipUtil.IsSipUri(_txtFromUri.Text), "From-uri");

            FormHelper.ValidateCondition(SipUtil.IsSipUri(_txtToUri.Text), "To-uri");

            var fromUri = SipUtil.ParseSipUri(_txtFromUri.Text);
            var toUri   = SipUtil.ParseSipUri(_txtToUri.Text);

            if (_chkPeerToPeer.Checked)
            {
                FormHelper.ValidateCondition(SipUtil.IsIpEndPoint(toUri.Host), "To-uri");
            }

            var requestUri   = toUri;
            var toAddress    = AddressFactory.CreateAddress(_txtToAlias.Text, toUri);
            var fromAddress  = AddressFactory.CreateAddress(_txtFromAlias.Text, fromUri);
            var toHeader     = HeaderFactory.CreateToHeader(toAddress);
            var fromHeader   = HeaderFactory.CreateFromHeader(fromAddress, SipUtil.CreateTag());
            var cseqHeader   = HeaderFactory.CreateSCeqHeader(SipMethods.Invite, ++commandSequence);
            var callIdheader = HeaderFactory.CreateCallIdHeader(SipUtil.CreateCallId());
            var viaHeader    = HeaderFactory.CreateViaHeader(SipProvider.ListeningPoint.Address,
                                                             SipProvider.ListeningPoint.Port, SipConstants.Udp,
                                                             SipUtil.CreateBranch());
            var maxForwardsHeader = HeaderFactory.CreateMaxForwardsHeader(1);
            var request           = MessageFactory.CreateRequest(
                requestUri,
                SipMethods.Invite,
                callIdheader,
                cseqHeader,
                fromHeader,
                toHeader,
                viaHeader,
                maxForwardsHeader);

            /*add routes and contacts*/
            if (!_chkPeerToPeer.Checked)
            {
                var proxyServerUri = AddressFactory.CreateUri(null, MainForm.SipStack.OutBoundProxy.ToString());
                proxyServerUri.IsLooseRouting = true;
                var routeHeader = HeaderFactory.CreateRouteHeader(proxyServerUri);
                request.Routes.Add(routeHeader);
            }
            var contactUri    = AddressFactory.CreateUri(fromUri.User, viaHeader.SentBy.ToString());
            var contactHeader = HeaderFactory.CreateContactHeader(contactUri);

            request.Contacts.Add(contactHeader);

            var transaction = SipProvider.CreateClientTransaction(request);

            _dialog = SipProvider.CreateClientDialog(transaction);
            transaction.SendRequest();
        }
예제 #6
0
파일: SendForm.cs 프로젝트: goupviet/Hallo
        private void _btnRegister_Click(object sender, EventArgs e)
        {
            try
            {
                var requestUri   = AddressFactory.CreateUri(null, "registrar." + MainForm.Configuration.RegistrarDomain);
                var toAddressUri = AddressFactory.CreateUri("hannes", MainForm.Configuration.RegistrarDomain);
                var toAddress    = AddressFactory.CreateAddress("hannes", toAddressUri);
                var toHeader     = HeaderFactory.CreateToHeader(toAddress);
                var fromHeader   = HeaderFactory.CreateFromHeader(toAddress, SipUtil.CreateTag());
                var cseqHeader   = HeaderFactory.CreateSCeqHeader(SipMethods.Register, 1028);
                var callId       = SipUtil.CreateCallId();
                var callIdheader = HeaderFactory.CreateCallIdHeader(callId);
                var viaHeader    = HeaderFactory.CreateViaHeader(SipProvider.ListeningPoint.Address, SipProvider.ListeningPoint.Port, SipConstants.Udp,
                                                                 SipUtil.CreateBranch());
                var maxForwardsHeader = HeaderFactory.CreateMaxForwardsHeader();
                var request           = MessageFactory.CreateRequest(
                    requestUri,
                    SipMethods.Register,
                    callIdheader,
                    cseqHeader,
                    fromHeader,
                    toHeader,
                    viaHeader,
                    maxForwardsHeader);

                var proxyServerUri = AddressFactory.CreateUri(null, MainForm.SipStack.OutBoundProxy.ToString());
                var localHostUri   = AddressFactory.CreateUri(null, MainForm.SipProvider.ListeningPoint.ToString());
                var routeHeader    = HeaderFactory.CreateRouteHeader(proxyServerUri);
                var contactHeader  = HeaderFactory.CreateContactHeader(localHostUri);
                request.Routes.Add(routeHeader);
                request.Contacts.Add(contactHeader);

                EventAggregator.Instance.Publish(
                    new LogEvent(">>>>" + SipFormatter.FormatMessageEnvelope(request) + Environment.NewLine));

                if (_chbSendStateFull.Checked)
                {
                    var transaction = SipProvider.CreateClientTransaction(request);
                    transaction.SendRequest();
                }
                else
                {
                    SipProvider.SendRequest(request);
                }
            }
            catch (Exception ex)
            {
                MainForm.HandleException(ex);
            }
        }
예제 #7
0
        /// <summary>
        /// creates the ids that must be attempted to match a transaction against the table
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        private List <string> CreateTxIdAttempts(SipRequest request)
        {
            var result = new List <string>();

            /*up to now the only request that can be cancelled is 'INVITE'*/
            var cancellableMethods = new[] { SipMethods.Invite };

            foreach (var method in cancellableMethods)
            {
                result.Add(SipProvider.GetServerTransactionId(request, method));
            }

            return(result);
        }
예제 #8
0
        protected override void Given()
        {
            //create invite that is addresses to the phone's sipuri
            _invite = CreateInviteRequest(_testClientUaUri, _phoneUaUri);
            //create phone that is located at IpEndPoint2
            var phoneCs = new FakeSipContextSource(_phoneUaEndPoint);

            _network      = new FakeNetwork();
            _sipProvider1 = new SipProvider(new SipStack(), phoneCs);

            _phone = new SoftPhone(_sipProvider1, new SipMessageFactory(), new SipHeaderFactory(), new SipAddressFactory(), _stateProvider, _timerFactory, new SipListeningPoint(_phoneUaEndPoint));
            phoneCs.AddToNetwork(_network);
            _network.AddReceiver(_testClientUaEndPoint, OnTestClientUaReceive);
            _phone.InternalStateChanged += new EventHandler <EventArgs>(_calleePhone_InternalStateChanged);
            _phone.IncomingCall         += new EventHandler <VoipEventArgs <IPhoneCall> >(_calleePhone_IncomingCall);
            _phone.Start();

            GivenOverride();
        }
예제 #9
0
        private void SendRinging()
        {
            if (_ringingResponse == null)
            {
                _ringingResponse        = _inviteRequest.CreateResponse(SipResponseCodes.x180_Ringing);
                _ringingResponse.To.Tag = SipUtil.CreateTag();
                var contactUri = AddressFactory.CreateUri("", MainForm.SipProvider.ListeningPoint.ToString());
                _ringingResponse.Contacts.Add(HeaderFactory.CreateContactHeader(contactUri));

                _inviteTransaction =
                    (SipInviteServerTransaction)SipProvider.CreateServerTransaction(_inviteRequest);
                _dialog = SipProvider.CreateServerDialog(_inviteTransaction);
                _inviteTransaction.SendResponse(_ringingResponse);
            }
            else
            {
                _inviteTransaction.SendResponse(_ringingResponse);
            }
        }
예제 #10
0
        public void Start()
        {
            if (_configuration == null)
            {
                throw new InvalidOperationException("The server is not configured.");
            }

            _stack = new SipStack();
            _stack.MaxWorkerThreads = _configuration.MaxThreadPoolSize;
            _stack.MinWorkerThreads = _configuration.MinThreadPoolSize;
            _stack.EnableThreadPoolPerformanceCounters = _configuration.EnableThreadPoolPerformanceCounters;
            var listeningPoint = _stack.CreateUdpListeningPoint(_ipEndPoint);

            _provider  = (SipProvider)_stack.CreateSipProvider(listeningPoint);
            _listener  = new SipServerListener();
            _registrar = InitializeRegistrar();
            _listener.AddRequestHandler(_registrar);
            _provider.AddSipListener(_listener);
            //_stack.Start();
        }
예제 #11
0
        private void SendRequest(Func <SipRequest> createRequest)
        {
            try
            {
                var request = createRequest();

                if (_chbSendTx.Checked)
                {
                    var transaction = SipProvider.CreateClientTransaction(request);
                    transaction.SendRequest();
                }
                else
                {
                    SipProvider.SendRequest(request);
                }
            }
            catch (Exception ex)
            {
                MainForm.HandleException(ex);
            }
        }
예제 #12
0
        private void _btnStartStop_Click(object sender, EventArgs e)
        {
            if (!_isStarted)
            {
                var ipEndPoint    = SipUtil.ParseIpEndPoint(Configuration.BindIpEndPoint);
                var outboundProxy = SipUtil.ParseIpEndPoint(Configuration.OutboundProxyIpEndPoint);
                SipStack = new SipStack();
                var listeningPoint = SipStack.CreateUdpListeningPoint(ipEndPoint);
                SipStack.MaxWorkerThreads = Configuration.MaxThreadPoolSize;
                SipStack.MinWorkerThreads = Configuration.MinThreadPoolSize;
                SipStack.OutBoundProxy    = outboundProxy;
                SipStack.EnableThreadPoolPerformanceCounters = Configuration.EnableThreadPoolPerformanceCounters;
                //SipStack.IsStateFull = Configuration.IsStateFull;
                SipProvider     = (SipProvider)SipStack.CreateSipProvider(listeningPoint);
                MainSipListener = new SipPipeLineListener(this);
                SipProvider.AddSipListener(MainSipListener);
                SipProvider.AddExceptionHandler(this);
                SipProvider.Start();


                HeaderFactory  = SipStack.CreateHeaderFactory();
                MessageFactory = SipStack.CreateMessageFactory();
                AddressFactory = SipStack.CreateAddressFactory();

                ExecuteActionHelper.ExecuteAction(delegate()
                {
                    FormsManager.OpenForm(typeof(LogForm), null);
                });

                _lblIpAddress.Text = string.Format("IP:{0}", ipEndPoint.ToString());
            }
            else
            {
                SipProvider.Stop();
            }

            _isStarted             = !_isStarted;
            _btnStartStop.Text     = _isStarted ? "Stop" : "Start";
            _grbNavigation.Enabled = _isStarted;
        }
예제 #13
0
        public static bool RegisterExt(string sExt)
        {
            try
            {
                IpAddress ip;
                int iPort = 5060;
                String sRealm = "10.0.0.8";
                String sFromUrl = "<sip:" + sExt + "@" + sRealm + ":" + iPort.ToString() + ">";    // FROM
                String toUrl = "<sip:" + "1000@" + sRealm + ":" + iPort.ToString() + ">";          // TO

                if (!SipStack.IsInit())
                {
                    SipStack.Init();
                }

                ip = IpAddress.GetLocalHostAddress();

                // Having the following line enabled creates the compiler error:
                SipProvider sipProvider = new SipProvider(ip.ToString(), iPort);

                /*
                Error	11	Error while compiling onReceivedMessage 
                * (Lorg/zoolu/sip/provider/Transport;Lorg/zoolu/sip/message/Message;)V 
                * in
                * org/zoolu/sip/provider/SipProvider: 
                * Unsupported type org/zoolu/sip/header/ViaHeader	
                * dot42SipTester1
                */

                return true;
            }
            catch
            {
                return false;
            }

           

        }
예제 #14
0
        public static bool RegisterExt(string sExt)
        {
            try
            {
                IpAddress ip;
                int       iPort    = 5060;
                String    sRealm   = "10.0.0.8";
                String    sFromUrl = "<sip:" + sExt + "@" + sRealm + ":" + iPort.ToString() + ">"; // FROM
                String    toUrl    = "<sip:" + "1000@" + sRealm + ":" + iPort.ToString() + ">";    // TO

                if (!SipStack.IsInit())
                {
                    SipStack.Init();
                }

                ip = IpAddress.GetLocalHostAddress();

                // Having the following line enabled creates the compiler error:
                SipProvider sipProvider = new SipProvider(ip.ToString(), iPort);

                /*
                 * Error	11	Error while compiling onReceivedMessage
                 * (Lorg/zoolu/sip/provider/Transport;Lorg/zoolu/sip/message/Message;)V
                 * in
                 * org/zoolu/sip/provider/SipProvider:
                 * Unsupported type org/zoolu/sip/header/ViaHeader
                 * dot42SipTester1
                 */

                return(true);
            }
            catch
            {
                return(false);
            }
        }
예제 #15
0
 public string GetId()
 {
     return(SipProvider.GetServerTransactionId(Request));
 }
예제 #16
0
        public void ProcessResponse(IInternalSoftPhone softPhone, Sip.Stack.SipResponseEvent responseEvent)
        {
            SipStatusLine statusLine = responseEvent.Response.StatusLine;

            _logger.Debug("processing response: {0} ...", statusLine.ResponseCode);

            int statusCodeDiv100 = statusLine.StatusCode / 100;

            if (responseEvent.ClientTransaction == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. In this state, the ResponseEvent is expected to have a 'NOT NULL' ClientTx. DebugInfo: TxId created from RESPONSE: '{1}'. This Id could not be matched to a clienttransaction in the provider's clienttransactiontable.", statusCodeDiv100, SipProvider.GetClientTransactionId(responseEvent.Response));
                }
                return;
            }

            /*wait for ok on cancel + 487 for invite*/

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("'{0}XX' response. Begin processing...", statusCodeDiv100);
            }

            if (statusCodeDiv100 < 2)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. Only FINAL (x200-x500) responses are processed in this state.");
                }
                return;
            }

            if (responseEvent.ClientTransaction.GetId() == softPhone.PendingInvite.CancelTransaction.GetId())
            {
                _receivedFinalCancelStatusCode = responseEvent.Response.StatusLine.StatusCode;

                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Received final response on 'CANCEL' request. StatusCode: {0}", _receivedFinalCancelStatusCode);
                }
            }

            if (responseEvent.ClientTransaction.GetId() == softPhone.PendingInvite.InviteClientTransaction.GetId())
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Received final response on 'INVITE' request.");
                }

                _receivedFinalInviteResponse = true;

                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Terminating the Dialog...");
                }

                softPhone.PendingInvite.Dialog.Terminate();

                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Dialog terminated.");
                }
            }

            //TODO: use locks.
            if (_receivedFinalCancelStatusCode == 481 ||                                 /*when cancel-tx x481 is received, the invite will NOT receive a final response. => go to idle immediately*/
                (_receivedFinalCancelStatusCode == 200 && _receivedFinalInviteResponse)) /*when cancel-tx x200 is received, the invite will receive a final response. => wait for x487  before going to idle*/
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Changing CallState to 'Cancelled'");
                }

                softPhone.PendingCall.RaiseCallStateChanged(CallState.Cancelled);

                /*go to idle*/
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Both 'CANCEL' & 'INVITE' Tx have received a final response. Transitioning to Idle...");
                }
                softPhone.ChangeState(softPhone.StateProvider.GetIdle());
            }
        }
예제 #17
0
 void DiagnosticsForm_Load(object sender, EventArgs e)
 {
     _sipProvider = MainForm.SipProvider;
     _tmrRefresh.Start();
     _usageThreadsInPool.Maximum = MainForm.SipStack.MaxWorkerThreads;
 }
예제 #18
0
        public void ProcessRequest(IInternalSoftPhone softPhone, Sip.Stack.SipRequestEvent requestEvent)
        {
            string method = requestEvent.Request.RequestLine.Method;

            _logger.Debug("processing request: {0} ...", method);

            if (method != SipMethods.Bye)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Received request: '{0}'. Request ignored.", method);
                }
                return;
            }

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("'BYE' received. Begin processing...");
            }

            if (requestEvent.Dialog == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. A 'BYE' RequestEvent is expected to have a 'NOT NULL' dialog. DebugInfo: DialogId created from BYE: '{0}'. This Id could not be matched to a dialog in the provider's dialogtable.", SipProvider.GetDialogId(requestEvent.Request, true));
                }
                return;
            }

            if (requestEvent.Dialog.GetId() != softPhone.PendingInvite.Dialog.GetId())
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. The 'BYE' RequestEvent.Dialog, is expected to match only to the Dialog of the PendingInvite. DebugInfo: DialogId created from BYE: '{0}'. This case is not supposed to occur, since the phone can only process ONE dialog at a time. Check what's going on !!", SipProvider.GetDialogId(requestEvent.Request, true));
                }
                return;
            }

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("Sending OK response to BYE..");
            }

            var okResponse = requestEvent.Request.CreateResponse(SipResponseCodes.x200_Ok);

            var tx = softPhone.SipProvider.CreateServerTransaction(requestEvent.Request);

            tx.SendResponse(okResponse);

            requestEvent.IsSent = true;

            softPhone.PendingInvite.Dialog.Terminate();

            softPhone.PendingCall.RaiseCallStateChanged(CallState.Completed);

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("OK Send.");
            }

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("Transitioning to 'IDLE'...");
            }

            softPhone.ChangeState(softPhone.StateProvider.GetIdle());
        }
예제 #19
0
 public DialogListener(SipProvider provider)
 {
     _provider = provider;
 }
예제 #20
0
        public void ProcessRequest(IInternalSoftPhone softPhone, Sip.Stack.SipRequestEvent requestEvent)
        {
            string method = requestEvent.Request.RequestLine.Method;

            _logger.Debug("processing request: {0} ...", method);

            if (method != SipMethods.Ack)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Received request: '{0}'. Request ignored.", method);
                }
                return;
            }

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("'ACK' received. Begin processing...");
            }

            if (requestEvent.Dialog == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. An 'ACK' RequestEvent is expected to have a 'NOT NULL' dialog. DebugInfo: DialogId created from ACK: '{0}'. This Id could not be matched to a dialog in the provider's dialogtable.", SipProvider.GetDialogId(requestEvent.Request, true));
                }
                return;
            }

            if (requestEvent.Dialog.GetId() != softPhone.PendingInvite.Dialog.GetId())
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. The 'ACK' RequestEvent it's Dialog, is expected to match only to the Dialog of the PendingInvite. DebugInfo: DialogId created from ACK: '{0}'. This case is not supposed to occur, since the phone can only process ONE dialog at a time. Check what's going on !!", SipProvider.GetDialogId(requestEvent.Request, true));
                }
                return;
            }

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("Transitioning to 'ESTABLISHED'...");
            }

            softPhone.ChangeState(softPhone.StateProvider.GetEstablished());
        }
예제 #21
0
        public void ProcessResponse(IInternalSoftPhone softPhone, Sip.Stack.SipResponseEvent responseEvent)
        {
            SipStatusLine statusLine = responseEvent.Response.StatusLine;

            _logger.Debug("processing response: {0} ...", statusLine.ResponseCode);

            int statusCodeDiv100 = statusLine.StatusCode / 100;

            if (responseEvent.ClientTransaction == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. In this state, the ResponseEvent is expected to have a 'NOT NULL' ClientTx. DebugInfo: TxId created from RESPONSE: '{1}'. This Id could not be matched to a clienttransaction in the provider's clienttransactiontable.", statusCodeDiv100, SipProvider.GetClientTransactionId(responseEvent.Response));
                }
                return;
            }

            /*wait for ok on bye*/

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("'{0}XX' response. Begin processing...", statusCodeDiv100);
            }

            if (statusCodeDiv100 != 2)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. Only 'x200-299' responses are processed in this state.");
                }
                return;
            }

            if (responseEvent.ClientTransaction.Request.CSeq.Command == SipMethods.Bye)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Received final response on 'BYE' request.Transitioning to Idle...");
                }

                softPhone.ChangeState(softPhone.StateProvider.GetIdle());
            }
            else
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("Response ignored. This is not the response to the 'BYE' request.");
                }
            }
        }
예제 #22
0
 private bool IsMatchByDialogId(SipResponse response)
 {
     return(GetId() == SipProvider.GetDialogId(response, this is SipInviteServerDialog));
 }
예제 #23
0
        public void ProcessResponse(IInternalSoftPhone softPhone, Sip.Stack.SipResponseEvent responseEvent)
        {
            SipStatusLine statusLine = responseEvent.Response.StatusLine;

            _logger.Debug("processing response: {0} ...", statusLine.ResponseCode);

            if (statusLine.ResponseCode == SipResponseCodes.x100_Trying)
            {
                if (_logger.IsDebugEnabled)
                {
                    _logger.Debug("'Trying' response received. Ignored");
                }
                return;
            }

            int statusCodeDiv100 = statusLine.StatusCode / 100;

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("'{0}XX' response. Begin processing...", statusCodeDiv100);
            }

            if (responseEvent.ClientTransaction == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. A '{0}XX' ResponseEvent is expected to have a 'NOT NULL' ClientTx. DebugInfo: TxId created from RESPONSE: '{1}'. This Id could not be matched to a clienttransaction in the provider's clienttransactiontable.", statusCodeDiv100, SipProvider.GetClientTransactionId(responseEvent.Response));
                }
                return;
            }

            if (responseEvent.ClientTransaction.GetId() != softPhone.PendingInvite.InviteClientTransaction.GetId())
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. The '{0}XX' ResponseEvent.ClientTransaction, is expected to match only to the InviteSendTransaction of the PendingInvite. DebugInfo: TxId created from RESPONSE: '{1}'. This case is not supposed to occur, since the phone can only process ONE PendingInvite at a time. Check what's going on !!", statusCodeDiv100, SipProvider.GetClientTransactionId(responseEvent.Response));
                }
                return;
            }

            if (responseEvent.Dialog == null)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. In this state the 'ResponseEvent' is expected to have a 'NOT NULL' dialog. DebugInfo: DialogId created from Response: '{0}'. This Id could not be matched to a dialog in the provider's dialogtable.", SipProvider.GetDialogId(responseEvent.Response, false));
                }
                return;
            }

            if (responseEvent.Dialog.GetId() != softPhone.PendingInvite.Dialog.GetId())
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Processing ABORTED. In this state the 'ResponseEvent' it's Dialog, is expected to match only to the Dialog of the PendingInvite. DebugInfo: DialogId created from response: '{0}'. This case is not supposed to occur, since the phone can only process ONE dialog at a time. Check what's going on !!", SipProvider.GetDialogId(responseEvent.Response, false));
                }
                return;
            }

            if (statusCodeDiv100 == 1)
            {
                /*go to wait for final*/
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Transitioning to 'WAITFINAL'...");
                }

                softPhone.ChangeState(softPhone.StateProvider.GetWaitFinal());
            }
            else if (statusCodeDiv100 == 2)
            {
                if (_logger.IsInfoEnabled)
                {
                    _logger.Info("Transitioning to 'ESTABLISHED'...");
                }

                Check.IsTrue(responseEvent.Dialog is SipInviteClientDialog, "Failed to respond to '200' response with ACK request. The 'ACK' can not be created. The responseEvent.Dialog is expected to be of type SipInviteClientDialog.");

                var clientDialog = (SipInviteClientDialog)softPhone.PendingInvite.Dialog;
                var ack          = clientDialog.CreateAck();
                clientDialog.SendAck(ack);

                softPhone.ChangeState(softPhone.StateProvider.GetEstablished());
            }
            else
            {
                //change callstate. don't go automatically to 'IDLE' state, but wait for the api user to invoke Call.Stop()

                if (statusLine.ResponseCode == SipResponseCodes.x486_Busy_Here)
                {
                    if (_logger.IsDebugEnabled)
                    {
                        _logger.Debug("Changing CallState to 'BusyHere'");
                    }
                    softPhone.PendingCall.RaiseCallStateChanged(CallState.BusyHere);
                }
                else
                {
                    if (_logger.IsDebugEnabled)
                    {
                        _logger.Debug("Changing CallState to 'Error'");
                    }
                    softPhone.PendingCall.RaiseCallErrorOccured(CallError.SipResponse, statusLine.ResponseCode);
                    softPhone.PendingCall.RaiseCallStateChanged(CallState.Error);
                }

                softPhone.PendingInvite.Dialog.Terminate();

                softPhone.ChangeState(softPhone.StateProvider.GetIdle());
            }
        }
예제 #24
0
        private void OnPhoneCallStarted(IInternalPhoneCall phoneCall)
        {
            Check.Require(phoneCall, "phoneCall");
            Check.IsTrue(InternalState == _stateProvider.GetIdle(), string.Format("Failed to start the call. The phone can only start calls while in 'IDLE' state. CurrentState: '{0}'", CurrentState));
            Check.IsTrue(_isRunning, "Failed to start the call. The phone must be started first.");

            _pendingPhoneCall = phoneCall;

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("Starting new phonecall...");
            }
            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("Creating 'INVITE' request...");
            }
            var thisUri = AddressFactory.CreateUri(string.Empty, ListeningPoint.ToString());

            var requestUri   = phoneCall.GetToUri();
            var toAddress    = AddressFactory.CreateAddress(string.Empty, phoneCall.GetToUri());
            var fromAddress  = AddressFactory.CreateAddress(string.Empty, thisUri);
            var toHeader     = HeaderFactory.CreateToHeader(toAddress);
            var fromHeader   = HeaderFactory.CreateFromHeader(fromAddress, SipUtil.CreateTag());
            var cseqHeader   = HeaderFactory.CreateSCeqHeader(SipMethods.Invite, MessageCounter++);
            var callIdheader = HeaderFactory.CreateCallIdHeader(SipUtil.CreateCallId());
            var viaHeader    = HeaderFactory.CreateViaHeader(ListeningPoint.Address,
                                                             ListeningPoint.Port, SipConstants.Udp,
                                                             SipUtil.CreateBranch());
            var maxForwardsHeader = HeaderFactory.CreateMaxForwardsHeader(1);
            var request           = MessageFactory.CreateRequest(
                requestUri,
                SipMethods.Invite,
                callIdheader,
                cseqHeader,
                fromHeader,
                toHeader,
                viaHeader,
                maxForwardsHeader);

            /*add contactheader*/
            var contactUri    = AddressFactory.CreateUri(thisUri.User, viaHeader.SentBy.ToString());
            var contactHeader = HeaderFactory.CreateContactHeader(contactUri);

            request.Contacts.Add(contactHeader);

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("'INVITE' request created. Sending to callee..");
            }

            var clientTransaction = SipProvider.CreateClientTransaction(request);
            var dialog            = SipProvider.CreateClientDialog(clientTransaction as SipInviteClientTransaction);

            clientTransaction.SendRequest();

            if (_logger.IsDebugEnabled)
            {
                _logger.Debug("'INVITE' sent.");
            }

            if (_logger.IsInfoEnabled)
            {
                _logger.Info("Request sent. Transitioning to 'WAITPROVISIONAL' state...");
            }

            PendingInvite = new InviteInfo()
            {
                OriginalRequest = request,
                From            = request.From.SipUri,
                To = request.To.SipUri,
                InviteClientTransaction = (SipInviteClientTransaction)clientTransaction,
                IsIncomingCall          = false,
                Dialog = dialog
            };

            ChangeState(_stateProvider.GetWaitProvisional());
        }
예제 #25
0
 public string GetId()
 {
     return(SipProvider.GetClientTransactionId(Request));
 }
예제 #26
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            Log("Received a request. RequestLine:'{0}'", requestEvent.Request.RequestLine.FormatToString());

            if (requestEvent.Request.RequestLine.Method == SipMethods.Invite)
            {
                Log("Received an INVITE request.");
                if (_state == PhoneState.Idle)
                {
                    _inviteRequest = requestEvent.Request;
                    _ringingRetransmitSubscription = Observable.Timer(TimeSpan.Zero, TimeSpan.FromSeconds(5)).ObserveOn(this).Subscribe((i) =>
                    {
                        Log("Sending a ringing response...");
                        SendRinging();
                        Log("Ringing response send.");
                        if (i == 0)
                        {
                            GoToState(PhoneState.Ringing);
                            RefreshDialogForm(_dialog);
                        }
                    });
                }
                else
                {
                    Log("Currently busy...");
                    //send busy here
                }
            }


            if (_state == PhoneState.Idle)
            {
                if (requestEvent.Request.RequestLine.Method == SipMethods.Invite)
                {
                    GoToState(PhoneState.Ringing);
                    _pendingRequestEvent = requestEvent;

                    this.OnUIThread(() =>
                    {
                        //show the name of the caller in the from textboxes.
                        _txtFromAlias.Text = requestEvent.Request.From.DisplayInfo;
                        _txtFromAlias.Text = requestEvent.Request.From.DisplayInfo;
                        //clear all other from-to textboxes
                        _txtFromUri.Text = ""; requestEvent.Request.From.SipUri.FormatToString();
                        _txtToUri.Text   = _txtToAlias.Text = "";
                    });

                    //block the processing thread
                    _waitHandle.WaitOne(30 * 1000);
                }
            }
            else if (_state == PhoneState.Ringing)
            {
                if (requestEvent.Request.RequestLine.Method == SipMethods.Cancel)
                {
                    //TODO: send 487 + stop ringing
                    GoToState(PhoneState.Idle);
                }
            }
            else if (_state == PhoneState.WaitingForAck)
            {
                if (requestEvent.Request.RequestLine.Method == SipMethods.Ack)
                {
                    Log("Received an ACK request. Going to 'CALLERESTABLISHED' state");
                    GoToState(PhoneState.CallerEstablished);
                }
            }
            else if (_state == PhoneState.CallerEstablished)
            {
                if (requestEvent.Request.RequestLine.Method == SipMethods.Bye)
                {
                    Debugger.Break();
                    Log("Received an BYE request.");
                    Log("Sending a OK response...");
                    /*send ok*/
                    var okResponse        = requestEvent.Request.CreateResponse(SipResponseCodes.x200_Ok);
                    var serverTransaction = SipProvider.CreateServerTransaction(requestEvent.Request);
                    serverTransaction.SendResponse(okResponse);
                    Log("OK response send.");
                    if (requestEvent.Dialog != null)
                    {
                        requestEvent.Dialog.Terminate();
                        Log("Terminating dialog.");
                    }
                    GoToState(PhoneState.Idle);
                }
            }
        }