Course 2 / Lecture 3

How to build a VoIP PBX in C#

How to create dial plan in your VoIP PBX

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.

This example program is based on the authentication settings that is introduced in the "VoIP PBX authentication settings" article.

Introduction

Please be informed that PBX development support is available in Ozeki VoIP SIP SDK from version 10.0. You can download the latest Ozeki SIP SDK version from the download page.

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.

This example program shows how you can 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 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 want to use some other rules, for example, you want to ring more than one end point at the same time, you need to override some methods in your PBX program. The following code shows how to do so.

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

The PBX project in this example program is a console application just like the previous ones and it also uses Ozeki VoIP SIP SDK as a reference.

This example project consists of two classes, one for the actual PBX and another for the dial plan. The PBX class is basically the same as in the default sample program introduced in the Default VoIP PBX functionality article, it is only extended with three code lines.

For the dial plan settings, you need to extend the PBX class with a new using line that is the 5th line in Code 1. This namespace contains the tools for the call managers and the dial plan providers that are neccessary for this example.

using Ozeki.Network;
using Ozeki.VoIP;
using Ozeki.VoIP.PBX;
using Ozeki.VoIP.PBX.Extensions;
using Ozeki.VoIP.PBX.Services;
using Ozeki.VoIP.SIP;
using Ozeki.VoIP.SIP.Authentication;
Code 1 - The dial plan settings need a new namespace to use

The dial plan setting needs a new object in the PBX class that is a call manager (Code 2). The 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. These three code lines are the only change in the default PBX implementation in this class.

protected override void OnStart()
{
    SetListenPort(localAddress, 5060, TransportType.Udp);
	Console.WriteLine("Listened port: 5060(UDP)");

	var callManager = GetService<ICallManager>();
	var extensionContainer = GetService<IExtensionContainer>();
	callManager.DialplanProvider = new MyDialplanProvider(userInfoContainer, extensionContainer);

	Console.WriteLine("PBX started.");
    base.OnStart();
}
Code 2 - The OnStart method needs to be extended with two lines

When defining a dial plan provider, you need to use the namespaces shown in Code 3. These using lines ensure that you will not have to label the tools you use in the dial plan provider class.

using Ozeki.VoIP;
using Ozeki.VoIP.PBX;
using Ozeki.VoIP.PBX.Dialplan;
using Ozeki.VoIP.PBX.PhoneCalls.Session;
using Ozeki.VoIP.PBX.Services;
Code 3 - Namespaces to use for the dial plan definition

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 (Code 4).

class MyDialplanProvider : IDialplanProvider
Code 4 - The dial plan provider implements an SDK inbuilt 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 you call the extension "200", the extensions in range 100 to 109 will ring at the same time.

Code 5 shows how you can define the dial plan rules. In case you want to call more than one extension at the same time, you need to set a group routing rule in the GetDestination method. The group routing rule is a set of single routing rules as you can see in the code.

The group routing rule can be set to call the group at the same time or even one after the other. These rules can be set as complex as you wish, this example program only demonstrates a simple dial plan.

		public IDialplanResult GetDestination(RouteInfo routeInfo)
        {
            var currentDialed = routeInfo.DialInfo.Dialed;

            // if dialed number was busy or not answered, hang up call
            if (routeInfo.State != RoutingState.Calling)
            {
                return null;
            }

            // if "200" dialed, ring the first available extension
            if (currentDialed == "200")
            {
                var userInfos = userInfoContainer.GetUserInfos();
                foreach (var userInfo in userInfos)
                {
                    // skip the caller extension
                    if (userInfo.UserName == routeInfo.SourceExtension.ExtensionID)
                        continue;

                    var extension = extensionContainer.GetExtension(userInfo.UserName);
                    if (extension != null)
                        return new Destination(extension.ExtensionID);
                }

                return null;
            }

            // if the dialed number was 300, send redirection response to the SIP extension
            if (currentDialed == "300")
            {
                return new RedirectDestination("103");
            }

            return new Destination(currentDialed);
        }
Code 5 - Setting the dial plan for the PBX

At this point your PBX system is ready to use with a custom dial plan setting. Now you can see the concept for defining dial plans in the PBX and you can write you own solution with the call routing rules you need using Ozeki SIP SDK.

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

You can select a suitable Ozeki VoIP SIP SDK license for PBX development on licensing information page

Related Pages

More information