How to manage VoIP PBX Dial Plans?

Ozeki VoIP SIP SDK makes it possible to include remarkable functions into your PBX system such as VoIP PBX dial planning. This article explains how you can define call routing rules in your PBX system when you use Ozeki SIP SDK. To fully understand this guide, you might have to visit the PBX custom functionality article first.

download icon Download: pbx-dial-plan.zip

What is dial plan? How does it work?

A Private Branch Exchange (PBX) establishes phone lines between communication hardware and software through SIP account registration and SIP messages. The basic communication is done between two end-points, however, calling methods can be extended to make them more sophisticated.

Phone calls are done by transferring data on the cables of a network. Smaller networks are connected to each other, forming bigger ones. If a phone call is made from a device, it can be aimed at another device at the exact same network, or it can be sent out to a device on another network. Either way, the data needs to be transferred from one device to another, possibly passing several stations (other networks) on the way. The proccess when the call arrives at its destination, meanwhile passes several devices, is called Call routing.

The default dialing protocol of a PBX is that if an end point calls a certain number, the end point attached to that number will ring. This is implemented in Ozeki VoIP SIP SDK. If you would like to use some other rules, for example; you would like to change the called destination in the cases of some callers, you can do it by overriding some methods in your PBX program.

How to implement PBX Dial Plan using C#?

This example is about to introduce how to define call routing rules in a PBX system. Ozeki VoIP SIP SDK provides all the background and tools for implementing PBX functionalities. If you wish you can redefine any PBX behavior to customize the program according to your needs.

The dial plan behavior is defined in the Ozeki VoIP SIP SDK by the IDialplanProvider interface. Ozeki VoIP SIP SDK provides a professional implementation of this behavior that rings the number you called. There is a possibility to extend this behavior: you need to write a class derived from this interface.
In the dial plan provider class you only need to redefine a single method that sets the dial plan rules. In this example the dial plan will be a simple one that will ensure that when caller extension's username is "1002", the call from that number will be redirected to phone number "1003", regardless of the originally dialed number.

The dial plan setting needs a new object in the PBX class that is a call manager. Ozeki VoIP SIP SDK provides a default implementation for this tool and this example program will use that implementation, you only need to create a new object from that class.

The call manager works with the actual dial plans. The SDK provides default dial plans too, but in this case, the example program redefines that behavior. For this purpose you need to call the SetDialplanProvider() method of the call manager and give a dial plan provider object as a parameter. The dial plan provider is the other class defined in this example project that redefines the standard dial plan behavior of Ozeki SIP SDK.
The call manager and dial plan provider settings need to be done in the OnStart method of the PBX class.

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 2012 or compatible IDE and .NET Framework installed on your system, as the program code below is written in C# language.

PBX Dial Plan example in C#

using System;
using Ozeki.Network;
using Ozeki.VoIP;

namespace PBX_DialPlan
{
    class MainClass
    {
        private static void Main(string[] args)
        {
            var myPBX = new MyPBX(NetworkAddressHelper.GetLocalIP().ToString(), 20000, 30000);
            myPBX.Start();

            Console.ReadLine();
            myPBX.Stop();
        }
    }

    class MyDialPlanProvider : IDialplanProvider
    {
        public string Name { get; private set; }

        public IDialplanResult GetDestination(RouteInfo routeInfo)
        {
            // when extension "1002" dials any number, the call will be redirected to extension "1003"
            if (routeInfo.SourceExtension.ExtensionID == "1002")
                return new Destination("1003");

            // by default, call the number dialed by the caller
            return new Destination(routeInfo.DialInfo.Dialed); 
        }

        public SessionMode GetSessionMode(IBaseCall caller, IBaseCall callee, SessionMode defaultSessionMode)
        {
            return SessionMode.ForceP2P;
        }
    }

    class MyPBX : PBXBase
    {
        string localAddress;

        public MyPBX(string localAddress, int minPortRange, int maxPortRange)
            : base(minPortRange, maxPortRange)
        {
            this.localAddress = localAddress;
            Console.WriteLine("PBX starting...");
            Console.WriteLine("Local address: " + localAddress);
        }

        protected override void OnStart()
        {
            Console.WriteLine("PBX started.");
            SetListenPort(localAddress, 5060, TransportType.Udp);
            var callManager = GetService<ICallManager>();   // callManager object which handles dial plans
            callManager.DialplanProvider = new MyDialPlanProvider();    // the callManager will work with the modified dial plans
            
            Console.WriteLine("Listened port: 5060(UDP)");
            base.OnStart();
        }

        protected override RegisterResult OnRegisterReceived(ISIPExtension extension, SIPAddress from, int expires)
        {
            Console.WriteLine("Register received from: " + extension.ExtensionID);
            return base.OnRegisterReceived(extension, from, expires);
        }

        protected override void OnUnregisterReceived(ISIPExtension extension)
        {
            Console.WriteLine("Unregister received from: " + extension.ExtensionID);
            base.OnUnregisterReceived(extension);
        }

        protected override void OnCallRequestReceived(ISessionCall call)
        {
            Console.WriteLine("Call request received. Caller: " + call.DialInfo.CallerID + " callee: " + call.DialInfo.Dialed);
            base.OnCallRequestReceived(call);
        }
    }
}

Related Pages

More information