Friday, August 23, 2013

TSAPI programming model

Introduction

The Telephony Services Application Programming Interface (TSAPI) specification is an implementation of the ECMA-179 and ECMA-180 standards. It is a generic, switch-independent API that describes how to implement Computer Telephony Integration (CTI) in a switch-independent way. The TSAPI Client provides applications with access to Avaya Communication Manager Call processing. The primary component of the TSAPI Client is the TSAPI client library. The TSAPI Client library (referred as client library from this point onwards) is the C library of function calls that enables an application to request CSTA Services.
Avaya provides an SDK to develop software using the TSAPI client library but since the TSAPI client library was written using C and is intended to be used in C programs we had to develop an intermediary software component for .Net applications. The TSAPI library project (referred as the telephony component from this point onwards) was developed using the open source TSAPI client library which comes as a part of Avaya SDK and is capable of working with any PBX switch which has a TSAPI server. The AE server platform on Avaya provides certain additional features which are specific to Avaya and these features are neither used nor supported in the telephony component.

Architecture


As it is visible from the above diagram the telephony component software requires interaction with the PBX switch through AE services server (AE server). The Telephony Client Library available in the SDK helps us to communicate with the server. The entire communication between the AE server and the telephony component is done through a network stream managed by the Telephony Client Library.
The telephony component includes some software modules (such as the TSAPI class) that act as a wrapper to invoke the methods available in Telephony Client Library. The other classes that are available in TSAPI library project either encapsulate the behavior or data. There are some controls that either facilitates the display or the telephony functions that can be performed using the telephony component on a PBX switch.
For more information about product architecture of Avaya Multivantage system please refer to the Avaya MultiVantage® Application Enablement Services TSAPI Programmer’s Reference.

Communication

 Since there are multiple components involved in a system that supports CTI (Computer Telephony Interface) feature it is required that they communicate with each other. The components that communicate involve hardware, software and middleware components that work in sync for the entire telephony system to work. A telephony system could be an ISDN, a PBX or an EPABX (or any telephony system including a system using VIOP) system). The Telephony Component Developed by me communicates directly with the client library) makes some request on the stream established with the TSAPI server and reads the data written by the AE server on a particular network stream established using the client library. The data received from the AE server comes as a byte stream so I had to parse it into a meaningful object using some custom algorithms depending on the type of data received. I will try to explain them in this document but since this requires extensive study of the code it is recommended that you just look how the events are parsed into each event class and the memory map provided there.

Calls

IN TSAPI programming context, call is in an object that is generated whenever a new call originates on a PBX switch. Any incoming, outgoing or consultation call will always have a call identifier which when combined with a device identifier and the type of device will help us to identify a call in the Multivantage system. Such identifiers are required to track the state of the call (identify a call) and perform operations on that particular call. ACD refers to a service running on the AE server that is responsible for distributing the incoming calls to agents in a call center, ACD service identifies agents based on their hunt groups and the DNIS associated with them. Every ACD will have a DNIS assigned to it that enables it to direct a particular call to an agent in a hunt group. DNIS stands for dialed number identification and Dialed Number Identification Service (DNIS) is a service sold by telecommunications companies to corporate clients that lets them determine which telephone number was dialed by a customer. This is useful in determining how to answer an inbound call. The telephone company sends a DNIS number to the client phone system during the call setup. The DNIS number is typically 4 to 10 digits in length. An ACD based on a particular DNIS determines where the call should be directed (to which hunt group or groups of agents if there are multiple hunt groups assigned to an ACD). The call model used in a TSAPI environment is depicted below.

Call Identifier - a TSAPI programming handle that the Switching Function assigns to each Call. The Call ID may or may not be unique among all calls within a Switching Sub-Domain, but coupled with a Device ID, the pair will form a unique Connection ID within a Switching Sub-Domain. To allow reference to a nascent call, the switch will assign a Call ID before a call is fully established. For example, a switch will assign a Call ID to an incoming call when the called Device is Alerting (the assignment is done before the call is answered). Certain Services merge multiple calls into a single call. Examples of such TSAPI Services are Transfer and Conference. During operations of Services that merge multiple calls, the call identifier may change, but the call continues as a TSAPI object.
Call state - a list of the Connection states for all the Devices that are a part of the Call. For simplicity, common call states for two-party calls have been given a single descriptive name. For example, a two-party call with a Connection State of "Connected" at one station and a Connection State of "Alerting" at the other has a Call State of "Delivered". Table 3-1 gives the mapping of descriptive names to Connection State lists for two-party calls. Simple call states are provided as single values, whereas uncommon call states are provided as a list.
The figure shown below depicts the possible call states on a device. The call states on the local and remote devices are used to determine the call state of a particular call. The table immediately below the figure will show the compound call states.


Devices

In TSAPI terminology a Device can refer to either a physical device (such as buttons, lines, trunks, and stations) or a logical device (such as groups of devices, pilot numbers, and ACDs). Devices have associated attributes, which allow applications to monitor and control them. The telephony component developed by me monitors an extension (an analog handset placed on an agent’s workstation to take calls). The device is monitored to get notifications of incoming calls, their states and other information that might be required in a CRM application to show a screen pop or do any other kind of processing. The telephony component reads data received on the network stream and parses it into meaningful information and raises certain events to notify the consuming application that something important has happened on the device being monitored, for example a CRM application would like to show a screen pop on every incoming call and provide the agent an option to dispose a call after it has been disconnected. Telephony component will raise events on activities such as agent login and logout on a device, incoming calls, call disconnection etc. There are a lot of events that are being raised by the telephony toolbar and they could be of great interest to a developer of CRM applications that consume the telephony component toolbar.
All devices are assigned identifiers by the AE server so that they can be identified in the system. There are attributes of device identifiers that help us in identifying the device, its type and its status. These attributes make up the identity of a particular device.
Read Avaya MultiVantage® Application Enablement Services TSAPI Programmer’s Reference for more information on devices.

TSAPI Programming Model

The client library defines and implements methods and data structures required to monitor and control telephony and reporting service. The telephony component discussed in this document uses the features required for agent login and call tracking from the client library available in the Avaya SDK.

TSAPI Service client libraries

The TSAPI Service client library provides a set of functions that acts as an interface between client applications and the TSAPI Service. Applications use these functions to establish an authorized connection with the TSAPI Service and to send telephony control messages (CSTA messages) to Avaya Communication Manager. The TSAPI SDK library files, CSTA32.DLL and ATTPRIV32.DLL, are private data version 7 import libraries. CSTA32.DLL defines the general methods and data structures defined in ECMA standards for TSAPI while the ATTPRIV32.DLL consists of data structures required to implement functionality specific to Avaya platform (features such as UUI – user to user information). The telephony component developed by me does not use the private features of Avaya library so it can run on a PBX system from any vendor and of any type.
Library
Description
CSTA32.DLL
Windows Contain TSAPI functions
ATTPRIV32.DLL
Windows Contains private data encoding and functions

Data Structures

The data structures contained in TSAPI SDK are C structures and Unions that are used to pass and receive data from the AE server. The communication takes place on a network stream and these data structures are passed and received on the stream.
For passing the data expected by the client library, the telephony component uses data structures, these structures are defined in the CSTA class in the TSAPI Library solution. Since .Net is a managed platform it is required that we define value types (with sequential memory) to pass them to a native software library.

Basic TSAPI programming tips

The TSAPI programming model involves making requests to the server and receiving events from the AE server. First we need to open a stream with the server, we write the data on the stream thus opened to make requests and then monitor the stream. We will first discuss the steps required to open a stream with the AE server.
The method acsOpenStream described in the CSTA32.DLL helps us to establish a stream with the server. We will now discus how to open a stream with the server.

Opening, Closing and Aborting a Stream

To access the TSAPI Service, an application must open an ACS stream (or session). This stream establishes a logical link between the application and call processing software on the switch. The application requests CSTA services (such as making a call) over the stream. The TSAPI Service provides ACS streams.
The TSAPI service can be set up to do security checking to ensure that an application receives CSTA services only for permitted devices. Each application must open an ACS stream before it requests any services. The system advertises CSTA services to applications. An application opens an ACS stream to use an advertised service. Each stream carries messages for the application to one advertised service.
Here is the sequence for opening an ACS stream.
1. The application calls acsOpenStream( ).
acsOpenStream ( ) is a request to establish an ACS stream with a Telephony Server. The acsOpenStream ( ) function returns an acsHandle to the application. The application will use this acsHandle to access the ACS stream (make requests and receive events).
2. The application receives an ACSOpenStreamConfEvent event message that corresponds to the acsOpenStream ( ) request.
The application monitors the acsHandle (returned from the acsOpenStream ( ) request) for the corresponding ACSOpenStreamConfEvent. The application should not request services on the ACS stream until it receives this corresponding ACSOpenStreamConfEvent.
After an application successfully receives the ACSOpenStreamConfEvent, it may request CSTA Services such as Device (telephone) monitoring.
An acsHandle is nothing but an identifier for the network stream established with the server. This identifier is required by the client library to make every request to the AE server.
After opening a stream we can start reading the network stream to read events and make requests to the AE server. Every request that goes along to the server is accompanied with the acsHandle.
For more information about the method calls please refer to Avaya MultiVantage® Application Enablement Services TSAPI Programmer’s Reference.

Starting a Monitor on a Stream

After you establish a stream with the AE server we can start a monitor a device or a call, the telephony component monitors a device to which the agent logs on to. Staring a monitor helps us to receive events and make requests for a particular device. The monitor placed on device will let us answer calls coming on that handset, put them on hold, and initiate a new call and everything else that could be done with a call object.
The Monitor Start service is used to initiate unsolicited event reporting for a device type monitoring on a device object. The unsolicited event reports will be provided for all endpoints within a CSTA switching sub-domain and optionally for endpoints outside of the CSTA switching sub-domain (implementation specific) which are involved with a monitored device.

CSTA Methods and Events

CSTA specifications (ECMA standards) define certain methods requests that can be sent to a server. On every method call the server will send back a response in the form of a confirmation event. There are two types of events. Confirmation events are received in response to a method call and unsolicited events are received to notify events that the AE server writes on a stream whenever something happens on a device that is being monitored. Confirmation events are a way with which the server notifies us about the result of a method request, for every failed request we receive a Universal Failure Confirmation Event (acsUniversalFailureConf_t and cstaUniversalFailureConf_t). A failure event will always contain information why the method call failed. There are two ways when a method call can fail, it can fail when you initially make a method call and in that case we receive an error code from the client library which could tell us why the method call failed, when a method call goes through the client library and the server is not able to process a particular method request it will send a universal failure confirmation event.

CSTA Events

Certain information is guaranteed to be found in an event data structure. As mentioned earlier the data types described in TSAPI library are C unions, all the events received on a TSAPI stream are C unions are C unions and we don’t have a way to simulate it on .Net platform, I used an array of bytes to parse and understand the information received on a stream. So every event received is parsed into a set of information from the bytes received from the server. Every event received in TSAPI library is parsed into an event argument class (Microsoft recommends this programming paradigm) and TSAPI class raises multiple events whenever an event is received and the event data is passed in the event arguments for each event. All the events in TSAPI library project derive from EventArg class and extend two base classes defined in the TSAPI library project.
All events (confirmation or unsolicited) are guaranteed to contain the following fields mentioned below:
ACS Handle: The identifier of the stream on which the event was received.
Event Class:  Event class defines the class of an event. An event can be either a confirmation event or an unsolicited one. As described earlier confirmation events are the events which are received in confirmation of a method call and AE server sends unsolicited events to notify about anything happening on a device.
Event Type: Event Type tells us about the type of event of a particular class, it varies depending on the class of event received and there are different types of confirmation and unsolicited events. While event class helps you to identify if it is a confirmation event or an unsolicited, event type let’s you know which confirmation or unsolicited event has been received on the network stream.
The fields mentioned above are common to each event received on an ACS stream but since confirmation and unsolicited events are different there are certain fields that you would find in a confirmation event but not an in an unsolicited event.
In a confirmation event you will definitely get an invoke ID (invoke ID is the ID of the request that is being sent to the server). Invoke ID’s help you to track the request that we make to the AE server. Every method call has an associated invoke ID. For more information about invoke ID please refer to Avaya MultiVantage® Application Enablement Services TSAPI Programmer’s Reference.
In Unsolicited events we receive a monitor cross reference ID which helps to identify the monitor (refer to “Start Monitoring on a Stream” section above) for which an unsolicited event is received. You can have several monitors active on a single stream and in such cases it is helpful to know the device or the call for which the event was received.
It is neither possible nor desired to show the data structure for each event here in this document, the classes in TSAPI project already have a memory map of the data received in those events along with the logics used to parse that data. This document is intended to be used as a reference material to understand the logics used in the TSAPI Library project.

Sequence


As shown in above diagram the TSAPI project takes care of a complex process and there are some complex algorithms involved in the entire process.
I followed a non blocking model in telephony component, we just send requests to the server, we don’t halt until we receive a response back, any response received on the stream is processed and then an action is taken, for example on every event received we just try to understand what happened and if some action is required we make a request to the AE server.

Event Receipt Mechanism

Client library lets us to receive the events received on the stream established by the client library. To receive events on stream you can either register a window handle (the client library will post messages on the specified window handle) or you can specify a call back function which will be called by the client library whenever it receives an event. Special attention is required while coding the call back function as the client library starts a new thread to execute the call back routine and you cannot perform CPU intensive tasks in the call back routine as it will create a bottleneck in the event notification process. In Telephony component we used the second approach to get notifications about the events received. acsSetESR () method of client library is used to register a routine for callbacks. The ESR (Event Service Routine) routine used in telephony component will just raise an event to notify us that an event has been received. Events in .Net are thread specific so any event raised will execute the event handler in same thread. We used a dispatcher object with reference to the main application thread to identify the main thread of the application; this dispatcher object is used by the EventGrabber class to notify the main application about the events received on the thread. There are three threads executing at any particular time, one of them being the thread started by the client library, the second thread is started by telephony component to fetch the event data asynchronously and then there is finally a main application thread for the application being executed.

Event Grab Procedure


Call Events

TSAPI library sends unsolicited events on the network stream whenever there is any activity on a device. Calls received, connected, held, transferred and conferences are also notified by the AE server. For every request there comes a confirmation event but you can receive an unsolicited event at any point since the server will send them whenever something important happens and hence the unsolicited call events are something which helps in identifying the talk mode of an agent and in response to which we send a query to check agent mode then we combine the agent mode and the talk mode to determine the state of the agent. I have listed the call events below along with a description so that it can be understood which event comes in response to what activity.

1.       CSTAServiceInitiated: Whenever the handset on device goes off hook this event comes on the stream to notify that the device is being used the dialing service has been initiated (The telephony component creates a new call object and the newly created call object is added to active call list whenever this event is received).
2.       CSTAOriginated: This event is sent by the AE server whenever a call (outbound call) originates on a switch, it could be an internal (a call within the switching domain or sub domain) or an external call (on the public network)
3.       CSTADelivered: A delivered event is received in two cases.
a.       When an outbound call has been delivered on the remote device (the device can identified from call object received in the event, see call object described above).
b.      When there is an incoming call on the device being monitored. A new call object is created and added to the active call list in this case.
4.       CSTAEstablished: This event is received as soon as both the devices go off hook meaning that a voice connection has been established.
5.       CSTAHeld: When we put a call on hold the AE server sends this event to notify us that the call has been put on hold.
6.       CSTARetrieved: When a call is retrieved from hold the AE server writes this event on the stream.
7.       CSTATransferred: When a call is transferred to different device the AE server sends information on the stream using this event.
8.       CSTAConferenced: Two calls can be merged together to initiate a three way conference. The AE server sends this event when two calls are merged together.
All these events are read from the stream, parsed into meaningful information and are either used to initiate a call object or update information in a call object.

A detailed review of the code is required to understand the entire working mechanism. The information contained herein is a supplementary and should be used as reference material.