How to forward an incoming call?

This guide will present you how you can do call forwarding and you can also find C# source codes provided by Ozeki SIP SDK for this solution. To use this example, you need to have Ozeki VoIP SIP SDK installed, and a reference to ozeki.dll should be added to your visual studio project. It's also recommended to visit the "How to accept an incoming call" article before you begin to study how to forward an incoming call.

call forwarding on a voip system
Figure 1 - Call forwarding on a VoIP system

What does forwarding mean? When is it needed?

Call forward is the operation when an incoming call is transmitted to another end-point without acceptance on the phone that was originally called (Figure 1).

Let's see a simple example. Given the telephone with the phone number 12345 that is Bob's home phone. When Bob is not at home, he set a forward direction on his phone to forward his calls to his mobile that has the number 52523. When Mary calls Bob on 12345 the home telephone will not ring, but the call will be forwarded to Bob's cell phone and so, Mary can talk to Bob as she had dialed 52523 instead of 12345.

How to forward an incoming call using C#?

The call forwarding is an easy task with Ozeki VoIP SIP SDK. You only need to set the number you want the call to forward to. The phone decides on forwarding in case of an incoming call. For this purpose you will need to call the ForwardCall() method into the SoftPhone_IncomingCall method.

The other parts of the implementation remain the same as in case of a simple softphone application and all the processes are working the same way.

You can find other call transfering solutions in C#, such as blind call transfer and attended call transfer. If you are interested in those technologies too, follow the links above and you will find all the information you need.

Forward an incoming call example in C#

using System;
using Ozeki.VoIP;

namespace Forward_Incoming_Call
{
    class Program
    {
        static ISoftPhone softphone;   // softphone object
        static IPhoneLine phoneLine;   // phoneline object
        static IPhoneCall call;

        private static void Main(string[] args)
        {
            // Create a softphone object with RTP port range 5000-10000
            softphone = SoftPhoneFactory.CreateSoftPhone(5000, 10000);

            // SIP account registration data, (supplied by your VoIP service provider)
            var registrationRequired = true;
            var userName = "858";
            var displayName = "858";
            var authenticationId = "858";
            var registerPassword = "858";
            var domainHost = "192.168.115.100";
            var domainPort = 5060;

            var account = new SIPAccount(registrationRequired, displayName, userName, authenticationId, registerPassword, domainHost, domainPort);

            // Send SIP regitration request
            RegisterAccount(account);

            // Prevents the termination of the application
            Console.ReadLine();
        }

        static void RegisterAccount(SIPAccount account)
        {
            try
            {
                phoneLine = softphone.CreatePhoneLine(account);
                phoneLine.RegistrationStateChanged += line_RegStateChanged;
                softphone.IncomingCall += softphone_IncomingCall;
                softphone.RegisterPhoneLine(phoneLine);
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error during SIP registration: " + ex);
            }
        }

        static void line_RegStateChanged(object sender, RegistrationStateChangedArgs e)
        {
            if (e.State == RegState.NotRegistered || e.State == RegState.Error)
                Console.WriteLine("Registration failed!");

            if (e.State == RegState.RegistrationSucceeded)
                Console.WriteLine("Registration succeeded - Online!");
        }

        // this method will be called, when an incoming call received
        static void softphone_IncomingCall(object sender, VoIPEventArgs<IPhoneCall> e)
        {
            call = e.Item;  // initializes the call
            call.CallStateChanged += call_CallStateChanged; // subscribes to the event to get notified about the call's states
            call.Forward("895");
        }

        static void call_CallStateChanged(object sender, CallStateChangedArgs e)
        {
            Console.WriteLine("Call state: {0}.", e.State);
        }
    }
}

Communication through the network

When the INVITE sip message arrives to the softphone, it can decide how to react to it. When the call is being forwarded, the sip message 302 Moved Temporarily is being sent back as an answer sip message, to the caller via PBX.

Step 1: Invite request arrives from caller - via PBX (UDP message, PBX -> Softphone)

INVITE sip:1000@192.168.115.172:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.115.172:5060;branch=z9hG4bK1d96158a-9fa9-4aa2-9b03-
d7c4e12a7362;rport
To: "1000"
From: "1003";tag=joyjqbio
CSeq: 1 INVITE
Call-ID: arxbrhjgkqpvjhufhkwivoutlyskrmrfevlpeqchnekorhsgbr
Max-Forwards: 70
Contact: 
User-Agent: Ozeki Phone System XE v5.2.1
Content-Type: application/sdp
Content-Length: 293
Allow: INVITE, ACK, CANCEL, OPTIONS, BYE, REGISTER, SUBSCRIBE, NOTIFY, REFER, 
INFO, MESSAGE

v=0
o=- 107392306 1106077975 IN IP4 192.168.115.172
s=Ozeki Call
c=IN IP4 192.168.115.172
t=0 0
m=audio 6366 RTP/AVP 8 0 3 101 9
a=rtpmap:8 PCMA/8000
a=rtpmap:0 PCMU/8000
a=rtpmap:3 GSM/8000
a=rtpmap:101 telephone-event/8000
a=rtpmap:9 G722/8000
a=fmtp:9 bitrate=64000
a=sendrecv

Step 2: Reply status message to indicate that the softphone is trying to be ringed (UDP message, Softphone -> PBX)

SIP/2.0 100 Trying
Via: SIP/2.0/UDP 192.168.115.172:5060;branch=z9hG4bK1d96158a-9fa9-4aa2-9b03-
d7c4e12a7362;rport=5060; 
received=192.168.115.172
From: "1003";tag=joyjqbio
Call-ID: arxbrhjgkqpvjhufhkwivoutlyskrmrfevlpeqchnekorhsgbr
CSeq: 1 INVITE
To: "1000"
User-Agent: Ozeki VoIP SIP SDK v10.1.8
Content-Length: 0

Step 3: The called softphone forwarded the call, which means a 302 Moved Temporarily sip reply (UDP message, Softphone -> PBX)

SIP/2.0 302 Moved Temporarily
Via: SIP/2.0/UDP 192.168.115.172:5060;branch=z9hG4bK1d96158a-9fa9-4aa2-9b03-
d7c4e12a7362;rport=5060; 
received=192.168.115.172
From: "1003";tag=joyjqbio
Call-ID: arxbrhjgkqpvjhufhkwivoutlyskrmrfevlpeqchnekorhsgbr
CSeq: 1 INVITE
To: "1000";tag=nbklqhpi
Contact: 
User-Agent: Ozeki VoIP SIP SDK v10.1.8
Content-Length: 0

Step 4: The acknowledgement from the caller arrives via PBX (UDP message, Softphone -> Softphone)

ACK sip:1000@192.168.115.172:5060 SIP/2.0
Via: SIP/2.0/UDP 192.168.115.172:5060;branch=z9hG4bK1d96158a-9fa9-4aa2-9b03-
d7c4e12a7362;rport
Call-ID: arxbrhjgkqpvjhufhkwivoutlyskrmrfevlpeqchnekorhsgbr
From: "1003";tag=joyjqbio
To: "1000";tag=nbklqhpi
CSeq: 1 ACK
Max-Forwards: 70
Content-Length: 0

Related Pages

More information