Ozeki VoIP SDK - Product Guide
Developers Guide
Introduction to Automatic call distribution / call routing
Ozeki VoIP SIP SDK offers a first-rate technology and background to implement automatic call distribution in your call center. This guide includes some introduction to automatic call distribution and elaborates source codes to start implementation with Ozeki SIP SDK.
Introduction
Call centers are usually used for a company's hotline services, where a server application accepts the incoming calls and transfers them to the clients, where the human call center agents are waiting for the calls. This transfer process is called call distribution that is usually made automatically in a call center server.
Figure 1 - VoIP call routing
Call distribution or call routing can be made according to a ruling system that defines the choosing method of the clients. This means that there are sets of rules that specify which call center agent will receive the call. This call routing can be defined directly in the PBX system but nowadays it is more usual to have the call routing specified in the call center server.
The following routing methods can be used for call routing:
- According to Agent ID: If more than one agent is available, the system will try the one with the lowest number in the Agent List (the one closer to the top of the list).
- Round robin: If more than one agent is available, the system will try the agent who goes after the last one who took a call in a round robin fashion.
- Most idle agent: If more than one agent is available, the system will look for the agent who has been waiting the longest for a call since the last call they received.
- Least Utilized Agent: If more than one agent is available, the system will look for the agent with the lowest utilization percentage (as defined by Duration of Check In Session / Time Talking to Callers).
If you want to set up call routing rules, first you need to decide which routing technology you want to establish. Then you need to create the data structure for the call routing that will handle the routing rules and make the decision of choosing a call center agent over an other.
In case of the agent ID routing, there is no need for a special data structure. You can put the agents in a sorted list and always get the first available element of the list and transfer the call to that agent (Code 1).
SortedDictionary<int, Ozeki.VoIP.SIPAccount> agents = new SortedDictionary<int,Ozeki.VoIP.SIPAccount>();
Dictionary<int, SIPAccount> busyAgents = new Dictionary<int, SIPAccount>();
IPhoneCall call;
public void routeAccordingToAgentID(IPhoneCall call)
{
call.BlindTransfer(agents.First().Value.UserName);
busyAgents.Add(agents.First().Key, agents.First().Value);
agents.Remove(agents.First().Key);
}
public void callEndedByAgent(int agentID, SIPAccount account)
{
agents.Add(agentID, account);
busyAgents.Remove(agentID);
}
Code 1 - Routing by Agent ID
In case of the round robin routing you can also use a list (sorted or not) and store the ID of the agent to whom you have transferred the latest call. When a new call comes in, it will be transferred it to the agent that is the next available in the list after the stored one. If you reach the end of the list, you can start the distribution from the beginning of the list again (Code 2).
SortedDictionary<int, Ozeki.VoIP.SIPAccount> agents = new SortedDictionary<int, Ozeki.VoIP.SIPAccount>();
Dictionary<int, SIPAccount> busyAgents = new Dictionary<int, SIPAccount>();
IPhoneCall call;
int lastKey;
int[] keys;
public int getNextAgent(int key)
{
int n = Array.IndexOf(keys, key) + 1;
return n >= keys.Count() ? 0 : n;
}
public void routeRoundRobin(IPhoneCall call)
{
int i = lastKey;
while (true)
{
if (!busyAgents.ContainsKey(keys[i = getNextAgent(i)]))
break;
}
call.BlindTransfer(agents.ElementAt(i).Value.UserName);
busyAgents.Add(agents.First().Key, agents.First().Value);
}
public void callEndedByAgent(int agentID, SIPAccount account)
{
busyAgents.Remove(agentID);
}
Code 2 - Round Robin routing
In case of the idlest agent routing, you need to use a list for the agents and when an agent ends a call, you put them at the end of the list. In this case the most idle agent will always be at the beginning of the list and therefore you will need to transfer the call to them (Code 3).
Dictionary<int, Ozeki.VoIP.SIPAccount> agents = new Dictionary<int, Ozeki.VoIP.SIPAccount>();
Dictionary<int, SIPAccount> busyAgents = new Dictionary<int, SIPAccount>();
IPhoneCall call;
public void routeAccordingToAgentID(IPhoneCall call)
{
call.BlindTransfer(agents.First().Value.UserName);
busyAgents.Add(agents.First().Key, agents.First().Value);
agents.Remove(agents.First().Key);
}
public void callEndedByAgent(int agentID, SIPAccount account)
{
agents.Add(agentID, account);
busyAgents.Remove(agentID);
}
Code 3 - Routing by most idle agent
In case of the least utilized agent routing, you need to store the duration of the check in session and the duration of the calls for each agent. You can compute the ratio of these two values (time of talk/time of being online) and sort the list of the agents according to it. The agent with the least utilization ratio will get the next call transferred.
SortedDictionary<double, Agent> agents = new SortedDictionary<double, Agent>();
Dictionary<double, Agent> busyAgents = new Dictionary<double, Agent>();
IPhoneCall call;
public void routeAccordingToAgentID(IPhoneCall call)
{
call.BlindTransfer((agents.First().Value).account.UserName);
agents.First().Value.startTalking();
busyAgents.Add(agents.First().Key, agents.First().Value);
agents.Remove(agents.First().Key);
}
public void callEndedByAgent(Agent agent)
{
double ratio = agent.getRatio();
agents.Add(ratio, agent);
busyAgents.Remove(ratio);
}
Code 4 - Routing according to the least occupied agent
In this case the Agent class stores the necessary information for the data structure (Code 5).
int checkedInDuration;
int talkingDuration;
int checkInTime;
int talkStartTime;
public Ozeki.VoIP.SIPAccount account;
public Agent()
{
checkInTime = DateTime.Now.Hour * 3600 + DateTime.Now.Minute * 60 + DateTime.Now.Second;
}
public double getRatio()
{
checkedInDuration = DateTime.Now.Hour * 3600 + DateTime.Now.Minute * 60 + DateTime.Now.Second - checkInTime;
talkingDuration = DateTime.Now.Hour * 3600 + DateTime.Now.Minute * 60 + DateTime.Now.Second - talkStartTime;
return (double)talkingDuration/checkedInDuration;
}
public void startTalking()
{
talkStartTime = DateTime.Now.Hour * 3600 + DateTime.Now.Minute * 60 + DateTime.Now.Second;
}
Code 5 - The Agent class for the least occupied agent routing
The above mentioned routing methods can be used in a call center server for call routing. You decide on the routing method and put the code segments into your application. You can customize the code for your needs if you wish.
Summary
This article elaborates automatic call distribution and showed how Ozeki VoIP SIP SDK can help you to fulfill your goals. If you have read through this page carefully, you already have all the knowledge you need to start building your own call center with automatic call distribution.
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 a suitable Ozeki VoIP SIP SDK license for call center development on Pricing and licensing information page >>>
Related Pages
- Simple call distribution system for inbound calls
- Skill based routing
- How to create and manage call queues
- Callback requests
- Download Ozeki VoIP SIP SDK form the Ozeki VoIP SIP SDK download page
INTERMEDIATE
VoIP technology walkthrough
Softphone development
Webphone development
Mobile development
Voice recording
GETTING AROUND
Sitemap
Search the manual
API documentation
FAQ
Appendix

