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.