Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles / desktop / WinForms

Call Control Implmentation Using the Windows Workflow Foundation

3.67/5 (5 votes)
28 Apr 2007CPOL2 min read 1   995  
A call control implmentation using the State machine Workflow.

Screenshot - newCall.jpg

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

Screenshot - stateDiagram.jpg

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.

Screenshot - singleStateEvent.jpg

Using the code

There are three components for this application:

  1. Call Control UI application (displayed on top as a screenshot).
  2. Call Control Workflow (implements the workflow, states, and activity as in the above state machine diagram).
  3. Call Control Services (described below with code).

ICallControlService: Interface

This interface describes all the events responsible for the transition of the call state.

C#
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

C#
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".

Screenshot - ActivityEventAssoc.jpg

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)