High performance VoIP SDK for .Net developers

VoIP SIP SDK

How to hold a call

Explanation

Prerequisities

Download: 16_CallHoldSoftphone.zip

In this guide you will find all the information required to implement call holding function into your softphone using Ozeki VoIP SIP SDK. After reading through this page you will be fully familiar with all the essential terms concerning call holding and what you will need for start to develop your softphone with call hold using Ozeki SIP SDK.

Introduction

There are cases in remote communication when we need to wait for the callee for some reason. Holding a call means that the call was accepted but the caller has to wait for a call transfer or for some other action (Figure 1).

The most essential case of call holding is when you call a call center or a customer service where there is a limited number of agents at a time. In the case when all the agents are engaged, the caller needs to hold the call and wait for an agent to get free.

In the most usual cases the call holding is indicated by the call center and the caller receives some music played during the waiting period.


Figure 1 - Hold a call

The following program code uses the background support of Ozeki VoIP SIP SDK, therefore you will need to download and install the SDK on your computer before starting to use the program code. You will also need to have Visual Studio 2010 or compatible IDE and .NET Framework installed on your system, as the program code below is written in C# language.

Call holding does not differ so much from the original softphone concept, it only extends it with one new function. Holding a call is not difficult, as Ozeki VoIP SDK provides the tools to do it. But first of all, you need to put a new function button on your GUI for performing the hold function (Figure 2).


Figure 2 - The Graphical User Interface

Ozeki VoIP SIP SDK provides the Hold() method for a call that will do the trick for you. The Hold() method can set the call state to LocalHeld and RemoteHeld. The LocalHeld state indicates that the call was held on the local computer, while the RemotHeld shows that the call was held by the remote party. Both states need to be handled in the call_CallStateChanged method (Code 1).

Basically, when a call is held the microphone and the speaker needs to be stopped. In case of a remote Hold() instruction a flag called remoteheld is set to true and the program performs a Click event for the Hold button to modify the GUI.

 private void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
        {
            InvokeGUIThread(() => { RegistrationState.Text = e.Item.ToString(); });

            switch (e.Item)
            {
            ...
            case CallState.LocalHeld:
                    microphone.Stop();
                    speaker.Stop();
                    break;
            case CallState.RemoteHeld:
                    remoteheld = true;
                    microphone.Stop();
                    speaker.Stop();
                    HoldButton.PerformClick();
                    break;
            }
        }

Code 1 - Handling the LocalHeld and RemoteHeld call states

The GUI changes according to the hold process. In cases when the call is not held the Hold button shows the text "Hold". When you press the Hold button, that means a local hold action, the button will show the text "Unhold". Only the one who has held the call can unhold it. When the remote party held the call, the Hold button will show the text "Held" and it becomes disabled, as only the remote party can unhold the call in that case. Code 2 shows how this action is performed. Pressing the Hold button sets a flag named localheld true in order to know if the button press needs to hold or unhold the call.

private void HoldButton_Click(object sender, EventArgs e)
        {
            if (call == null)
                return;
            if (remoteheld)
            {
                HoldButton.Text = "Held";
                HoldButton.Enabled = false;
                return;
            }
            if (!localheld)
            {
                call.Hold();
                HoldButton.Text = "Unhold";
                localheld = true;
                return;
            }
            HoldButton.Text = "Hold";
            localheld = false;
            call.Hold();

        }

Code 2 - The Hold button's default event handler

The call state handling needs some other extra actions in this softphone example. When a call is first established, the audio devices (microphone and speaker) are started and the MediaHandlers are connected to the each other, and the sender and receiver objects are attached to the call. This action needs to be done only once or in every case when a call is held, they need to be undone. In this example there is a flag that indicates that the call is established at the first time, or that the call state only became InCall again after unholding the call. In the first case the handler are established, but they will not be bothered by the hold events after that time (Code 3).

private void call_CallStateChanged(object sender, VoIPEventArgs<CallState> e)
        {
            InvokeGUIThread(() => { RegistrationState.Text = e.Item.ToString(); });

            switch (e.Item)
            {
                case CallState.InCall:
                    HoldButton.Enabled = true;
                    HoldButton.Text = "Hold";
                    microphone.Start();
                    speaker.Start();
                    remoteheld = false;
                    if (firstInCallState)
                    {
                        firstInCallState = false;

                        connector.Connect(microphone, mediaSender);
                        connector.Connect(mediaReceiver, speaker);

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

Code 3 - Handling the MediaHandler objects

The other functionalities of this softphone are implemented the same way as in case of any simple softphone. The flags need to be initiated when the program starts and after every call. The flags initial values are the follows:

Flag nameInitial value
firstInCallStatetrue
localheldfalse
remoteheldfalse

This article shows how you can implement call holding function into your softphone using Ozeki VoIP SIP SDK. If you have read through this page carefully, you already have all the knowledge you need to start your own solution.

As you are now familiar with all the terms concerning this topic, now it is time to take a step further and explore what other extraordinary solution Ozeki VoIP SIP SDK can provide to you.

If you have any questions or need assistance, please contact us at info@voip-sip-sdk.com

You can select an Ozeki VoIP SIP SDK on Pricing and licensing information

Related Pages

Operating system: Windows 8, Windows 7, Vista, 200x, XP
Development environment: Visual Studio 2010 (Recommended), Visual Studio 2008, Visual Studio 2005
Programming language: C#.NET
Supported .NET framework: .NET Framework 4.5, .NET Framework 4.0, .NET Framework 3.5 SP1
Software development kit: OZEKI VoIP SIP SDK (Download)
VoIP connection: 1 SIP account
System memory: 512 MB+
Free disk space: 100 MB+