Ozeki register always fail

1k Views Asked by At

I want to build a application with SIP calling system, I use Ozeki'SDK.

Here I understand about SIP is (roughly): client -> SIP server -> client OR client -> SIP server 1 -> SIP server 2 -> client

So I install Ozeki Phone System EX on my computer as a SIP server, below I add two phone: image here

Two phone are setting by Bria, and these phones can be communicated. reocrd image

Next step, I create a visual studio project and install ozeki.voip.sip.client, it established two file automatically: CallHandlerSample.cs, TestCall.cs

CallHandlerSample.cs:

using Ozeki.Media.MediaHandlers;
using Ozeki.VoIP;
using Ozeki.VoIP.SDK;


namespace OzekiTestApplication
{
    //These classes is just an example how to use OZEKI VoIP SIP SDK, what dll is added to the References in Solution Explorer
    //Feel free to use the other components of this SDK
    //For More information please visit : http://www.voip-sip-sdk.com and http://www.ozekiphone.com/ozeki-voip-sip-client-997.html
    class CallHandlerSample
    {
        private ISoftPhone softPhone;
        private IPhoneLine phoneLine;
        private RegState phoneLineInformation;
        private IPhoneCall call;
        private readonly Microphone microphone;
        private readonly Speaker speaker;
        private readonly MediaConnector connector;
        private readonly PhoneCallAudioSender mediaSender;
        private readonly PhoneCallAudioReceiver mediaReceiver;

        /// <summary>
        /// Event triggered when the registered softphone has called
        /// </summary>
        public event EventHandler<VoIPEventArgs<IPhoneCall>> IncomingCallReceived;

        /// <summary>
        /// Event the softphone has successfully registered
        /// </summary>
        public event EventHandler RegistrationSucceded;

        /// <summary>
        /// Handler of making call and receiving call
        /// </summary>
        /// <param name="registerName">The SIP ID what will registered into your PBX</param>
        /// <param name="domainHost">The address of your PBX</param>
        public CallHandlerSample(string registerName, string domainHost)
        {
            microphone = Microphone.GetDefaultDevice();
            speaker = Speaker.GetDefaultDevice();
            connector = new MediaConnector();
            mediaSender = new PhoneCallAudioSender();
            mediaReceiver = new PhoneCallAudioReceiver();

            InitializeSoftPhone(registerName, domainHost);
        }


        /// <summary>
        ///It initializes a softphone object with a SIP PBX, and it is for requisiting a SIP account that is nedded for a SIP PBX service. It registers this SIP
        ///account to the SIP PBX through an ’IphoneLine’ object which represents the telephoneline. 
        ///If the telephone registration is successful we have a call ready softphone. In this example the softphone can be reached by dialing the registername.
        /// </summary>
        /// <param name="registerName">The SIP ID what will registered into your PBX</param>
        /// <param name="domainHost">The address of your PBX</param>
        private void InitializeSoftPhone(string registerName, string domainHost)
        {
            try
            {
                softPhone = SoftPhoneFactory.CreateSoftPhone(SoftPhoneFactory.GetLocalIP(), 5000, 10000);
                softPhone.IncomingCall += softPhone_IncomingCall;
                var sp = new SIPAccount(true, registerName, registerName, registerName, registerName, domainHost, 5060);
                phoneLine = softPhone.CreatePhoneLine(sp);
                phoneLine.RegistrationStateChanged += phoneLine_PhoneLineInformation;

                softPhone.RegisterPhoneLine(phoneLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("You didn't give your local IP adress, so the program won't run properly.\n {0}", ex.Message);
            }
        }

        /// <summary>
        /// Create and start the call to the dialed number
        /// </summary>
        /// <param name="dialedNumber"></param>
        public void Call(string dialedNumber)
        {
            if (phoneLineInformation != RegState.RegistrationSucceeded)
            {
                Console.WriteLine("Phone line state is not valid!");
                return;
            }

            if (string.IsNullOrEmpty(dialedNumber))
                return;

            if (call != null)
                return;

            call = softPhone.CreateCallObject(phoneLine, dialedNumber);
            WireUpCallEvents();
            call.Start();
        }

        /// <summary>
        /// Occurs when phone line state has changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void phoneLine_PhoneLineInformation(object sender, RegistrationStateChangedArgs e)
        {
            phoneLineInformation = e.State;
            Console.WriteLine("Register name:" + ((IPhoneLine)sender).SIPAccount.RegisterName);

            if (e.State == RegState.RegistrationSucceeded)
            {
                Console.WriteLine("Registration succeeded. Online.");
                OnRegistrationSucceded();
            }
            else
            {
                Console.WriteLine("Current state:" + e.State);
            }
        }

        /// <summary>
        /// Occurs when an incoming call request has received.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void softPhone_IncomingCall(object sender, VoIPEventArgs<IPhoneCall> e)
        {
            Console.WriteLine("Incoming call from {0}", e.Item.DialInfo);
            call = e.Item;
            WireUpCallEvents();
            OnIncomingCallReceived(e.Item);
        }

        /// <summary>
        /// Occurs when the phone call state has changed.
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void call_CallStateChanged(object sender, CallStateChangedArgs e)
        {
            Console.WriteLine("Call state changed: " + e.State);

            switch (e.State)
            {
                case CallState.InCall:
                    ConnectDevicesToCall();
                    break;
                case CallState.Completed:
                    DisconnectDevicesFromCall();
                    WireDownCallEvents();
                    call = null;
                    break;
                case CallState.Cancelled:
                    WireDownCallEvents();
                    call = null;
                    break;
            }
        }

        private void OnRegistrationSucceded()
        {
            var handler = RegistrationSucceded;

            if (handler != null)
                handler(this, EventArgs.Empty);
        }

        private void OnIncomingCallReceived(IPhoneCall item)
        {
            var handler = IncomingCallReceived;

            if (handler != null)
                handler(this, new VoIPEventArgs<IPhoneCall>(item));
        }

        /// <summary>
        /// Connecting the microphone and speaker to the call
        /// </summary>
        private void ConnectDevicesToCall()
        {
            if (microphone != null)
                microphone.Start();
            connector.Connect(microphone, mediaSender);

            if (speaker != null)
                speaker.Start();
            connector.Connect(mediaReceiver, speaker);

            mediaSender.AttachToCall(call);
            mediaReceiver.AttachToCall(call);
        }

        /// <summary>
        /// Disconnecting the microphone and speaker from the call
        /// </summary>
        private void DisconnectDevicesFromCall()
        {
            if (microphone != null)
                microphone.Stop();
            connector.Disconnect(microphone, mediaSender);

            if (speaker != null)
                speaker.Stop();
            connector.Disconnect(mediaReceiver, speaker);

            mediaSender.Detach();
            mediaReceiver.Detach();
        }

        /// <summary>
        ///  It signs up to the necessary events of a call transact.
        /// </summary>
        private void WireUpCallEvents()
        {
            if (call != null)
            {
                call.CallStateChanged += ( call_CallStateChanged );
            }
        }

        /// <summary>
        /// It signs down from the necessary events of a call transact.
        /// </summary>
        private void WireDownCallEvents()
        {
            if (call != null)
            {
                call.CallStateChanged -= (call_CallStateChanged);
            }
        }

        ~CallHandlerSample()
        {
            if (softPhone != null)
                softPhone.Close();
            WireDownCallEvents();
        }
    }
}

TestCall.cs:

using Ozeki.VoIP;

namespace OzekiTestApplication
{
    //These classes is just an example how to use OZEKI VoIP SIP SDK, what dll is added to the References in Solution Explorer
    //Feel free to use the other components of this SDK
    //For More information please visit : http://www.voip-sip-sdk.com and http://www.ozekiphone.com/ozeki-voip-sip-client-997.html

    class TestCall
    {
        private static CallHandlerSample _callHandlerSample;

        public TestCall()
        {
            _callHandlerSample = new CallHandlerSample("888", "192.168.2.69");

            SubscribeCallHandlerSampleEvents();

            UnsubscribeCallHandlerSampleEvents();
        }

        static void callHandlerSample_IncomingCallReceived(object sender, VoIPEventArgs<IPhoneCall> incomingCall)
        {
            incomingCall.Item.Answer();
        }

        private static void callHandlerSample_RegistrationSucceded(object sender, EventArgs e)
        {
            _callHandlerSample.Call("1000");
        }

        private static void SubscribeCallHandlerSampleEvents()
        {
            _callHandlerSample.RegistrationSucceded += callHandlerSample_RegistrationSucceded;
            _callHandlerSample.IncomingCallReceived += callHandlerSample_IncomingCallReceived;
        }

        private static void UnsubscribeCallHandlerSampleEvents()
        {
            _callHandlerSample.RegistrationSucceded -= callHandlerSample_RegistrationSucceded;
            _callHandlerSample.IncomingCallReceived -= callHandlerSample_IncomingCallReceived;
        }
    }
}

The problem is, every time I call softPhone.RegisterPhoneLine(phoneLine), after a while, event phoneLine_PhoneLineInformation always return Error. What do I missing? Am i misunderstanding the SIP structure ?

1

There are 1 best solutions below

0
On

I don't know if this is your issue with the limited information you have provided. But I was just debugging similar code and there the issue is that GetLocalIP() only gets the first IP-address on the computer, and in the case of having a software VPN on the computer the softphone was sending the register requests out the wrong interface.

Try changing:

SoftPhoneFactory.CreateSoftPhone(SoftPhoneFactory.GetLocalIP(), 5000, 10000);

To:

SoftPhoneFactory.CreateSoftPhone(5000, 10000);

The Ozeki documentation is pretty lackluster, but here is the documentation I know of: http://www.voip-sip-sdk.com/doc/html/118347ff-efa9-1054-7747-9154f85380a2.htm and http://voip-sip-sdk.com/p_7333-voip-sdk-softphone-development-voip.html

I only figured this out with my networking knowledge and by testing it with WireShark.

If you absolutely have to set a source IP-address, I suggest checking this answer: https://stackoverflow.com/a/27376368/5815327