Example #1
0
 protected override void AfterPhoneProcessedRequest(IInternalSoftPhone softPhone, SipRequestEvent requestEvent)
 {
     if (requestEvent.Request.CSeq.Command == SipMethods.Invite)
     {
         _waitingforInviteReceived.Set();
     }
 }
Example #2
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            Console.WriteLine("Received '{0}' message", requestEvent.Request.CSeq.Command);

            /*prevent a exception from being thrown*/
            requestEvent.IsSent = true;
        }
Example #3
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            EventAggregator.Instance.Publish(new LogEvent("<<<< [RECEIVED REQUEST] " + SipFormatter.FormatMessageEnvelope(requestEvent.Request)));

            if(_siplistener != null) _siplistener.ProcessRequest(requestEvent);

            //MainForm.SendMessage(new LogMessage() { Text = "<<<<" + SipFormatter.FormatMessageEnvelope(requestEvent.Response) });
        }
Example #4
0
        public void ProcessRequest(IInternalSoftPhone softPhone, SipRequestEvent requestEvent)
        {
            ProcessRequestCounter++;

            _state.ProcessRequest(softPhone, requestEvent);

            _afterProcessRequest(softPhone, requestEvent);
        }
Example #5
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            var okResponse = requestEvent.Request.CreateResponse(SipResponseCodes.x200_Ok);

            var serverTransaction = _receiverProvider.CreateServerTransaction(requestEvent.Request);
            serverTransaction.SendResponse(okResponse);

            /*instruct the sipprovider that we have already sent the response*/
            requestEvent.IsSent = true;
        }
Example #6
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            var enumerator = _requestHandlers.GetEnumerator();

            while(enumerator.MoveNext())
            {
                enumerator.Current.ProcessRequest(requestEvent);
                if (requestEvent.IsHandled) break;
            }
        }
Example #7
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            var response = requestEvent.Request.CreateResponse(SipResponseCodes.x200_Ok);

            if(requestEvent.ServerTransaction != null)
            {
                requestEvent.ServerTransaction.SendResponse(response);
            }
            else
            {
                requestEvent.Response = response;
                requestEvent.IsHandled = true;
                MainForm.SipProvider.SendResponse(requestEvent.Response);
            }
        }
Example #8
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            if (requestEvent.Request.RequestLine.Method == SipMethods.Invite)
            {
                var inviteTransaction = (SipInviteServerTransaction)_provider.CreateServerTransaction(requestEvent.Request);
                var dialog = _provider.CreateServerDialog(inviteTransaction);
                /*let the phone of the receiver ring to indicate someone is calling to you+
                 send back a ringing response to inform to callee, you received the invite*/
                WavePlayer player = new WavePlayer(AudioOut.Devices[0]);
                player.Play(ResManager.GetStream("ringing.wav"), 10);
                var response = CreateRingingResponse(requestEvent.Request);
                inviteTransaction.SendResponse(response);

                //start timer that does the above untill the dialog state != Early
                //the listener is in some state. In this state the callee can answer or cancel the call.
                //when it does it goes to another state.
            }
            else if (requestEvent.Request.RequestLine.Method == SipMethods.Ack &&
                requestEvent.Request.CSeq.Command == SipMethods.Invite)
            {
               /*TODO: */
            }
        }
Example #9
0
        public void ProcessRequest(IInternalSoftPhone softPhone, SipRequestEvent requestEvent)
        {
            string method = requestEvent.Request.RequestLine.Method;

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

            if (_logger.IsInfoEnabled) _logger.Info("'CANCEL' received. Start processing...");

            #region attempt to match transaction

            /*terminate pending invite with 487 (assumption: PendingInvite.OriginalRequest= requestEvent.ServerTransaction.Request)*/

            if (_logger.IsDebugEnabled) _logger.Debug("Attempting to match 'CANCEL' target-tx against a tx in the ServerTransactionTable...");

            var txIdAttempts = CreateTxIdAttempts(requestEvent.Request);

            ISipServerTransaction serverTransaction = null;
            foreach (var txIdAttempt in txIdAttempts)
            {
                serverTransaction = softPhone.SipProvider.FindServerTransactionById(txIdAttempt);
                if(serverTransaction !=null) break;
            }

            #endregion

            if (serverTransaction == null)
            {
                #region no match

                if (_logger.IsDebugEnabled) _logger.Debug("Could not match 'CANCEL' to an existing transaction. Sending x487 response...");

                var cancelResponse = requestEvent.Request.CreateResponse(SipResponseCodes.x481_Call_Transaction_Does_Not_Exist);
                var cancelTx = softPhone.SipProvider.CreateServerTransaction(requestEvent.Request);
                cancelTx.SendResponse(cancelResponse);
                requestEvent.IsSent = true;

                if (_logger.IsDebugEnabled) _logger.Debug("x487 response send.");

                #endregion
            }
            else
            {
                #region matched

                #region respond to cancel with ok

                if (_logger.IsDebugEnabled) _logger.Debug("'CANCEL' target-tx matched. Answering to cancel with ok...");

                var cancelOkResponse = requestEvent.Request.CreateResponse(SipResponseCodes.x200_Ok);
                var cancelOkTx = softPhone.SipProvider.CreateServerTransaction(requestEvent.Request);
                cancelOkTx.SendResponse(cancelOkResponse);
                requestEvent.IsSent = true;

                if (_logger.IsDebugEnabled) _logger.Debug("Answered.");

                #endregion

                #region respond to matched tx with x487

                if (serverTransaction.GetId() != softPhone.PendingInvite.InviteServerTransaction.GetId())
                {
                    if (_logger.IsInfoEnabled) _logger.Info("'CANCEL' target-tx does NOT match 'INVITE.' Processing ABORTED. The 'CANCEL' target-tx is expected, to match only to the pending 'INVITE' servertransaction.");
                }
                else
                {
                    if (_logger.IsDebugEnabled) _logger.Debug("Creating '487-Request terminated' response and sending...");

                    var requestToCancel = serverTransaction.Request;
                    var terminateResponse = requestToCancel.CreateResponse(SipResponseCodes.x487_Request_Terminated);

                    /*terminate pending invite.*/
                    softPhone.PendingInvite.InviteServerTransaction.SendResponse(terminateResponse);

                    if (_logger.IsDebugEnabled) _logger.Debug("Response send.");

                    if (_logger.IsDebugEnabled) _logger.Debug("Changing callstate to 'CANCELLED'.");

                    softPhone.PendingCall.RaiseCallStateChanged(CallState.Cancelled);

                    if (_logger.IsInfoEnabled) _logger.Info("'CANCEL' Processed. Transitioning (back) to 'Idle'");

                    softPhone.ChangeState(softPhone.StateProvider.GetIdle());
                }

                #endregion

                #endregion
            }
        }
Example #10
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            var request = requestEvent.Request;
            var requestLine = request.RequestLine;
            var toUri = request.To.SipUri;
            var aor = toUri.FormatToString();
            var newContacts = request.Contacts.ToList();

            if (requestLine.Method == SipMethods.Register)
            {
                if (!string.IsNullOrWhiteSpace(requestLine.Uri.User))
                {
                    /*throw invalid exception bc the user portion for a register request must be empty*/
                    throw new SipException(SipResponseCodes.x400_Bad_Request, "The sip uri can not contain a user.");
                }

                /*10.3. 1. The registrar inspects the Request-URI to determine whether it
                 has access to bindings for the domain identified in the
                 Request-URI.  If not, and if the server also acts as a proxy
                 server, the server SHOULD forward the request to the addressed
                 domain, following the general behavior for proxying messages
                 described in Section 16.*/

                /*The registrar inspects the Request-URI to determine whether it
                 has access to bindings for the domain identified in the Request-URI.
                 Here we give an exception back to the client because we only supports single domain */

                if (requestLine.Uri.Host != _settings.Domain)
                {
                    throw new SipException(SipResponseCodes.x404_Not_Found);
                }

                if (toUri.Host != _settings.Domain)
                {
                    /*If the address-of-record is not valid for the domain in the Request-URI,
                     * the registrar MUST send a 404 (Not Found) response and skip the remaining steps.*/
                    throw new SipException(SipResponseCodes.x404_Not_Found);
                }

                bool hasWildCard = newContacts.Any(c => c.IsWildCard);
                if (hasWildCard)
                {
                    if (IsInvalidWildCardRequest(request))
                    {
                        throw new SipException(SipResponseCodes.x400_Bad_Request);
                    }

                    /*case: deregister: remove all bindings for the aor */
                    foreach (var binding in _addressBindingService.GetByAddressOfRecord(aor))
                    {
                        if (binding.CallId != request.CallId.Value)
                        {
                            _addressBindingService.Remove(binding);
                            continue;
                        }
                        if (request.CSeq.Sequence > binding.CSeq)
                        {
                            _addressBindingService.Remove(binding);
                        }
                    }
                }
                /*The registrar extracts the address-of-record from the To header
                    field of the request. If the address-of-record is not valid
                    for the domain in the Request-URI, the registrar MUST send a
                    404 (Not Found) response and skip the remaining steps.  The URI
                    MUST then be converted to a canonical form.  To do that, all
                    URI parameters MUST be removed (including the user-param), and
                    any escaped characters MUST be converted to their unescaped
                    form.  The result serves as an index into the list of bindings.*/
                /* Each binding record records the Call-ID and CSeq values from the request.*/
                foreach (var contact in newContacts)
                {
                    if (!SipUtil.IsIPAddress(contact.SipUri.Host))
                    {
                        throw new SipException(SipResponseCodes.x400_Bad_Request, "Contact uri must have numeric IP format.");
                    }
                    var host = new IPEndPoint(SipUtil.ParseIpAddress(contact.SipUri.Host), contact.SipUri.Port);

                    int expires = _settings.DefaultExpires;
                    if (request.Expires != null) expires = request.Expires.Value;
                    if (contact.Expires.HasValue) expires = contact.Expires.Value;

                    var newAddressBinding =
                          new SipAddressBinding(
                              aor,
                              host,
                              request.CSeq.Sequence,
                              request.CallId.Value,
                              expires);

                    if(expires == 0)
                    {
                        _addressBindingService.Remove(newAddressBinding);
                    }
                    else if (expires < _settings.MinimumExpires)
                    {
                        throw new SipException(SipResponseCodes.x423_Interval_Too_Brief);
                    }
                    else
                    {
                        _addressBindingService.AddOrUpdate(newAddressBinding);
                    }
                }

                var okResponse = request.CreateResponse(SipResponseCodes.x200_Ok);
                var contactsAddresses = new List<SipContactHeader>();

                foreach(var binding in _addressBindingService.GetByAddressOfRecord(aor))
                {
                    var contactAddress = new SipContactHeader();
                    contactAddress.Expires = (int) (binding.EndTime - DateTime.Now).TotalSeconds;
                    contactAddress.SipUri = new SipUri()
                    {
                        Host = binding.Host.Address.ToString(),
                        Port = binding.Host.Port
                    };
                    contactsAddresses.Add(contactAddress);
                }

                contactsAddresses.ForEach(okResponse.Contacts.Add);

                /*set the response*/
                if(requestEvent.ServerTransaction != null)
                {
                    requestEvent.ServerTransaction.SendResponse(okResponse);
                    requestEvent.IsHandled = true;
                    requestEvent.IsSent = true;
                }
                else
                {
                    requestEvent.Response = okResponse;
                    requestEvent.IsHandled = true;
                }
            }
        }
Example #11
0
 internal void Update(SipRequestEvent requestEvent)
 {
     Response = requestEvent.Response;
     IsHandled = requestEvent.IsHandled;
     IsSent = requestEvent.IsSent;
 }
 protected virtual void AfterPhoneProcessedRequest(IInternalSoftPhone softPhone, SipRequestEvent requestEvent)
 {
 }
Example #13
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            Console.WriteLine("Received '{0}' request on {1}", requestEvent.Request.CSeq.Command, DateTime.Now.ToString("hh:mm:ss"));

            requestEvent.IsSent = true;
        }
Example #14
0
        private void SendErrorResponse(Exception exception, SipRequestEvent requestEvent)
        {
            Check.Require(exception, "exception");
            Check.Require(requestEvent, "requestEvent");
            Check.Require(requestEvent.Request, "requestEvent.Request");

            var request = requestEvent.Request;
            var sipException = exception as SipException;

            string responseCode = sipException != null ? sipException.ResponseCode : SipResponseCodes.x500_Server_Internal_Error;
            SipResponse response = sipException != null ? _stack.CreateMessageFactory().CreateResponse(request, responseCode) :
                _stack.CreateMessageFactory().CreateResponse(request, responseCode + ", " + exception.Message);

            if(requestEvent.ServerTransaction != null)
            {
                requestEvent.ServerTransaction.SendResponse(response);
            }
            else if (response.Vias.GetTopMost() != null)
            {
                IPEndPoint ipEndPoint = SipProvider.DetermineSendTo(response);

                try
                {
                    _contextSource.SendTo(SipFormatter.FormatMessage(response), ipEndPoint);
                    if (_responseSentObserver != null) _responseSentObserver.OnNext(response);
                }
                catch (SocketException err)
                {
                    _logger.Error("Failed to send response to " + ipEndPoint.ToString(), err);
                }
            }
            else
            {
                _logger.Warn("Response can not be sent. Via TopMost header missing.");
            }
        }
Example #15
0
        private void OnIncomingRequestContext(SipContext context)
        {
            if (_requestReceivedObserver != null) _requestReceivedObserver.OnNext(context.Request);

            if (_logger.IsDebugEnabled) _logger.Debug("Validating the request...");

            var result = new SipValidator().ValidateMessage(context.Request);

            if (!result.IsValid)
            {
                if (_logger.IsDebugEnabled) _logger.Debug("The received request is not valid. Throwing a sip exception.");

                ThrowSipException(result);
            }

            if (_logger.IsDebugEnabled) _logger.Debug("Request valid.");

            /*firewall traversal not supported. SupportFirewalTraversal(context);*/

            var requestEvent = new SipRequestEvent(context);

            ISipRequestProcessor sipRequestProcessor = _sipListener;

            //8.2.2.2: merged requests, not implemented

            SipAbstractServerTransaction stx;

            if (_logger.IsDebugEnabled) _logger.Debug("Searching the table for a matching tx..");

            if(_stxTable.TryGetValue(GetServerTransactionId(context.Request), out stx))
            {
                if (_logger.IsTraceEnabled) _logger.Trace("Found a matching tx. Setting it as the requestprocessor.");

                sipRequestProcessor = stx;

                //if (IsDialogInitiatingRequest(stx.Request))
                //{
                    //if (_logger.IsDebugEnabled) _logger.Debug("The received request is an 'INVITE' request. Try setting the dialog on tx...");

                    //set the dialog, so it can initiate
                    SipAbstractDialog found;
                    if(TryGetDialogOnTx(context.Request, out found))
                    {
                        requestEvent.Dialog = found;
                    }
                //}
            }
            else
            {
                if (_logger.IsDebugEnabled) _logger.Debug("Could not find a matching tx..");

                if (_logger.IsDebugEnabled) _logger.Debug("Searching the table for a matching dialog...");

                SipAbstractDialog dialog;
                if (_dialogTable.TryGetValue(GetDialogId(context.Request, true), out dialog))
                {
                    if (_logger.IsTraceEnabled) _logger.Trace("Found a matching dialog. Setting it as the requestprocessor.");

                    sipRequestProcessor = dialog;
                    requestEvent.Dialog = dialog;
                }
                else
                {
                    if (_logger.IsTraceEnabled) _logger.Trace("Could not find a matching dialog. Using the SipProvider's SipListener as the requestprocessor.");
                }
            }

            try
            {
                sipRequestProcessor.ProcessRequest(requestEvent);

                if (requestEvent.IsSent)
                {
                    if (_logger.IsDebugEnabled) _logger.Debug("Processed '{0}' request. The response has already been sent. Skipping automatic response sending.", requestEvent.Request.RequestLine.Method);
                    return;
                }

                if (!ShouldHaveResponse(requestEvent.Request))
                {
                    if(_logger.IsDebugEnabled) _logger.Debug("Processed '{0}' request. The request does not require a response. Skipping automatic response sending.", requestEvent.Request.RequestLine.Method);
                    return;
                }

                if(requestEvent.Response == null)
                    throw new SipCoreException("Response to send can not be null. The ProcessRequest method is supposed to create a response message that is to be sent.");

                if (!requestEvent.IsSent)
                {
                    var response = requestEvent.Response;

                    var remoteEndPoint = SipProvider.DetermineSendTo(response);

                    _contextSource.SendTo(SipFormatter.FormatMessage(response), remoteEndPoint);

                    if (_responseSentObserver != null) _responseSentObserver.OnNext(response);
                }
            }
            catch (SipCoreException coreException)
            {
                throw coreException;
            }
            catch (SipException sipException)
            {
                if(ShouldHaveResponse(requestEvent.Request))
                    SendErrorResponse(sipException, requestEvent);
            }
            catch (Exception err)
            {
                _logger.ErrorException("Request failed.", err);

                try
                {
                    if (ShouldHaveResponse(requestEvent.Request))
                        SendErrorResponse(err, requestEvent);
                }
                catch (Exception errr)
                {
                    _logger.Debug("Failed to send the response.", errr);
                }
            }
        }
Example #16
0
        public void ProcessRequest(SipRequestEvent requestEvent)
        {
            string method = requestEvent.Request.RequestLine.Method;

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

            ValidateSipSchema(requestEvent.Request);

            ////not sure if this is the right place?
            //if (State is IdleState)
            //{
            //    throw new SipException(SipResponseCodes.x486_Busy_Here);
            //}

            InternalState.ProcessRequest(this, requestEvent);

            _logger.Debug("Request processed.");
        }
 public void ProcessRequest(SipRequestEvent requestEvent)
 {
     throw new NotImplementedException();
 }
Example #18
0
 public void ProcessRequest(SipRequestEvent requestEvent)
 {
     OnProcessRequest(requestEvent);
 }
Example #19
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);
                }
            }
        }