Course 1 / Lecture 10

How to develop a softphone in C#

How to build Multi-line Autodialer in C# with Ozeki VoIP SIP SDK

Download: multi-sip-account.zip

This guide is about to introduce how to develop autodialer softphone which is able to use multiple sip accounts. With the help of this guide, you can select phone lines for specified phone numbers (or for any information you can set).
To fully understand this guide, you might have to visit the Autodialer article first, since this guide is about to continue to develop that.

What is multi-line autodialer

An autodialer is an electronic device or software that automatically dials telephone numbers, and once a call has been answered, the autodialer either plays a recorded message or connects the call to a live person.
Multi-line autodialer is able to register to more PBXes with more SIP Accounts. With this feature, the softphone can be set to make calls to the destination using specified phone lines, for example via the cheapest available one.
From this example you can learn how to create an autodialer softphone, which asks for SIP accounts, and stores the ones (and the phone lines, created to the accounts) which have been successfully registered to the selected PBX.

What knowledge would you need?

To fully understand this guide, you might need to study the following chapters first:

  • SIP registration: you can learn how to begin softphone developing and how to be able to register to a pbx with a sip account.
    Learn more...
  • Managing media handlers: you can find here examples and a simple guide about how to be able to use, connect and manage different media handlers, and how can you attach them to calls.
    Learn more...
  • Making and accepting calls: from this guide you can learn how can your softphone make and accept calls, and handle the calls' states.
    Learn more...
  • Parallel call management: from this guide you can learn how can you develop softphones, which are able to manage multiple calls simultaneously.
    Learn more...
  • Multiple phone lines: you can learn from this article about multiple phone line management; how to register with multiple SIP Accounts.
    Learn more...
  • How to build an Autodialer: this simple autodialer application is going to be continued and changed during this example, so it's highly recommended to study the simplier example first.
    Learn more...

How to develop multi-line autodialer softphone in C#?

Since the multi-line autodialer softphone should be able to communicate with users, read and parse (.csv) files, make and manage parallel calls, manage multiple SIP accounts and phone lines and much more, it's highly recommended to design and separate functions and classes providently.

The example is using five classes:

  • Softphone.cs: a simple softphone which is able to ask for SIP accounts, register to a PBX, and can create call objects for specified phone lines.
    The class also contains two lists: the list of registered SIP Accounts, and the list ofavailable phone lines (which are not in call). Also provides methods to manage these lists, such as adding, removing, getting items etc.
  • Program.cs: a class to communicate with users; asks them about the SIP accounts, the amount of simultaneously makeable calls and a .csv file path.
  • CallInfo.cs: instances of this class are functioning as types; each CallInfo objects represents a line within the csv file, and contains a phone number and a message separately. (The message is being played into the call as voice, using text-to-speech.)
  • CallHandler.cs: since the autodialer softphone should be able to manage calls simultaneously, the softphone can create instances from this class for each of the calls, to handle those separately in the same time.
  • Autodialer.cs: creates CallHandler objects for the purpose to handle the calls defined by the CallInfo objects, and also handles the list of clients, and creating the callhandler objects to them when the application indicates this intent through events.
    The Autodialer class provides the GetLine() method for the purpose to provide the opportunity to set dial plans (call routings) to selected client attributes. Please note that, you can expand this method or write new ones with similar functions, if you would like to be able to create dial plans for other attributes as well.

Please note that, this guide is continuing to develop the Autodialer example, so you will find here only the new steps, features, and the differences between the two application examples.

What is Softphone.cs used for?

The autodialer's softphone class is able to register to a pbx, provides information about the phone line's sate, and also creates call objects, when needed.
Please note that, the ReadRegisterInfos() method has been moved here from the Program.cs file (for the purpose to be able to be called from different parts of the source code).

The class handles two lists: the list of successfully registered SIP Accounts, and the list of available phone lines (which are not being used at the moment). Please note that, if you would like to make calls through a SIP account, you will have to select the account's phone line at the call object's creation.
The class also provides methods to manage the lists:

  • _registeredSipAccounts: the list of successfully registered SIP accounts. The following methods are available to manage it:
    • GetSipAccountCount(): returns the amount of successfully registered SIP accounts.
    • ListSipAccounts(): lists public information about the successfully registered SIP accounts.
  • _availablePhoneLines: the list of available phone lines (which are not being used at the moment). The following methods are available to manage this list:
    • GetAvailablePhoneLineCount(): returns the amount of available phone lines. Please note that, if you would like to get the amount of every phone line regardless of being used or not at the moment, you can ask for the amount of successfully registered sip accounts (since every phone line has been created to a single SIP account).
    • GetAvailablePhoneLine(): returns the first available phone line from the list.
    • GetAvailablePhoneLine(string userName, string domainHost): returns the phone line selected by the SIP account's username and domain host. If the list doesn't contian the selected phone line, it returns the first available one.
      Please note that, you have to provide the domain host at the selection to identify a unique phone line (and sip account), since there could be more SIP accounts registered to different PBXes with the same username.
    • public IPhoneLine GetAvailablePhoneLine(string userName, string domainHost)
      {
          lock (_sync)
          {
              foreach (var phoneLine in _availablePhoneLines)
              {
                  if (phoneLine.SIPAccount.UserName.Equals(userName) &&
                      phoneLine.SIPAccount.DomainServerHost.Equals(domainHost))
                  {
                      return phoneLine;
                  }
              }
              Console.WriteLine("No available phone line with those attributes! First available phone line is being selected.");
              return _availablePhoneLines[0];
          }
      }
      
    • ListAvailablePhoneLines(): lists the available phone lines.
    • AddAvailablePhoneLine(IPhoneLine phoneLine): adds the phone line to the available phone lines' list.
    • RemoveAvailablePhoneLine(IPhoneLine phoneLine): removes the phone line from the available phone lines' list.

To learn more about the original Autodialer Softphone class, please visit the Autodialer article.

What is Program.cs used for?

The Program class uses a Softphone instance, handles the phone line's state, asks the user about sip account information, amount of simultaneously makeable calls and a .csv file path, reads, parses the given file and creates CallInfo objects to represent the file's lines.
The class is able to receive more SIP accounts from the user.

Please note that, the methods which ask the user about SIP account information has been moved to the Softphone class. The methods have been set to be public, so the Program class can use them as it did before, regardless about where those are being stored.

Even if you set larger number for possible simultaneously outgoing calls, the application will not manage more calls at a time than the maximum number of available phone lines.
When all of the previous steps are done, it calls the Autodialer class's Start() method.

To learn more about the original Autodialer Program class, please visit the Autodialer article.

What is CallInfo.cs used for?

Each CallInfo object represents a line within the csv file, which is being used as a complex value, as it stores a phone number and a message which is being played into the accepted call with the help of the text-to-speech feature. CallHandler objects will be created for all of the CallInfo objects, to manage the calls separately.

What is CallHandler.cs used for?

The softphone can handle multiple calls simultaneously, and each of those is being handled by a CallHandler instance, set by a CallInfo object. Since a CallInfo object stores a phone number, the call will be created to that number, and if the call is being accepted by the client, the CallInfo object's message value is being converted to voice with the text-to-speech feature, and than being played into the call.

There is change within the Start() method of the class, since it waits for a phoneLine object from now for the purpose to make the phone line selectable.

To learn more about the original Autodialer CallHandler class, please visit the Autodialer article.

What is Autodialer.cs used for?

The Autodialer class creates the CallHandler instances from CallInfo and phone line objects, by calling their Start() method.
The class also listens to the CallHandler class's events, which indicate when a client call has been accepted or ended.

There is a new method within the class, called GetLine(), which waits for a CallInfo object as parameter, and returns a phone line.
You can set here dial plans and routing rules for the selected CallInfo attributes.
Please note that, you can expand the functionality of this method, or you can create similar ones for similar functions, if you would like to manage other extension, user, phone line etc. attributes as well.

The method with default usage, which simply calls the client via the first available phone line:

IPhoneLine GetLine(CallInfo callInfo)
{
    IPhoneLine phoneLine = _softphone.GetAvailablePhoneLine();

    _softphone.RemoveAvailablePhoneLine(phoneLine);
    return phoneLine;
}

The edited method, which if the dialed number is "+44123456789", than it tries to call it via the SIP Account, selected by the "1001" username and "192.168.112.215" domain host:

IPhoneLine GetLine(CallInfo callInfo)
{
    IPhoneLine phoneLine = _softphone.GetAvailablePhoneLine();
	var number = callInfo.PhoneNumber;
    
    if (number.Equals("+44123456789"))
    {
        phoneLine = _softphone.GetAvailablePhoneLine("1001", "192.168.112.215");
    }

    _softphone.RemoveAvailablePhoneLine(phoneLine);
    return phoneLine;
}

You can even write string parser methods for the purpose to be able to create call routings for phone numbers, which starts or ends with specified numbers etc.

To learn more about the original Autodialer class, please visit the Autodialer article.

Conclusion

From this example you could learn how to create multi-line autodialer, which is a softphone application and is able register with multiple SIP accounts, to read and process csv files and make calls simultaneously to the destinations, via the selected phone lines.
With this knowledge, you are able to create autodialer softphones, which can select phone lines at the call objects' creation for the purpose to make calls on the cheapest lines (for example).

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

Related Pages

More information