Introduction
This article describes the design of a Call Control mechanism for any Telephony application that uses TAPI as its base framework. This article doesn't make use of any TAPI but provides a generic call control mechanism that can be hooked to any PBX or Call based system.
Background
This application uses Microsoft's new framework technology - Windows Workflow Foundation's state machine workflow. The state flow diagram below describes a very common mechanism starting from a new call until the call ends as the disconnected state. This example makes use of the following call states.
WaitingForCallState
CallNewstate
CallInboundState
CallOutboundState
CallOnholdState
CallConnectedState
CallDisconnected
Call State Diagram
Event Driven Activity
Each state consists of one or more activities. For example, WairingForCallState
defines an Event driven activity on "OnNewCallCreated
". This activity enables execution of the contained activities base on an event. Here, they are "handleCallCreated
" and "setCallNewState
". "handleCallCreated
" subactivity enables receiving an event into the workflow and "setCallNewState
" causes the state machine to transition to another state. In this case, it is the transition to "CallNewState
". How to map an external event with "handleCallCreated
" is described in the next section, with code snippets.
Using the code
There are three components for this application:
- Call Control UI application (displayed on top as a screenshot).
- Call Control Workflow (implements the workflow, states, and activity as in the above state machine diagram).
- Call Control Services (described below with code).
ICallControlService: Interface
This interface describes all the events responsible for the transition of the call state.
using System;
using System.Workflow.Activities;
namespace CallControlServices
{
[ExternalDataExchange]
public interface ICallControlService
{
event EventHandler<CallEventArgs> CallCreated;
event EventHandler<CallEventArgs> CallDialingOut;
event EventHandler<CallEventArgs> CallOffering;
event EventHandler<CallEventArgs> CallConnected;
event EventHandler<CallEventArgs> CallOnHold;
event EventHandler<CallEventArgs> CallDisconnected;
}
}
CallControlService: Implementation of above interface
using System;
namespace CallControlServices
{
[Serializable]
public class CallControlService : ICallControlService
{
public void RaiseCallCreatedEvent(string callId,Guid instanceId)
{
if (CallCreated != null)
{
CallEventArgs e = new CallEventArgs(instanceId, callId);
CallCreated(this, e);
}
}
public void RaiseCallDialingOutEvent(string callId, Guid instanceId)
{
if (CallDialingOut != null)
{
CallEventArgs e = new CallEventArgs(instanceId, callId);
CallDialingOut(this, e);
}
}
public void RaiseCallOfferingEvent(string callId, Guid instanceId)
{
if (CallOffering != null)
{
CallEventArgs e = new CallEventArgs(instanceId, callId);
CallOffering(this, e);
}
}
public void RaiseCallConnectedEvent(string callId, Guid instanceId)
{
if (CallConnected != null)
{
CallEventArgs e = new CallEventArgs(instanceId, callId);
CallConnected(this, e);
}
}
public void RaiseCallOnHoldEvent(string callId, Guid instanceId)
{
if (CallOnHold != null)
{
CallEventArgs e = new CallEventArgs(instanceId, callId);
CallOnHold(this, e);
}
}
public void RaiseCallDisconnectedEvent(string callId, Guid instanceId)
{
if (CallDisconnected != null)
{
CallEventArgs e = new CallEventArgs(instanceId, callId);
CallDisconnected(this, e);
}
}
public event EventHandler<CallEventArgs> CallCreated;
public event EventHandler<CallEventArgs> CallDialingOut;
public event EventHandler<CallEventArgs> CallOffering;
public event EventHandler<CallEventArgs> CallConnected;
public event EventHandler<CallEventArgs> CallOnHold;
public event EventHandler<CallEventArgs> CallDisconnected;
}
}
Associate an Event to a workflow activity
We now know something about the workflow, state, and activity. We have also defined the CallControlService
interface and its implementation. Now, we will see how to associate an external event defined above with the workflow. This event will cause the workflow state to be transitioned to another state. This is really very simple! The Workflow Visual Studio designer provides a facility to go to each state/activity and define their properties. As shown below, the 'handleCallCreated
' subactivity is defined as EventName
= CallCreated
and InterfaceType
= "CallControlServices.ICallControlService
".