Sign in using DevConnect ID

Forgot password?

Trouble logging in?

Submit a ticket for Registration Support.

I have an SSO ID

?
sign in

Don't have a DevConnect or SSO ID ?

Create a DevConnect account or join the program.

register now
^

FAQ: Application Enablement Services

See All Content
X

FAQ: TSAPI

General

What is the procedure for enabling and accessing the AE Services logs for TSAPI (trace, tracing, g3trace, csta_trace)?

To enable and access the AE Services logging of TSAPI events:

  1. Login to the Linux interface of the AE Services server. Navigate to the '/opt/mvap/conf' directory.
  2. If the file named 'tracemask' does not exist, create a file called 'tracemask' and insert the one of the following lines in it:
    • TSAPI= 0xffffffff Everything on
    • TSAPI=0x00000c3e Everything on except mutex tracing and message tracing
    • TSAPI=0x00000c3f To see the messages to/from CM for TSAPI use
  3. If there is a file named 'tracemask', modify the TSAPI values, if required.
  4. Save and close the file.

Starting with AE Services Release 6, it is possible to enable logging from the AE Services Web Interface

  1. From the AE Services Management Console main menu, navigate to Status > Log Manager > Trace Logging Levels.
  2. On the Trace Logging Levels page, select "Everything on" for the "TSAPI Service" and click "Apply Changes".
  3. On the Log Manager Confirmation page, click "Apply".

When tracing is complete, if needed disable tracing and then collect the logs using the following procedure. Navigate to the '/opt/mvap/logs' directory. When a TSAPI message is received, a new directory named 'TSAPI' will be created in it. Root privileges are required to access the TSAPI directory. The 'TSAPI' directory contains the log files (g3trace.out and csta_trace.out) related to the events occurring in different portions of the system that handle TSAPI messages. You can copy files off the server using a secure FTP tool such as winscp.

Can TSAPI be used to get to the media stream on Communication Manager?

No, TSAPI cannot be used to get to the media stream on Communication Manager. Use DMCC to access the media stream on Communication Manager.

I have successfully opened an ACS stream using acsOpenStream() and I received some events, but suddenly I have stopped receiving any events. Why?

There may be many reasons for this behavior. The network connectivity between the client machine and the AE Services server may be broken. If you are sure that your network connectivity is functioning properly, check to see what value you supplied to the notifyAll argument of the acsEventNotify() function. If you supplied the Boolean value FALSE for this argument, you will only be notified when the incoming event queue transitions from empty to non-empty. It is possible that additional events can arrive in the queue before you have removed the first event from the queue. When this happens you will NOT receive another event notification when these additional events arrive. To deal with this situation, be sure to check the numEvents argument returned when acsGetEventPoll() is called. If the value of numEvents is greater than zero when acsGetEventPoll() returns, there are more events in the queue. Since you set the notifyAll argument to acsEventNotify() to FALSE, you will not get any notification that these additional events are in the queue. You will need to insure that acsGetEventPoll() gets called again until the value returned in numEvents is zero. Remember, it is the programmer?s responsibility to retrieve these events in a timely manner or the stream may be closed by TSAPI.

What is the message capacity of the TSAPI Service on AE Services?

To understand the message capacity between AE Services and Communication Manager one must understand a couple of things. First is the capacity of a CLAN interface. The CLAN (on Communication Manager) can transmit 240 messages per second toward AE Services and will recieve 200 per second. The second concept is that of a 'switch connection'. A switch connection is a collection of CLANs that are bundled together to logically provide more through put than a single CLAN can handle. This aggregation allows more messages to be exchanged between Communication Manager and AE Services than a single CLAN can support. Using mutiple CLANs basically multiplies the total message capacity (the number of CLANs * the number of messages a CLAN can handle in a particular direction). The third concept is that different Communication Manager platforms may or may not support CLAN interface circuit packs. The platforms that do not support CLANs allow the processor ethernet connection (procr) to be used to carry CTI messages. However depending on the switch release and platform the capacity of the procr was limited by the software (in order to avoid swamping the system with CTI traffic), or completely blocked (on the larger platforms to force the CTI message traffic to use the CLAN interfaces). Smaller platforms (G3si and S8300 servers) limit the CTI traffic to 240 outbound/200 inbound. With larger systems the system release plays into the maximum CTI traffic allowed. Prior to Communication Manager release 5.0 the upper limit of CTI messages was 720 per second. Starting with Release 5.0 Communication Manager allows 1000 messages per second, and the procr interface can be used for CTI traffic on the medium and large platforms.

The capacities of the various system platforms is documented in of the 'Avaya Communication Manager System Capacities' documentation which can be found on www.avaya.com/support under documentation for Communication Manager. Given the information is release specific, make sure you select the system release you are interested in.

Do I need to recompile my TSAPI application against the AES 3.1 TSAPI SDK if I install the AES TSAPI r3.1.0 client on the applications target machine.

If your application was built using any version of the TSAPI SDK prior to the AES TSAPI 3.1 SDK and it is using private data (any version) you must recompile it using the AES 3.1 TSAPI SDK. Be sure to refer to the "Upgrading and maintaining applications that use private data" section in Chapter 5 of the "Avaya MultiVantage Application Enablement Services TSAPI for Avaya Communication Manager Programmers Reference Release 3.1.0" for details regarding coding changes that may be required in your application.

Is TSAPI sample code available?

Both JTAPI and TSAPI sample applications are available on the DevConnect web portal. The sample applications can be found by clicking on the Sample Applications link in the left hand navigation bar on the left hand side of the main page. The sample applications can be tested against the AES-CM Remote Lab. Please see more details about this remote lab here

When I execute acsEnumServerNames or if I call acsOpenStream with the IP address of the AES server as the serverId, I keep getting ACSERR_NOSERVER. Why?

This generic error is documented in "Avaya MultiVantage Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference Release 3.1.0" document 02-300544 issue 2 dated May 2006 (http://support.avaya.com/elmodocs2/AES/3.1.1/02_300544_2.pdf). Notice that it is a generic TSAPI document, and not specific for Communication Manager. In Chapter 3, section 'API Control Services (ACS) functions and confirmation events', it is mentioned that the serverID field is passed as part of acsOpenStream() call, and the field should contain the advertised service - NOT the IP address of AES server.

Can I obtain the caller ID names using TSAPI?

There is provision in TSAPI to obtain calling party phone number but not caller ID (caller Name) but applications can utilize the ANI information to look up the caller name from their customer database.

We are developing an application to interact with Avaya Communication Manager and AES server and want to know when we receive an DELIVER or ESTABLISHED event from the AES server, which field(s) of the CSTAEvent_t contains the information regarding the trunk and/or the trunk group?

The fields that contain the trunk related information are trunkGroup, trunk and trunkMember These 3 fields are all part of the private parameters. This information is documented in the Avaya Computer Telephony 1.3 TSAPI for Avaya MultiVantage Programmer's Reference document, issue 1, dated October 2003. (http://support.avaya.com/elmodocs2/centre_vu_ip/r1.3/1d3Defprog.pdf)

Is there a limit in the number of simultaneous conferences initiated using the 'Single Step Conference' feature from Avaya CT within a unique Communication Manager System (or the previous versions of Definity ECS-Multivantage)?

There is no specific limit on the number of simultaneous single-step-conferences or service-observe calls. Having said that, there are two other system capacities that would have a bearing on the maximum number of calls for the above. One is the maximum number of simultaneous 3-way conference calls, and the other is the maximum number of active adjunct control associations, and both parameters vary by switch platform and release. To check out the specific limit of these two parameters for the switch platform and software version you have, please refer to "Avaya Communication Manager System Capacities Table Release 3.0" (http://support.avaya.com/elmodocs2/comm_mgr/r3/pdfs/245601_4_1.pdf)

Does the TSAPI client get notified for each event? How can one reduce the load between the Avaya server and the TSAPI client application?

Yes, by default, when a 'cstaMonitorDevice' request is sent, the TSAPI client application gets notified for all the events. To reduce the load between the Avaya server and the TSAPI client application, use any of the following methods:

  • Use filtering to control the number of events that are sent by the server. The 'cstaChangeMonitorFilter()' function could be used to filter out certain CSTA unsolicited events. Other events cannot be filtered.
  • When the 'Event Minimization' feature on CM is set to 'y' on the CTI link, only one set of events is sent to the TSAPI service even when more than one device is monitored. For more information, see the TSAPI Programmer's Guide.

What is the time out duration for TSAPI requests?

TSAPI (G3PD) requests that are sent to CM timeout after nine seconds.

How can a TSAPI application get the IP addresses in use for media transmission for an IP phone, given the IP phone's extension?

TSAPI does not provide functionality for getting the IP addresses used for media transmission, given an extension. For getting the IP addresses in use for media transmission for the device, use the 'status station' command in the SAT session of Communication Manager (CM). Similarly, the IP addresses can be obtained from the System Management Service (SMS) Web Service in AE Services server 4.1 by executing the 'status station <extension-number>' command where "status" is the operation type and "station" is the model type and <extension-number> is the qualifier. This gives the IP address used for media transmission in the 'IP_Signaling_Switch_End_IP_Address' field.

With the 'list registered-ip-stations' command in the SAT session of Communication Manager (CM), the IP address for the registered devices can be listed. The IP addresses of the stations can be obtained from the System Management Service (SMS) Web Service in AE Services server 4.1 by executing the 'list RegisteredIPStations' command where "list" is the operation type and "RegisteredIPStations" is the model type. This gives the IP addresses of the stations in the 'Station_IP_Address' field.

Is it possible with TSAPI to receive an (unsolicited) Forwarding Event?

The forwarding event is supported beginning with AE Services release 4.1. For more details, refer to chapter 4 in the document - "Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, (December 2007) (02-300544)".

Is it possible to invoke a delay between Agent login and Auto-available? If that is not possible, then is there any other method to ascertain the instantaneous call status of that extension?

It is not possible to introduce delay between Agent login and AutoIn using the Auto Available Split (AAS) feature. Use the TSAPI snapshot services like 'cstaQueryAgentState', 'cstaQueryDeviceInfo', 'attQueryACDsplit' and 'attQueryAgentLogin' to get the desired status information.

How can my TSAPI application determine the active parties participating in the call, if the extension number is bridged to multiple stations and any one can answer the call?

Using TSAPI, a developer can use the 'cstaSnapshotCallReq()' request and the response for this request has the connection state information associated with all the devices in the bridged call. All the parties on the bridged appearance will be listed in the response. For all the active parties in the call, the 'Local Conn Info' field shows 'Connected' status for parties in a talking state, where as it shows 'null' when the party has not joined the call. Snapshot Response data for the scenario mentioned above is given below:

12:53:38 0 SERVICE: Make Call: Calling Device: 3000 Called Device: 2009
12:53:38 0 CONFIRM: Make Call: New Call: [Call ID: 6812 Static Device ID: 3000]

Private Data: Vendor: ECS
Event Type: ATT_MAKE_CALL_CONF
Service: Make Call
UCID: 00000000000000000000

12:53:49 0 SERVICE: Answer Call: Alerting Call: [Call ID: 6812 Static Device ID: 2024]
12:53:49 0 CONFIRM: Answer Call
12:53:55 0 SERVICE: Snapshot Call: Snapshot Object: [Call ID: 6812 Static Device ID: 2024]
12:53:55 0 CONFIRM: Snapshot Call: Number of Devices: 3
  Device: [Status: ID Provided Type: Explicit Private Local   Number Device ID: 3000]
  Call: [Call ID: 6812 Static Device ID: 3000] Local Conn Info: Connected
  Device: [Status: ID Provided Type: Explicit Private Local Number Device ID: 2009]
  Call: [Call ID: 6812 Static Device ID: 2009] Local Conn Info: Null
  Device: [Status: ID Provided Type: Explicit Private Local Number Device ID: 2024]
  Call: [Call ID: 6812 Static Device ID: 2024] Local Conn Info: Connected

Private Data: Vendor: ECS
Event Type : ATT_SNAPSHOT_CALL_CONF

How can an application get trunk information (trunk group number, trunk member) for inbound trunk calls through private data?

In case of an inbound trunk call, trunk information is provided as private data delivered with events such as Delivered event (CSTADeliveredEvent), Established event (CSTAEstablishedEvent). In order to properly access this information, the application must first negotiate the private data version during the acsOpenStream() process so that the server sends private data associated with the events. If private data accompanies an event, for example CSTADeliveredEvent, then the private data will be stored in the location that the application specified as the privateData parameter in the acsGetEventBlock() or acsGetEventPoll() request. If the privateData pointer is set to NULL in these requests, then the private data is not delivered to the application for that event. If acsGetEventBlock() or acsGetEventPoll() returns a Private Data length of 0, then no private data is provided with this event. For events which report trunk group and trunk member information in the private data will have appropriate fields for them in the event structure. Following snippet shows how to extract the trunk information from the private data of a Delivered event.

retcode = acsGetEventBlock(acsHandle, (void *)&cstaEvent, &eventBufSize, (PrivateData_t *)&privateData, NULL);
if(rc == ACSPOSITIVE_ACK) // success case
{
if ((cstaEvent.eventHeader.eventClass == CSTAUNSOLICITED) && (cstaEvent.eventHeader.eventType == CSTA_DELIVERED))
{
if (privateData.length > 0)
{
// Confirmation contains private data
if (attPrivateData(&privateData, &attEvent) != ACSPOSITIVE_ACK)
{
// Decoding error
}
else if( attEvent.eventType == ATT_DELIVERED)
{
ATTDeliveredEvent_t *deliveredEvent = attEvent.u.deliveredEvent;
DeviceID_t Group = deliveredEvent.trunkGroup ;
DeviceID_t member = deliveredEvent.trunkMember;
}
}
}
}

In order to develop software applications using Telephony Services API (TSAPI), is it necessary to have the same version for the TSAPI SDK and the TSAPI Client?

Yes, to develop software applications using TSAPI, the TSAPI Client version and the TSAPI SDK version must be the same. For example, TSAPI SDK 4.1 should be used with TSAPI Client 4.1.

How can I find the most recent version of the TSAPI Client?

Follow the 'DevConnect Search' link in the left navigation bar of this page; enter the keywords of 'TSAPI Client' and check the SDKs/APIs box; Click 'Submit'; Examine the results for the highest numbered release (sometimes it is necessary to look at the "From Page:" information below the specific link to the information to find the release information).

What is new for the TSAPI Windows client, Release 4.1.0?

Release 4.1.0 of the AE Services TSAPI client used with AE Services Server 4.1.x contains several enhancements from AE Services Release 3.1, as described below:

  • The AE Services Release 4.1.0 TSAPI Windows client library provides support for secure client connections with a Release 4.1 AE Services Server via Transport Layer Security (TLS).
  • The AE Services Release 4.1.0 TSAPI Windows client library provides better detection of network connectivity problems when communicating with a Release 4.1 AE Services Server.
  • The AE Services Release 4.1.0 TSAPI Windows client library allows up to four alternate TSAPI links (Tlinks) to be specified for a given TSAPI link. In the event that the library is unable to connect to the preferred TSAPI link, it will attempt a connection to an alternate TSAPI link.
  • AE Services Release 4.1.0 Avaya Private Data Library enhances private data version 7, enabling applications to receive additional call event reports during predictive call scenarios.
  • The AE Services Release 4.1.0 Avaya Private Data Library now supports private data version 8. Private data version 8 provides applications with access to the single-step transfer call feature.

How can my application determine which external party has dropped out of the conference call?

When external party joins the conference call, trunk information such as trunk member and trunk group is available in the private data in the Established Events. This trunk related information is not available in the connection clear event, i.e. when a party drops out of the call.

In TSAPI, if a call is connected through a trunk with an unknown device identifier, a dynamic device identifier is created for the purpose of identifying the external party. The TSAPI service may use different dynamic identifiers to represent the external parties connected to the same trunk at different times. A trunk identifier is meaningful to an application only for the duration of the call and cannot be retained and used at a later time. The party which dropped out can be found with the help of this dynamic device id. For example, if one off-PBX extension joins the conference call, then a dynamic device id will be assigned to it (example: T478#3) for that call. This off-PBX number will have trunk group member and trunk member associated with it for the current call duration. So when the T478#3 is dropped out, then it means that the extension associated with the trunk group number and group member has dropped out.

How can my application discover the call ID for an active call on a specified device?

There are two ways to do this:

  • Monitor the device using cstaMonitorDevice() to initiate event reporting for a specific device. Call ID can be extracted from the call control events such as delivered, established, etc. The Application will continue to receive the events until Monitor Stop Service is used.
  • Using snapshotdevice() method, the call ID for calls which exist at that moment at the device can be obtained. Device Snapshot Services return information about calls that are associated with a given CSTA Device objects. This information includes a list of calls associated with the given Device and the Connection State of each call (at that Device).

What does this error mean: "CSTA_UNIVERSAL_FAILURE_CONF, error: 33(RESOURCE_BUSY)"?

The error "CSTA_UNIVERSAL_FAILURE_CONF, error: 33(RESOURCE_BUSY)" indicates that the requested device is busy or not in the idle state.

The device can be in a "busy" state ("not idle") in the following situations:

  • The user at the specified extension is busy on a call.
  • The switch is busy with another CSTA request. This can happen when two TSAPI Services are issuing requests, such as, Hold, Retrieve Call, Clear Connection, Make Call, etcetera, for a common device.

Information on error responses to requests can be found in the "Avaya MultiVantage Applicatio Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference" document for the release of the API you are working with.

Why is my application not getting Events for stations that went "out-of-service" or are in a "not connected" state?

When a device is not connected or switches to out-of-service state, after the device monitor is started, monitoring for this device ends. The application will receive a cstaMonitorEndedEvent reporting this situation. The application must periodically try to re-establish the monitor. The monitor will be successfully established when the device is back in "in-service" state.

Communication Manager uses the Monitor Ended Event Report to cancel a subscription to a previously requested cstaMonitorCall, cstaMonitorDevice or cstaMonitorCallsViaDevice() Service when a monitor object is removed or changed to become an invalid object by switch administration or when the switch can no longer provide the information.

Why is "acsOpenStream()" returning a negative value?

Following are the reasons for the "acsOpenStream()" method to return negative values:

  1. Returns -1 (ACSERR_APIVERDENIED): The requested API version (apiVer) is invalid or the client library does not support it.
  2. Returns -2 (ACSERR_BADPARAMETER): One or more of the parameters is invalid.
  3. Returns -4 (ACSERR_NODRIVER): No TSAPI Client Library Driver was found or installed on the system.
  4. Returns -5 (ACSERR_NOSERVER): The advertised service (serverID) is not available in the network.
  5. Returns -6 (ACSERR_NORESOURCE): There are insufficient resources to open an ACS Stream.

What causes the error ACS_UNIVERSAL_FAILURE_CONF error:
TSERVER_DEVICE_NOT_SUPPORTED during monitoring of an extension (station) using TSAPI?

This error occurs when the Security Database (SDB) is turned on and the CTI user login that is used by the TSAPI application does not have the permission to access the database. There are two possibilities why you might encounter the above specified error:

  1. The SDB is enabled. If there are no more dependencies on SDB for the application then disabling the SDB will resolve the issue. Avaya does not recommend this approach for field sites. It is appropriate for lab testing environments.
  2. The CTI user configured on AE Services may have limited access to the device it is attempting to control. By changing the administration of the CTI user or the devices it is allowed to operate on, the problem can be corrected. The CTI security data base on AE Services can be accessed via the web based OA&M interface by navigating through the following path: Administration > Security Database . The procedures for provisioning the SDB are covered in chapter 5 of Avaya MultiVantage® Application Enablement Services Administration and Maintenance Guide Release 4.1 document number 02-300357, Issue 8, December 2007. This is the preferred solution.

How can an application get agent state change events using TSAPI?

The Automatic Call Distribution (ACD) extension should be monitored in order to get the agent logged in and out state change events. Use the cstaMonitorDevice() request with the ACD/Hunt Group extension as the input parameter to establish this monitor. By putting a monitor on a hunt group the application will get events every time agents login or logout. To stop getting such events, use the cstaMonitorStop()request.

After establishing the monitor, the ACD/hunt group should be queried to see if there are already any agents logged in. Use the attQueryAgentLogin() request with the hunt group's extension for this task. The system's response includes the number of logged in agents, and the station extension's of the logged in agents. The application should then use the cstaQueryAgentState() request to discover the status of each logged in agent (e.g. Work mode, Talk mode, etc). The application can use the cstaQueryDeviceInfo() request to discover the station extension to agent extension binding.

To receive other agent state change events, the agent extension or station extension must be polled by the application using the cstaQueryAgentState() request.

Why would the TSAPI acsGetEventBlock() method return multiple identical messages for the same event?

Multiple copies of an event will occur when the cstaMonitorDevice() request is called multiple times on the same device. The cstaMonitorDevice() request adds the device (e.g. station) being monitored into a list of monitors. If a single device is being monitored multiple times, the application receives an event for each of the monitors started for the device.

What are the reasons for receiving 'PRIVILEGE_VIOLATION_ON_SPECIFIED_DEVICE' error during single step conference?

The 'PRIVILEGE_VIOLATION_ON_SPECIFIED_DEVICE' error occurs because of any one of the following reasons:

  1. Invalid destination specified.
  2. Toll restrictions on destination
  3. COR restrictions on destination.
  4. Destination is a remote access extension.
  5. Call origination restriction on the redirecting device.
  6. Call is in vector processing.

Is there a feature available which can allow the supervisor to eavesdrop on the agent - customer conversation?

The service observing feature provided by Communication Manager allows a 'supervisor' to eavesdrop on a specified agent and customer conversation in either the "no-talk", "listen only" or the "listen and talk" service observing mode. To access this functionality this through a TSAPI application, the application makes use of the MakeCall method with the appropriate service observing FAC (Feature Access Code) and the extension that the agent logged in from. For example, if the Talk/Listen Service Observing FAC is *70 and the extension the agent logged in from is 4000, a MakeCall request would be issued with *704000 as the called party. The MakeCall() request is issued on behalf of a third extension (the observer). In a call recording scenario this third extension is typically a DMCC softphone (client media mode device) which records the agent/customer conversation, but that is not a requirement for service observing.

There are three FACs associated with service observing. The application must decide which mode it wishes to be in for the duration of the service observing session when it invokes service observing.

  • Listen only - the service observer can hear the conversation but can not be heard.
  • Listen/Talk - the service observer can hear and be heard.
  • No Talk - This mode is used by call recording applications since it reduces timeslot consumption on G650 gateways increasing call recording capacity on the system.
In all modes the agent and customer are unaware of the service observing party unless the service observer talks.

An alternative way to "eavesdrop" on a conversation would be to use the "SingleStepConference" operation. The difference in this method when compared to the former is that the application would have to get the call ID for the call in question. It can be done by either by monitoring all agents and tracking the call ID in the call progress events, or by issuing a SnapshotDevice command on the agent extension. The Single Step Conference can be done in either Silent or Active mode. In Silent mode the observer can not be heard, or 'seen'. In Active mode the observer can talk and listen to the conversation and is 'seen' via a display update. In Silent mode the agent and customer are unaware of the listen in party through the system station display.

With servicing observing and single step conference the additional party in the call can be discovered either through CTI events, system access terminal commands, unexpectedly encountering system parties in a call limits, and other feature interactions.

For more information on Service Observing see section "Service Observing" from document Feature Description and Implementation for Avaya Communication Manager 555-245-205 Issue 6 January 2008.

What would cause the TSAPI Test on Application Enablement Services Server OAM (Operations Administration and Maintenance) webpage to fail with - ACS Universal Error 35?

When any TSAPI application tries to access a device, either for call control or monitoring purposes, TSAPI service performs validation and verification before providing the access to the device. When any of these validations fail for a device, the error TSERVER_DEVICE_NOT_SUPPORTED (35) is returned. It is necessary to understand this validation sequence and then ensure that the configuration is correct.

  1. If the Security Database (SDB) is enabled then the access to devices is validated as per the SDB. In a test setup, applications may choose to disable the SDB and then no further checking is required. However, Avaya recommended use of SDB for security reasons in fielded applications. To verify if the SDB is enabled, please browse to "CTI OAM Administration > Administration > Security Database > SDB Control" is enabled for DMCC and TSAPI/JTAPI services.
  2. If the SDB is enabled, then CTI user credentials provided by the application must be valid and the CTI user should have permissions to perform the desired operations. There are various service types such as Call Origination and Termination, device/device call/device and call/call. Permissions can be set to restrict access to any of these services for any CTI user. Setting a CTI user to "unrestricted" access allows access to all the service types and all devices. Developers should ensure that the right permissions are set for the CTI user used by the application. To verify or change the permissions browse to "CTI OAM Administration > Administration > Security Database > CTI Users > List All Users", then select the desired user and click Edit.
  3. If the user does not have unrestricted access, then access to any device depends upon the device configuration. The device type needs to be set appropriately set to PHONE/VDN/AGENT ID to gain access permission. To verify this, browse to "CTI OAM Administration > Administration > Security Database > Devices", select the appropriate device and click Edit Device" and check the device Type.
  4. Every device, added to the SDB, is associated with a Tlink group. This group restricts which devices can be accessed with a selected Tlink (aka switch connection). To verify the device is associated with the Tlink provided by the application, browse to "CTI OAM Administration > Administration > Security Database > Devices, select the appropriate device and click Edit Device" and check the tlink group associated with this device. Now browse to "CTI OAM Administration > Administration > Security Database > Tlink Group", select the appropriate Tlink group and click Edit Tlinks Group" and check if the Tlink selected by the application is part of this group.
The user should ensure that the configuration is correct with respect to the above mentioned parameters, User may refer chapter "The Security Database" from Avaya MultiVantage® Application Enablement Services Administration and Maintenance Guide Release 4.2 02-300357 Issue 10 May 2008

Are events such as NotReadyEvent, ReadyEvent, WorkNotReadyEvent, WorkReadyEvent, CallCompletion, OutOfService and BackInService supported with the AE Services server?

None of the above mentioned events are supported with any version of the AE Services server.

How can an application retrieve IP agent information, like Agent ID, Agent Extension, etc., from a CTI Server for TSAPI?

In TSAPI, to know which extension an agent is logging into, use the 'cstaMonitorDevice' function to monitor the hunt group extension. Then the application will get Login and Logout event reports for agents logging in and logging out of that hunt group. The application can also use the 'attQueryAgentLogin' function to find out which agents are logged into a particular hunt group. Then, the 'cstaQueryDeviceInfo' function can be used to query the agent ID so as to know which extension it is logged into. The 'cstaQueryAgentState' service provides the application with the current agent state for a device. For more details, see Chapter 4 - "Switching Function Services" of the document Avaya MultiVantage Application Enablement Services TSAPI Programmer's Reference, 02-300545, Release 4.1, December 2007, Issue 3.

Which is the latest TSAPI SDK version available supporting the Solaris SPARK platform?

The latest TSAPI SDK version available for supporting the Solaris SPARK platform is R3.1. Please refer to Avaya MultiVantage® Application Enablement Services TSAPI, JTAPI, and CVLAN Client and SDK Installation Guide Release 3.1.0, Document number 02-300543, Release 3.1.0, June 2006, Issue 3 for more details about the Solaris version. In AE Services R4.1 and later, support for Solaris and other operating systems such as HP-UX and SCO UnixWare has been discontinued.

Where can I find the TSAPI Programmer's Reference Guide?

1. Navigate to the Release History in the main Avaya Aura Application Enablement Services topic.

2. Select the AE Services release you are using to open to the appropriate Release Contents topic.

3. Select TSAPI Downloads in the Topic Contents box.

4. Click on the link to the TSAPI Programmer's Reference.

Is it possible to use the CSTA protocol without the TSAPI library to communicate with Avaya's Communication Manager?

CSTA is a protocol whereas the TSAPI library is Avaya's implementation of the CSTA protocol. It is not possible to use any implementation of CSTA protocol other than the Avaya's implementation to communicate with Avaya's Communication Manager through Avaya's AE Services server. Avaya's implementation of CSTA protocol is provided as TSAPI library. Avaya's TSAPI service and DMCC services are the only ways to communicate with the Avaya's AE Services server using the CSTA protocol. The TSAPI service conforms to the CSTA I specification and provides the call control functionality. The DMCC Service conforms to the CSTA III specification and provides first party as well as third party call control.

What is the difference between UNSOLICITED and CONFIRMATION events in TSAPI?

There are two different categories for events that an application can receive - UNSOLICITED includes ACSUNSOLICITED/CSTAUNSOLICITED events and CONFIRMATION includes ACSCONFIRMATION/CSTACONFIRMATION events.

A CONFIRMATION event is received as a response to a TSAPI request. There is only one response or confirmation event sent for each TSAPI request. The application needs to setup the notification mechanism for receiving these events. For example, the TSAPI service will send CSTAMakeCallConfEvent to an application after it (TSAPI) has successfully processed the cstaMakeCall() method.

UNSOLICITED events report state changes of various objects, such as call or device objects, managed by Communication Manager. In addition to setting up the notification mechanism, applications need to start the monitors on the desired object (call or device). Once the monitor is started, any changes to the object state are reported to the application through these events. Multiple unsolicited events could be received for a single monitor. For example, after a call monitor is started by the application, events such as CSTA_DELIVERED, CSTA_ESTABLISHED are sent to the application when the call state changes.

What is a heartbeat interval and how can a TSAPI application set this value?

Whenever any TSAPI application is initialized, a session is established with the AE Services server in the form of an ACS stream over which all the requests and responses are sent and received, respectively. The TSAPI service sends a heartbeat event at a regular interval to indicate that the communication channel is still open for further requests. These internal heartbeat events are sent to the TSAPI client at a regular interval called the "heartbeat interval". The TSAPI service will only send a heartbeat event if no other events have been sent to the TSAPI client for the same stream within the last heartbeat interval, and thereby avoiding undue network traffic. When the TSAPI client does not receive two successive heartbeat events within the heartbeat interval duration, the TSAPI client library assumes a network failure and notifies the application with the ACSUNSOLICITED ACS_UNIVERSAL_FAILURE_CONF event.

With AE Services server Release 4.1.0 or later, a TSAPI application can set this heartbeat interval value. The following code sample illustrates how to set the heartbeat interval in TSAPI.

ACSHandle_t acsHandle;		// handle for ACS stream
InvokeID_t invokeID;		// invoke ID for the request
unsigned short interval_value;	// heartbeat interval value, this can not be
					// less than 5 or greater then 60, and by
 					// default this value is set to 20

// With AE Services server 4.1 the last parameter (i.e. privateData) is
// ignored for acsSetHeartbeatInterval(). 
RetCode_t rc = acsSetHeartbeatInterval(acsHandle,invokeID,interval_value, NULL); // set as NULL

// If the function is successfully executed, then a positive value is 
// returned when library generated InvokeIDs are used. 
// In case application generated InvokeIDs are used, then a successful
// completion of the function returns ACSPOSITIVE_ACK and a negative value if
// the function fails.
					

What is the difference between the "Auto In" and "Manual In" Agent work modes and how can an application change the Agent work mode in TSAPI?

The "Auto In" and "Manual In" Agent work modes differ in the state Agent automatically moves to after handling a call. In the "Auto In" mode, Agent stays in the "READY" state whereas in "Manual In" mode Agent's state changes to "WORK_NOT_READY" after handling a call.

In TSAPI, Agent's work mode can be selected using the cstaSetAgentState method. The following code snippet illustrates how to change the agent work mode and state.

PrivateData_t privateData;		// Privatedata
ACSHandle_t m_acsHandle;		// handle return by acsOpenStream
InvokeID_t invokeID;		// APP_GEN/LIB_GEN
DeviceID_t device;			// Agent Terminal 
AgentMode_t agentMode;		// the mode in which Agent logs in
AgentPassword_t agentPassword	// Agent Password
AgentID_t AgentID;			// AgentID
AgentGroup_t agentGroup;		// Hunt Group Extension (optional)
ATTWorkMode_t workMode;		// "AutoIn"/"ManualIn"
RetCode_t retcode;			// return value from the API
long reasoncode;

agentMode = AM_LOG_IN;		// Requested Agent Mode, allows agent to log 					// in
	
// attV6SetAgentState(privateData, workMode, reasoncode, enablePending)
// this function is used here to set the workMode for Agent.
// workMode is a g3Private Data variable; thus it needs to be set using this
// method. The V6 version of this method is used here as its structure is
// retained for further PDV environment (i.e. PDV 7 and PDV 8) for setting
// Agent's workMode

workMode = WM_AUTO_IN;		// for "AutoIn mode"
//  workMode = WM_MANUAL_IN;	// for "ManualIn mode"

// When Agent Log's in with agentMode as "AM_LOG_IN" then while setting
// privateData information, reasoncode is ignored.

retcode = attV6SetAgentState((ATTPrivateData_t *)&privateData,
				  workMode,	// "WM_AUTO_IN/WM_MANUAL_IN"
				  reasoncode,	// can be set to 0
				  FALSE);	// enablePending flag, set to 							// FALSE, not significant while 							// login Agent 
if (retcode < 0) 
{
	//Error encoding private data 
}


retcode = cstaSetAgentState (m_acsHandle,
				  (InvokeID_t)invokeID,
				  (DeviceID_t *)&device,
				  agentMode,
				  (AgentID_t *)&agentID,
				  (AgentGroup_t *)&agentGroup,
				  (AgentPassword_t *)&agentPassword,
				  (PrivateData_t *)&privateData);

if (retcode < 0)
{
	// error setting the agent state
}
	

How can the TSAPI SDK be obtained?

The procedure to order the TSAPI SDK is listed below:

  1. Login to the DevConnect portal at http://www.avaya.com/devconnect.
  2. Click on the link for Procurement from the left hand navigation box.
  3. Click on the link for Access DevConnect Procurement Benefits in the middle of the page.
  4. Click on the link for Request Procurement in the middle of the page.
  5. Click on the link for Request Procurement to the left of the Quick Response Solution.
  6. Click on the Details/order link to the left of TSAPI SDK vX.Y (the version will change periodically) which is the eighth procurement offer on this page.
  7. Complete this page and place the order.
The user will receive an email from Innovative Development with an invoice within one business day.

What causes the error CSTA_MONITOR_ENDED: EC_RESOURCES_NOT_AVAILABLE to occur while monitoring an object with TSAPI?

CSTA_MONITOR_ENDED is an unsolicited event received by the application indicating that the monitor associated with the monitorCrossRefID provided with the event has been stopped. One of the causes for this event is EC_RESOURCE_NOT_AVAILABLE, which is encountered when a previously monitored object is no longer available or valid due to switch administration changes or communication protocol errors. For example, when a monitored extension is removed from Communication Manager, the CSTA_MONITOR_ENDED event is generated with EC_RESOURCES_NOT_AVAILABLE as the error cause.

What causes the user application to receive a 'TSAPIPlatformException' exception while setting the agent's state to ACW (After Call Work) with error code 33 (RESOURCE_BUSY)?

The TSAPIPlatformException exception indicates an implementation specific error that denotes some form of an unrecoverable platform specific problem. The error code 33 (RESOURCE_BUSY) indicates that the resource in question (e.g. a station, a PBX (i.e. Avaya Communication Manager), an agent etc.) is busy with some other activity.

Thus, while setting an agent's state to ACW, the TSAPIPlatformException exception is encountered with the error code set to 33 (RESOURCE BUSY) which indicates that an agent is already busy with some other call. Moreover, the agent's state control (BUSY) is handled by Communication Manager and a change in the agent's state from BUSY to ACW/WORK_NOT_READY using the API is not allowed to the application. Thus, for any invalid state changes, the TSAPIPlatformException exception is thrown. Once the agent is in READY_STATE, its state can be changed to ACW.

From private data version 6, the cstaSetAgentState function allows the application to defer the state change using the enablePending flag. If this flag is set to true, the requested state change will be made pending and will take effect as soon as the agent clears the call. The request in such cases will be positively acknowledged.

How can the calling party information be extracted when a call is directed to a monitored ACD?

When an application creates the cstaMonitorCallsViaDevice request on either the ACD Split device (i.e. hunt group extension) or a VDN (Vector Directory Number), information for the calls involving the ACD Split device or the VDN will be sent to the application through call events. Communication Manager provides a Delivered and an Established event through which information such as the calling device, the alerting device, the called device and the monitoring cross reference ID can be obtained.

The code snippet provided below can be used to retrieve call related information:

RetCode_t retcode = NULL;
CSTAEvent_t cstaEvent; 		// CSTA event buffer
unsigned short eventBufSzise; 	// CSTA event buffer size
ATTPrivateData_t privateData; 	// ATT service request private    
                                 // data buffer

eventBufSzise = sizeof(CSTAEvent_t);
privateData.length = ATT_MAX_PRIVATE_DATA;

retcode = acsGetEventBlock(acsHandle, (void *)&cstaEvent,  
           &eventBufSzise, (PrivateData_t *)&privateData, NULL);

if (retcode != ACSPOSITIVE_ACK) 
	return;    
if (cstaEvent.eventHeader.eventClass == CSTAUNSOLICITED && 
         cstaEvent.eventHEader.evnetType == CSTA_DELIVERED)
{
	SubjectDeviceID_t AlertingDevice;
	CalledDeviceID_t calledDevice;
	CallingDeviceID_t callingDevice;

	AlertingDevice = 
	cstaEvent.event.cstaUnsolicited.u.delivered.alertingDevice;
						// gives the alerting device 
	calledDevice = cstaEvent.event.cstaUnsolicited.u.delivered.calledDevice;        
						// gives the calledDevice
	callingDevice = 	   cstaEvent.event.cstaUnsolicited.u.delivered.callingDevice;    
						// gives the calling Device
}
		

What causes the error ACS_UNIVERSAL_FAILURE : TSERVER_STREAM_FAILED on AE Services server to occur very often?

The ACS_UNIVERSAL_FAILURE : TSERVER_STREAM_FAILED error occurs when the TSAPI client library detects a connection failure with the AE Services server. The connection may be broken by the AE Services server due to any one of several errors reported to the TSAPI client before the connection was broken. In such cases, the resolution path would be the resolution for the errors reported earlier. In some cases, the error cannot be reported to the client and the AE Services log files must be examined for the root cause of the issue. These are typically buffer overflow problems caused due to a high traffic rate from the AE Services server to an application which is not properly designed to handle such an amount of traffic.

If no other errors are received from TSAPI services, then it needs to be verified that the TSAPI service and the AE Services server are still running and that there are no network connectivity problems. To do this, log into the AE Services OA&M web page, browse to CTI OAM Administration -> Maintenance -> Service Controller and check the status of the TSAPI service as running. A ping is an adequate first level network connectivity verification tool, but intermittent problems may need to be diagnosed with more sophisticated analysis tools (for example, packet sniffers).

What causes TSAPI to display the following error:
CSTA_MONITOR_ENDED cause:EC_RESOURCES_NOT_AVAILABLE?

The CSTA_MONITOR_ENDED event indicates that the object being monitored no longer exists. For example, if a call monitor is added on a call object, then the monitor ends when the call is terminated. In case of a device monitor, this event may be received due to the device becoming unavailable. This may be due to switch administration, device maintenance state changes or AE Services to/from Communication Manager connectivity state changes.

When the CSTA_MONITOR_ENDED event is received, it indicates that the application will not receive any more events for the referenced monitored object.

The application will not automatically start receiving events for the previously monitored call/device even if the monitored object becomes valid again. The application needs to add a new monitor on the desired object and start again.

How is lost network connectivity between the AE Services server and the application signaled to the application?

The AE Services Release 4.1 TSAPI Windows client library provides a better detection of network connectivity problems when communicating with a Release 4.1 AE Services server. The client library monitors "heartbeat" messages from the AE Services server. If two consecutive heartbeat messages are missed, the client library reports a stream failure, closes the ACS stream, and notifies the application with an ACSUniversalFailureEvent event with the TSERVER_STREAM_FAILED error code.

No application changes are necessary to take advantage of this new capability. The default interval between heartbeat events is twenty (20) seconds. An application may change this interval using the new ACS service acsSetHeartbeatInterval(). In addition to Windows, the heartbeat functionality is also available for the Linux platform. The way that the developer is notified of the stream failure is via an ACSUniversalFailureEvent event.

A sample code snippet to detect a stream failure is shown next.

RetCode_t rc; 
CSTAEvent_t eventBuf; 
unsigned short eventBufSize; 
EventClass_t eventClass; 
EventType_t eventType; 
unsigned short numEvents; 
ATTPrivateData_t privateData; 
ACSUniversalFailure_t acsError; 

/* Initialize buffer sizes */ 
eventBufSize = sizeof(CSTAEvent_t); 
privateData.length = sizeof(privateData.data); 

/* Block for event */ 
rc = acsGetEventBlock (acsHandle, (void *)&eventBuf, &eventBufSize,
	(PrivateData_t*)&privateData, &numEvents);

if (rc != ACSPOSITIVE_ACK)
{ 
	/* Handle error condition */ 
	return; 
} 

eventClass = EventBuf.eventHeader.eventClass; 
eventType = EventBuf.eventHeader.eventType; 

if (eventClass == ACSUNSOLICITED && eventType == ACS_UNIVERSAL_FAILURE) 
{ 
	acsError = eventBuf.event.acsUnsolicited.u.failureEvent.error; 
	if (acsError == TSERVER_STREAM_FAILED) 
	{ 
		/* Network connection has been lost */ 
		return; 
	} 
}
		
For more information on ACSUniversalFailureEvent and acsSetHeartbeatInterval(), refer Avaya MultiVantage®Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, 02-300544, Release 4.2, May 2008, Issue 4, section Control Services, subsection ACS functions and confirmation events.

Is it possible to conference in an announcement extension into an existing call using Single Step Conference?

An announcement is a recorded message a caller may hear while the call is in a queue, or when a call receives intercept treatment for some reason. The source or the storage unit for announcements can be integrated in a server or an external unit. Integrated announcements reside on a circuit pack in the switch carrier or on an Avaya G700 media gateway Virtual Announcement Board (VAB).

Announcement extensions are the virtual or logical extensions administered on Communication Manager that are accessed to hear the announcement.

To add an announcement extension, use the SAT terminal to run these commands:

  • Use the SAT command add announcement <extension number>.
  • In the Extension field, type the extension number xxxx.
  • In the COR field, type a valid Class of Restriction code.
  • In the Annc Name field, type the name for this announcement.
  • In the TN field, type a valid tenant number.
  • In the Annc Type field, type 'integrated'.
  • Rest of the fields can be accepted with their default values.
  • Press Enter to save the changes.
  • Use the SAT command list station data-module to determine the announcement extension.
Single Step Conference (SSC) cannot be used to SSC in an announcement extension because an announcement extension does not respond properly to the forced off-hook request used by SSC.

Instead of performing a Single Step Conference, a Consultation Conference could be used to listen to the announcements. Using Consultation Conference poses the risk that the very first part of the announcement could be clipped if the application does not complete the conference request quickly enough.

What are the prerequisites to run a TSAPI application on a Windows platform?

The prerequisites to run an application on TSAPI are as follows:

  1. A TSAPI client should be installed on the machine deploying the application. The latest TSAPI client version is available at http://www.avaya.com/devconnect.
  2. The following dlls should be copied to the C:\WINNT\system32 folder on the machine:
    • ATTPRV32.dll
    • Csta32.dll
    • Instsrvc.dll
    • AES-libeay32.dll
    • AES-ssleay32.dll
    • The TSLIB.INI file
  3. The registry entry HKEY_LOCAL_MACHINE\SOFTWARE\Avaya\TSAPI Client\3.1\IniDirectory must be available with the path set to the location that the TSAPI client was installed (the default path is C:\Program Files\Avaya\AE Services\TSAPI Client\) so that the TSAPI client library can locate the TSLIB.INI file and other installed files (such as the Trusted Certificate Authority certificate when making a secure TSAPI client connection).

What operating systems are TSAPI libraries supported on?

TSAPI libraries for Avaya AE Services are supported only on two operating systems: Windows and Linux. Avaya no longer supports TSAPI libraries for HP-UX and Solaris operating systems starting with AE Services server version 4.0.

Is Avaya's TSAPI implementation compatible with C#?

No, Avaya's implementation of TSAPI is not compatible with C#. Avaya's TSAPI implementation is a C/C++ based API that provides third party call control capabilities using Avaya Communication Manager.

Is it possible to determine the state of an extension using TSAPI?

An extension can be either in an Idle (on-hook) or in a Busy (off-hook) state. In TSAPI, the attQueryStationStatus()method can be used to retrieve the extension's state. It is also possible to get the state of an extension using the cstaSnapshotDeviceReq() method that returns details about each call on the device and status of the extension. Refer to the screenshot below that shows the output of the cstaSnapshotDeviceReq() method invoked using TSAPI exerciser.


As seen in the figure above, the extension's state is Idle when it doesn't have a call and its state is Busy when there is a call at the station.

Why is the TSAPI Test Application installed with the TSAPI client failing with an error?

Please refer to the following FAQ available on http://www.avaya.com/devconnect to validate the configuration between the AE Services server and Avaya Communication Manager: What are the steps to verify that the communication channel between the AE Services server and Avaya Communication Manager is configured correctly?

Even if the configuration is correct, TSAPI Test can fail to run successfully due to several reasons:

  1. Confirm that the TSAPI client has been installed and configured correctly on the machine where test application is running. For information about installing and configuring TSAPI client, see Avaya MultiVantage® Application Enablement Services TSAPI, JTAPI, and CVLAN Client and SDK Installation Guide, 02-300543.
  2. For details on error codes, refer to "Appendix A: Universal Failure Events" in Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, 02-300544, Release 4.2, May 2008, Issue 4.
  3. In TSAPI Test Application, select the desired Tlink in the Server field and enter the CTI username and password that is allowed to access the Tlink, in the respective fields. If the user is not a valid CT user or the password is incorrect, the TSAPI Test application will fail, as shown in the screenshot below.


  4. If the extension number mentioned in the From field does not exist in Avaya Communication Manager, then TSAPI Test returns an invalid csta device identifier(12) error message as shown in the screenshot below.


  5. If the CTI user has restricted access, change the user to have unrestricted access by browsing to and the CTI OAM Administration -> Administration -> Security Database -> CTI Users and change the user to unrestricted access. If this works follow the procedures in Avaya MultiVantage® Application Enablement Services Administration and Maintenance Guide, Release 4.2, 02-300357, Issue 10, May 2008 to properly configure the Security Database.

    If using an unrestricted user does not correct the issue, then the problem lies in Communication Manager. Attempt the test call using the physical station. Consult Communication Manager technical support organization for further assistance.

    Note that TSAPI Test Application can only be used on certain station types - the ones with speaker phones and under certain conditions with an Analog phone.

  6. There are a couple of related FAQs available on http://www.avaya.com/devconnect in the TSAPI FAQ section related to troubleshooting the situation, as outlined below:
    1. What would cause TSAPI Test on the AE Services server OAM (Operations Administration and Maintenance) web page to fail with "ACS Universal Error 35?"
    2. Why does the TSAPI Test application fail with the error: "No device records found?"

What causes the error TSERVER_BAD_PDU in a TSAPI application?

The TSERVER_BAD_PDU error occurs when the TSAPI service cannot parse the request data received from a TSAPI client. This happens when the TSAPI client library from a higher version sends a service request which is available only in the higher version to a lower version TSAPI service. In this case, the TSAPI service is unable to parse the request and returns the TSERVER_BAD_PDU error. For example, when a TSAPI 4.1.0 client sends a acsSetHeartbeatInterval request (supported in TSAPI service version 4.1.0 and later) to a TSAPI 4.0.0 service, the TSAPI service returns the TSERVER_BAD_ERROR error.

This error can be avoided by using only the API methods supported by the TSAPI service serving the request. An application can check the TSAPI service version using the "tsrvVer" field in acsOpenStreamConfEvent.

For further information about the services that are supported in a particular TSAPI version, refer to the document titled Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference.

Can a non-Avaya CSTA implementation be used instead of the Avaya TSAPI client to access CTI services from Avaya Communication Manager?

Telephony Services Application Programming Interface (TSAPI) is an Avaya specific implementation of the Computer Supported Telecommunications Applications (CSTA) standard. Avaya's TSAPI implementation requires the use of Avaya's TSAPI Client. Non-Avaya CSTA API implementations are typically not compatible with the Avaya TSAPI service implementation on Avaya Applications Enablement Services (AE Services). Avaya only provides support for applications using the Avaya TSAPI client.

How can TSAPI be used to set reason codes for a Call Center Agent?

In TSAPI, the cstaSetAgentState() request can be used to set the reason code for a Call Center Agent. The method allows a client application to login or logout a Call Center Agent to/from a Split and to specify a change to the work mode for a Call Center Agent along with a reason code. The method takes 'Device', 'AgentMode', 'AgentID', 'AgentGroup' and 'AgentPassword' as parameters, and 'Work Mode', 'Reason Code' and 'Enable Pending' as Private Data parameters. The reason code can be set only if the 'AgentMode' is being set to 'Not Ready', 'Work Not Ready' or 'Logout'.

Private Data version 7 and later supports reason codes in the range of 0 to 99. Private Data versions 5 and 6 support single digit reason codes from 1 through 9. Private Data version 4 and earlier does not support reason codes. A reason code value of '0' means that the reason code is not available. Logout reason codes can only be in the range of 0 to 9.

What is an invokeID?

An invokeID is a unique numeric identifier used to match a confirmation/failure event with the corresponding Telephony Services API (TSAPI) service request.

There are two options supported by the Avaya TSAPI to generate and associate an invokeID with the TSAPI service requests:

  1. Application generated invokeID (APP_GEN_ID): If the application chooses this option, then it is the application's responsibility to provide a unique numeric value in the invokeID parameter in all successive TSAPI service requests for a session wherever applicable. An application can choose this option by passing APP_GEN_ID in the invokeIDType parameter of the acsOpenStream() method.
  2. Library generated invokeID (LIB_GEN_ID): If the application chooses this option, then the TSAPI Client library generates a unique numeric value in the invokeID parameter (on behalf of the application) for all successive TSAPI Service requests for a session wherever applicable. In this case, the return value of a method is the invokeID generated by the TSAPI client library for the corresponding request. An application can choose this option by passing LIB_GEN_ID in the invokeIDType parameter of the acsOpenStream() method.
The application has to specify one of the above mentioned invokeID types while opening a session with TSAPI Service. The invokeID type once selected during the acsOpenStream()method call cannot be changed later, and the type selected remains valid till the session is closed. In both the cases, the TSAPI Service will send this same invokeID value in the confirmation/failure event for the corresponding TSAPI Service request

For more information on, how a TSAPI application can match the confirmation/failure event with the corresponding TSAPI Service request, refer to the FAQ document titled "How does a TSAPI application relate a particular ACS or CSTA confirmation/failure event with the corresponding TSAPI service request" available on the DevConnect portal at https://www.avaya.com/devconnect.

For more information about the invokeID types, refer to the acsOpenStream()method description in the section ACS functions and confirmation events of the document titled Avaya MultiVantage Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference Doc-ID: 02-300544, Release 4.2, May 2008, Issue 4 available on http://www.avaya.com/devconnect.

What is the difference between the acsCloseStream() and the acsAbortStream() TSAPI Client APIs?

TSAPI Client provides the following two APIs for terminating the active communication channel (i.e., ACS Stream) between the application and the AE Services Server:

  1. acsCloseStream()
  2. acsAbortStream()

While both acsCloseStream() and acsAbortStream() serve a similar purpose, there are some differences between them. A list of these differences is presented below:

  1. In the case of the acsAbortStream(), the ACS Stream's handle becomes invalid immediately after the acsAbortStream() returns, while in the case of acsCloseStream(), the Stream's handle remains valid until the application receives a corresponding confirmation event for acsCloseStream().
  2. In the case of acsCloseStream(), there is an associated confirmation event, while there is no associated confirmation event for acsAbortStream().
  3. In the case of the acsAbortStream(), the system frees all resources associated with the aborted ACS Stream immediately, including any events queued on this Stream, while in the case of acsCloseStream(), the application will continue to receive events until it receives the confirmation event for the acsCloseStream() . Once the confirmation event is received, the system will free all resources associated with the closed ACS Stream.

How does a TSAPI application relate a particular ACS or CSTA confirmation/failure event with the corresponding TSAPI Service request?

An application relates a particular ACS or CSTA confirmation/failure event with the corresponding TSAPI Service request by comparing the invokeID value passed in the TSAPI Service request with the invokeID value received in the confirmation/failure event. The invokeID value needs to be unique so that the application can relate a particular ACS or CSTA confirmation/failure event with the corresponding TSAPI Service request.

The sample code snippet below shows how an application sends the invokeID in a TSAPI method.

// The code snippet below shows how to send invokeID in the monitor request.

// Assuming APP_GEN_ID value has been passed in invokeIDType parameter in the 
// acsOpenStream() method, thus this application itself generates and provides 
// a unique invokeID value in the service request.  
// If the application is designed to use Library generated invokeID, then the 
// return code of the called method will act as an invokeID.

ACSHandle_t ulAcsHandle;		// handle returned by the 
                                        // acsOpenStream() method.

unsigned long ulInvokeIDforDevice = GenerateUniqueNumber();
				// GenerateUniqueNumber() method
				// is a user defined method that
				// returns a unique numeric value. The 
				// application can choose any appropriate 
				// implementation.

DeviceID_t szDeviceID= "40010";   	// Set the deviceID of the device to
                                        // be monitored.
CSTAMonitorFilter_t noFilter;           // for storing the monitor filter setting

// Passing 0 to the call filter indicates that this application will receive 
// all the supported call events.
noFilter.call = 0;

// The Agent Filter, Feature Filter, and Maintenance Filter are not supported 
// in Avaya's CSTA implementation when a device is monitored. If one of these 
// is present, it will be ignored.
noFilter.agent = 0; 
noFilter.feature = 0;	
noFilter.maintenance = 0;

// By setting no private filter, all private Events will be received.
noFilter.privateFilter = 0;
			
RetCode_t nRetCode;	              // stores the return code of the request.

nRetCode = cstaMonitorDevice (ulAcsHandle,           // ACS Stream's Handle.
			ulInvokeIDforDevice , // invokeID to be sent. 
			&szDeviceID,          // Device to be monitored.
		                     &noFilter,            // monitor Filter. 
		 	NULL);                // this parameter is 
                                                               // optional and is passed 
                                                              // as NULL here.
if (nRetCode < 0)
{
		// some error occurred while sending the request
		cout<< "Failed to monitor Device" <<endl;
		cout<< "Error Code: "<<nRetCode; 
		// handle error.
} // end of if

 

// for demonstration purposes, another call to cstaMonitorDevice is made for 
// monitoring a Hunt-group Extension with a different invokeID value.

DeviceID_t szHuntgroupID= "49000";

// Call the custom GenerateUniqueNumber() routine to generate another unique 
// number.
unsigned long ulInvokeIDforHuntgroup = GenerateUniqueNumber(); 

nRetCode = cstaMonitorDevice (ulAcsHandle,     		// ACS Stream's Handle.
		ulInvokeIDforHuntgroup, 	// invokeID to be sent. 
		&szHuntgroupID,        		// Hunt-group Extension
					// to be monitored.
			&noFilter,	          	// monitor Filter. 
		 			NULL);                			// this parameter is 
					// optional and is passed 
					// as NULL here.
	if (nRetCode < 0)
{
		// some error occurred while sending the request
		cout<< "Failed to monitor Hunt-group device" <<endl;
		cout<< "Error Code: "<<nRetCode; 
		// handle error.
} // end of if

// When the application receives the corresponding confirmation/failure event
// for the two monitor requests, the application can use invokeID to 
// relate the confirmation/failure event to a particular monitor request. This 
// process is explained in the code snippet below.
		
The sample code snippet below shows how to retrieve the invokeID from the confirmation/failure event.
CSTAEvent_t cstaEvent;	// Assuming the event has been retrieved using one
                        // of the two methods i.e. cstaGetEventPoll() or
                        // cstaGetEventBlock() and the event data is
                        // preserved in cstaEvent.

unsigned long ulInvokeIDforDevice; // assuming the application has preserved
                                   // the invokeID it used while sending the
                                   // monitor request for monitoring a device
                                   // in ulInvokeIDforDevice variable.

unsigned long ulInvokeIDforHuntgroup; // assuming the application has preserved
                                      // the invoked it used while sending the
                                      // monitor request for monitoring a
                                      // Hunt-group in ulInvokeIDforHuntgroup
                                      // variable.

// The application can choose to maintain a deviceID-invokeID mapping to enable 
// invokeID lookup.

 
unsigned long ulRetrievedInvokeID; // To store the invokeID, received in the
                                   // confirmation event. 

// Check for the confirmation event
if (cstaEvent.eventHeader.eventClass == CSTACONFIRMATION)
{
		// extract the invokeID from the confirmation event received.
		ulRetrievedInvokeID = cstaEvent.event.cstaConfirmation.invokeID;	     	       
		cout<<" Retrieved InvokeID:"<< ulRetrievedInvokeID <<endl;

		// check for the event type
		switch(cstaEvent.eventHeader.eventType)
		{
			case CSTA_UNIVERSAL_FAILURE_CONF:
			{
				if (ulRetrievedInvokeID == ulInvokeIDforDevice)
				{
				    cout<<"Failure Event for monitor request for "
					  << "monitoring a Device";
				    // handle error.
				}// End of if

				else if (ulRetrievedInvokeID == ulInvokeIDforHuntgroup )
				{
				    cout<<"Failure Event for monitor request for "
 						  <<"monitoring a Huntgroup Extension" ;
				    // handle error
				}// End of else if
				break;
			}// End of case 

			case CSTA_MONITOR_CONF:	
			{		
				if (ulRetrievedInvokeID == ulInvokeIDforDevice)
				{
					cout<<"Monitor request for monitoring a Device is " 
					    <<"successful";
					cout<<"The application will receive call state "
 					    <<"change notifications for the call activity "
					    <<"on the monitored device ";		
				}// End of if

				else if (ulRetrievedInvokeID == ulInvokeIDforHuntgroup )
				{
				     cout<<"Monitor request for monitoring Hunt-group "
 					   <<"Extension is successful";
				     cout<<"The application will receive the Log-in/Log-
				     cout<<"out event when any Agent Log-in/Log-out ";
				         <<"on this monitored Hunt-group extension ";
				}// end of else If
				break;
			}// End of case
			default: 
			{
				cout<<" Some other confirmation event";
				break;
			}// End of default
		}// End of switch
	}// End of Outer if.

		

As demonstrated in the code above, the application can relate a confirmation/failure event with the corresponding issued TSAPI Service request by comparing the invokeID supplied in the monitor request with the invokeID retrieved from the confirmation/failure event.

Is it possible for a TSAPI application to obtain a list of all the advertised services of a specific stream type offered by a given list of AE Services Server?

Yes, a TSAPI application can use acsEnumServerNames()method to obtain a list of all the advertised services of a specific stream type offered by a given list of AE Services Server. Using acsEnumServerNames()method, the application can specify a callback method that will be called for each server name. When acsEnumServerNames()method is invoked by the application, the TSAPI Client library reads the Fully Qualified Domain Name (FQDN) or IP addresses of the AE Services Server from the TSAPI Client configuration file (i.e., TSLIB.INI). Using these FQDN or IP addresses, the TSAPI Client library queries each AE Services Server for advertised services of the given stream type. For each advertised service name returned by each AE services server, the TSAPI client invokes the callback method with the serverName parameter set to the advertised service name. The code snippet below demonstrates the use of the acsEnumServerNames() method.

// serverName contains name of advertised service name. This name can be used 
// as serverID in acsOpenStream method.
// lParam will be set to the value of user defined variable provided in  
// acsEnumServerNames method call.
Boolean DisplayServerNames(char* serverName, unsigned long lParam)
{  
   Boolean bReturnValue = FALSE;
   if(strlen(serverName) > 0)
   {
	   // An application can choose to add serverName to a list,
    	   // so that such list of advertised names can be presented 
	   // for selecting serverID while opening the ACS Stream later.
 		      cout << endl << "Server Name: " << serverName;
        bReturnValue = TRUE; 
// Return TRUE so that the callback is called 
  // again with the name of the next advertised 
  // service found.
   }// End of if
   return bReturnValue; // If the callback method returns FALSE then,
 		//enumeration will terminate.
}

void EnumerateServerNames()
{
   // acsEnumServerNames()method is used to enumerate the names of all 
   // servers of a specified stream type.
   RetCode_t rc = acsEnumServerNames(
			ST_CSTA,	// Indicates that CSTA services are to be 
				// enumerated.  
			DisplayServerNames, // Call back function, defined above
			NULL, 	// user defined variable, value of this 
				// variable will be passed to the callback 
				// method as lParam parameter. Passed as NULL 
				// here
			);	
	  if ( nRetCode != ACSPOSITIVE_ACK )
   {
		// some error occurred while sending request
		cout<<" Error Code: "<<nRetCode;
		// handle error.
   }
}
		

For more information, refer to the description of acsEnumServerNames in the section ACS functions and confirmation events of document titled Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference Doc-ID: 02-300544, Release 4.2, May 2008, Issue 4 available on http://www.avaya.com/devconnect.

Will an existing application continue to work with an upgraded version of AE Services Server?

Yes, upgrading AE Services Server does not impact the functionality of existing applications. An application connects to the AE Services Server through the TSAPI Client library. AE Services Server is backward compatible; i.e. it supports previous versions of the TSAPI client library. Thus an existing application will continue to work without any modification.

How can a TSAPI application distinguish between call state change notifications when multiple devices (stations) are monitored?

For each device monitor request, TSAPI Service returns a unique identifier (MonitorCrossRefID) in its confirmation event to the application. Once the application receives the confirmation event, it starts receiving call state change notifications for any call activity on the monitored device.

The sample code below shows how to retrieve monitorCrossRefID from the confirmation event for the monitor request:

CSTAEvent_t cstaEvent; // Assuming the event has been retrieved using one 
			   // of the two methods i.e. cstaGetEventPoll() or 
			   // cstaGetEventBlock() and the event data is present in 
			   // cstaEvent.

long lOriginalMonitorCrossRefID; // To store the monitorCrossRefID from the 
				      // confirmation event of the monitor request.
// Check for the event type
if( cstaEvent.eventHeader.eventType == CSTA_MONITOR_CONF )
{
     // confirmation event for the monitor request, extract monitorCrossRefID.
     lOriginalMonitorCrossRefID = 						
				cstaEvent.event.cstaConfirmation.u.
							monitorStart.monitorCrossRefID;
     cout<<"MonitorCrossRefID :"<< lOriginalMonitorCrossRefID <<endl;
}
		

Each call state change notification contains a unique identifier which is same as that received in the confirmation event for the monitor request for a particular device. The sample code below shows how to retrieve the monitorCrossRefID from the call state change notification:
CSTAEvent_t cstaEvent; // Assuming the call state change unsolicited event has 
			   // been retrieved by using one of the two methods i.e. 
			   // cstaGetEventPoll() or cstaGetEventBlock() and the 
			   // event data is present in cstaEvent.

long lRetrievedMonitorCrossRefID; // To store the monitorCrossRefID from the 
					// call state change notification received.
	lRetrievedMonitorCrossRefID = 						
				cstaEvent.event. cstaUnsolicited.monitorCrossRefId;
	cout<<"MonitorCrossRefID :"<< lRetrievedMonitorCrossRefID <<endl;
}
		

Now, by comparing the lRetrievedMonitorCrossRefID (received in the call state change notification) with the lOriginalMonitorCrossRefID (received from the confirmation event of the monitor request), the application can associate the call state change notification with the corresponding monitor device request.

Why is the UniversalFailure: valueOutOfRange error received in response to a TSAPI request?

The valueOutOfRange error occurs when an invalid value is specified for any parameter in a service request. When the TSAPI Service detects an invalid value in a service request, it returns the valueOutofRange error in a service response to the TSAPI application.

For example, in reference to the cstaSetAgentState() request, if the private data parameter workMode is set as WM_AUX_WORK, and when the agentMode is specified as AM_READY, then on detecting this invalid value (AM_READY agent mode is invalid for the WM_AUX_WORK work mode), the TSAPI Service returns the valueOutOfRange error to the TSAPI application

For more information about this error and to find the methods that can return this error, the developer can look for VALUE_OUT_OF_RANGE keyword in the document titled Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, Doc-ID - 02-300544, Release 4.2, May 2008, Issue 4 available on http://www.avaya.com/devconnect.

When would an application need to add a monitor on a device (station)?

When an application wants to receive call state change notifications for any call on a particular device, the TSAPI application needs to add a monitor on that device.

For information about the types of events that can be received by the application after adding a monitor on a device, refer to chapter 11 of the document titled Avaya MultiVantage Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, Doc-ID - 02-300544, Release 4.2, May 2008, Issue 4 available on http://www.avaya.com/devconnect.

While all events related to a call on a device are made available to the application, at times, the application may not be interested in receiving all the events. The Filter service is provided to reduce the number and types of event reports generated; this helps in reducing message traffic over the network.

For more information about the supported monitor services and Filter service, refer to Chapter 10 of the document titled Avaya MultiVantage Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, Doc-ID - 02-300544, Release 4.2, May 2008, Issue 4 available on http://www.avaya.com/devconnect.

How can an application receive event notifications for call state changes on a device (station)?

The application can receive event notifications for call state changes on a device by adding a monitor to the device using the cstaMonitorDevice() method. After processing the cstaMonitorDevice() service request, the TSAPI Service sends a confirmation event (CSTA_MONITOR_CONF) to the application. Once the confirmation event (CSTA_MONITOR_CONF) is received by the application, the application starts receiving call state change notifications for all the call activity at the monitored device.

The sample code snippet below shows how to add a monitor on a device.

/* This code snippet shows how to add a monitor on the device with some
 * specific filter settings. The user can choose the filter settings as per 
 * the application requirements.
 * For information about types of events that can be used for the settings
 * filter, refer to chapter 10 of the document titled TSAPI for Avaya 
 * Communication Manager Programmer's Reference, Doc-ID - 02-300544, Release
 * 4.2, May 2008, Issue 4.
 */

// handle returned by acsOpenStream
ACSHandle_t g_ulAcsHandle;	

// Set the DeviceID of the device to be monitored.
DeviceID_t szDeviceID = "40010"; 

// specifying a value for a type of filter ensures that events reports for 
// the specified filter will be blocked.
// Note: Call cleared events are not sent to the application when the monitor 
//       is added using cstaMonitorDevice method. If the application needs to 
//       receive call cleared events, then it needs to add monitor on call 
//       using cstaMonitorCall() method. 

// Store the Monitor Filter setting
CSTAMonitorFilter_t filter;		 

// A simple TSAPI application that does not require diverted and 
// held events can set a filter for these events as shown. 
filter.call = cfDiverted | cfHeld;

// The Agent Filter, Feature Filter, and Maintenance Filter are not supported 
// in Avaya's CSTA implementation. If one of these is present, it will be 
// ignored.
filter.agent = 0; 
filter.feature = 0;	
filter.maintenance = 0;

// By setting no private filter, all private Events will be received
filter.privateFilter = 0;

// Storage for the Return code from the method
RetCode_t nRetCode = 0;

nRetCode = cstaMonitorDevice (g_ulAcsHandle, // ACS Stream handle
			  		             0,    	     // library generated invokeID
	  			      &szDeviceID, // ID of device to be monitored
				      &filter,    // Filter setting that will apply
 						     // on the monitor. Set to NULL 
						     // to receive all events 
  			              NULL       // private Data set to NULL
				    );

// Check for errors
if (nRetCode < 0)
{
	// some error occurred while sending the request
	cout<< "Failed to monitor Device" <<endl;

	switch( nRetCode )
	{
		case ACSERR_BADHDL:
	  	{	
		    cout<<"g_ulAcsHandle being used is an invalid handle" 
			  <<endl;
		    // handle error
	      }

		break;
	  	case ACSERR_BADPARAMETER:
	  	{
		    cout<<"One or more of the parameters are Invalid" 
			  <<endl;
		    // handle error
	  	}
		break;
		default:
		{
			cout<<"Unexpected/Unknown Error response ";
			cout<<"Return Code: "<<nRetCode<<endl;
		}
		break;
	}//End of Switch
}// End of If

Note 1: The confirmation event CSTA_MONITOR_CONF contains a reference key (monitorCrossRefID) which is a unique value within an ACS session for the duration that the monitor is active and is used by the application to detect event reports associated with the monitor request. This reference key is used when the application needs to remove the monitor. The application can remove the monitor on a station by using cstaMonitorStop() method .

Note 2: In case where multiple devices are being monitored, the monitorCrossRefID is used to distinguish between the events received for each established monitor request. Applications can receive events such as Delivered, Established, etc. for a monitored device, each having a monitorCrossRefID attached with the event. These events can be matched to the monitored device using the monitorCrossRefID.

How can the correct installation and proper operation of the TSAPI client be verified?

After the TSAPI client is installed, the installer (or user) can use the TSAPI Test application provided along with the client to verify connectivity from the client system to AE Services Server and ultimately Communication Manager. The Microsoft Windows version of the TSAPI Test application is generally found at "C:\Program Files\Avaya\AE Services\TSAPI Client\ Program\ TSTEST32.exe" location depending upon your installation directory.

For more information about how to use and configure TSAPI Test application, refer to the section "Procedure to verify the TSAPI Windows client installation" in chapter 2 of the document titled "Avaya MultiVantage® Application Enablement Services TSAPI, JTAPI, and CVLAN Client and SDK Installation Guide, Doc-ID- 02-300543, Release 4.2, May 2008 Issue 5", available at location http://www.avaya.com/devconnect.

TSAPI Test is a basic application for making a call. A successful call ensures that the TSAPI client is correctly installed and working. If the TSAPI Test application fails to make the call, an error message is provided to aid in troubleshooting the cause of the failure. Refer to the FAQ document titled "Why is the TSAPI Test Application installed with the TSAPI client failing with an error?" available at location http://www.avaya.com/devconnect -> FAQs -> AE Services TSAPI FAQ, to resolve the error.

What is the difference between the cstaClearCall() and the cstaClearConnection() TSAPI client API methods?

The cstaClearCall() method is used for clearing an entire call, whereas the cstaClearConnection() method is used for clearing a connection from a call. A Call is a reference to a set of Connections through which a set of Terminals are communicating. A Connection is a reference to the binding between a Terminal (telephone) and a Call.

The cstaClearCall() method disconnects all the connections (participants) from a specified call and terminates the call itself, rendering all the connections associated with the call invalid. When there is a need to terminate all the connections from a specified call, this method can be used by a TSAPI application.

As shown in the figure below, when three devices are in a conference and the cstaClearCall() method is called by the application for any device, all the connections are disconnected.

Note: The cstaClearCall() method requires a valid CallID to terminate the call. The second parameter (DeviceID) is ignored by this method.

The cstaClearConnection() method disconnects a specified connection (participant) from the designated call and the connection state changes to Null. The connection identifier is no longer associated with the call.

When there is a need to disconnect only a particular connection from a call, the cstaClearConnection() method can be used in a TSAPI application.

As shown in the figure below, when three devices are in a conference call and cstaClearConnection() is called by the application for a particular device, then the associated connection between that device and call will be disconnected. The remaining two devices would still remain connected.

Notes:

  • If a connection is in the alerting state, it cannot be cleared using the cstaClearConnection() method. In this case, the connection can be cleared either when its state changes to Connected, or by clearing the call (using the cstaClearCall() method).
  • cstaClearConnection method needs both a valid CallID and DeviceID to clear a connection.
  • In case where the call has only two connections, the result of invoking either of these methods will be the same, i.e., both connections will be cleared.

Will a call to the acsOpenStream() API fail if the network connection between the AE Services Server and Avaya Communication Manager is down?

No, the call to the acsOpenStream()API will not fail due to the network connection loss between the AE Services Server and Communication Manager. In fact, the network connection between AE Services Server and Communication Manager doesn't affect the state of the ACS stream at all. The application, however, will not be able to access services that require communication with Communication Manager (for example, the Make Call/Monitor Device services).

In the case when there is no connectivity between the AE Services Server and Communication Manager, if the application invokes any of the APIs that require communication with Communication Manager, the TSAPI Service sends an event of type UniversalFailureConfEvent with GENERIC_OPERATION_REJECTION as the error cause. In such case, the application needs to check the connection status, and when the connection is restored, the application can invoke the API again; there is no need for the application to close and reopen the ACS stream.

The application can check the connection status by using cstaSysStatReq() method. The cstaSysStatReq() method provides a snapshot of the connection status at the time the method is called. Please note that this method does not register for system state change notifications, so the application has to call this method each time the application wishes to know the connection status.

The application can use cstaSysStatStart() method to register for events. The cstaSysStatStart() method registers for system state change notifications, allowing the application to receive a system state change notification whenever the AE Services Server's network connection to Communication Manager is lost/re-covered. The parameter systemStatus in the system state change notification indicates the connection status. A value of 'Disabled' for systemStatus indicates 'no connectivity' whereas a value of 'Enabled' indicates that the network connection is 'stable'. The confirmation event of cstaSysStatStart() method provides the application a snapshot of the connection status at the time the method is called. The application can call cstaSysStatStop() method to cancel a previously registered request for system status event reporting.

For more information on the cstaSysStatReq(), cstaSysStatStart(),and cstaSysStatStop() methods, please refer to Chapter 13 titled "System Status Service Group" of the document titled "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, Doc-ID: 02-300544, Release 4.2, May 2008, Issue 4", available on http://www.avaya.com/devconnect.

What are the different ways in which a TSAPI application can retrieve events from the TSAPI Client library?

The Avaya implementation of TSAPI provides two different ways through which a TSAPI application can retrieve events from the TSAPI Client library:

  1. One way is to use the acsGetEventBlock() method which runs in the blocking mode, i.e., the application's calling thread will be blocked until there is an event available in the Client library's event queue. This method will return with an event that is copied in the application's defined event buffer.
  2. The other way is by using the acsGetEventPoll() method which runs in a non-blocking mode, i.e., if there is no event available in the Client library's event queue, the acsGetEventPoll() method will return immediately with an error code indicating that there is no event available in the Client library's event queue at the moment. When there is more than one event available, the oldest event available on the specified active ACS stream is retrieved and copied in the application's defined event buffer.
For more information on the acsGetEventBlock()/acsGetEventPoll() methods, please refer to the section titled "ACS functions and confirmation events" in the document titled "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, Doc-ID: 02-300544, Release 4.2, May 2008, Issue 4", available on http://www.avaya.com/devconnect.

How can a TSAPI application use Event Service Routine (ESR) to register for events?

Event Service Routine (ESR) is a mechanism that allows a TSAPI application to register with the TSAPI Client library to receive a notification when an event is added in the Client library's event queue. The application can make use of the acsSetESR() method to implement the ESR mechanism. This method allows the application to register a callback method that will be invoked whenever an event is added in the Client library's event queue.

Please note the following important points about the ESR mechanism:

  1. The acsSetESR() method should be invoked after the acsOpenStream() method has returned successfully.
  2. Whenever the callback method is called, the application must retrieve the events from the Client library's event queue to prevent the queue from overflowing. It is recommended that the application should be designed to have a separate thread (one different from the callback method thread) for retrieving and processing the events. In case, the application chooses to receive a notification for each event whenever an event is added in the Client library's event queue, the need to retrieve and process the events in a separate thread becomes more evident. Retrieving and processing the events in a separate thread ensures that the callback method's thread is not blocked and remains free to receive further notifications from the Client library.
  3. The acsSetESR() method allows the application to pass a user defined value to the callback method. For example, the application may pass an object pointer as demonstrated in the code snippet below.
The notifyAll parameter of the acsSetESR() method allows the application to specify the notification type. A value of TRUE for the notifyAll parameter will allow the application to receive a notification for each event and a value of FALSE will allow the application to receive a notification when the Client library's event queue becomes non-empty (i.e., the queue count changes from zero (0) to one (1)). Using FALSE for the notifyAll parameter will reduce the overhead of notifications.

For more information on the acsSetESR() method's signature and for a description of all the method's parameters, please refer to the section titled "ACS functions and confirmation events" in the document titled "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, DocID: 02-300544, Release 4.2 May 2008 Issue 4", available on http://www.avaya.com/devconnect.

The sample code snippet shown below demonstrates how the ESR mechanism works.

// Callback method to receive event notifications.
// @esrParam:esrparam will be set to the value of user defined variable 
// provided in acsSetESR() method call. 
void __stdcall ESRCallback(unsigned long esrParam)
{
		cout<<" New event added in the client queue"<<endl<<endl;
		
		// In this example, TSAPIInterface class object is passed in the
		// acsSetESR() method call, converting esrParam back to TSAPIInterface 
		// type. 
		TSAPIInterface* pTSAPIObject = (TSAPIInterface*) esrParam;
   
		pTSAPIObject->retrieveEvents();	// retrieveEvents() is a method of 
							// TSAPIInterface class that contains the 
							// code to retrive events from the Client 
							// library event queue. 
} // End of method

// Assume TSAPIInterface is a user defined class that is responsible for 
// opening an ACS Session.

// setESR() method is a member of TSAPIInterface class.
void TSAPIInterface::setESR()
{
		ACSHandle_t* pAcsHandle; // Handle returned by the acsOpenStream(), 
		// probably avaiable as a member variable.
		// Register a callback method with client library to receive a notification
		// when an event is added in the Client library's event queue.
		// Upon success, the Client library will call ESRCallback method whenever
		// the client library's event queue becomes non-empty.
   	
		RetCode_t nRetCode = acsSetESR(*pAcsHandle, // handle returned by
								 // acsOpenStream method.
							ESRCallback,// callback method defined by 
									// the application.
							(unsigned long)this, // passing the object 
									// of the TSAPIInterface class. 
									// as user defined parameter
							FALSE 	// Setting FALSE to receive 
									// callback only when the client 
									// library's event queue becomes non-
									// empty.
							);
   	// Verification for the positive response
		if(nRetCode != ACSPOSITIVE_ACK)
		{
			cout << "ERROR IN SET ESR ";
			if(nRetCode == ACSERR_BADHDL)
			{
				cout <<" pAcsHandle being used is not a valid handle"<<endl;
			}// End of if
			else
			{
				cout << " acsSetESR() failed with unknown error. " <<	endl;
				cout << " Error code: " << nRetCode;
			}// End of else
		}// End of outer if
}// End of method

// retrieveEvents() method is a member of TSAPIInterface class.
void TSAPIInterface:: retrieveEvents()
{
		// code to retrieve events from client queue goes here?
}
		

How can an application determine the number of calls queued at a specific ACD Split (or Hunt Group)?

An application can determine the number of calls queued in for a specific ACD Split (or Hunt Group) by using the attQueryACDSplit() and cstaEscapeService() methods.

The attQueryACDSplit() method is used to prepare private data information that is passed through the cstaEscapeService() method to query ACD Split. The attQueryACDSplit() method takes two parameters as inputs:

  • The first parameter is privateData (i.e., the ATT private data buffer), and is passed as an output parameter.
  • The second parameter is device, which is of type DeviceID_t and contains the ACD Split number to be queried.
The sample code snippet below illustrates how to invoke the attQueryACDSplit() and cstaEscapeService() methods:
// <summary>
// Query ACD Split via cstaEscapeService().
// </summary>
// <param name="aAcsHandle"> An opened ACS Stream Handle.</param>

void QueryACDSplit(ACSHandle_t aAcsHandle)
{
	InvokeID_t invokeID = 1; // Application generated Invoke ID
	DeviceID_t huntgroupDeviceID = "49000"; // Device associated with ACD split
	RetCode_t retCode; // Return code for service requests
	ATTPrivateData_t privateData; // ATT private data buffer
	
	// encode private data using attQueryAcdSplit
	retCode = attQueryAcdSplit(&privateData, &huntgroupDeviceID);
	
	if (retCode == 0 ) 
	{
		retCode = cstaEscapeService(aAcsHandle, invokeID,
			(PrivateData_t*)&privateData);

		if (retCode != ACSPOSITIVE_ACK) 
		{
			// cstaEscapeService failed, write error handling code here.
		}
	}
	else
	{
		// attQueryAcdSplit failed, write error handling code here.
	}
}
		

For the cstaEscapeService() method, that is called with the private data encoded using attQueryACDSplit, a confirmation event "CSTAEscapeServiceConfEvent" (containing event type ATT_QUERY_ACD_SPLIT_CONF) is provided that provides the following information:
  1. availableAgents: Number of agents logged in to the specified ACD Split and available to receive a call.
  2. callsInQueue: Number of calls in queue for the specified ACD Split.
  3. agentsLoggedIn: Number of agents logged in to the specified ACD Split.
The sample code snippet below illustrates how to retrieve the information about number of available agents, calls in queue, and the number of logged-in agents at a specific ACD Split, from the CSTAEscapeServiceConfEvent event:
// <summary>
// Invoke this method to process CSTA Confirmation events. Call this method 
// after retrieving event (along with private data) using either 
// cstaGetEventPoll() or cstaGetEventBlock() when the 
// cstaEvent.eventHeader.eventClass is CSTACONFIRMATION.
// </summary>
// <param name="cstaEvent"> Pointer to CSTAEvent_t object that contains 
// event's information.</param>
// <param name="privateData"> Pointer to ATTPrivateData_t object that 
// contains private data information.</param>

void HandleCSTAConfirmationEvent(CSTAEvent_t* cstaEvent, ATTPrivateData_t* privateData)
{
// Check for event type.
switch(cstaEvent->eventHeader.eventType)
{
case CSTA_ESCAPE_SVC_CONF:
	{
		// Assuming the private data was negotiated during opening of ACS
		// Stream.

		// check the privateData length
		if ( privateData->length > 0)
		{
			// Event buffer that will contain the decoded 
			// private data information.
			ATTEvent_t attEvent;

			// Decode the private Data received.
			// Check to ensure that the private data 
			// is successfully decoded.
			if ( attPrivateData(privateData,&attEvent) == ACSPOSITIVE_ACK)
			{
				//checking the event type
				if ( attEvent.eventType == ATT_QUERY_ACD_SPLIT_CONF )
				{
					cout<<"Number of calls queued at the ACD Split :";
					cout<< attEvent.u.queryAcdSplit.callsInQueue;
					cout<<"Number of Agents logged on to the ACD Split :";
					cout<< attEvent.u.queryAcdSplit.agentsLoggedIn;
					cout<<"Number of Agents avaiable to receive a call :";
					cout<< attEvent.u.queryAcdSplit.availableAgents;
				}
			}
			else
			{
				// Error while decoding private data
				// handle error.
			}
		}
		else
		{
			// Event does not contain private data
		}
		break;
	}// End of case
	// Application can add other cases here for processing other events as 
	// needed.
}// End of switch
}// End of method

		

How can a TSAPI application get a list of Agents logged into a specific ACD Split (or Hunt Group)?

There is no direct method call to get a list of Agents logged into a specific ACD Split (or Hunt Group). There is, however, an indirect way for obtaining a list of Agents logged into a specific ACD Split. A TSAPI application can follow the steps mentioned below to obtain a list of Agents logged into a specific ACD Split:

  1. Obtain a list of all devices associated with the ACD Split: The Query Agent login service provides the deviceID (extension) associated with each ACD agent logged into a specific ACD Split. The Query Agent login service is a escape service that can be invoked using the cstaEscapeService() method, and involves passing private data encoded using the attQueryAgentLogin()method. In response to the cstaEscapeService() method request, TSAPI Service sends a CSTA_ESCAPE_SRV_CONF confirmation event with the private data event type set to ATT_QUERY_AGENT_LOGIN_CONF in the private data. After sending the confirmation event, the TSAPI Service sends a sequence of CSTAPrivateEvent (CSTA_PRIVATE) events. The private data received in CSTA_ESCAPE_SRV_CONF confirmation event also contains a private cross reference ID that the application can use to associate subsequent CSTAPrivateEvent events, with the original request, by matching with the private event cross reference ID contained in the private data received as part of CSTAPrivateEvent. The private data received as part of CSTAPrivateEvent also contains the count of total devices and a list of deviceIDs (extensions). The list can contain up to 10 deviceIDs of ACD agents logged into the ACD Split. When the count field in the private data of CSTAPrivateEvent is set to zero, it indicates that no more events will be sent to the application in response to the original escape service request. Upon receiving the CSTAPrivateEvent event, the application can store all the deviceIDs in a data structure (for e.g. array, list, etc.), so that the application can further query each device (see Step 2 below) using the deviceID to get the AgentID associated with the device.
  2. Obtain AgentID associated with each device: In this step, the application should query each device using a deviceID stored in the data structure (in Step 1 above) to get the AgentID associated with the device. The application can use the cstaQueryDeviceInfo() method for this purpose. The corresponding CSTAQueryDeviceInfoConfEvent(CSTA_QUERY_DEVICE_INFO_CONF) event provides the AgentID associated with the device.
The implementation procedure to obtain a list of Agents logged into a specific ACD Split is shown below:

  1. Call the attQueryAgentLogin() method to encode the private data and call the cstaEscapeService() method (with the encoded private data) to send the request to obtain the deviceIDs associated with the Agent(s) logged into a specific ACD Split.
    // <summary>
    // This method invokes the attQueryAgentLogin()
    // and cstaEscapeService() method to obtain the extension associated
    // with each ACD agent logged into a specific ACD Split.
    // </summary>
    // <param value="a_pAcsHandle">Handle returned by acsOpenStream()</param>
    // <param value="a_szHuntgroupID">contains the ACD Split number</param>
    
    void QueryAgentLogin(ACSHandle_t a_AcsHandle, char* a_szHuntgroupID)
    {
    
    ATTPrivateData_t privateData; // Private data buffer
    // Encode private data using attQueryAgentLogin() method
    RetCode_t nRetCode = attQueryAgentLogin(
    		(ATTPrivateData_t*)&privateData, // Private data buffer
    		(DeviceID_t*)a_szHuntgroupID // ACD Split number
    		);
    
    // check to ensure that private data is correctly encoded.
    if(nRetCode == 0)
    {
    	// Call cstaEscapeService() method using the private data encoded
    	// above.
    	nRetCode = cstaEscapeService(a_AcsHandle, // Handle to opened stream
    		0, // Library defined InvokeID used
    		(PrivateData_t*)&privateData // encoded Private data 
    		);
    
    	// Checking for the negative response
    	if ( nRetCode < 0)
    	{
    	cout<<" cstaEscapeService() failed with error. " << endl;
    	cout<<"Error Code:"<<nRetCode;
    	}
    	else
    	{
    	// request is successful, check CSTA_ESCAPE_SRV_CONF event.
    	}
    }
    }// End of method
    				
  2. Process the CSTA_ESCAPE_SRV_CONF event to retrieve the private event cross reference ID.
    // <summary>
    // Invoke HandleCSTAConfirmationEvent() method to process CSTA Confirmation 
    // events. Call this method after retrieving event, when the 
    // cstaEvent.eventHeader.eventClass is CSTACONFIRMATION.
    // </summary>
    // <param name="a_pCstaEvent"> Pointer to CSTAEvent_t object </param>
    // <param name="a_pPrivateData"> Pointer to ATTPrivateData_t object</param>
    
    void HandleCSTAConfirmationEvent(CSTAEvent_t* a_pCstaEvent, ATTPrivateData_t* a_pPrivateData)
    {
    // To hold the private event cross reference ID
    ATTPrivEventCrossRefID_t	privateEventRefID;
    // Check for event type.
    switch(a_pCstaEvent->eventHeader.eventType)
    {
    case CSTA_ESCAPE_SVC_CONF:
    	{
    	// Assuming the private data was negotiated during opening of ACS
    	// Stream.
    
    	// check the privateData length
    	if ( a_pPrivateData->length > 0)
    	{
    	// Event buffer that will contain the decoded 
    	// private data information.
    	ATTEvent_t attEvent;
    
    	// Decode the private data received.
    	// Check to ensure that the private data 
    	// is successfully decoded.
    	if ( attPrivateData(a_pPrivateData,&attEvent) == ACSPOSITIVE_ACK)
    	{
    	//checking the event type
    	if ( attEvent.eventType == ATT_QUERY_AGENT_LOGIN_CONF )
    	{
    	privateEventRefID = attEvent.u.queryAgentLogin.
    			privEventCrossRefID;
    	cout<<" The Private Event Cross Reference ID :" 
    			<< privateEventRefID;
    	// Use this private event cross reference ID to match the 
    	// subsequent CSTA_PRIVATE events.
    	}
    	}
    	else
    	{
    	// Error while decoding private data
    	// handle error.
    	}
    	}// End of if
    	else
    	{
    	// Event does not contain private data
    	}
    	break;
    	}// End of case
    	// Application can add other cases here for processing other events as 
    	// needed.
    }// End of switch
    }// End of method.
    				
  3. Process the CSTA_PRIVATE event to get the list of devices.
    // <summary>
    // Invoke HandleCSTAEventReport() method to process CSTA_PRIVATE events. 
    // Call this method when cstaEvent.eventHeader.eventClass is 
    // CSTAEVENTREPORT.
    // </summary>
    // <param name="a_pCstaEvent"> Pointer to CSTAEvent_t object.</param>
    // <param name="a_pPrivateData"> Pointer to ATTPrivateData_t object. 
    // </param>
    // <param name="a_PrivateEventRefID">ATTPrivEventCrossRefID_t object that 
    // contains private event reference ID as retrieved in CSTA_ESCAPE_SVC_CONF
    // event.</param>
    // <param name="a_DeviceList">Pointer that points to list of 
    // deviceIDs</param>
    // <return>Return 1 on success and 0 on failure.</return>
    static int nDeviceListIndex  = 0; // Index for storing DeviceIDs in 
    				 // DeviceList
    int  HandleCSTAEventReport(CSTAEvent_t* a_pCstaEvent, ATTPrivateData_t* a_pPrivateData, 
    			 ATTPrivEventCrossRefID_t a_PrivateEventRefID,DeviceID_t* a_DeviceList)
    {
    int nDeviceCount = 0; // To count total number of devices
    
    
    // Check for event type
    switch(a_pCstaEvent->eventHeader.eventType)
    {
    case CSTA_PRIVATE:
    	{
    	// check the privateData length
    	if (a_pPrivateData->length > 0)
    	{
    	// Event buffer that will contain the decoded 
    	// private data information.
    	ATTEvent_t attEvent;
    
    	// Decode the private Data received.
    	// Check to ensure that the private data 
    	// is successfully decoded.
    	if ( attPrivateData(a_pPrivateData,&attEvent) == ACSPOSITIVE_ACK)
    	{
    	//checking the event type
    	if ( attEvent.eventType == ATT_QUERY_AGENT_LOGIN_RESP )
    	{
    	if(a_PrivateEventRefID == attEvent.u.queryAgentLoginResp.
    					 privEventCrossRefID)
    	{
    	  nDeviceCount = attEvent.u.queryAgentLoginResp.list.
    					     count;
    	if(nDeviceCount == 0)
    	{
    	// No more devices present. 
    	// Post a message to execute the logic to get the 
    	// device information using cstaQueryDeviceInfo for 
    	// each of the devices added to the list a_DeviceList.
    	}
    	else
    	{
    	cout<<" Total Devices :" << nDeviceCount;
    	for(int nDeviceIndex = 0; nDeviceIndex < nDeviceCount;
    					nDeviceIndex++)
    	{
    	// Store all the devices
    	strcpy(a_DeviceList[nDeviceListIndex++],
    	(DeviceID_t)attEvent.u.queryAgentLoginResp
    	.list.device[nDeviceIndex]); // Make sure 
    	// that the array a_DeviceList is of sufficient size to store the maximum 
    	// number of devices returned, indicated by the possible number of agents 
    	// logged into ACD at a give time. 
    	}
    	}// End of else
    	}// End of if
    	}// End of if
    	}// End of if
    	else
    	{
    	// Error while decoding private data
    	// handle error.
    	return 0;
    	}
    	}// End of if
    	else
    	{
    	// Event does not contain private data
    	return 0;
    	}
    	break;
    	}// End of case
    }// End of inner switch
    return 1;
    }// End of method
    
  4. Call the cstaQueryDeviceInfo() method iteratively with each deviceID retrieved in Step c above to get the AgentID associated with each device.
    // <summary>
    // Query device info via cstaQueryDeviceInfo().
    // </summary>
    // <param name="a_AcsHandle"> Handle to opened ACS Stream.</param>
    // <param name="a_szDevice"> contains device ID.</param>
    void QueryDeviceInfo(ACSHandle_t a_AcsHandle, DeviceID_t a_szDevice)
    {
    
    RetCode_t retCode; // To store the method return code
    
    	// Call cstaQueryDeviceInfo method to obtain the AgentID associated 
    	//	with a device. 
    
    retCode = cstaQueryDeviceInfo(a_AcsHandle, // Handle to opened ACS Stream
    0, // Library generated InvokeID used
    (DeviceID_t*) a_szDevice, // DeviceID of device to be
    			// queried
    NULL // No private data sent with this request
    );
    
    	if( retCode < 0)
    	{
    	// Error while sending Query Device Info request
    	cout<<" Error Code: "<<retCode;
    	// handle error
    	} // End of If
    	else
    	{
    	// request is successful, check CSTA_QUERY_DEVICE_INFO_CONF event.
    	}	
    }// End of method.
    
  5. Process the CSTA_QUERY_DEVICE_INFO_CONF confirmation event to retrieve the associatedDevice parameter that represents the AgentID associated with the device.
    // <summary>
    // Invoke HandleCSTAConfirmationEvent() method to process confirmation 
    // events. Call this method when the cstaEvent.eventHeader.eventClass is 
    // CSTACONFIRMATION.
    // </summary>
    // <param name="a_pCstaEvent "> Pointer to CSTAEvent_t object.</param>
    // <param name="a_pPrivateData"> Pointer to ATTPrivateData_t object.</param> 
    
    void HandleCSTAConfirmationEvent(CSTAEvent_t* a_pCstaEvent, ATTPrivateData_t* a_pPrivateData)
    {
    	// Check for event type.
    	switch(a_pCstaEvent->eventHeader.eventType)
    	{
    	case CSTA_QUERY_DEVICE_INFO_CONF:
    	{
    	// Check for private data length
    	if (a_pPrivateData->length > 0)
    	{
    	// Event buffer that will contain the decoded 
    	// private data information.
    	ATTEvent_t attEvent;
    
    	// Decode the private Data received.
    	// Check to ensure that the private data 
    	// is successfully decoded.
    	if (attPrivateData(a_pPrivateData,&attEvent)==ACSPOSITIVE_ACK)
    	{
    	//checking the event type
    	if ( attEvent.eventType == ATT_QUERY_DEVICE_INFO_CONF )
    	{
    	// Check the associated class
    	if ( attEvent.u.queryDeviceInfo.associatedClass ==
    		ecLogicalAgent)
    	{
    	char* AgentID = attEvent.u.queryDeviceInfo.
    			associatedDevice;
    	cout<<"The AgentID: :"<<AgentID;
    	// a_pAgentList and a_AgentIndex are defined by the 	
    	// application. a_pAgentList will store all 
    	// AgentIDs retrieved in this method. 
    	// a_AgentIndex is an integer used as array index. 
    
    	strcpy(a_pAgentList[a_AgentIndex++],(DeviceID_t)
    	attEvent.u.queryDeviceInfo.associatedDevice);
    	}// End of if
    	else
    	{
    	// No Agent ID is Present.
    	}// End of else
    	} // End of if
    	}// End of if
    	else
    	{
    	// error while decoding private data
    	}
    	}// End of if
    	else
    	{
    	// No private data received.
    	}
    	break;
    	}// End of case
    	// Application can add other cases here for processing other events
    	// as needed.
    }// End of switch
    }// End of method
    
Once all the devices have been queried and their respective confirmation events received, the application can make use of the a_pAgentList that contains Agent IDs of all the Agents logged into specified ACD Split.

For more information on the attQueryAgentLogin(), cstaEscapeService() and cstaQueryDeviceInfo() methods, refer to the document titled "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference 02-300544 Release 4.2 May 2008 Issue 4", available at http://www.avaya.com/devconnect.

What is the purpose of the acsQueryAuthInfo() method exposed by Avaya TSAPI Client?

A TSAPI application can use the acsQueryAuthInfo() method to determine the CTI login and password requirements dynamically before opening an ACS stream with a particular advertised service or Tlink. The acsQueryAuthInfo() method places the result of a query in a user-provided structure before returning, and there is no confirmation event for this method.

An application can use acsQueryAuthInfo() method to determine the authentication requirements for an advertised service dynamically and accordingly, on the basis of the response returned by the acsQueryAuthInfo() method, prompt the user to enter only the information required for authentication. This way the application can avoid prompting for both loginID and password, when the service is configured to use default user. Similarly, based on the response of the acsQueryAuthInfo() method, the application can take corrective action when the application can open a stream by only using the loginID provided by the service, or when the service requires the user to authenticate with an external authentication service before opening an stream.

For more information on the acsQueryAuthInfo() method, please refer to the section titled "ACS functions and confirmation events" in the document titled "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference, DocID: 02-300544, Release 4.2 May 2008 Issue 4", available on http://www.avaya.com/devconnect.

The sample code snippet given below demonstrates invoking the acsQueryAuthInfo() method:

// Call this method to get the CTI user loginID and password
// that needs to be supplied in the acsOpenStream() method.
// p_szServiceName: This is an input parameter that will contain the advertised
// service name or Tlink value.
// p_szLoginID: This is an output parameter that will be filled with 
// appropriate CTI user login ID.
// p_szPassword: This is an output parameter that will be filled with 
// appropriate CTI user password.

void GetLoginPassword(ServerID_t* p_szServiceName, 
LoginID_t* p_szLoginID,	Passwd_t* p_szPassword)
{
// To hold authentication information
ACSAuthInfo_t authInfo;

// Use acsQueryAuthInfo( ) to determine the login and password requirements
// when opening an ACS stream to a particular advertised service.
RetCode_t nRetCode = acsQueryAuthInfo(
	(ServerID_t*) p_szServiceName, // Tlink name
	&authInfo // To store authentication information
	);
if(nRetCode != ACSPOSITIVE_ACK)
{
	cout << " Error: acsQueryAuthInfo method failed.";
}
else
{
	switch(authInfo.authType)
	{
	case requiresExternalAuth:
		{
			// Authentication with an external authentication service
			// is required.
			break;
	}
	case authLoginIdOnly:
		{
			// loginID returned in authInfo.authLoginID.
			p_szLoginID = &authInfo.authLoginID;
			// Password will be ingnored, initializing with empty string.
			strcpy((char*)p_szPassword, "");
			break;
		}
	case authLoginIdIsDefault:
		{
			// The application can use authInfo.authLoginID value
			// for loginID and passwd will be ingnored.
			// Alternatively, the application cas also use a different user 
			// than authInfo.authLoginID, in this case 
			// the application must supply both loginID and passwd.
		}
	case needLoginIdAndPasswd:
		{
			// The application should request the user to enter both login ID 
			// and password in this case.
			cout << endl << " Please enter CTI User login ID: ";
			// Store login ID in output parameter
			cin >> *p_szLoginID;
			cout << endl << " Please enter CTI User password: ";
			// Store password in output parameter
			cin >> *p_szPassword;
			break;
		}
	case anyLoginId:
		{
			// Any login ID can be supplied
			strcpy((char*)p_szLoginID, "avaya");
			// passwd will be ignored
			strcpy((char*)p_szPassword, "");
			break;
		}
	}
}
// On return of this method, the calling method can use the p_szLoginID and 
// p_szPassword value to pass in acsOpenStream() method to open a 
// stream with Tlink specified by p_szServiceName.
// For the case of requiresExternalAuth, the application needs to make sure 
// that the user is successfully authenticated with the required external 
// authentication service before opening a stream.
}

What operating system platforms are supported by Avaya TSAPI client libraries?

Avaya TSAPI client libraries are supported on specific Windows and Linux operating system platforms. Under Windows the following 32 bit operating systems are supported:

  • Windows 2000
  • Windows 2003
  • Windows XP
  • Windows Vista
Note that 64 bit Windows operating systems are not supported through AE Services release 4.2 timeframe.

Under Linux, Red Hat Enterprise Linux 3.1 or later are supported.

For more information on installation and supported operating system platforms, refer "Avaya MultiVantage® Application Enablement Services TSAPI, JTAPI, and CVLAN Client and SDK Installation Guide 02-300543," available on http://www.avaya.com/devconnect.

What is the difference between monitoring a call using the cstaMonitorCall() and the cstaMonitorDevice() methods in TSAPI?

The cstaMonitorCall() method is specifically designed to support a single call monitor whereas the cstaMonitorDevice() method will allow an application to monitor all the calls that utilize the monitored device.

In the case of the cstaMonitorCall() method, event reports are provided after the monitor request is acknowledged and events that occurred prior to the monitor request are not reported. For example, consider a simple call scenario where extension 40010 calls 40011. The callID for this call is 198. cstaMonitorCall() is then used to monitor callID 198. The Service Initiated, Originated, and Delivered events that occur before call is monitored will not be provided. In similar scenario, if cstaMonitorDevice() is used to monitor extension 40010 and then the call is initiated, the Service Initiated, Originated, and Delivered events will be provided.

These two methods are also different in the Call Cleared event reporting. In case of cstaMonitorDevice() method, only the Connection Cleared event is provided; the Call Cleared event is never provided. In case of the cstaMonitorCall() method, both the Connection Cleared and Call Cleared events are provided.

A call that is being monitored using the cstaMonitorCall() method may have a new call identifier assigned to it after a conference or transfer. In these cases, event reports continue for that call with the new call identifier. However in case of the cstaMonitorDevice() method, no further events for a call are reported when that call is transferred from the monitored device i.e., the monitored device ceases to participate in the call.

In the case of cstaMonitorCall() method, only Call Filter/Call Event Reports and Private Filter are supported. Agent Event Reports and Feature Event Reports are not provided. In the case of cstaMonitorDevice() method, Call Event Reports for station devices as well as Agent Event Reports for ACD Split devices are supported. Maintenance Event Reports are not provided for both the methods i.e., cstaMonitorCall() and cstaMonitorDevice() method.

For more information on the cstaMonitorCall() and cstaMonitorDevice() methods, refer section "Chapter 10: Monitor Service Group" in the document "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference 02-300544", available on http://www.avaya.com/devconnect.

Is there any method that an application can use to determine the date and time information on the Communication Manager at runtime?

The attQueryTimeOfDay() method can be used to obtain the current time of day information from Communication Manager. The information returned contains the year, month, day, hour, minute, and second.

The application can use obtained date and time information for any purpose; for example event logging. Having date and time information that is aligned across multiple servers is helpful in troubleshooting. It is also possible to use NTP (Network Time Protocol) to more closely align the time of day clocks across multiple systems for this purpose.

The attQueryTimeOfDay() method is used to prepare private data information that is passed through the cstaEscapeService() method to query Communication Manager. The attQueryTimeOfDay() method takes one parameter: privateData (i.e., the ATT private data buffer). The attQueryTimeOfDay() method populates the privateData structure and returns the resulting populated structure through the passed in parameter.

The sample code snippet below illustrates how to invoke the attQueryTimeOfDay () and cstaEscapeService() methods:

// <summary>
// Query Communication Manager for date and time information.
// </summary>
// <param name="a_pAcsHandle"> An opened ACS Stream Handle.</param>
void GetTimeOfTheDay(ACSHandle_t* a_pAcsHandle)
{
  // ATT service request private data buffer 
  ATTPrivateData_t privateData;

  // To store method return value
  RetCode_t retCode;

  // encode private data using attQueryTimeOfDay()
  retCode = attQueryTimeOfDay(&privateData);

  if (retCode == 0 ) 
  {
    InvokeID_t invokeID = 101; // Application generated Invoke ID
    
    // Send a query for Time of Day service
    retCode = cstaEscapeService(*a_pAcsHandle, invokeID,
			(PrivateData_t*)&privateData);

    if (retCode != ACSPOSITIVE_ACK) 
    {
      // cstaEscapeService failed, write error handling code here.
    }
  }
  else
  {
    // attQueryTimeOfDay failed, write error handling code here.
  }
}

For the cstaEscapeService() method, that is called with the private data encoded using attQueryTimeOfDay, a confirmation event "CSTAEscapeServiceConfEvent" (containing event type ATT_QUERY_TOD_CONF) is provided that provides year, month, day, hour, minute, and second as of when Communication Manager handled the request.

The sample code snippet below illustrates how to retrieve the date and time information, from the CSTAEscapeServiceConfEvent event:


// <summary>
// Invoke this method to process CSTA Confirmation events. 
//
// This method is intended to be called after the application has used either 
// cstaGetEventPoll() or cstaGetEventBlock() to retrieve an event and the 
// cstaEvent.eventHeader.eventClass is CSTACONFIRMATION.
//
// The calling entity must pass the retrieved event along with any received 
// private data to this method.
//
// </summary>
// <param name="cstaEvent"> Pointer to CSTAEvent_t object that contains 
// event's information.</param>
// <param name="privateData"> Pointer to ATTPrivateData_t object that 
// contains private data information.</param>

void HandleCSTAConfirmationEvent(CSTAEvent_t* cstaEvent, ATTPrivateData_t* privateData)
{
  // Check for event type.
  switch (cstaEvent->eventHeader.eventType)
  {
  case CSTA_ESCAPE_SVC_CONF:
    {
	// Assuming the private data was negotiated during opening of ACS
	// Stream.

	// check the privateData length
	if ( privateData->length > 0)
	{
	  // Event buffer that will contain the decoded 
	  // private data information.
	  ATTEvent_t attEvent;

	  // Decode the private Data received.
	  // Check to ensure that the private data 
	  // is successfully decoded.
	  if ( attPrivateData(privateData,&attEvent) == ACSPOSITIVE_ACK)
	  {
	    //checking the event type
    if ( attEvent.eventType == ATT_QUERY_TOD_CONF )
	    {
		cout<< "Year : " << attEvent.u.queryTod.year;
		cout<< "Month : " << attEvent.u.queryTod.month;
		cout<< "Day : " << attEvent.u.queryTod.day;
		cout<< "Hour : " << attEvent.u.queryTod.hour;
		cout<< "Minute : " << attEvent.u.queryTod.minute;
		cout<< "Second : " << attEvent.u.queryTod.second;
	    }
           // else handle other attEvent.eveytType s as needed.
	  }
	  else
	  {
	    // Error while decoding private data
	    // handle error.
	  }
       } 
       else
       {
	  // Event does not contain private data
       }
       break;
     }// End of case
     // Application can add other cases here for processing other events as 
     // needed.
  }// End of switch
}// End of method

Does TSAPI have any method to check that how many monitors are active on a particular station extension?

No. TSAPI does not provide any method through which an application can determine number of active monitors on a particular station extension.

If an application is monitoring multiple devices which are participating in a common call, will the application receive separate events for each monitored device?

The TSAPI service sends separate events for each monitored device that are participating in a call. For example, if the application is monitoring device 40010 and 40011, and a call is made from device 40010 to 40011, the application will receive two Delivered events, one for each monitored device.

Each of these events may provide different information specific to device for which the event is being reported. For example, in the above call scenario the first delivered event (for 40011) will contain 'Alerting' in the Local Connection Information whereas the second delivered event (for 40010) will contain 'Connected'. Each event is tagged with a monitor ID (monitorCrossRefID) which allows the application to track which device monitor the event is associated with.

For more information on the monitorCrossRefID, perform a search for "monitorCrossRefID" in the document "Avaya MultiVantage® Application Enablement Services TSAPI for Avaya Communication Manager Programmer's Reference 02-300544", available on http://www.avaya.com/devconnect. Additionally, you can refer tutorial titled "Application Initialization using Avaya AE Services TSAPI SDK for Windows", available on http://www.avaya.com/devconnect.

Is there any difference between TSAPI SetDoNotDisturb and Avaya Aura Communication Manager Do Not Disturb button on a station?

As stated in the TSAPI for Avaya Communication Manager Programmer's Reference, TSAPI SetDoNotDisturb turns on the Send All Calls (SAC) feature for a user station. This feature was designed to give a short notification ring on the called number and then the call is redirected according to the coverage path provisioned for the station. For details on provisioning call coverage see the Administering Avaya Aura Communication Manager documentation available on the Avaya support portal at www.avaya.com/support.

The Do Not Disturb feature on Communication Manager is a hospitality feature used mostly in hotels. By default when this feature is enabled either through a button or FAC via the phone, the call does not go through to the called number. The default behavior for DND is to provide a tone to the calling party. If you wish the call go to coverage, provisioning changes are required. Bring up a SAT session on Communication Manager. Type the command 'change system-parameters features'. Go to page 4 and change a setting called "Controlled Termination Restriction (Do Not Disturb)". By default this set to 'tone'. Change the setting to 'coverage'. Once this is done, submit the form. Now when DND is enabled, the call will go to assigned coverage station(s). There is no indication of call arrival at the initial called number as this feature redirects the call immediately to the station set up in the associated coverage path.

Why does Avaya Aura Communication Manager SA8481 no longer work with TSAPI when using a SIP trunk?

Starting with Communication Manager 6.0.1 functionality for Special Application 8481 (SA8481) was extended to include SIP trunks. The application must be changed in order for SA8481 to work when using SIP trunks. The application changes will work with ISDN trunks as well. In the old method the protocol descriptors 0x00 (for hex) and 0x04 (for ASCII) were used. With the functionality being added for use with SIP trunks, the ability to replace calling party number, AND send UUI was added. For this to happen two new protocol descriptors were added, 0x10 (for hex) and 0x14 (for ASCII). There are additional changes to allow for using the calling party replacement and sending UUI.

Here is an example string with an explanation:

7e 12 10 0c 00 21 39 37 30 32 32 32 31 32 33 34 03 01 02 03
12 - is the total UUI IE length in hex
10 - is the new format Hex bytes
0c - is the length of the Calling Name replacement
00 - Presentation not restricted
21 - Existing encoding of NPI/TON byte as used in ISDN
39 37 30 32 32 32 31 32 33 34 – replacement calling number 9702221234
03 - length of UUI data
01 02 03 – this is the UUI data bytes 1-3. Ignored on ISDN trunks if calling party replacement is used.

NOTE: ISDN trunks still only support replacing the calling party OR sending UUI, they will not allow both. So if replacing the calling party the UUI will be ignored.

Salient points:

  1. Introduce 2 new PD values for UUI IE
    1. 0x10 – Calling party information followed by UUI data in Hex
    2. 0x14 – Calling party information followed by UUI data in IA5 (ASCII)
  2. If UUI IE is received with the new PD values
    1. If the SA 8481 is turned ON, UUI IE is interpreted
    2. If the SA is turned off, the UUI IE is ignored (dumped)
  3. If UUI IE is received with the any other PD (old or undefined)
    1. If the SA 8481 is turned ON, UUI IE is interpreted based on rules laid out in the original SRAD.
    2. If the SA is turned off, the UUI IE is processed based on rules laid out in the original SRAD.
  4. The format of UUI IE payload for the new PDs (0x10 and 0x14) is explained in the table above.

  5. When the call is routed over a SIP trunk ONLY the new format of UUI IE must be used to specify calling party info. i.e. PD of UUI IE should be either 0x10 or 0x14.

  6. When routing over ISDN trunk, the old format (‘*’ as first byte) of sending calling party information will continue to work
    1. Note that when using the old format, the UUI IE payload can either contain UUI data or calling party info, not both. (Existing feature functionality)
    2. In the old format, if UUI data is interpreted as calling party information, the IEs PD is ignored. (Existing feature functionality)

What is the reason for receiving 'INVALID_OBJECT_TYPE' error during Single Step Conference?

There may be a brief period, immediately after a call is answered, where the media path of the call is unstable. This will occur when a call involves a SIP trunk and Direct IP-IP (shuffling) is enabled. In older releases (see below) of Communication Manager, attempting a Single Step Conference at this stage could cause the call to drop or to end up with no audio.

In order to address this issue, an update was added to CM 7.0.1.1, CM 6.3.15 and 6.3.115. This update causes Communication Manager to reject a Single Step Conference request during this period with the error code INVALID_OBJECT_TYPE (18).

If an application receives an error of INVALID_OBJECT_TYPE to a Single Step Conference request, it should wait for a short period (200ms is recommended) and try again. The second attempt will, most likely, succeed.

In some environments, the extra delay in starting the recorder may be unacceptable. In these cases, a workaround would be to disable shuffling on the appropriate signaling group(s) or network region(s).

For further information, see PSN020242u which is available on support.avaya.com