Пример #1
0
        public SipEventHandlerResult CloseCall(SipDialogMessage sipMessage)
        {
            log.Debug("Closing call with id:\"{0}\", hash id:\"{1}\", hash entry:\"{2}\"", sipMessage.CallId, sipMessage.HashId, sipMessage.HashEntry);

            try
            {
                CallInfo call = _callRepository.GetCallInfo(sipMessage.CallId, sipMessage.HashId, sipMessage.HashEntry);

                if (call == null)
                {
                    log.Warn("Unable to find call with call id: {0}, hash id:{1}, hash entry:{2}", sipMessage.CallId, sipMessage.HashId, sipMessage.HashEntry);
                    return(NothingChangedResult);
                }

                if (call.Closed)
                {
                    log.Warn("Call with call id: {0} already closed", sipMessage.CallId);
                    return(NothingChangedResult);
                }

                _callRepository.CloseCall(call.Id);
                return(SipMessageResult(SipEventChangeStatus.CallClosed, call.Id));
            }
            catch (Exception ex)
            {
                log.Error(ex, "Error while closing call with call id: {0}", sipMessage.CallId);
                return(NothingChangedResult);
            }
        }
Пример #2
0
        private SipDialogMessage ParseDialog(KamailioData kamailioData)
        {
            DialogStatus dialogStatus;

            if (!Enum.TryParse(kamailioData.GetField("dstat"), true, out dialogStatus))
            {
                log.Warn("Unable to parse dstat field of Kamailio dialog message");
                return(null);
            }

            var dialog = new SipDialogMessage
            {
                Status          = dialogStatus,
                CallId          = kamailioData.GetField("ci"),
                HashId          = kamailioData.GetField("hashid"),
                HashEntry       = kamailioData.GetField("hashent"),
                FromDisplayName = ParseDisplayName(kamailioData.GetField("fn")),
                ToDisplayName   = ParseDisplayName(kamailioData.GetField("tn")),
                FromSipUri      = new SipUri(kamailioData.GetField("fu")),
                ToSipUri        = new SipUri(kamailioData.GetField("ru")),
                FromTag         = kamailioData.GetField("fot"),
                ToTag           = kamailioData.GetField("tot"),
                Sdp             = kamailioData.GetField("sdp"),
                HangupReason    = kamailioData.GetField("hr")
            };

            // Fix for empty ru-field in Kamailio data
            if (dialog.ToSipUri == null || string.IsNullOrEmpty(dialog.ToSipUri.User))
            {
                dialog.ToSipUri = new SipUri(kamailioData.GetField("tu"));
            }

            return(dialog);
        }
Пример #3
0
        public void when_call_ended_registeredsip_should_be_updated_in_cache()
        {
            try
            {
                // Lägg till registrerade kodare
                var codec1 = "*****@*****.**";
                var codec2 = "*****@*****.**";

                RegisterSip(codec1, "192.0.2.236", "MTU 01", "QuantumST/3.5.3g");
                RegisterSip(codec2, "192.0.2.4", "MTU 02", "QuantumST/3.5.3g");
                RegisterSip("*****@*****.**", "192.0.2.215", "MTU 31", "QuantumST/3.5.3g");

                //PrintCodecStatus(codec1, codec2);

                for (int i = 0; i < 10; i++)
                {
                    // Starta samtal
                    var dialogMessage = new SipDialogMessage
                    {
                        FromSipUri = new SipUri(codec1),
                        ToSipUri   = new SipUri(codec2),
                        CallId     = Guid.NewGuid().ToString(),
                        HashId     = "0",
                        HashEntry  = "0"
                    };

                    var result = _kamailioMessageManager.RegisterCall(dialogMessage);
                    Console.WriteLine("Call from {0} to {1} started with status {2}", codec1, codec2, result.ChangeStatus);

                    // Läs ut kodare-status
                    PrintCodecStatus(codec1, codec2);

                    // Läs ut samtal
                    var call = _callRepository.GetCallInfo(dialogMessage.CallId, dialogMessage.HashId, dialogMessage.HashId);
                    Console.WriteLine("Call from {0} to {1} started {2}", call.FromSipAddress, call.ToSipAddress, call.Started);

                    // Avsluta samtal
                    var hangupResult = _kamailioMessageManager.CloseCall(dialogMessage);
                    Console.WriteLine("Call from  {0} to {1} ended with result: {2}", codec1, codec2, hangupResult.ChangeStatus);

                    // Läs ut kodare-status
                    PrintCodecStatus(codec1, codec2);
                }
            }
            finally
            {
                TearDown();
            }
        }
Пример #4
0
        public SipEventHandlerResult RegisterCall(SipDialogMessage sipMessage)
        {
            log.Debug("Register call from {0} to {1}, call id \"{2}\", hash id:\"{3}\", hash entry:\"{4}\"",
                      sipMessage.FromSipUri.UserAtHost, sipMessage.ToSipUri.UserAtHost, sipMessage.CallId, sipMessage.HashId, sipMessage.HashEntry);

            if (_callRepository.CallExists(sipMessage.CallId, sipMessage.HashId, sipMessage.HashEntry))
            {
                // TODO: Find out what HashId and HashEntry is and if they are both needed
                log.Debug("Call with id {0}, hash id:{1}, hash entry:{2} already exists", sipMessage.CallId, sipMessage.HashId, sipMessage.HashEntry);
                return(NothingChangedResult);
            }

            var call = new Call();

            // If the user-part is numeric, we make the assumption
            // that it is a phone number (even though sip-address
            // can be of the numeric kind)
            var fromSip = sipMessage.FromSipUri.User.IsNumeric() ? sipMessage.FromSipUri.User : sipMessage.FromSipUri.UserAtHost;
            var from    = _sipRepository.GetRegisteredUserAgents().SingleOrDefault(x => x.SipUri == fromSip);

            call.FromSip         = fromSip;
            call.FromDisplayName = sipMessage.FromDisplayName;
            call.FromId          = from?.Id ?? Guid.Empty;

            var toSip = sipMessage.ToSipUri.User.IsNumeric() ? sipMessage.ToSipUri.User : sipMessage.ToSipUri.UserAtHost;
            var to    = _sipRepository.GetRegisteredUserAgents().SingleOrDefault(x => x.SipUri == toSip);

            call.ToSip         = toSip;
            call.ToDisplayName = sipMessage.ToDisplayName;
            call.ToId          = to?.Id ?? Guid.Empty;

            call.Started     = DateTime.UtcNow;
            call.CallId      = sipMessage.CallId;
            call.DlgHashId   = sipMessage.HashId;
            call.DlgHashEnt  = sipMessage.HashEntry;
            call.Updated     = DateTime.UtcNow;
            call.ToTag       = sipMessage.ToTag;
            call.FromTag     = sipMessage.FromTag;
            call.IsPhoneCall = sipMessage.FromSipUri.User.IsNumeric() || sipMessage.ToSipUri.User.IsNumeric();

            _callRepository.UpdateCall(call);
            return(SipMessageResult(SipEventChangeStatus.CallStarted, call.Id));
        }
Пример #5
0
        /// <summary>
        /// Handles the dialog received
        /// </summary>
        /// <param name="sipDialogMessage"></param>
        private SipEventHandlerResult HandleDialog(SipDialogMessage sipDialogMessage)
        {
            switch (sipDialogMessage.Status)
            {
            case DialogStatus.Start:
                return(RegisterCall(sipDialogMessage));

            case DialogStatus.End:
                // TODO: Check hangup reason. Only close calls where reason = Normal
                // TODO: Handle timeout message and add warning to call but don't end it
                log.Info("Received End command from Kamailio. HangUp reason: {0}, From: {1}, To: {2}", sipDialogMessage.HangupReason, sipDialogMessage.FromSipUri, sipDialogMessage.ToSipUri);
                return(CloseCall(sipDialogMessage));

            case DialogStatus.SingleBye:
                // If BYE in kamailio and no dialog is in Kamailio, a single bye is sent to CCM
                // TODO: Handle single bye message and close call
                log.Info("Received SingleBye command from Kamailio. HangUp reason: {0}, From: {1}, To: {2}", sipDialogMessage.HangupReason, sipDialogMessage.FromSipUri, sipDialogMessage.ToSipUri);
                return(NothingChangedResult);

            default:
                return(NothingChangedResult);
            }
        }
Пример #6
0
        private SipDialogMessage ParseDialog(KamailioSipEvent kamailioData)
        {
            if (!Enum.TryParse(kamailioData.DialogState, true, out DialogStatus dialogStatus))
            {
                log.Warn($"Dialog state field = {kamailioData.DialogState} of Kamailio dialog message");
                return(null);
            }

            var dialog = new SipDialogMessage
            {
                Status          = dialogStatus,
                CallId          = kamailioData.CallId,
                HashId          = kamailioData.DialogHashId,
                HashEntry       = kamailioData.DialogHashEntry,
                FromDisplayName = ParseDisplayName(kamailioData.FromDisplayName),
                ToDisplayName   = ParseDisplayName(kamailioData.ToDisplayName),
                FromSipUri      = new SipUri(kamailioData.FromUri),
                ToSipUri        = new SipUri(kamailioData.RequestUri), //new SipUri(kamailioData.ToUri),
                FromTag         = kamailioData.FromTag,
                ToTag           = kamailioData.ToTag,
            };

            return(dialog);
        }