134
Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002

Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

  • Upload
    others

  • View
    21

  • Download
    0

Embed Size (px)

Citation preview

Page 1: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Avaya™ Interaction Center Release 6.0IC Client and Server Programmer’s Design Guide

DXX-1026-02Issue 1.0

June 2002

Page 2: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

2002, Avaya Inc.All Rights ReservedNoticeEvery effort was made to ensure that the information in this book was complete and accurate at the time of printing. However, information is subject to change.

Preventing Toll Fraud�Toll fraud� is the unauthorized use of your telecommunications system by an unauthorized party (for example, a person who is not a corporate employee, agent, subcontractor, or working on your company's behalf). Be aware that there may be a risk of toll fraud associated with your system and that, if toll fraud occurs, it can result in substantial additional charges for your telecommu-nications services.

Avaya Fraud InterventionIf you suspect that you are being victimized by toll fraud and you need technical support or assistance, call Technical Service Center Toll Fraud Intervention Hotline at +1 800 643 2353.

Providing Telecommunications SecurityTelecommunications security (of voice, data, and/or video communications) is the prevention of any type of intrusion to (that is, either unauthorized or mali-cious access to or use of your company's telecommunications equipment) by some party.

Your company's �telecommunications equipment� includes both this Avaya product and any other voice/data/video equipment that could be accessed via this Avaya product (that is, �networked equipment�).

An �outside party� is anyone who is not a corporate employee, agent, subcon-tractor, or working on your company's behalf. Whereas, a �malicious party� is anyone (including someone who may be otherwise authorized) who accesses your telecommunications equipment with either malicious or mischievous intent.

Such intrusions may be either to/through synchronous (time-multiplexed and/or circuit-based) or asynchronous (character-, message-, or packet-based) equip-ment or interfaces for reasons of:

� Utilization (of capabilities special to the accessed equipment)� Theft (such as, of intellectual property, financial assets, or toll-facility

access)� Eavesdropping (privacy invasions to humans)� Mischief (troubling, but apparently innocuous, tampering)� Harm (such as harmful tampering, data loss or alteration, regardless of

motive or intent)Be aware that there may be a risk of unauthorized intrusions associated with your system and/or its networked equipment. Also realize that, if such an intru-sion should occur, it could result in a variety of losses to your company (includ-ing but not limited to, human/data privacy, intellectual property, material assets, financial resources, labor costs, and/or legal costs).

Your Responsibility for Your Company's Telecommunications SecurityThe final responsibility for securing both this system and its networked equip-ment rests with you - an Avaya customer's system administrator, your telecom-munications peers, and your managers. Base the fulfillment of your responsibility on acquired knowledge and resources from a variety of sources including but not limited to:

� Installation documents� System administration documents� Security documents� Hardware-/software-based security tools� Shared information between you and your peers� Telecommunications security experts

To prevent intrusions to your telecommunications equipment, you and your peers should carefully program and configure your:

� Avaya-provided telecommunications systems and their interfaces� Avaya-provided software applications, as well as their underlying

hardware/software platforms and interfaces� Any other equipment networked to your Avaya products.

Avaya National Customer Care CenterAvaya provides a telephone number for you to use to report problems or to ask questions about your contact center. The support telephone number is 1-800-242-2121.

Ordering InformationAvaya Publications Center Voice: +1 800 457 1235 International Voice: 410 568 3680 Fax: +1 800 457 1764 International Fax: 410 891 0207 Email: [email protected]

Write: GlobalWare Solutions Attention: Avaya Account Manager200 Ward Hill Avenue Haverhill, MA 01835 USA

Order: Document No. DXX-1026-02, Issue 1.0, June 2002

To order product documentation online, go to http://www.avayadocs.com, click on Online Services, and select the appropri-ate product group.

WarrantyAvaya Inc. provides a limited warranty on this product. Refer to the �Limited Use Software License Agreement� or other applicable documentation provided with your package to establish the terms of the limited warranty.

Avaya Web Pagehttp://www.avaya.com

TrademarksAvaya, Conversant, CustomerQ, Definity, DefinityOne, Nabnasset, Quintus, and WebQ are registered trademarks or trademarks of Avaya Inc. in the United States or other countries or both.

Portions of Avaya Interaction Center include technology used under license as listed below, and are copyright of the respective companies and/or their licen-sors:

ActivePerl is a trademark of ActiveState Tool Corp. This product includes software developed by the Apache Software Foundation (http://www.apache.org/). Cognos, Impromptu and Powerplay are registered trademarks of Cognos Incorporated. YACC++ is a registered trademark of Compiler Resources, Inc. APEX, ComponentOne, VideoSoft, True DBGrid, VSVIEW, SizerOne, VS-OCX, VSFlexGrid, VSFORUM, VSREPORTS, VSDOCX, VSSPELL, and TrueDBList are either registered trademarks or trademarks of ComponentOne LLC. CT Connect, Dialogic, Intel, and Pentium are trademarks or registered trademarks of Intel Corporation or its subsidiaries in the United States and other countries. Hummingbird is a registered trademark of Hummingbird, Ltd. SearchServer is a trademark of Hummingbird, Ltd. RISC System/6000 and DirectTalk/2 are trademarks of International Business Machines Corporation in the United States or other countries or both. IBM, OS/2, AS/400, CICS, WebSphere, CT, VisualAge, and DirectTalk are registered trademarks of International Business Machines Corporation in the United States or other countries or both. Lotus and Lotus Sametime are trademarks or registered trademarks of Lotus Development Corporation and/or IBM Corporation in the United States, other countries, or both. VisualX is a registered trademark of Intergroup Technologies, Inc. ActiveX, Visio, Internet Explorer, Windows, Windows NT, Windows 2000, Win32s, SQL Server, Visual Basic, Visual C++, Outlook, and FrontPage are either registered trademarks or trademarks of Microsoft Corporation in the United States and/or other countries. TimesTen is a registered trademark of TimesTen Performance Software. Oracle is a registered trademark, and Oracle8i and Oracle® SQL/Services are trademarks or registered trademarks of Oracle Corporation. Rogue Wave and .h++ are registered trademarks of Rogue Wave Software Inc. SourcePro is a trademark of Rogue Wave Software, Inc. Siebel is a trademark of Siebel Systems, Inc. BasicScript is a registered trademark of Summit Software Company. Sun, iPlanet, Java, Solaris JRE, J2EE, JavaServer Pages, and all Java-based trademarks are trademarks or registered trademarks of Sun Microsystems, Inc. in the United States, other countries, or both. SPARC is a registered trademark of SPARC International, Inc. Products bearing SPARC trademarks are based on an architecture devel-oped by Sun Microsystems, Inc. In3D is a trademark of Visual Insights, Inc. InstallShield® is a registered trademark and service mark of InstallShield Software Corporation in the United States and/or other countries. ORBacus is a trademark of IONA Technologies PLC. Formula One is a licensed trademark and Tidestone Technologies, Inc. Visual Components, First Impression, and VisualSpeller are registered trademarks of Tidestone Technologies, Inc. JRun is a trademark of Macromedia, Inc. in the United States and/or other countries. Intervoice is a registered trademark of Intervoice-Brite, Inc. UNIX is a registered trademark of The Open Group in the United States and other countries. Acrobat is a registered trademark of Adobe Systems.

Other product and brand names are trademarks of their respective owners.

AcknowledgmentThis document was written by the CRM Information Development group of Avaya

Page 3: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

3

BEFORE YOU BEGIN . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 7

1 OVERVIEW. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11What is Avaya Interaction Center? . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 11The ORB Toolkit . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 12ORB Toolkit Components . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 13Components of the Product Set . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 14

2 GENERAL CONCEPTS . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Implementation Repository (vesp.imp File) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 17Interface Repository (vespidl.pk File) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18Sessions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 18The Environment Variable . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 19Exceptions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20Events . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 20Alarms . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Timeouts . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Security . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 21Debugging Techniques . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 23

3 CORBA AND THE ORB IDL. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Telephony and CORBA Specification Differences . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25

Unsupported CORBA Structures . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Preprocessing Directives . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 25Enhancements to CORBA . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

The IDL . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 26

Predefined types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27Creating New Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 27

CONTENTS

Page 4: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

4 IC Client and Server Programmer�s Design Guide

Contents

Unsupported Data Types . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28Describing Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28

Interface Naming Scheme . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 28Oneway (void) Methods . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29Inheritance of Interfaces . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29The Virtual Extension . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29

Describing Constants . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 29Preprocessing Directives (Partial Set) . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30Scope Rules in an IDL File . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 30The IDL Compiler . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31Adding a Server in a UNIX Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 31Adding Data Types on UNIX Systems . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 32

4 THE HYBRID INTERFACE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33Introduction . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33Tradeoffs of Hybrid Binding . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 33Synchronous Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34

Synchronous Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 34Synchronous Hybrid API: Vesp_Request_Sync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 36Memory Management for Synchronous Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . 37Input Arguments to Vesp_Request_Sync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38Output Arguments to Vesp_Request_Sync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 38

Asynchronous Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39Asynchronous Architecture . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 39Asynchronous Hybrid API - Vesp_Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 41Memory Management for Asynchronous Operations . . . . . . . . . . . . . . . . . . . . . . . . . 43Input Arguments to Vesp_Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43Output Arguments to Vesp_Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 43

Timing of Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 45

5 CLIENT DEVELOPMENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47Developing a Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47Basic Flow of Operation for a Client . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 47

Page 5: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Issue 1.0 June 2002 5

Contents

Example of a Client Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 48

6 SERVER DEVELOPMENT . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59Components of a Telephony Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59

Inputs and Outputs . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 59The Poll Loop . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 60

Requests on Behalf of Clients . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61Coding the Application Layer . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 61Example Server . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 62Servicing Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81

Method Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 81Memory Allocation for Output Parameters . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83

Callback Functions . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 83Passing Data to the Callback Function: user_data . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85Deferred Requests . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 85Deferred Request Example: Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 86

A MEMORY ALLOCATION CODE SAMPLES . . . . . . . . . . . . . . . . . . . . . . . 93Output Arguments to Vesp_Request_Sync . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 93Source Code Sample 1: synchronous request � output type long . . . . . . . . . . . . . . . . . . . . 94Memory Management for Asynchronous Operations . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98

Input Arguments to Vesp_Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 98Output Arguments to Vesp_Request . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 99

B CLIENT CODE EXAMPLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105Example of a Client Application . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 105Custom Telephony Client: source code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 106

C SERVER CODE EXAMPLE . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117Server Source Code Example . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 117Custom Telephony Server Source Code . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 119Custom Telephony Server : Server makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 125Building SDK Custom Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126

Page 6: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

6 IC Client and Server Programmer�s Design Guide

Contents

Solaris 8 Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 126Windows NT or 2000 Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127

Testing OOTB SDK Custom Servers . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 127Troubleshooting . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 129

Custom Telephony Server : vespidl.idl file . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 130Custom Telephony Server: IDL makefile . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 131

INDEX . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 133

Page 7: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

7

BEFORE YOU BEGIN

Typographical ConventionsThis guide uses the following font conventions:

Notes, Tips, and CautionsNote: A note calls attention to important information.

Tip: A tip offers additional how-to advice.

Caution: A caution points out actions that may lead to data loss or other serious problems.

Contacting Technical SupportIf you are having trouble using Avaya software, you should:1 Retry the action. Carefully follow the instructions in written or online documentation.

2 Check the documentation that came with your hardware for maintenance or hardware-related issues.

Font Type Meaning

code This font signifies commands, information that you enter into the computer, or information contained in a file on your computer.

italics This font is used to add emphasis to important words and for references to other chapter names and manual titles.

It also indicates variables in a command string.

jump Blue text in online documents indicates a hypertext jump to related information. To view the related material, click on the blue text.

!

Page 8: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

8 IC Client and Server Programmer�s Design Guide

3 Note the sequence of events that led to the problem and the exact messages displayed. Have the Avaya documentation available.

4 If you continue to have a problem, contact Avaya Technical Support by:

� Logging in to the Avaya Technical Support Web site (http://www.avaya.com/support/qq).

� Calling or faxing one of the following numbers from 8:30 a.m. to 8:30 p.m. (Eastern Standard Time), Monday through Friday (excluding holidays):� Toll free in the U.S. only: 1-888-TECH-SPT (1-888-832-4778)� Direct line for international and domestic calls: 512-425-2201� Direct line for faxes: 512-719-8225

� Sending email with your question or problem to [email protected]. You may be asked to email one or more files to Technical Support for analysis of your application and its environment.

Note: If you have difficulty reaching Avaya Technical Support through the above URL or email address, please go to www.avaya.com for further information.

Product DocumentationMost Avaya product documentation is available in both printed and online form. However, some reference material is available only online, and certain information is available only in printed form. A PDF document with detailed information about all of the documentation for the Avaya Interaction Center is included in the Doc directory on the product CD-ROM. This PDF document is also included on the separate documentation CD-ROM.

Readme FileThe Readme file is an HTML file included on the Avaya Interaction Center software CD-ROM. This file contains important information that was collected too late for inclusion in the printed documentation. The Readme file can include installation instructions, system requirements, information on new product features and enhancements, suggested work-arounds to known problems, and other information critical to successfully installing and using your Avaya software. You may also receive a printed Addendum to the Readme, containing similar information uncovered after the manufacture of the product CD-ROM. You should review the Readme file and the Readme Addendum before you install your new Avaya software.

Electronic DocumentationThe electronic documentation (in PDF or HTML format) for each Avaya Interaction Center product is installed automatically with the program. Electronic documentation for the entire Avaya product suite is included on the product CD-ROM and the documentation CD-ROM.

You can also view the documentation set online at http://www.avayadocs.com.

Page 9: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Educational Services

Issue 1.0 June 2002 9

Printed DocumentationYou can purchase printed copies of these manuals separately. For details, see �Ordering Information,� on the back of this manual�s title page.

License to Print the Electronic DocumentationOnline copies of documentation are included on the CD-ROM that accompanies every software release. An Avaya customer who has licensed software (a �Licensee�) is entitled to make this online documentation available on an internal network or �intranet� solely for the Licensee's use for internal business purposes. Licensees are granted the right to print the documentation corresponding to the software they have purchased solely for such purposes.

Right-To-Print License Terms

Documents must be printed �as-is� from the provided online versions. Making changes to documents is not permitted. Documents may be printed only by any employee or contractor of Licensee that has been given access to the online documentation versions solely for Licensee's internal business purposes and subject to all applicable license agreements with Avaya. Both online and printed versions of the documents may not be distributed outside of Licensee enterprise or used as part of commercial time-sharing, rental, outsourcing, or service bureau use, or to train persons other than Licensee's employees and contractors for Licensee's internal business purposes, unless previously agreed to in writing by Avaya. If Licensee reproduces copies of printed documents for Licensee's internal business purposes, then these copies should be marked �For internal use only within <Licensee> only.� on the first page or cover (where <Licensee> is the name of Licensee). Licensee must fully and faithfully reproduce any proprietary notices contained in the documentation. The copyrights to all documentation provided by Avaya are owned by Avaya and its licensors. By printing any copy of online documentation Licensee indicates its acceptance of these terms and conditions. This license only governs terms and conditions of printing online documentation. Please reference the appropriate license agreement for terms and conditions applicable to any other use, reproduction, modification, distribution or display of Avaya software and documentation.

Educational ServicesAvaya University provides excellent training courses on a variety of topics. For the latest course descriptions, schedules, and online registration, you can get in touch with us:� Through the web at http://www.avaya-learning.com� Over the telephone at 800-288-5327 (within the U.S.) +001 303-406-6089 (outside of the U.S.)� Through email at [email protected]

Page 10: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

10 IC Client and Server Programmer�s Design Guide

Page 11: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

11

CHAPTER 1OVERVIEW

This chapter provides an overview of Avaya Interaction Center (Avaya IC), an overview of the Avaya IC ORB Toolkit, and a list of components in the Avaya IC product set.

What is Avaya Interaction Center?Avaya IC is a powerful set of components that allows contact centers to provide personalized customer service. By qualifying and routing contacts to the resource best able to assist them, and by providing agents with easy access to customer information in corporate databases, Avaya IC enables companies to interact effectively with their customers.

Avaya IC manages workflow across multiple platforms and heterogeneous components, including automated call distributors (ACDs), private branch exchanges (PBXs), interactive voice response units (IVRs/VRUs), and desktop and host computer applications.

Each component of Avaya IC communicates with other Avaya IC objects across the network � processing requests, responses and events � without regard to the hardware platform, operating system, physical location or state of the other objects in the system. The domain of Avaya IC objects spans the entire network (LAN or WAN).

The objects in Avaya IC consist of clients and servers. Servers are software objects that provide services to other objects. Services are requested of servers by invoking methods. A method is a published service with a predetermined set of inputs and outputs. A server�s methods may be invoked by any other server or client in the Avaya IC domain.

One use of an Avaya IC server is to encapsulate a proprietary communication link. When an Avaya IC server is designed to provide an interface to a device (such as a piece of telecommunications hardware), the resources associated with that hardware become available to every client and server in the Avaya IC domain. Similarly, the resources of all the Avaya IC servers become available to the proprietary hardware.

Page 12: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 1 Overview

12 IC Client and Server Programmer�s Design Guide

The ORB ToolkitThe Avaya IC ORB Toolkit manages the communication between objects in the Avaya IC system and the flow of work within a server. The Toolkit provides a set of network-based functions for the creation of data structures and application programming interfaces (APIs). The toolkit is a shared object that is dynamically linked to every client and server in the Avaya IC system.

The ORB is an object request broker that enables user-developed servers to be available across a network. The servers can then be accessed through API directives. This significantly speeds up the development of user-specific software. The types of software development that benefit from these features include:� Providing the software environment supporting data prefetch. For example, when a caller

enters a Personal Identification Number in a voice response application, database information about the caller can be queried and placed in a cache, ready to pass to the agent who receives the call.

� Using Avaya IC functions to create, read, and write data in Avaya IC servers electronic data units (EDUs) and agent data units (ADUs).

� Creating servers that interface to new devices, such as voice response units, PBXs or ACDs, FAX gateways, or other device-specific drivers.

� Creating network-based database clients and servers. A common role for the ORB is converting database information into structures that are easily accessed by applications on the network. For example, the user might develop an Avaya IC server to access an IBM 3270 data stream.

The ORB is based on the Common Object Request Broker Architecture (CORBA) specification published by the Object Management Group. The ORB supports the basic CORBA constructs and the interface description language (IDL).

To simplify access to CORBA functions and to ensure compatibility with future releases of CORBA, Avaya IC has added a hybrid invocation interface, which encapsulates dynamic invocation. The hybrid interface offers many advantages over the OMG CORBA interface, including events, sessions, and callback capability.

Refer to �Telephony and CORBA Specification Differences,� on page 25 for a discussion of differences between the ORB implementation and the CORBA specification.

Page 13: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

ORB Toolkit Components

Issue 1.0 June 2002 13

ORB Toolkit ComponentsThe Avaya IC ORB Toolkit includes the following components. Each of these will be discussed in this manual

The following example illustrates the interaction of these components in an Avaya IC client/server implementation.

Component Name Description

Hybrid Invocation Interface Combination of dynamic and static binding, where the location of a service is determined on demand. This is the interface that you write applications to. These API functions call the CORBA Dynamic Invocation interface. Refer to �Tradeoffs of Hybrid Binding,� on page 33 for information on the hybrid interface.

Avaya IC ORB Core Creates and sends requests; receives and decodes responses and events.

Basic Object Adapter Calls methods contained in the server.

Methods Routines that do the actual work for the clients.

IDL Compiler Generates code for creation of new interfaces and generates the interface repository.

Interface Repository Contains the IDL (Interface Definition Language) descriptions of all interfaces and data types known to the Avaya IC system (vespidl.pk).

Implementation Repository Contains a local copy of the specific location of each server in the Avaya IC system (vesp.imp).

Page 14: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 1 Overview

14 IC Client and Server Programmer�s Design Guide

Components of the Product SetAvaya IC consists of the Toolkit components and a collection of specialized client and server objects. The servers and clients provided by Avaya IC encompass the standard functionality required for most CTI applications.

A brief explanation of major Avaya IC components is provided below. For more information about individual components, refer to the documentation for that component.

The official interface name of each server is shown first, followed by the common or expanded name of the server in parentheses. Not all of the listed components are part of the Avaya IC release.

Avaya TS (Telephony Server)

The Avaya TS encapsulates communication with the switch or PBX. Through the Avaya TS, other servers and clients in the Avaya IC environment can request telephony services (transfer or route a call, hang up a call, etc.) by invoking methods. Clients and servers can also assign to the Avaya TS, enabling them to receive telephone-related events (e.g., �there is a call on line 1200�).

Data Network

Client Application Code

Hybrid Binding

Avaya Com puterTelephony ORB

Core

Avaya ComputerTelephony Client

Dynam icBinding

StaticBinding

Server ApplicationCode (Methods)

Basic O bject Adapter

Avaya Com puterTelephony Server

InterfaceRepository

Im plem entationRepository

Avaya Com puterTelephony ORB

Core

Page 15: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Components of the Product Set

Issue 1.0 June 2002 15

EDU (Electronic Data Unit Server)

The EDU Server is the custodian of the Electronic Data Unit � a data repository for contact-related information. Each EDU has a unique identifier called an EDUID. This makes it possible for each object (client or server) associated with a call to place information in a common location for other objects to see, and to retrieve data written by other objects. Data is read and written by invoking methods on the EDU Server.

Note: The term �EDU� refers to both the individual data repository for one contact, and to the interface name of the server. It is used in both contexts throughout the documentation set. �EDU� is synonymous with �VDU,� which appears sporadically in the code base. �VDU� is a deprecated term, which has not yet been changed internally to �EDU� on a global basis.

VOX (Voice Response Unit Server)

The VOX Server encapsulates communication with a Voice Response Unit (VRU). Part of the Avaya IC code called a concentrator or data interchange program (DIP) resides on the VRU providing a communication link to the VOX Server. This link with the VOX Server makes Avaya IC resources available to the VRU native scripting language. Several Avaya IC functions are automatically included in the communication protocol between the VRU and the VOX Server. These allow the VRU to find the EDUID of a new call, to read/write values in the EDU for the current call, and to transfer a call.

WorkFlow (WorkFlow Server)

The Workflow server is a user-customizable server that can control the flow of a contact until it arrives at the first client application in the flow. It provides routing information when a PBX makes a route request to the Avaya TS. In this process it often interfaces with database servers and other resources to determine correct routing for the call.

DS (Directory Server)

The Directory Server is a central repository for information about the Avaya IC environment. It maintains configuration data for servers, login names and permissions of agents, and various other system information. Much of its work is invisible to the user. In conjunction with the Avaya IC Toolkit layer of every client and server, it assists in locating services as they are needed. Much of the information stored in the DS can be modified through the administrative client application, IC Manager.

ORBServer (Object Request Broker Server)

The ORB Server operates behind the scenes to ensure that services are available to clients in a truly location-independent manner. It is capable of restarting a stopped server when its services are needed. It also assists in locating the required services to fulfill a client�s requests. An ORB Server will reside on each physical computer that contains one or more Avaya IC servers.

Page 16: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 1 Overview

16 IC Client and Server Programmer�s Design Guide

Customer Interaction Repository

Customer Interaction (CI) Repository is a database in which contact-related information is stored. When a contact has been completed, events that occurred during the life of the contact are recorded in the CI Repository. The data is used to create reports on general call data over a period of time.

Alarm (Alarm Server)

The Alarm Server is called by any client or server that wishes to report an alarm condition. The method Alarm.Alarm is a one-way method (no response) containing parameters such as priority (Info, Low, High, EMERGENCY) and descriptive text (�VRU is not defined in configuration�). When Alarm.Alarm is invoked, the Alarm Server will send an event to IC Manager (or other registered objects) to notify the system administrator or initiate automated responses.

ADU (Agent Data Unit Server)

The Agent Data Unit Server tracks the call-related activities of contact center agents. Information about the various call states the agent enters and the duration of each state is monitored, as well as the time of Avaya IC login and logoff. Agent data is stored in a data repository called an Agent Data Unit (ADU). ADU data is read and written by invoking methods on the ADU Server.

VTel Engine

The VTel engine is responsible for CORBA communications and the handling of all telephony functions and events. Custom client applications can interface to the VTel engine (using DDE, OLE, or other means) to invoke methods, receive events, etc. from Avaya IC servers. The VTel Engine can be used with the Avaya Agent softphone or integrated with a third party softphone.

IC Manager

IC Manager is an administration and system management tool that enables the management, configuration, and monitoring of the components of Avaya IC. IC Manager also provides the ability to add, delete, and modify information for agents, servers, queues, and tables. It also configures the media channels used by agents to handle contacts. IC Manager can start and stop Avaya IC servers.

Page 17: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

17

CHAPTER 2GENERAL CONCEPTS

This chapter contains information fundamental to understanding the concepts introduced in subsequent chapters.

Implementation Repository (vesp.imp File)The file vesp.imp is Avaya IC's implementation repository file. It contains information that allows the Toolkit to find clients and servers. This file must reside in the working directory of each client and each server at startup.

The implementation repository is created during the Avaya IC installation. The text file it creates (vesp.imp) can be transferred to other platforms. It is updated by the ORB Server's Update method.

Each entry in the repository contains at least: � The official interface name that matches a name in the interface repository. � The UUID (Universal Unique Identifier) that was generated when the server was added to

Avaya IC. The UUID contains the IP address of the machine on which this server resides, the port this server listens on, and the creation date and time.

� A domain attribute that defines the domain to which this object belongs.� A home attribute that identifies the location of this server's home directory. Log files are

written to this directory.� An executable attribute that identifies the location of this server's executable file.

The following is an example of an implementation repository entry for an Avaya TS.

Interface TSUUID 2ba7c91d00000a017800002807dc0002Attribute group EngineeringAttribute executable /NAB/release/test/tssrvAttribute home /NAB/release/test

Page 18: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 2 General Concepts

18 IC Client and Server Programmer�s Design Guide

Interface Repository (vespidl.pk File) The file vespidl.pk is Avaya IC's interface repository. It is created by the IDL compiler. This file defines server capabilities. It also defines the interfaces and methods available in Avaya IC. This information is used by the Toolkit to pack and unpack all requests and must be available wherever the Toolkit runs.

This file is produced on each run of the IDL compiler, whether or not you request C generation. The .pk file is also the input to the second stage of the IDL compiler, which generates C code.

Note: Each time the IDL compiler is run it generates new code. Do not edit machine generated code; it will be overwritten.

SessionsA session is a relationship between objects in the Avaya IC system. There are two types of sessions: sessions and default sessions.� A session is a relationship between a specific client and a specific server. This relationship goes

beyond a simple ORB request and response in that it adds persistence. That is, once a session exists between a client and server, the server automatically notifies the client of events in which it is interested, and services requested by the client are automatically routed to a particular instance of a server, providing continuity during a series of related requests.

Sessions are created with the Vesp_Session_Create function. The session is given a unique ID number. A client or server is related to a session with the Vesp_Assign_Request function.

SCHECK( Vesp_Login( "vesp", "funfun", &client_obj ) );SCHECK( Vesp_Session_Create( client_obj, &session ) );SCHECK( Vesp_Assign_Request( TEST.Assign", &ev, NULL, OUL, event_callback,session, NULL ) );

To add more services to a session, call the Assign method again with the session that was returned by the Vesp_Session_Create method. This is very powerful because you then have one handle for almost any number of servers.

It is also possible to have many different sessions existing at once. Having multiple sessions allows a client application to run concurrent activities.

The Vesp_Deassign_Request function destroys the session between the client and server. All of the resources associated with the session are deleted, including all objects, pending messages, and so on. If a client terminates abnormally, a server automatically calls the Deassign method, if registered, once for each session the client had with the server. For server developers, this is a very good place to put anything you have to clean up. The Vesp_Session_Delete method deletes the session created with Vesp_Session_Create.

Page 19: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

The Environment Variable

Issue 1.0 June 2002 19

� Default sessions are created by the Toolkit. When a client or server logs into Avaya IC, a session is created for initial communication required for start up. This is the default session; it contains the security of the client or server that logged in. (See �Security,� on page 21 for information on Security levels.) This session is also used later on for certain requests.

The default session can be accessed with the function

Vesp_get_default_session( object, &session )

where �object� is either the object returned from login or the Object representation of the server's UUID string. For more detailed information on Object representation of strings, refer to the ORB_string_to_object function in the Core Services Programmer�s Guide.

The Environment VariableThe environment is used to store environment-specific information about the client and the client's transaction. User and system exceptions are raised in the environment by the server's method. The environment contents can be examined to get the request handle or session number.

If an exception is returned, no other output values may be relied upon, not even the return code. Valid data generally cannot be safely returned.

The definition of the environment variable is subject to change; do NOT modify the environment directly.

The current contents of the environment are:

typedef struct Environmentexception_type _major;char vesp_error_description[132];char name[36];

unsigned long user_security;

Object session;Object request;Object cobject;} Environment;

_major The exception major code as specified in the CORBA Specification. There are three possible values:

#define NO_EXCEPTION (unsigned long )(0)#define USER_EXCEPTION (unsigned long )(1)#define SYSTEM_EXCEPTION (unsigned long )(2)

_minor Minor code used to describe the error, as specified in the file generic.idl.

vesp_error_description Text used to describe the error.

name Name of the error.

Page 20: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 2 General Concepts

20 IC Client and Server Programmer�s Design Guide

ExceptionsAn exception is raised when a problem has occurred that prevents the method from proceeding, such as a bad parameter or an insufficient resource.

An exception is raised by calling the routine:

void vesp_set_exception( Environment *ev, ULONG major, ULONG minor, char*description )

The environment variable used is the one passed to the method as the second parameter, as described in �The Environment Variable,� on page 19. This routine calls the BOA_set_exception routine. Do NOT call BOA_set_exception directly.

EventsAn event is a message sent from a server to one or more clients as a result of some trigger other than a request from those clients. Events are "unsolicited" messages, in that the client does not necessarily do anything to trigger a particular event.

To receive events, a client must establish a session with a server by invoking the server's Assign method. After a client has established a session with a server, events may be sent from the server to the client. Events are sent to a specific client session.

Several convenience functions are supplied to simplify event creation, some of which are illustrated below:

event = vesp_event_create( "Test.EventName" );

vesp_event_add_couple( event, "arg1", "value1" );vesp_event_add_couple( event, "arg2", "value2" );vesp_event_add_couple( event, "arg3", "value3" );vesp_event_add_couple( event, "arg4", "value4" );

SCHECK( Session_send_event( ev->session, &local_ev"Test.EventName", event ));

vesp_event_delete( event );

user_security User security level. This is a bit mask. See �Security,� on page 21.

session The permanent or temporary session of the client. This can be used to send events back to the client.

request The request handle of the current request. This is useful if you want to defer the current request. You have to save this handle to send back the response at a later time. (Refer to �Deferred Requests,� on page 85 for information on deferring requests.)

cobject A string that uniquely identifies the client.

Page 21: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Alarms

Issue 1.0 June 2002 21

AlarmsAlarms are generated by servers or clients to broadcast problem information to any device that is set up to receive them. To send an alarm, use the Vesp_Send_Alarm or Send_Alarm_No_History functions. These functions invoke the Alarm Server's Alarm.Alarm method, which generates an alarm event.

ORBStatus Vesp_Send_Alarm( Object object, char *name,char *priority, char *description );

extern ORBStatus Vesp_Send_Alarm_No_History( Object object,char *name, char *priority, char *description );

For complete information, refer to the Alarm Server chapter of the Core Services Programmer�s Guide.

TimeoutsIf a hybrid interface request takes more than a set amount of time, it will �time out,� sending a message back to the client that the request was not filled in time. To adjust the amount of time allowed, call the function:

ORBStatus Session_set_message_timeout( Session, session, Environment *ev,unsigned long timeout_in_seconds )

This function controls the timeout value for the whole session. The new value is applied to all new requests associated with this session.

SecuritySecurity levels can be set through the BOA_set_method function. Bit settings are listed in the file generic.idl. The following security levels are available.

VESP_SEC_ADMIN Administrator (all privileges). Create/Delete/Updated/Monitor all Avaya IC entities (Agent, Group, Server, Queue)Agent Queue/Group AssignmentAdministration of scriptsAssigning supervisor accountsAssigning roles

VESP_SEC_OPERATOR Monitor system status.Stop and start servers.Monitor Queue Activity

VESP_SEC_POSTMASTER Email filtersMail accounts - POP3/SMTP accountsScripts (for routing to pool)Email Queue Changes

Page 22: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 2 General Concepts

22 IC Client and Server Programmer�s Design Guide

The following security levels are maintained for backward compatibility with earlier versions.

Composite Security Levels:

The Toolkit assigns a security level of �All� to all servers.

VESP_SEC_CLERK Add/Remove/Update agent accounts.Create workgroups.Assign agent to workgroups

VESP_SEC_AGENT Receive tasksView personal statisticsSubmit new WRU documents

VESP_SEC_SUPERVISOR All Agent and Clerk PrivilegesTask Load/Ceiling Assignment.Monitor Agent.Report Generation Administration of scripts.Content and resource manipulationCreate Mail Templates Administration of wru documentsSubmit new wru documents Approve agent submitted wru documents.Auto Reply and other messages Editor

VESP_SEC_NONE No security

VESP_SEC_GROUP Can change group

VESP_SEC_REPORT Can generate reports

VESP_SEC_SET_SEC_LEVEL Can change security level

VESP_SEC_SERVER_MODIFY Modify Server access

VESP_SEC_USER_MODIFY Modify User access

VESP_SEC_PROCESS_CONTROL Can control and terminate servers

VESP_SEC_MONITOR Monitor system

VESP_SEC_ALL All Security

VESP_SEC_USR1 - 8 User definable security levels

VESP_SEC_SYSTEM_MANAGER �manager� equivalent to VESP_SEC_ALL

VESP_SEC_SYSTEM_MONITOR �monitor� equivalent to VESP_SEC_REPORT, VESP_SEC_GROUP, and VESP_SEC_MONITOR

Page 23: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Debugging Techniques

Issue 1.0 June 2002 23

Debugging TechniquesBe sure to check all values returned from the ORB routines. If anything is returned that you are not handling, you should return before you send your request to the server.

Always remember to check the _major exception code of the environment used with a function call before checking any other return codes. If the environment indicates an error, no other output values may be relied upon, not even the return code.

When testing code, be sure to print out where you are and what you are doing. This saves a lot of time in the long run, and beats adding error codes when you're done.

The functions vesp_log_info and log_unparsable are used to force information to a log file. Use vesp_log_info first, to place a machine-parsable header into the log file, followed by log_unparsable to write the human-readable text. Note that the information will be logged regardless of the trace level set for the log file.

Note: When log files exceed the maximum size set with the logfilesize configuration parameter, they are renamed to .old and a new log file is started. This mechanism is embedded in the vesp_log_info function, but is not included in log_unparsable.

Page 24: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 2 General Concepts

24 IC Client and Server Programmer�s Design Guide

Page 25: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

25

CHAPTER 3CORBA AND THE ORB IDL

This chapter outlines the differences between the Avaya IC ORB Toolkit and the CORBA Specification, and describes the Interface Description Language (IDL) syntax.

Telephony and CORBA Specification Differences This section lists differences between the ORB Toolkit and the CORBA Specification. Several of the concepts mentioned in this section are described in detail in other sections of this manual.

Unsupported CORBA StructuresAvaya IC has created a set of software tools that enable programmers to contribute to the improved use of existing data by rapidly linking it to customer telephone inquiries. The ORB provides the framework needed to instantly access the data you specify for any given situation.

Due to Avaya IC's need for real-time performance in all of its applications, there are some CORBA structures that are not supported. The intention is to make Avaya IC compatible with the CORBA 3.0 Specification when it becomes available

Currently Avaya IC does not support Context Interface, Interface Repository Interface, and Static Binding.

Preprocessing DirectivesThe CORBA IDL specification calls for full C++ preprocessing. Avaya IC only supports ANSI C preprocessing. If you need C++ capability, run your IDL file through a C++ preprocessor. Refer to �Preprocessing Directives (Partial Set),� on page 30 for a list of supported preprocessing directives.

Page 26: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 3 CORBA and the ORB IDL

26 IC Client and Server Programmer�s Design Guide

Enhancements to CORBAThe following are Avaya IC�s enhancements to CORBA:

The IDLThe IDL is a means of describing the interface between clients and servers. Using the IDL syntax you can describe methods (functions) and data types.

It is important to realize that the IDL describes data types and functions, analogous to ANSI C typedefs and function prototypes. You do not write code in IDL. The IDL compiler uses your IDL statements and writes the code for you. Software interfaces described by this language are both machine and language independent.

An interface definition written in IDL completely defines the interface and fully specifies each operation�s parameters.

The IDL is defined within the CORBA standards. You can find information about IDL syntax and semantics in the published CORBA standards entitled The Common Object Request Broker: Architecture and Specification.

Data TypesThe following data types are supported by the IDL. ANSI C is the assumed programming language.

Event An event is generated by a server to which a client is assigned. An event indicates that some action relevant to the client has occurred. Events may arrive at any time. Refer to �Events,� on page 20 for more information about events.

Sessions A session is a relationship between a client and a server. This goes beyond a simple ORB request because it adds persistence. That is, the server can send events to clients that have assigned to it. Refer to �Sessions,� on page 18 for more information about sessions.

Callbacks A callback routine is a user-defined routine associated with a request to a server. The callback routine is called after control has been returned to the calling application. The address of this routine is saved in the request that was sent to the server and is run from within the API handler routine. Callback routines are used to allow asynchronous operation. They are essential for continuous operation of clients and servers. Refer to �Callback Functions,� on page 83 for more information about callback routines.

Server selection The server to perform the client's request is selected by the hybrid interface. Refer to �Tradeoffs of Hybrid Binding,� on page 33 for more information about the hybrid interface.

Page 27: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Data Types

Issue 1.0 June 2002 27

Predefined types

Creating New Types

Long Long is 32 bits. The IDL supports the unsigned version.

String A string can be either fixed or variable length.

Enum An enum is mapped to an unsigned long constant by CORBA.

Void (for method return types)

As in ANSI C, you can specify a method that takes no parameters by a parameter list of (void). This is a trivial extension to the IDL, for those accustomed to typing (void) to signal an empty parameter list. The IDL syntax for an empty parameter list is ().

Any A data type designed to hold data of any type. It is basically a string to describe the data and a pointer to that data. Supported only for C clients.

Typedef Works exactly like C's typedef command.

Struct Works exactly like C++'s struct command. The type created has a type name; struct X defines a type X. References to incomplete types are supported for C only, and only to the extent tolerated by the CORBA specification. It is wise not to use incomplete types.

Sequence A sequence is a variable length array of some other type. It has no direct equivalent in C. The syntax for unlimited sequences is sequence <data type> The syntax for limited sequences is sequence <data type, maximum_length>All sequences have the structure:

typedef struct {unsigned long _maximum;unsigned long _length;pointer-to-data} seq foo;

A sequence has a data type (sequence of longs), a maximum length (0 for no limit), and a current length. You can append new instances to a sequence. In C, they are implemented by a struct and a lot of code. You can have sequences of sequences.

Sequence is usually used with typedef, because (in C) the type name generated is unwieldy (_IDL_SEQUENCE_short for the example below).

In C, limited sequences are slightly more efficient. Very large limited sequences are usually a mistake.

You can declare sequences of any data type, including other sequences, as in this example:

typedef<sequence <sequence < short > > SeqSeqShort >;

Page 28: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 3 CORBA and the ORB IDL

28 IC Client and Server Programmer�s Design Guide

Note: The CORBA definition has a minor syntactical glitch: Use spaces around the delimiting >�s or the >> will be mistaken for a logical shift operator, not a deliminator.

Couples in a sequence can occur in any order and the order may change anytime.

Unsupported Data TypesThe following data types are unsupported:

Describing InterfacesAn interface is a group of data types and methods gathered under a single name and associated with an object (a server in the Avaya IC system).

Interface Naming SchemeInterface names and method names follow the same rules; they start with a letter and contain up to 15 letters and digits. You can use more, but the target language may have problems dealing with them. Do not use underscores in these names.

MethodsMethods contain the following:

A nameThe name of the function associated with a method is essentially

interfacename_methodname.

A return typeAll methods have a return type, even if it is only void. The current implementation limits you to void, long, or unsigned long (ORBStatus is unsigned long).

Parameters (0 or more)Parameters come in two flavors: in and out. Input parameters cannot be modified by the server, while output parameters can be and generally are.

Fixed Length String A fixed length string offers no obvious advantage over the simple string type.

Union

Array Type 'Sequence' can be used instead.

Short

Char

Page 29: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Describing Constants

Issue 1.0 June 2002 29

The value in output parameters is not seen by the server and is overwritten. The IDL inout declaration is not supported. Sequences are special in that an out sequence has its maximum length value sent to the server, and the server is expected to honor it.

Syntax: {in | out} datatype parametername

Oneway (void) MethodsA Oneway method returns no value and cannot have out parameters.

Inheritance of InterfacesAn interface can be built atop other interfaces by drawing in the methods and data types defined in other interfaces. This is called inheritance. If interface A has a method M (creating function A_M), then if an interface X inherits A, a function X_M will also exist, with the same parameters and data types. This is used, in Avaya IC interface definitions, to provide a base set of functions common to all servers.

In the following example, interface Z has one method, Floyd, and inherits interface X. The server would be expected to support both Z_Pink and Z_Floyd.

interface X { unsigned long Pink(); } // define a normalinterface

interface Z : X { void Floyd(); } // define A and inheritX into it

You can inherit from more than one interface at a time:

interface Z : A, B, C { ...}

You cannot inherit from two interfaces that contain identical method names or data type names.

The Virtual ExtensionThis is an Avaya IC extension to the IDL. By declaring an interface as virtual, you tell the compiler not to generate any code for it, but other interfaces can still inherit it. This is used every time you inherit the GeneralS IDL class.

Describing ConstantsYou can describe constants as part of your interfaces using the syntax:

const <type> <name> = value

as in

const short Foo = 3

Only strings and integral types are supported as constant initializers. You can use simple expressions and string concatenation. Floating point is not supported.

Page 30: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 3 CORBA and the ORB IDL

30 IC Client and Server Programmer�s Design Guide

Preprocessing Directives (Partial Set)The CORBA IDL specification calls for full C++ preprocessing. Avaya IC only supports ANSI C preprocessing. If you need C++ capability, run your IDL file through a C++ preprocessor.

Scope Rules in an IDL FileIf you define a data type within an interface, it is only visible within that interface (and interfaces that inherit from it). The name of the data type is prefixed by the interface name that owns it, just as method names are. For example, type blue in interface Cards would be called:

CARDS_BLUE

If you define data types outside of interface definitions, they are visible to all interfaces from that point down. That is the simpler procedure, and usually appropriate.

The same rules apply to consts, or anything else, defined in interfaces.

Avoid creating data types for the first time within a parameter list. The CORBA Specification is unclear about the scoping and naming of definitions within parameter lists, and the Avaya IC solution might have to change when CORBA is revised.

Examples are:

void Y( sequence<long, 27> list);

// This is a bad idea.

typedef sequence<long, 27> SeqLong27;void Y( inSeqLong27 list );

// This is better.

#include "file" The <file> form is not provided. Do not use backslash in filenames.

#define name tokens... As in C, define a name to be replaced by the following tokens whenever it occurs.

string concatenation �x� �y� is really �xy�

#ifdef, #ifndef, #endif These are defined automatically and can be tested.

_C_ via #ifdef when you request C code generation.

Page 31: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

The IDL Compiler

Issue 1.0 June 2002 31

The IDL CompilerThe IDL compiler is an application that runs under UNIX and Windows NT / Windows 2000.

The compiler is made up of three executable files: idl, idlcgen, and idltype.

The running syntax is:

idl {switches} filename

where {switches} can be:

The source file is named xxxx.idl, where xxxx can be any valid filename. Omit the.idl when you specify the filename on the command line.

Ensure that your path includes the directory in which the files idlcgen and idltype reside. These will be run automatically when the -c switch is specified, and the following files will be generated:

vespidl.cvespidl.hvespidl.pkvespidl.pkhvespidl.pkt

Refer to the Core Services Programmer�s Guide for a list of platform-specific compile/link options.

Adding a Server in a UNIX EnvironmentTo add a server to the Avaya IC environment on UNIX:

Note: If you are also adding data types, you must relink the toolkit as described in �Adding Data Types on UNIX Systems,� on page 32.

1 Write an IDL description. Example:

interface Test : GeneralS {

ORBStatus Echo( in unsigned long arg1,out unsigned long arg2 );

-c Generate C code. Defines __C__

-Dname{=value} Define a symbol. The default value is 1.

-i Inputdir. Read all input files relative to the given directory. This is applied to include files as well.

-o Outputdir. Write the output files relative to the given directory.

-t Compress the type table. Highly recommended.

-w Minimize warnings.

Page 32: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 3 CORBA and the ORB IDL

32 IC Client and Server Programmer�s Design Guide

ORBStatus Echo2( in string arg1, out string arg2 );

ORBStatus Echo3( in SeqCouple arg1, out SeqCouple arg2 );

ORBStatus Echo4( in Couple arg1, out Couple arg2 );

ORBStatus Echo5( in SeqSeqCouple arg1,out SeqSeqCouple arg2 );

ORBStatus Assign(void);

}

2 Add the new IDL interface into vespidl.idl.

3 Run the idl Compiler../idl -c vespidl

4 Copy all vespidl.* to your build path.

5 Compile your application and link in Avaya IC libraries as shown in the Core Services Programmer�s Guide.

6 With the IC Manager application, add your new server to the Implementation Repository (do an Add Server).

7 Do an update to the ORB Server; this generates a new vesp.imp file (implementation repository).

8 Copy the new vesp.imp and vespidl.pk files to all clients and servers in the environment.

9 Use IC Manager to start the server or access the server with a client application to start the server.

Adding Data Types on UNIX SystemsTo add new data types to the Telephony environment, relink the toolkit:1 Customize the file vespidl.idl to add your new structures.

2 Run the IDL compiler as described above.

3 Compile the .c file generated by the IDL compiler to create vespidl.o.

4 Link vespidl.o into a new libvespidl.so.

5 Copy the vespidl.pk file from Step 2 and the vespidl.so file from step 4 to the Avaya IC system.

6 Shut down all servers and restart them to allow the new vespidl.pk file to be read.

Page 33: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

33

CHAPTER 4THE HYBRID INTERFACE

This chapter describes invoking methods in synchronous and asynchronous modes, responding to a request from another client or server, deferring a response, and related memory management issues.

The topics in this chapter are discussed from the point of view of a server or client making requests of another server. Refer to �Server Development,� on page 59 for a description of method invocation from the point of view of the server invoked.

IntroductionThe Hybrid Interface provides an application programming interface (API) for client/server and server/server communication. It consists of �C� function calls to invoke methods on servers, process responses, assign to resources, respond to events, and perform many other operations.

The hybrid interface combines the best of CORBA dynamic and static bindings.� Dynamic binding allows creation of requests to a server on the fly. A request is built piece by

piece and then sent to the server. It takes many steps to make one request to a server and requires that the application developer manage all memory allocation and delete old requests.

� Static binding is similar to a function call (or a remote procedure call). The call can only be synchronous, and it must be compiled and linked as the code is generated by the IDL compiler.

The Hybrid Interface builds a request dynamically in one step, manages memory allocation, and can be synchronous or asynchronous. This is accomplished by a library of functions that sit on top of the dynamic API.

Tradeoffs of Hybrid BindingSome trade-offs were made to simplify method invocation, including:� The return result (the value returned by a method) is of type ORBStatus (unsigned long) or

void. If the server method raises an exception, the return, as well as any output parameters, is invalid.

Page 34: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

34 IC Client and Server Programmer�s Design Guide

� Only longword data types are allowed. These are types struct, any, long, unsigned long, string, and sequences. No char, floats, shorts, or doubles are allowed. Arrays are also not currently supported by the IDL compiler or the ORB.

� A maximum of 12 parameters are allowed for any method.

Synchronous RequestsThe Avaya IC hybrid API allows a server to make asynchronous or synchronous requests of other servers. Synchronous calls are seldom used in time-sensitive or repetitive operations, because they are blocking from the point of view of the caller. They are often used for initialization tasks, or for other tasks that require verified completion before operation continues.

Synchronous calls may be triggered at initialization or by a method invocation from a client, but they cannot be made inside a callback function or while servicing an event. (See �Callback Functions,� on page 83 for information regarding callback functions.)

Synchronous ArchitectureThe anatomy of a synchronous method request is illustrated in the following diagram. The client and server are each divided into an application layer and an Avaya IC Toolkit layer. The application layer consists of all code unique to the particular client or server. The Toolkit layer is divided into the hybrid API and the ORB Core. The functions in the hybrid API will be discussed in the sections that follow.

Note: The label �Client� refers to the role of the software object in question, not its identity. When a server invokes a method on another server, it is acting as a client.

Page 35: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Synchronous Requests

Issue 1.0 June 2002 35

The following diagram illustrates a Synchronous Method Request:

1 Client issues a request for data with the Vesp_Request_Sync hybrid function. The client sees this as a normal call to a function and does not care where or how the actual request is processed.

2 The API builds the request to the server with ORB functions and performs any verification and error checking of the request that it can. The hybrid invocation also tries to select a specific server that can fulfill the client request using the implementation repository (vesp.imp) and the interface repository (vespidl.idl).

3 If the API detects an error in the client's request, it returns control and an error (in the environment structure) to the client application without passing the request to the ORB or the server. If the request was built successfully, the hybrid invocation passes the request to the ORB.

4 The ORB core processes the request and queues it for transmission to the server object.

5 The request is successfully packaged and sent off to the server.

6 The server processes the request and executes the appropriate method.

7 The server sends the results of the request to the ORB.

R e ce iveR eq ues t

W as R eq ues t

B u ilt?

P roc es sR eq ues t

S en dR eq ues t

R ec e iveR e s pons e

Ye s

P roc es sR e s pons e

C on tinueexec u tio n o fA pp lic a tion

C ode

N o

Ap p lica tio nL a ye r

Av aya IC AP I

O R BC o re

Avaya IC T o o lk it L ayer

C a ll to H yb ridA P I fro m

A pp lic a tio nC ode

C lie n t

S e rve r

Ap p lica tio n L aye r

Ava ya IC H yb rid L a ye r

O R B

To o lk it L aye r

Page 36: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

36 IC Client and Server Programmer�s Design Guide

8 The ORB receives and processes the server's response. All output parameters are filled with the information retrieved. If the server raised an exception, the return result and all output parameters are invalid.

9 The ORB returns control to the client. The request information is deleted with all the output and copied input parameters when the user makes a call to the toolkit function Vesp_Request_Delete.

Note: The synchronous call is blocking from the point of view of the client. No other calls can be serviced until the response from the server has arrived and been processed. Requests arriving from another server are queued. Events and callbacks are still processed.

Synchronous Hybrid API: Vesp_Request_SyncThe function Vesp_Request_Sync provides the interface to invoke methods on other servers in synchronous mode. The general format for Vesp_Request_Sync is:

Status Vesp_Request_Sync (

Identifier interface, /* Interface name */

Environment *env_ptr, /* Pointer to an Environment structure */

Session session, /* A valid session */

Request *request_ptr, /* Pointer to a new request structure */

arg1, /* Arguments to the method... */

arg2,

arg3,

arg4,

...);

Page 37: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Synchronous Requests

Issue 1.0 June 2002 37

Note: Convention dictates that input arguments precede output arguments in the argument list for a method.

Vesp_Request_Sync does not return to the calling function until the request has been sent and a result (or exception) received and processed. The amount of time spent in this function depends on the response time of the server invoked. The return value is of type ORBStatus, indicating any error condition. Successful calls return VESP_SUCCESS or VESP_PARTIAL_SUCCESS.

Memory Management for Synchronous OperationsMemory is allocated automatically by the system for output arguments and other purposes when Vesp_Request_Sync is called. In general, all memory allocated by Vesp_Request_Sync is freed with a call to Vesp_Request_Delete, passing the session and request as parameters.

Note: If Vesp_Request_Delete is not called after every synchronous request, the calling process making the requests will leak memory. As the calling process continues to operate, this will expend resources and eventually affect system performance and/or cause the server to crash.

Argument Purpose

interface Interface name: A string composed of the server name, a period, and the method name. Example: �Server.Method�

env_ptr Pointer to an Environment structure. The structure may be declared locally in the calling function. No initialization is necessary. It will be filled in by the Toolkit or the invoked server with any exceptions or error conditions encountered in executing the method. It can be checked when Vesp_Request_Sync returns. The definition of the Environment data type is in idlpk.h; it is described in �The Environment Variable,� on page 19.

session Session structure. The session represents a relationship between objects in the Telephony system, and is used by the Toolkit. It may be considered an opaque data type. If the function from which Vesp_Request_Sync is called has a session as an input argument, this session should be passed to Vesp_Request_Sync. Otherwise, a session should be declared locally and pointed at the global server session by calling Vesp_get_default_session. Refer to �Sessions,� on page 18 for more information about sessions.

request_ptr Pointer to a Request structure. This structure may be declared locally in the calling function. No initialization is necessary. It will be filled in by the Toolkit and used to maintain a record of the request and match it with the response when it arrives. This data type may be considered opaque.

arg1... The arguments for the particular method, as defined in the IDL specification. These definitions are in generic.idl (Telephony Servers) or vespidl.idl (custom servers). See the following section, on memory management, for more details.

Page 38: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

38 IC Client and Server Programmer�s Design Guide

Input Arguments to Vesp_Request_SyncThe caller is responsible for allocating memory for input arguments to Vesp_Request_Sync, and freeing it afterwards. Vesp_Request_Delete has no effect on input arguments as they are copied.

Output Arguments to Vesp_Request_SyncOutput arguments for Vesp_Request_Sync must be handled based on type.

The caller must initialize all output parameters to zero or null before calling Vesp_Request_Sync.

Refer to �Memory Allocation Code Samples,� on page 93 for source code examples illustrating the memory management techniques outlined in this section.

Type: longunsigned longenum

These simple fixed length types must be allocated by the caller. Vesp_Request_Sync receives a pointer and fills in the value.

Type: string

A pointer to the output string must be allocated by the caller. Vesp_Request_Sync allocates space for the returned string and fills in the data.

Type: sequence

A sequence in the output parameter list for a synchronous method invocation acts as an input as well as an output. The sequence->_maximum is filled in by the caller to specify the maximum number of data elements the method should return (a _maximum of 0 means no maximum). Therefore, the sequence structure itself must be allocated by the caller. Data elements are added to the sequence by Vesp_Request_Sync when the response is received.

The order in which Vesp_Request_Delete and vesp_couple_seq_delete are called is important. Vesp_Request_Delete will always try to free the memory for the couples it added to the output sequence; vesp_couple_seq_delete can then delete the empty sequence. If vesp_couple_seq_delete is called first, it will free the sequence and its contents, and Vesp_Request_Delete will fail, resulting in memory problems.

Note: Output sequences are handled in this same fashion regardless of content. For example, a sequence of longs, a sequence of couples, and a sequence of sequences are handled the same. One initial sequence structure is allocated (and freed) by the caller, and all members of the sequence are allocated (and freed) by the Toolkit, with calls to the hybrid API.

Type: structure

Page 39: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Asynchronous Requests

Issue 1.0 June 2002 39

A structure in the output parameter list for a synchronous method invocation is handled similarly to a sequence. The structure itself is allocated by the caller. This may be done statically or dynamically. Data elements will be added to the structure by Vesp_Request_Sync when the response is received, and any memory required for that purpose will be allocated by the Toolkit.

Asynchronous RequestsThe Telephony hybrid API allows a client or server to make asynchronous requests of other servers. Asynchronous calls are generally used in time-sensitive or repetitive operations, because they are non-blocking from the point of view of the caller. Unlike synchronous requests, they may be used inside callback functions and while servicing events.

Asynchronous ArchitectureThe anatomy of an asynchronous method request is depicted in the following diagram, which shows an Avaya IC client and an Avaya IC server, expanded to show features of the internal architecture. Each is divided into an application layer and a Toolkit layer. The application layer consists of all code unique to the particular client or server. The Toolkit layer is divided into the Telephony hybrid API and the ORB Core.

Note: The label �Client� refers to the role of the software object in question, not its identity. When a server invokes a method on another server, it is acting as a client.

Page 40: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

40 IC Client and Server Programmer�s Design Guide

The interactions that occur during an asynchronous request are described below.

1 Client issues a request for data with the Vesp_Request hybrid function. The client sees this as a normal call to a function and does not care where or how the actual request is processed.

2 The API builds the request to the server with ORB functions and performs any verification and error checking of the request that it can. The hybrid invocation also tries to select a specific server that can fulfill the client request.

3 If the API detects an error in the client's request, it returns control and an error to the client application without passing the request to the ORB or the server. If the request was built successfully, the hybrid invocation passes the request to the ORB.

4 The ORB core processes the request and queues it for transmission to the server object.

5 The request is successfully packaged and sent off to the server.

6 The ORB immediately returns control to the client through the API. If the ORB was not able to successfully package and send off the request to the server, the ORB returns a failure to the API.

Note: While the asynchronous request is being performed the client application can do other tasks.

Call to HybridAPI from

ApplicationCode

ReceiveRequest

Was Request

Built?

ProcessRequest

SendRequest

ProcessResponse

Yes

InvokeCallback

Continueexecution ofApplication

Code

No

Application

Layer

AvayaComputerTelephonyHybrid API

ORBCore

Avaya Computer TelephonyToolkit Layer

ReturnControl

ReceiveResponse

ExecuteCallbackFunction

Client

Server

Application Layer

ORB

Toolkit Layer

AvayaComputerTelephonyHybrid API

Page 41: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Asynchronous Requests

Issue 1.0 June 2002 41

7 The server processes the request and executes the appropriate method.

8 The server sends the results of the request to the ORB.

9 The ORB receives and processes the server's response. All output parameters are filled with the information retrieved. If the server raised an exception, the return result and output parameters are invalid when the callback function returns.

10 The ORB invokes the user-defined callback routine and releases control. The request information is deleted with all the output and copied input parameters.

Note: The asynchronous call is non-blocking from the point of view of the client. The call to the hybrid API returns almost immediately, and processing continues in the application layer. Additional methods can be invoked, incoming events serviced, etc., before the server response has arrived and been processed.

Asynchronous Hybrid API - Vesp_RequestThe function Vesp_Request provides the interface to invoke methods on other servers in asynchronous mode. The general format for Vesp_Request is as follows:

ORBStatus Vesp_Request (Identifier interface, /* Interface name */ULONG *callback, /* Pointer to a callback function */ULONG user_data, /* Data to pass to the callback function */Session, /* A valid session */arg1, /* Arguments to the method... */arg2,arg3,arg4,...);

Page 42: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

42 IC Client and Server Programmer�s Design Guide

Note: Convention dictates that input arguments precede output arguments in the argument list for a method.

Vesp_Request returns to the calling function almost immediately. Its return type is ORBStatus. VESP_SUCCESS is returned if the request was successfully built. The callback function is not invoked until the response is received and processed. The amount of time between the call to Vesp_Request and the execution of the callback depends on the response time of the server invoked.

The callback function must have the following general format:

ORBStatus callback_function (Identifier interface, /* Interface name */ORBStatus return_result, /* Result of method invocation */Environment *env_ptr, /* Pointer to filled in env. structure */ULONG user_data /* Data passed from calling function */session, /* A valid session */arg1, /* Arguments to the method... */arg2,arg3,arg4,...);

Argument Purpose

interface Interface name: A string composed of the server name, a period, and the method name. Example: �Server.Method�

callback Pointer to a callback function. This function will be invoked by the Toolkit automatically when the response is received.

user_data Data to pass through to the callback function. An unsigned long can be passed this way, but more often a pointer to data is cast as an unsigned long and passed.

session Session structure. The session represents a relationship between objects in the Telephony system, and is used by the Toolkit. It may be considered an opaque data type. If the function from which Vesp_Request is called has a session as an input argument, this session should be passed to Vesp_Request. Otherwise, a session should be declared locally and pointed at the global server session by calling Vesp_get_default_session. (Refer to �Sessions,� on page 18 for information about sessions.)

arg1... The arguments for the particular method, as defined in the IDL specification. These definitions are in generic.idl (Telephony Servers) or vespidl.idl (custom servers). See the following section, on memory management, for more details.

Page 43: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Asynchronous Requests

Issue 1.0 June 2002 43

The callback function must be declared with the same method input and output parameters as the matching call to Vesp_Request. Particular care must be taken since a mismatch in the method parameters will not cause compiler or linker warnings to be generated.

Memory Management for Asynchronous OperationsCalls to Vesp_Request allocate memory for output arguments and other purposes. Memory allocated by Vesp_Request is freed automatically after the callback function has been executed.

Input Arguments to Vesp_RequestThe caller is responsible for allocating memory for input arguments to Vesp_Request, and freeing it afterwards. Vesp_Request makes copies of all input arguments, so the caller may free this memory as soon as Vesp_Request returns.

Output Arguments to Vesp_RequestOutput arguments for Vesp_Request must be handled based on type. This section outlines the supported data types and their handling.

The caller must initialize all output parameters to zero or null before calling Vesp_Request.

Argument Purpose

interface Interface name: A string composed of the server name, a period, and the method name. Example: �Server.Method�

*env_ptr Pointer to an Environment structure. It has been filled in by the Toolkit or the invoked server with any exceptions or error conditions encountered in executing the method. The definition of the Environment data type is in idlpk.h. (Refer to �The Environment Variable,� on page 19 for a description of the Environment variable.)

user_data Data to pass through to the callback function from the calling function. An unsigned long can be passed this way, but more often a pointer to data is cast as an unsigned long and passed instead.

session Session structure. The session represents a relationship between objects in the Avaya IC system, and is used by the Toolkit. It may be considered an opaque data type. If Vesp_Request is called again within this callback function (to make another asynchronous request of another server) this session should be passed to Vesp_Request. (Refer to �Sessions,� on page 18 for more information on sessions.)

arg1... The arguments for the particular method, as defined in the IDL specification. These definitions are in generic.idl (Telephony Servers) or vespidl.idl (custom servers). The arguments are echoed just as they appeared in the initial call to Vesp_Request. The Toolkit does not alter the input arguments.

Page 44: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

44 IC Client and Server Programmer�s Design Guide

Refer to �Memory Allocation Code Samples,� on page 93, for source code examples illustrating memory management techniques.

Type: longunsigned longenum

These simple fixed length types must be allocated by the caller. Vesp_Request receives a pointer and fills in the value. Unlike the synchronous request, the output variable cannot be an automatic. The output will be processed in the callback function; therefore, the scope and lifetime of the output variables must include the callback. This can be accomplished by allocating the space statically outside the calling function. Note that the sequence of events when the Toolkit processes responses is such that, no matter how many calls to Vesp_Request may be pending simultaneously, they can all use the same static variable space for output parameters because only one callback routine is run at a time.

Type: string

A pointer to the output string must be allocated by the caller. Vesp_Request allocates space for the returned string and fills in the data. When the callback function has completed execution, the Toolkit frees the memory.

Type: sequence

A sequence in the output parameter list for a method acts as an input as well as an output. The sequence->_maximum is filled in by the caller to specify the maximum number of data elements the method should return (a _maximum of 0 means no maximum). Therefore, the sequence structure itself must be allocated by the caller before invoking Vesp_Request. Data elements will be added to the output sequence by the Toolkit when the response arrives. The output can then be processed in the callback function. The output memory will be freed automatically by the system when the callback is completed. Therefore, the scope and lifetime of the output sequence must include the callback, and the output sequence itself must still exist after the callback function is completed. This is accomplished by allocating the output sequence statically outside the calling function. Note that the order of events when the Toolkit processes responses is such that, no matter how many calls to Vesp_Request may be pending simultaneously, they can all use the same static variable space for output parameter data.

Note: Output sequences are handled in this same fashion regardless of content. For example, a sequence of longs, a sequence of couples, and a sequence of sequences are handled the same. A static sequence structure is allocated by the caller, and all members of the sequence are allocated (and freed) by the Toolkit.

Type: structure

A structure in the output parameter list for a method is handled similarly to a sequence. The structure itself must be allocated by the caller before invoking Vesp_Request. Data elements will be added to the structure by the Toolkit when the response arrives. The output can then be processed in the callback function. The output memory will be freed automatically by the system

Page 45: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Timing of Requests

Issue 1.0 June 2002 45

when the callback is completed. Therefore, the scope and lifetime of the output structure must include the callback, and must still exist after the callback function is completed. This is accomplished by allocating the output structure statically outside the calling function.

Note that the order of events when the Toolkit processes responses is such that, no matter how many calls to Vesp_Request may be pending simultaneously, they can all use the same static variable space for output parameter data.

Timing of RequestsIf a command to a server is dependent on a previous request, be sure to wait for the user callback routine to start execution before you issue another command. This is particularly true of the Assign method where you may be allocating some resource. If this method fails, you do not want to be sending requests that will fail right away.

It is not essential that you wait for all callbacks to run before you make another call to a server. However, in some instances it may be required. If a server is not dependent on a sequence of requests to fulfill your needs, you will have no problem. For example, you should be able to issue any number of requests to retrieve zip code translations as long as the server is implemented cleanly.

If the application blocks, you may want to call the method synchronously. When called, the client waits for the response to return or a time-out. Any asynchronous routine runs in the background. Use synchronous calls within a server carefully as it blocks other methods from running.

Page 46: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 4 The Hybrid Interface

46 IC Client and Server Programmer�s Design Guide

Page 47: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

47

CHAPTER 5CLIENT DEVELOPMENT

This chapter describes client development and presents a sample Avaya IC client. An additional client code example is presented in Appendix B.

Developing a ClientThe ORB simplifies the development of client/server applications and allows Avaya IC, users, and system integrators to have a consistent user interface on which to build applications.

The ORB also makes it possible to write seamless applications. An application can access data from many different databases as well as voice/data functions with a consistent interface. This greatly reduces application development time and minimizes startup time and retraining of staff.

The main idea is to have the bulk of developers build applications on top of consistent APIs that are provided to them. The building of the APIs and the servers to which they talk can be left to specialized teams of engineers with the expertise in databases, integrated voice/data applications, or anything that requires substantial development, overhead, training, or platform dependence. This saves developers of applications from having to learn another database or platform.

Basic Flow of Operation for a ClientAll Avaya IC client applications follow the same basic configuration:

Vesp_Login Initializes the client, gets the client's configuration from the Directory Server as well as authorization information. An object handle is returned that identifies this client to the ORB. This is a synchronous routine.

vesp_set_tracing (optional) Set tracing level for the client. Tracing goes to the logfile.

Vesp_Session_Create Create a session to hold information about the servers. This routine takes the object handle from the Vesp_Login request and returns a session handle. More than one session may be created for a client's object handle.

Page 48: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 5 Client Development

48 IC Client and Server Programmer�s Design Guide

Example of a Client Application The example client application presented on the following pages shows how a client is initialized, messages processed, and callback routines run. This example does an assign, some requests, and a deassign. An electronic version of this file is included with the Toolkit; it can be used to test the Avaya IC installation. Since the purpose of this client is to test the system, some functions are atypical of an Avaya IC client, but it is useful as an example of a simple client.

The following notes correspond to numbered sections in the program example.1 Include ORB.

2 Declare callback routines.

3 Set the tracing level to see requests and responses in the log.

4 Initialize the more complex requests.

5 Login to Avaya IC ORB. This must be done before any calls are made to the ORB that call a server.

Vesp_Assign_Request Associate the client with a server. Anytime a client calls this interface, the server that was selected with this call is sent the request. This allows for some persistence between requests and prevents a multi-step request from going to different servers.

Remember that you may have to wait for the callback.

If the client makes a request to a server with the hybrid invocation when it has not done an Assign, a temporary Assign is done for the client. If it subsequently does an Assign, the temporary Assign is promoted to a permanent assign.

Vesp_poll Vesp_poll is used by the ORB to receive and process incoming events and messages. This routine must be called at least 10 times a second. If this routine is not frequently processed, messages may be lost.

Do Server Methods Invoke a server method with Vesp_Request or Vesp_Request_Sync in �C� or Vesp_Request_DDE_Sync. Vesp_Deassign_Request When done with a server, a client should Deassign from it. This is a one-way request with no parameters.

The Deassign method destroys a session between a client and a server, invalidates the association with the server, and frees all the associated memory.

Vesp_Logout Disconnect from the ORB. Do this only when no further communication is needed with the ORB. All connections to sessions and servers become invalid. Deassign requests are sent to all servers used in any current session.

Page 49: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example of a Client Application

Issue 1.0 June 2002 49

6 Create a session to hold information about the servers to be used.

7 Vesp Poll sends and receives requests, responses, and events in the ORB. It must be called about 10 times a second. Synchronous methods call this routine automatically.

8 Assign to the test server synchronously.

9 Try to assign a second time, causing an error to occur.

10 Call the method Echo synchronously.

11 Call the method Echo2 synchronously.

12 Send an alarm just for fun.

13 Call the method Echo2 synchronously. (Asynchronous routines will run in synchronous routines; events also.)

14 Call the method Echo4 synchronously. (Echo a couple structure.)

15 Call the method Echo3 synchronously. (Echo a couple structure sequence.) Make sure the length is set to zero for the out argument or in a loop, elements are added to the end of the sequence.

16 Call the method Echo5 synchronously. (Echo a sequence of sequences.)

17 Do a Deassign request to terminate the session on the server side.

18 A logout command deletes all sessions and issues Deassign directives to all sessions associated with the login.

19 Echo method callback routine.

20 Check the return result. If the method failed in the ORB, the return result is set to VESP_ERROR. Check the environment for more information.

21 Print the environment to the log file.

22 Echo2 method callback routine.

23 Echo3 method callback routine.

24 Echo4 method callback routine.

25 Event handling routine. This function is associated with a server by the Vesp_Assign_Request function. This routine runs every time an event is generated for this client from the server specifiedin the assign function.

Note: Do not attempt to call a synchronous Telephony method until you've returned from an event handling routine.The method will fail. Queueing of such requests would work around the problem.

Page 50: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 5 Client Development

50 IC Client and Server Programmer�s Design Guide

/********************************************************************* Copyright (c) 1997, 1998, 1999 Quintus Corporation USA* All rights Reserved*********************************************************************** Name: ctest.c Example client** Audit Trail*** @(#)ctest.c 1.20 6/26/97*********************************************************************/#include <orb.h> 12ULONG echo_routine( Identifier interface, ORBStatus status,

Environment *ev, long user_date, Session session,long arg2, long * arg3 );

ULONG echo_routine2( Identifier interface, ORBStatus status,Environment *ev, long user_date, Session session,char * arg2, char * *arg3 );

ULONG echo_routine3( Identifier interface, ORBStatus status,Environment *ev, long user_date, Session session,_IDL_SEQUENCE_Couple * arg2,_IDL_SEQUENCE_Couple * arg3 );

ULONG echo_routine4( Identifier interface, ORBStatus status,Environment *ev, long user_date, Session session,

Couple * arg2, Couple * arg3 );

ULONG echo_routine5( Identifier interface, ORBStatus status,Environment *ev, long user_date, Session session,_IDL_SEQUENCE_sequence_Couple *arg2,_IDL_SEQUENCE_sequence_Couple *arg3 );

ULONG assign_routine( Identifier interface, ORBStatus status,Environment *ev, long user_date, Session session );

ULONG deassign_routine( Identifier interface, ORBStatus status,Environment *ev, long user_date, Session session );

ULONG event_callback( Identifier interface, Object object,Session session, Event * event);

ORBStatus main( void *arg ){Object client_obj;Environment ev;Request request;ULONG memory_blocks;ULONG number_of_transactions;ULONG i,j;

Page 51: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example of a Client Application

Issue 1.0 June 2002 51

Event *event;Session session;

long *output;char *output2;Couple *couple_in;Couple *couple_in2;Couple *couple_out;

_IDL_SEQUENCE_Couple *seq_couple_in;_IDL_SEQUENCE_Couple *seq_couple_out;_IDL_SEQUENCE_Couple *seq_couple_in2;_IDL_SEQUENCE_sequence_Couple *seqseq_couple_in;_IDL_SEQUENCE_sequence_Couple *seqseq_couple_out;

char *string_out;char *error_out;/* must be first thing done *//* do this synchronously */

vesp_set_tracing( VESP_TRACE_IDL| VESP_TRACE_FLUSH ); 3

4couple_in = vesp_couple_create();couple_in2 = vesp_couple_create();couple_out = vesp_couple_create();seq_couple_in = vesp_couple_seq_create();seq_couple_in2 = vesp_couple_seq_create();seq_couple_out = vesp_couple_seq_create();vesp_couple_set_values( couple_in, "name", "value" );vesp_couple_set_values( couple_in2,"name2", "value2" );

/* add a copy of couple_in to seq_couple_in */vesp_couple_seq_add_couple( seq_couple_in, couple_in );

/* add a bunch more to the echo5 method */vesp_couple_seq_add_couple( seq_couple_in2, couple_in );vesp_couple_seq_add_couple( seq_couple_in2, couple_in2 );vesp_couple_seq_add_couple( seq_couple_in2, couple_in );vesp_couple_seq_add_couple( seq_couple_in2, couple_in2 );

/* input sequence for Echo 5 */seqseq_couple_in = vesp_couple_seqseq_create( );vesp_couple_seqseq_add_seq( seqseq_couple_in, seq_couple_in );vesp_couple_seqseq_add_seq( seqseq_couple_in, seq_couple_in2 );vesp_couple_seqseq_add_seq( seqseq_couple_in, seq_couple_in );

/* output for echo 5 */seqseq_couple_out = vesp_couple_seqseq_create( );

SCHECK( Vesp_Login( "vesp", "funfun", &client_obj ) )5SCHECK( Vesp_Session_Create( client_obj, &session ) ) 6SCHECK( Vesp_Request( "TEST.LoseHeap", NULL, 0UL, session ) );SCHECK( Vesp_Request( "TEST.SetTracing", NULL, 0UL,

Page 52: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 5 Client Development

52 IC Client and Server Programmer�s Design Guide

session, VESP_TRACE_DEBUG ) );

for (i=0;;i++){

Vesp_poll( 0UL ); 7

SCHECK( Vesp_Assign_Request( "TEST.Assign", &ev, NULL,0UL, event_callback, session, NULL ) ); 8

/* This is supposed to fail */Vesp_Assign_Request( "TEST.Assign", &ev, NULL, 0UL,

event_callback, session, NULL ); 9

SCHECK( Vesp_Request_Sync( "TEST.Echo", &ev, session,&request, 0x2323UL, &output ) ); 10

if ( ev._major != NO_EXCEPTION){

exit(-1);}

log_unparsable( "Sync output arg2=%lx ", (ULONG)output );SCHECK( Vesp_Request_Delete( session, request ) );

/* make an exception happen */Vesp_Request_Sync( "TEST.Exception", &ev, session, &request );

SCHECK( Vesp_Request_Delete( session, request ) );

SCHECK( Vesp_Request_Sync( "TEST.Echo", &ev, session, &request,0x0UL, &output ) );

if ( ev._major != NO_EXCEPTION){

exit(-1);}

log_unparsable( "Sync output arg2=%lx ", (ULONG)output );SCHECK( Vesp_Request_Delete( session, request ) );

SCHECK( Vesp_Request( "TEST.Echo2", echo_routine2, 1233UL, session,"abcd", &output2 ) ); 11

Vesp_poll( 0UL );

SCHECK( Vesp_Request( "TEST.Echo2", echo_routine2, 1233UL, session,"efgh", &output2 ) );

/* send test to Alarm Server */Vesp_Send_Alarm( client_obj, "CTESTTestEvent", "low",

"This is a Test Event" ); 12

SCHECK( Vesp_Request_Sync( "TEST.Echo2", &ev, session, &request,"ijklm", &output2 ) ); 13

if ( ev._major != NO_EXCEPTION){

exit(-1);}

log_unparsable( "Sync output arg2=%s ", output2 );SCHECK( Vesp_Request_Delete( session, request ) );

Page 53: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example of a Client Application

Issue 1.0 June 2002 53

SCHECK( Vesp_Request_Sync( "TEST.Echo4", &ev, session, &request,couple_in, couple_out ) ); 14

if ( ev._major != NO_EXCEPTION){

exit(-1);}SCHECK( Vesp_Request_Delete( session, request ) );

/* Echo couple sequences */seq_couple_out->_length = 0;SCHECK( Vesp_Request_Sync( "TEST.Echo3", &ev, session, &request,

seq_couple_in, seq_couple_out ) ); 15if ( ev._major != NO_EXCEPTION){

exit(-1);}SCHECK( Vesp_Request_Delete( session, request ) );

/* Echo3 couple sequences */seq_couple_out->_length = 0;SCHECK( Vesp_Request_Sync( "TEST.Echo3", &ev, session, &request,

seq_couple_in, seq_couple_out ) );if ( ev._major != NO_EXCEPTION){

exit(-1);}SCHECK( Vesp_Request_Delete( session, request ) );

/* Echo5 sequence sequence of couples *//* have to reset max output for return */

seqseq_couple_out->_length = 0;SCHECK( Vesp_Request_Sync( "TEST.Echo5", &ev, session, &request,

seqseq_couple_in, seqseq_couple_out ) );if ( ev._major != NO_EXCEPTION){

exit(-1);}

SCHECK( Vesp_Request_Delete( session, request ) );

/* get the memory count from the server */vesp_log_info( VESP_CAT_ALL, "GetMemoryCount", "start");SCHECK( Vesp_Request_Sync( "TEST.GetMemoryCount", &ev, session,

&request, &memory_blocks ) );if ( ev._major != NO_EXCEPTION){

exit(-1);}

SCHECK( Vesp_Request_Delete( session, request ) );vesp_log_info( VESP_CAT_ALL, "GetMemoryCount", "end");

/* get the total transaction count from the server */vesp_log_info( VESP_CAT_ALL, "Echo5", "start");

/* have to reset max output for return */

Page 54: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 5 Client Development

54 IC Client and Server Programmer�s Design Guide

seqseq_couple_out->_length = 0;SCHECK( Vesp_Request_Sync( "TEST.Echo5", &ev, session, &request,

seqseq_couple_in, seqseq_couple_out ) ); 16if ( ev._major != NO_EXCEPTION){

exit(-1);{

SCHECK( Vesp_Request_Delete( session, request ) );vesp_log_info( VESP_CAT_ALL, "Echo5", "end");

/* Get Server status */seq_couple_out->_length = 0;SCHECK( Vesp_Request_Sync( "TEST.GetStatus", &ev, session,

&request, seq_couple_out ) );if ( ev._major != NO_EXCEPTION){

exit(-1);}

SCHECK( Vesp_Request_Delete( session, request ) );

/* Tell the Server to flush its log */SCHECK( Vesp_Request( "TEST.FlushLog", NULL, 0UL, session) );

SCHECK( Vesp_Deassign_Request( "TEST.Deassign", &ev, NULL, 0UL,session ) ); 17

/* SCHECK( Vesp_Request( "TEST.Exit", NULL, 0UL, session ) ); *//*

SCHECK( Vesp_Logout( client_obj ) ); 18*/

}}

ULONG assign_routine( Identifier interface, ORBStatus return_result,Environment *ev, long user_date, Session session )

{if( ev->_major != NO_EXCEPTION )

log_unparsable( "I got an %s Response session=%lx Error=%lxdes=%s ",interface, (ULONG)session, ev->_minor,

ev->vesp_error_description );}return( VESP_SUCCESS );

}ULONG deassign_routine( Identifier interface, ORBStatus return_result,

Environment *ev, long user_date, Session session ){

if( ev->_major != NO_EXCEPTION ){

log_unparsable( "I got an %s Response session=%lx Error=%lxdes=%s ",interface, (ULONG)session, ev->_minor,

ev->vesp_error_description );}SCHECK( Session_delete( session, ev ) );return( VESP_SUCCESS );

Page 55: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example of a Client Application

Issue 1.0 June 2002 55

}ULONG echo_routine( Identifier interface, ORBStatus return_result,

Environment *ev, long user_date, Session session,long arg1, long * arg2 ) 19

{if( ev->_major != NO_EXCEPTION ) 20{

log_unparsable( "I got an %s Response session=%lx Error=%lxdes=%s ",interface, (ULONG)session, ev->_minor,

ev->vesp_error_description ); 21exit(1);

}else{

if( arg1 != *arg2 ){PRINT_ERROR_WHERE( VESP_BAD_PARAMETER );exit(1);

}log_unparsable( "I got an %s Response session=%lx arg1=%lx arg2=%lx",

interface, (ULONG)session, arg1, *arg2);}return( VESP_SUCCESS );

}ULONG echo_routine2( Identifier interface, ORBStatus return_result,

Environment *ev, long user_date, Session session,char * arg1, char **arg2 ) 22

{if( ev->_major != NO_EXCEPTION )

{log_unparsable( "I got an %s Response session=%lx Error=%lx

des=%s "interface, (ULONG)session, ev->_minor,ev->vesp_error_description );

exit(1);}else{

if( strcmp( arg1, *arg2 ) ){PRINT_ERROR_WHERE( VESP_BAD_PARAMETER );exit(1);

}log_unparsable( "I got an %s Response session=%lx arg1=%s arg2=%s",

interface, (ULONG)session, arg1, *arg2);}return( VESP_SUCCESS );

}

ULONG echo_routine3( Identifier interface, ORBStatus return_result,Environment *ev, long user_data,Session session, _IDL_SEQUENCE_Couple * arg1,

_IDL_SEQUENCE_Couple * arg2 ) 23{ULONG i;

Page 56: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 5 Client Development

56 IC Client and Server Programmer�s Design Guide

if( ev->_major != NO_EXCEPTION ){log_unparsable( "I got an %s Response session=%lx Error=%lx des=%s ",

interface, (ULONG)session, ev->_minor,ev->vesp_error_description );

exit(1);}else{

log_unparsable( "I got an %s Response session=%lx arg1=%lx arg2=%lx",interface, (ULONG)session, (ULONG)arg1, (ULONG)arg2);

for ( i= 0; i< arg2->_length; i++ ){

if( (!strcmp( arg1->_buffer[i].name, arg2->_buffer[i].name )) &&(!strcmp( arg1->_buffer[i].value, arg2->_buffer[i].value ) ) )

{PRINT_ERROR_WHERE( VESP_BAD_PARAMETER );exit(1);

}}

}return( VESP_SUCCESS );

}ULONG echo_routine4( Identifier interface, ORBStatus return_result,

Environment *ev, long user_data,Session session, Couple *arg1, Couple *arg2 ) 24

{if( ev->_major != NO_EXCEPTION ){log_unparsable( "I got an %s Response session=%lx Error=%lx des=%s ",

interface, (ULONG)session, ev->_minor,ev->vesp_error_description );

exit(1);}

if( (strcmp( arg1->name, arg2->name )) ||( strcmp( arg1->value, arg2->value)) )

{PRINT_ERROR_WHERE( VESP_BAD_PARAMETER );exit(1);

}return( VESP_SUCCESS );

}

ULONG event_callback( Identifier interface, Object object,Session session, Event * event) 25

{ULONG output;Environment ev;Request request;

log_unparsable( "I got an event" );

Page 57: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example of a Client Application

Issue 1.0 June 2002 57

/* This should fail sync requests are not allowed in async routines */if ( Vesp_Request_Sync( "TEST.Echo", &ev, session, &request,

0x2323UL, &output ) == VESP_SUCCESS ){log_unparsable( "I got a Successful sync request in async routine" );

exit(1);}else{

log_unparsable( "sync request failed as it should" );}return( VESP_SUCCESS );

}

Page 58: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 5 Client Development

58 IC Client and Server Programmer�s Design Guide

Page 59: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

59

CHAPTER 6SERVER DEVELOPMENT

This chapter describes the basic structure of an Avaya IC Server and contains an example of a simple server. An additional server example is provided in �Server Code Example,� on page 117.

Components of a Telephony ServerA server in the Avaya IC environment is a software object capable of providing services to other objects. It generally runs on UNIX, Windows NT / 2000, or a similar multi-processing operating system. In contrast to the common use of the word �server� to refer to a dedicated computer (e.g., file server, database server), an Avaya IC CORBA server is merely one running process. Several Telephony Servers can run simultaneously on a single physical computer, as can multiple instances of a single Telephony Server.

Every Telephony Server reflects the same standard architecture. This architecture is based on the Avaya IC Toolkit compiled into every object (server or client).

Inputs and OutputsA generalized schematic representation of the Avaya IC server architecture is illustrated in the following diagram. Note the main division into the Toolkit layer and the application layer. The Toolkit layer of the server handles all CORBA communications and related functionality. It also controls the sequence of events in the server application layer.

Page 60: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

60 IC Client and Server Programmer�s Design Guide

The application layer contains code specific to a particular server. It processes incoming method requests. These are requests for services from a client or another server. All servers share a basic set of generic methods. When a new server is created, additional methods are generally added. The method invocation may or may not result in the server issuing events to, or invoking methods on, other servers. Except for ONEWAY methods, all methods eventually result in an outgoing response.

Two types of output issue from the server:1 Outgoing responses

These responses are issued to servers that made incoming method requests. Responses may be sent immediately after method requests are received, or they may be deferred and sent at a later time. (See �Deferred Requests,� on page 85 for information on deferring requests.)

2 Outgoing eventsAn event is sent to a client or server that has previously assigned to this server. The event may be triggered by a method request or event from another server, by input from a link to another device (such as a piece of telephony equipment), or by an internally generated signal, such as a periodic timer.

The Poll LoopThe flow of events between input and output is handled by a polling loop built into the server Toolkit layer. This polling loop checks for incoming events, requests, and responses that need to be processed, and for outgoing events, requests, and responses that need to be sent. It properly sequences function calls to the application layer so as to service requests efficiently while avoiding backlogs. For instance, if a number of method requests are pending, and a number of responses are queued to be sent out, the loop alternates between the two to prevent either from backing up.

Server Application Layer

Incoming methods - Outgoing responses- Outgoing events

LAN/WAN

Avaya IC Toolkit Layer

CORBA Interface

Avaya ICServer

Page 61: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Requests on Behalf of Clients

Issue 1.0 June 2002 61

The server programmer has a hook into this polling loop to perform periodic functions. These may include monitoring communications from some non-CORBA link (serial connection, interface to hardware, etc.), performing periodic tasks, and so on.

Requests on Behalf of ClientsServers can make requests on behalf of clients by using the hybrid routines. It is good practice to use the client's security information in these requests; all subsequent calls would share the origin information of the triggering request, which prevents a client from initiating a change that is beyond its security level. To use the client's security information, use the session number as specified in the environment variable.

Servers can make synchronous requests on behalf of clients as long as the requests are not to the server itself, which would be a deadlock.

Coding the Application LayerA server programmer must code the following types of functions in order to create a server:1 Initialization function

This code will include calls to registration functions that associate method names with method functions. This informs the Toolkit which functions to call when methods are invoked. It may include code to assign to another server. It may include code to initialize custom resources, such as a database or a communications link.

2 Method functionsThe method functions have the names that were registered during initialization. The main custom functionality of the server usually goes here. Incoming method requests may cause invocation of methods on other servers, sending of events, and so on.

3 Generic Update functionThis is a special case of a method function. This method is included in the generic set inherited by all servers, and is called by IC Manager when an administrator selects the server and clicks on the �Update Server� button. Although the method exists in the IDL server description by default, code must be added if any meaningful functionality is desired.

4 Event Processing functionThe Toolkit calls a single e vent processing function when the server receives an event. The programmer inserts code to parse the event name and execute appropriate functionality. Thismay or may not include invocation of methods on other servers, sending of events, etc.

Note: Do not attempt to call a synchronous telephony method until you've returned from an event handling routine.The method will fail. Queueing of such requests would work around the problem.

5 Periodic functionsA function is provided for the programmer to insert code into the Toolkit polling loop. Periodic operations, such as monitoring a communications link, flushing a data stream, etc., go here.

Page 62: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

62 IC Client and Server Programmer�s Design Guide

6 Exit/Shut DownThe programmer codes a function that is executed when the server exits normally. This code may include closing a database, logging out of a mainframe connection, or similar cleanup operations.

7 Exception HandlingThe programmer also codes a function to be executed if the server crashes. Usually the same tasks are performed in both the exit and exception cases. This function may or may not be executed depending on the failure mode of the server. In case of a UNIX command line �kill� or an internal segment violation, the function will be executed.

Example ServerThe example server shown on the following pages contains comments describing significant components of an Avaya IC server. Comments of particular importance are highlighted. Refer to �The IDL Compiler,� on page 31 for information about adding a server to the Avaya IC environment.

An electronic version of this server is included with your Toolkit.1 /*2 Copyright (c) 1994-1999 Quintus Corporation USA3 All Rights Reserved

4 Description: test_server is an example server, demonstrating how to do some5 useful things when you're writing a server.

6 Name: test_server.c

7 The Id and Log are specific to Quintus's revision control system.8 $Id: test_server.c,v 1.9 1998/02/13 17:11:16 jonathan Exp $

9 Revision History:10 $Log: test_server.c,v $11 Revision 1.9 1998/02/13 17:11:16 jonathan12 JR: Minor changes in comments for documentation.

13 Revision 1.8 1997/12/15 20:12:04 jonathan14 Comment/cosmetic changes.

15 Revision 1.7 1997/12/04 19:34:19 jonathan16 Comment/cosmetic changes.

17 Revision 1.6 1997/12/03 00:01:52 jonathan18 Removed SetRejectFlag method.19 Various post-review bug fixes.20 Made most alarms become log-file entries.21 Cosmetic and comment changes.

22 Revision 1.5 1997/11/21 17:04:34 jonathan23 Server rewrite, adding more error checking, more comments, and the24 DeferRequest method.

Page 63: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 63

25 */

26 /* orb.h contains declarations for the vesp functions. It also pulls in27 vespidl.h, which contains the machine generated prototypes for this28 server's methods.29 */30 #include <orb.h>

31 /* A note about some of the Hungarian prefix characters used in this example:

32 m Bitmask. This is an integral type used to store a number of33 single-bit flags. In VESP, ORBStatus should be a Bitmask.34 o Object: Any kind of opaque type. In C, a FILE * is an obvious35 example. In VESP, a Session, and a Request are both36 Objects.37 t Type, a structure, union, or typedef'd object. In VESP, an38 Environment is a Type.39 */

40 /* oMyObject_gbl is the object ID of this server. The object ID is passed to41 the server by the ORBServer in argv[1], and we'll assign oMyObject_gbl42 to that value.

43 In this server example, if a variable is named MySomething, it generally44 means that the value is local to the function. The typical use of this is45 for methods where there are two environment variables, tEnv and tMyEnv.46 If we make a request inside that method, we have to use the local47 environment (tMyEnv ) for checking the result of the Vesp_Request. Using48 the client environment (tEnv) to do so would be a mistake.49 */50 static Object oMyObject_gbl = NULL;

51 /* oMySession_gbl is this server's session ID - any requests made by this52 process should carry this session, unless the requests are being made53 on the behalf of a client and need to carry that client's information.54 */55 static Session oMySession_gbl = NULL;

56 /* This structure is used to hold request and session information relevant to57 a request which is deferred in TEST_Assign. */58 struct deferred_assign_info {59 Request oDeferredRequest;60 Session oDeferredSession;61 };

62 /* This is the declaration for a structure that will be used to hold the63 information about the request, the session, and a pointer to the output64 data associated with a deferred request in TEST_DeferRequest.65 */66 struct saved_for_callback {67 Request oRequest;68 Session oSession;69 void *pxUserData;

Page 64: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

64 IC Client and Server Programmer�s Design Guide

70 };

71 /* These are forward declarations for callback functions used in this module.72 In this file, callback functions are placed immediately below the method73 that uses them.74 */75 static ORBStatus76 assign_ping_callback (Identifier, ORBStatus, Environment *,77 unsigned long, Session);

78 static ORBStatus79 defer_request_callback (Identifier, ORBStatus, Environment *, long,80 Session, SeqCouple *);

81 /* ARGSUSED is used to prevent lint from warning against unused function82 arguments for only the function it precedes.83 */

84 /*********************************************************************/85 /* This routine is called before the server is registered with the86 ORBServer. It is called only once, and at server startup.87 */88 /*********************************************************************/89 /*ARGSUSED */90 ORBStatus91 Server_user_init (Object oObject)92 {93 Environment tMyEnv;94 Context oMyCtx;95 SeqCouple *ptConfig;96 int i;

97 /* The function prototypes may look like they're not in scope, but98 they're in idlpk.h, put there by the idl compiler and pulled in by99 orb.h.

100 The SCHECK macro will return to the caller if the result of the101 function call it wraps is anything other than VESP_SUCCESS.102 SCHECK only checks the return value of the function it wraps.103 It does not check the environment.104 */

105 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Assign",106 VESP_SEC_NONE, VESP_SEC_NONE,107 (unsigned long)TEST_Assign));108 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Deassign",109 VESP_SEC_NONE, VESP_SEC_NONE,110 (unsigned long)TEST_Deassign));111 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Echo",112 VESP_SEC_NONE, VESP_SEC_NONE,113 (unsigned long)TEST_Echo));114 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Echo2",115 VESP_SEC_NONE, VESP_SEC_NONE,116 (unsigned long)TEST_Echo2));

Page 65: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 65

117 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Echo3",118 VESP_SEC_NONE, VESP_SEC_NONE,119 (unsigned long)TEST_Echo3));120 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Echo4",121 VESP_SEC_NONE, VESP_SEC_NONE,122 (unsigned long)TEST_Echo4));123 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Echo5",124 VESP_SEC_NONE, VESP_SEC_NONE,125 (unsigned long)TEST_Echo5));126 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "Exception",127 VESP_SEC_NONE, VESP_SEC_NONE,128 (unsigned long)TEST_Exception));129 SCHECK (BOA_set_method (VESP_BOA, &tMyEnv, oObject, "DeferRequest",130 VESP_SEC_NONE, VESP_SEC_NONE,131 (unsigned long)TEST_DeferRequest));

132 /* Here's where we get our configuration information. For this server,133 there is no relevant information. Just for grins, we get it anyway.134 */

135 SCHECK (Vesp_get_default_session (oMyObject_gbl, &oMySession_gbl));136 SCHECK (Session_get_context (oMySession_gbl, &tMyEnv, &oMyCtx));137 SCHECK (Context_get_configuration (oMyCtx, &tMyEnv, &ptConfig));

138 /* Now loop through the configuration information to fish out what we're139 interested in. */140 for (i = 0; i < ptConfig->_length; i++) {141 char *pcName = ptConfig->_buffer[i].name;142 char *pcValue = ptConfig->_buffer[i].value;

143 /* if (!strcmp ("our_expected_value", pcName)) {144 here's where to copy out the configuration value;145 }146 */147 }

148 /* OK, all done with configuration information for now. If you have149 extra processing and checking of parameters, this is a good place to150 do it. */

151 /* Here's where we set the server version...this format is specific to152 the NabCTI build environment. You will probably use a different153 version string. */154 SCHECK (vesp_set_server_version (VERSION));

155 /* Here's where we can set the tracing to be what we want at startup. To156 change the trace level while the server is running, you invoke the157 TEST.SetTracing method, passing in the trace level that you want.158 For example, to change the tracing at runtime to log information about159 all IDL method requests, to flush the log after every message, and to160 turn off USR1 tracing, you would do:

161 Vesp_Request_Sync ("TEST.SetTracing", tMyEnv, tMySession, oRequest,162 VESP_TRACE_IDL_CODING | VESP_TRACE_FLUSH_LOG);163 */

Page 66: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

66 IC Client and Server Programmer�s Design Guide

164 vesp_set_tracing (VESP_TRACE_USR1);165 return VESP_SUCCESS;166 }

167 /*********************************************************************/168 /* This method gets invoked several times a second when the server is running.169 Use this to drive processing other than that which would occur as a result170 of client requests. In this case, we have no other tasks which need to171 be done.172 */173 /*********************************************************************/174 /*ARGSUSED */175 ORBStatus176 Server_user_poll ()177 {178 return VESP_SUCCESS;179 }

180 /*********************************************************************/181 /* Called by the toolkit if the server receives a signal such as abort or182 segv. In this case, there's not much information to put in the logfile.183 */184 /*********************************************************************/185 /*ARGSUSED */186 void187 Server_user_exception ()188 {189 vesp_log_info (VESP_CAT_ALL, "Crash", "Server_user_exception");190 }

191 /*********************************************************************/192 /* Called by the toolkit when the process exits. Again, in this case there's193 not much information that we want to put in the logfile.194 */195 /*********************************************************************/196 /*ARGSUSED */197 void198 Server_user_exit ()199 {200 vesp_log_info (VESP_CAT_ALL, "Exit", "Server_user_exit");201 }

202 /*********************************************************************/203 /* Called by the toolkit when a client who was assigned to us goes away204 unexpectedly. When a client dies, the deassign method is called first,205 then this method is called.206 */207 /*********************************************************************/208 /*ARGSUSED */209 ORBStatus210 Server_client_terminate (Object oObject)211 {212 vesp_log_info (VESP_CAT_ALL, "Problem", "Server_client_terminate");213 return VESP_SUCCESS;

Page 67: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 67

214 }

215 /*********************************************************************/216 /* This routine is called any time the method GetStatus is called, you can217 add your own info on top of the system info.218 */219 /*********************************************************************/220 /*ARGSUSED */221 void222 Server_hook_routine (SeqCouple * ptSeq)223 {224 vesp_couple_seq_add_couple_values (ptSeq, "TEST", "my_status");225 }

226 /*********************************************************************/227 /*228 Here's where the program begins when the ORBServer execs it.229 argv[1] is this server's UUID, argv[2] is the ORBServer's UUID.230 */231 /*********************************************************************/232 int233 main (int argc, char *argv[])234 {235 Environment tMyEnv;236 ORBStatus mMyStatus;237 Object oBoaObject = NULL;

238 /* Initialize the handler routines. This is so the toolkit knows what239 functions to call for various purposes. */240 Server_set_user_init_routine (Server_user_init);241 Server_set_user_poll_routine (Server_user_poll);242 Server_set_user_exception_routine (Server_user_exception);243 Server_set_user_exit_routine (Server_user_exit);244 Server_set_client_terminate_routine (Server_client_terminate);245 Server_set_status_hook_routine (Server_hook_routine);

246 /* When the ORBServer starts TEST, it passes two arguments. The first is247 this server's UUID, the second is the ORBServer's UUID */248 if (argc < 3 || NULL == argv[1] || NULL == argv[2]) {249 /* We have to have both arguments. This should not happen in normal250 use. Maybe someone typed in the executable name at the command251 line. */252 vesp_log_info (VESP_CAT_ALL, "EMERGENCY",253 "Missing arguments at startup");254 return ORB_EXIT_FATAL;255 }256 oMyObject_gbl = ORB_string_to_object (VESP_ORB, &tMyEnv, argv[1]);257 if (tMyEnv._major != NO_EXCEPTION || NULL == oMyObject_gbl) {258 vesp_log_info (VESP_CAT_ALL, "EMERGENCY",259 "ORB_string_to_object failed");260 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);261 return ORB_EXIT_FATAL;262 }263 oBoaObject = ORB_string_to_object (VESP_ORB, &tMyEnv, argv[2]);264 if (tMyEnv._major != NO_EXCEPTION || NULL == oBoaObject) {

Page 68: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

68 IC Client and Server Programmer�s Design Guide

265 vesp_log_info (VESP_CAT_ALL, "EMERGENCY",266 "ORB_string_to_object failed");267 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);268 return ORB_EXIT_FATAL;269 }270 /* This is where this server is registered with the ORB. If the server271 can't log in, there's no point to continuing. */272 mMyStatus = Vesp_Server_Login (oMyObject_gbl, oBoaObject);273 if (mMyStatus != VESP_SUCCESS) {274 vesp_log_info (VESP_CAT_ALL, "EMERGENCY", "Vesp_Server_Login failed");275 log_unparsable ("Status: %s", vesp_find_error (mMyStatus));276 return ORB_EXIT_FATAL;277 }278 /* Loop here and process incoming requests. This is what drives the279 processing, since Vesp_poll drives the toolkit's messaging. */280 for (;;) {281 Vesp_poll (20UL);282 }283 }

284 /*********************************************************************/285 /* This method is used to allow a client to associate itself with this server.286 If an assigned client crashes, the server will be told about it by the287 toolkit. This also allows for a client to receive unsolicited events from288 the server.

289 In this example, we defer responding to the Assign request from the client290 until after we ping the ORBServer. This is to demonstrate what to do in a291 situation where you need to take another action ( such as a DS lookup )292 before you allow a client assign request to complete.293 */294 /*********************************************************************/295 /*ARGSUSED */296 ORBStatus297 TEST_Assign (Object oObject, Environment * ptEnv)298 {299 Environment tMyEnv;300 Event *ptEvent;301 ORBStatus mMyStatus;

302 struct deferred_assign_info *ptAssignInfo;

303 vesp_log_info (VESP_CAT_ALL, "Info", "Entering Assign method");

304 mMyStatus = Vesp_Send_Alarm (oMyObject_gbl, "TEST.TESTAlarm", "low",305 "blabla description");306 if (mMyStatus != VESP_SUCCESS) {307 vesp_log_info (VESP_CAT_ALL, "Problem", "Vesp_Send_Alarm failed");308 log_unparsable ("Status: s", vesp_find_error (mMyStatus));309 }

310 ptEvent = vesp_event_create ("TEST.Vafoo");311 vesp_event_add_couple (ptEvent, "arg1", "value1");312 vesp_event_add_couple (ptEvent, "arg2", "value2");313 vesp_event_add_couple (ptEvent, "arg3", "value3");

Page 69: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 69

314 vesp_event_add_couple (ptEvent, "arg4", "value4");

315 /* This is legal, you can send events before the Assign has succeeded. */316 mMyStatus = Session_send_event (ptEnv->session, &tMyEnv,317 "TEST.Vafoo", ptEvent);

318 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {319 vesp_log_info (VESP_CAT_ALL, "Problem",

"Session_send_event");320 log_unparsable ("Event: %s, Error: %s, Status: %s", ptEvent->name,321 tMyEnv.vesp_error_description,322 vesp_find_error (mMyStatus));

323 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,324 tMyEnv.vesp_error_description);

325 vesp_event_delete (ptEvent);326 return VESP_ASSIGN_FAILURE;327 }328 vesp_event_delete (ptEvent);

329 /* The request and session associated with the request we are deferring330 are copied out. This is because we will need them for comparisons331 after the callback to the method we are invoking is called and before332 we send a response to the client. */333 ptAssignInfo = vesp_calloc (1, sizeof (struct deferred_assign_info));

334 ptAssignInfo->oDeferredRequest = Object_duplicate (ptEnv->request,335 &tMyEnv);336 if (tMyEnv._major != NO_EXCEPTION) {

337 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_duplicate");338 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);

339 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,340 tMyEnv.vesp_error_description);341 vesp_free (ptAssignInfo);342 return VESP_ASSIGN_FAILURE;343 }344 ptAssignInfo->oDeferredSession = Object_duplicate (ptEnv->session,345 &tMyEnv);346 if (tMyEnv._major != NO_EXCEPTION) {347 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_duplicate");348 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);

349 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,350 tMyEnv.vesp_error_description);

351 Object_release (ptAssignInfo->oDeferredRequest, &tMyEnv);352 if (tMyEnv._major != NO_EXCEPTION) {353 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");354 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);355 }356 vesp_free (ptAssignInfo);357 return VESP_ASSIGN_FAILURE;

Page 70: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

70 IC Client and Server Programmer�s Design Guide

358 }359 /* Notice that this request is being made by test_server on behalf of the360 client, since the session information included in the request is the361 client session, not this server's session. This way, you can pass362 along the proper client information, if necessary, to the server you363 are making a request to. */364 mMyStatus = Vesp_Request ("ORBServer.Ping", assign_ping_callback,365 (unsigned long) ptAssignInfo, ptEnv->session);

366 if (mMyStatus != VESP_SUCCESS) {367 vesp_log_info (VESP_CAT_ALL, "Problem", "Vesp_Request");368 log_unparsable ("Status: %s", vesp_find_error (mMyStatus));

369 vesp_set_exception (ptEnv, SYSTEM_EXCEPTION, VESP_FAILURE,370 "assign method request failed");

371 Object_release (ptAssignInfo->oDeferredRequest, &tMyEnv);372 if (tMyEnv._major != NO_EXCEPTION) {373 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");374 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);375 }376 Object_release (ptAssignInfo->oDeferredSession, &tMyEnv);377 if (tMyEnv._major != NO_EXCEPTION) {378 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");379 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);380 }381 vesp_free (ptAssignInfo);382 return VESP_ASSIGN_FAILURE;383 }384 /* Now we can defer the response to the client until after we ping the385 ORBServer. */386 mMyStatus = Request_defer (ptEnv->request, &tMyEnv);387 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {388 vesp_log_info (VESP_CAT_ALL, "Problem", "Request_defer");389 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,390 vesp_find_error (mMyStatus));

391 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,392 tMyEnv.vesp_error_description);393 /* Notice that we don't free the assign callback info. The request394 went off OK, so our callback will be hit. If we free the callback395 struct now, we'll have a problem in the callback when we look for396 the request. */397 return VESP_ASSIGN_FAILURE;398 }399 return VESP_SUCCESS;400 }

401 /*********************************************************************/402 /* This is the callback for a method invocation that was made inside403 TEST_Assign. It will be called when we receive a response to the404 ORBServer.Ping request or when the request times out and the toolkit405 calls this function.406 */407 /*********************************************************************/

Page 71: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 71

408 /*ARGSUSED */409 static ORBStatus410 assign_ping_callback (Identifier tInterface, ORBStatus mStatus,411 Environment * ptEnv, unsigned long ulUserData,412 Session oSession)413 {414 any tReturnResult;415 Environment tMyEnv;416 ORBStatus mMyStatus;417 ORBStatus mTmpStatus;

418 Environment *ptRequestEnv;419 Event *ptEvent;

420 struct deferred_assign_info *ptAssignInfo = NULL;

421 /* Make the user data look like a pointer again. */422 ptAssignInfo = (struct deferred_assign_info *) ulUserData;

423 /* For this example, we will be blindly passing along the result of the424 method request to the client. Start by fishing out the request and425 session that were duplicated. */

426 mMyStatus = Request_get_ev (ptAssignInfo->oDeferredRequest, &tMyEnv,427 &ptRequestEnv);428 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {429 * This could be a problem at the server, or the Request_defer failed430 and there's no request deferred. */431 vesp_log_info (VESP_CAT_ALL, "Problem", "Request_get_ev");432 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,433 vesp_find_error (mMyStatus));

434 Object_release (ptAssignInfo->oDeferredRequest, &tMyEnv);435 if (tMyEnv._major != NO_EXCEPTION) {436 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");437 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);438 }439 Object_release (ptAssignInfo->oDeferredSession, &tMyEnv);440 if (tMyEnv._major != NO_EXCEPTION) {441 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");442 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);443 }444 vesp_free (ptAssignInfo);445 return VESP_SUCCESS;/* This goes to the toolkit, not the client. */446 }447 /* The client could have crashed or deassigned before this callback was448 called. Check that there's a session to send a response to. */449 mMyStatus = Session_exist (ptAssignInfo->oDeferredSession, &tMyEnv);450 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {451 vesp_log_info (VESP_CAT_ALL, "Problem", "Session_exist");452 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,453 vesp_find_error (mMyStatus));

454 Object_release (ptAssignInfo->oDeferredRequest, &tMyEnv);455 if (tMyEnv._major != NO_EXCEPTION) {

Page 72: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

72 IC Client and Server Programmer�s Design Guide

456 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");457 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);458 }459 Object_release (ptAssignInfo->oDeferredSession, &tMyEnv);460 if (tMyEnv._major != NO_EXCEPTION) {461 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");462 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);463 }464 vesp_free (ptAssignInfo);465 return VESP_SUCCESS;466 }467 /* OK, so there's a request and session to send the response to. The468 type of the return result has to match the type of the original method469 invoked as described in the IDL file. */470 tReturnResult._type = "ORBStatus";

471 /* Now check the environment that we were passed. If there's an472 exception set, we can't use the CORBA output parameters. */

473 if (NO_EXCEPTION == ptEnv->_major) {474 /* Everything looks OK, send back the results we were called with. */475 tReturnResult._value = &mStatus;476 } else {477 vesp_set_exception (ptRequestEnv, ptEnv->_major, ptEnv->_minor,478 ptEnv->vesp_error_description);

479 /* Here's where we use mTmpStatus - since we can't use the output480 value, we have to have a local variable to set. */481 mTmpStatus = VESP_ASSIGN_FAILURE;482 tReturnResult._value = &mTmpStatus;483 }

484 /* Now send the deferred response. */

485 mMyStatus = Request_send_deferred_response (ptAssignInfo->oDeferredRequest,486 &tMyEnv, &tReturnResult);487 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {488 vesp_log_info (VESP_CAT_ALL, "Problem",489 "Request_send_deferred_response");490 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,491 vesp_find_error (mMyStatus));492 }493 /* We're done with these now... */494 Object_release (ptAssignInfo->oDeferredRequest, &tMyEnv);495 if (tMyEnv._major != NO_EXCEPTION) {496 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");497 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);498 }499 Object_release (ptAssignInfo->oDeferredSession, &tMyEnv);500 if (tMyEnv._major != NO_EXCEPTION) {501 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");502 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);503 }504 vesp_free (ptAssignInfo);

Page 73: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 73

505 /* Just for fun, send an event. It should be received by the client506 _after_ the assign response. */507 ptEvent = vesp_event_create ("TEST.Vabar");508 vesp_event_add_couple (ptEvent, "Arg1", "Value1");509 vesp_event_add_couple (ptEvent, "Arg2", "Value2");510 vesp_event_add_couple (ptEvent, "Arg3", "Value3");511 vesp_event_add_couple (ptEvent, "Arg4", "Value4");

512 mMyStatus = Session_send_event (oSession, &tMyEnv, "TEST.Vabar", ptEvent);513 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {514 vesp_log_info (VESP_CAT_ALL, "Problem", "Session_send_event");515 log_unparsable ("Event: %s, Error: %s, Status: %s", ptEvent->name,516 tMyEnv.vesp_error_description,517 vesp_find_error (mMyStatus));518 }519 vesp_event_delete (ptEvent);520 return VESP_SUCCESS;521 }

522 /*********************************************************************/523 /* This is the method called when a client invokes the deassign method. This524 is also invoked whenever a client terminates abruptly. */525 /*********************************************************************/526 /*ARGSUSED */527 ORBStatus528 TEST_Deassign (Object oObject, Environment * ptEnv)529 {530 Event *ptEvent;531 Environment tMyEnv;532 ORBStatus mMyStatus;

533 /* Use vesp_get_trace_level to find out which level server tracing is set534 to before writing information to the logfile. */535 if ((vesp_get_trace_level () & VESP_TRACE_USR1)) {536 vesp_log_info (VESP_CAT_ALL, "Deassign", "TEST_Deassign");537 }538 ptEvent = vesp_event_create ("TEST.Vabaz");539 vesp_event_add_couple (ptEvent, "ARG1", "VALUE1");540 vesp_event_add_couple (ptEvent, "ARG2", "VALUE2");

541 mMyStatus = Session_send_event (ptEnv->session, &tMyEnv, ptEvent->name,542 ptEvent);543 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {544 vesp_log_info (VESP_CAT_ALL, "Problem", "Session_send_event");545 log_unparsable ("Event: %s, Error: %s, Status: %s", ptEvent->name,546 tMyEnv.vesp_error_description,547 vesp_find_error (mMyStatus));548 }549 vesp_event_delete (ptEvent);550 return VESP_SUCCESS;551 }

552 /*********************************************************************/553 /* This method just echoes the input parameter back the to client using the554 output parameter. Notice that the output parameter is the address of an

Page 74: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

74 IC Client and Server Programmer�s Design Guide

555 unsigned long, rather than the unsigned long itself. */556 /*********************************************************************/557 /*ARGSUSED */558 ORBStatus559 TEST_Echo (Object oObject, Environment * ptEnv, unsigned long ulArg1,560 unsigned long *pulArg2)561 {562 *pulArg2 = ulArg1;

563 if ((vesp_get_trace_level () & VESP_TRACE_USR1)) {564 log_unparsable ("vesp_general_echo: arg1=%#x arg2=%#x \n",565 ulArg1, *pulArg2);566 }567 return VESP_SUCCESS;568 }569 /*********************************************************************/570 /* This method echoes an input string to an output string. */571 /*********************************************************************/572 /*ARGSUSED */573 ORBStatus574 TEST_Echo2 (Object oObject, Environment * ptEnv, char *pcArg1, char **ppcArg2)575 {

576 /* Allocate enough space to hold the string we're going to echo. Notice577 that while we create the space to hold an output argument, we were578 given a pointer to where to put it. The toolkit will free this memory579 for us, so we don't have to free it ourselves. */580 *ppcArg2 = (char *) vesp_calloc (1, strlen (pcArg1) + 1);581 strcpy (*ppcArg2, pcArg1);

582 if ((vesp_get_trace_level () & VESP_TRACE_USR1)) {583 log_unparsable ("vesp_general_echo2: arg1=%s arg2=%s", pcArg1,584 *ppcArg2);585 }586 return VESP_SUCCESS;587 }

588 /*********************************************************************/589 /* This method echoes an input sequence of couples onto an output sequence590 of couples.591 */592 /*********************************************************************/593 /*ARGSUSED */594 ORBStatus595 TEST_Echo3 (Object oObject, Environment * ptEnv, SeqCouple * ptArg1,596 SeqCouple * ptArg2)597 {598 int i;

599 for (i = 0; i < ptArg1->_length; i++) {600 vesp_couple_seq_add_couple_values (ptArg2, ptArg1->_buffer[i].name,601 ptArg1->_buffer[i].value);602 }

603 if ((vesp_get_trace_level () & VESP_TRACE_USR1)) {

Page 75: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 75

604 log_unparsable ("vesp_general_echo3:");605 vesp_print_any ("SeqCouple", ptArg1);606 vesp_print_any ("SeqCouple", ptArg2);607 }608 return VESP_SUCCESS;609 }

610 /*********************************************************************/611 /* This method echoes an input couple to an output couple. */612 /*********************************************************************/613 /*ARGSUSED */614 ORBStatus615 TEST_Echo4 (Object oObject, Environment * ptEnv, Couple * ptArg1,616 Couple * ptArg2)617 {618 ptArg2->name = vesp_strdup (ptArg1->name);619 ptArg2->value = vesp_strdup (ptArg1->value);

620 if ((vesp_get_trace_level () & VESP_TRACE_USR1)) {621 log_unparsable ("vesp_general_echo4:");622 vesp_print_any ("Couple", ptArg1);623 vesp_print_any ("Couple", ptArg2);624 }625 return VESP_SUCCESS;626 }

627 /*********************************************************************/628 /* This method echoes an input sequence of sequences of couples to an output629 sequence of sequences of couples. */630 /*********************************************************************/631 /*ARGSUSED */632 ORBStatus633 TEST_Echo5 (Object oObject, Environment * ptEnv,634 SeqSeqCouple * ptArg1, SeqSeqCouple * ptArg2)635 {636 int i, j;637 SeqCouple *ptTmpSeq;

638 /* This part demonstrates looping through sequences of couples, copying639 the contents of the first to the second. This could also be640 accomplished by using the vesp_couple_seqseq_duplicate toolkit641 function. For this example, however, we'll do it the hard way. */

642 /* Loop through each sequence. */643 for (i = 0; i < ptArg1->_length; i++) {

644 /* This is a check that we're not exceeding the maximum size that was645 set by the calling routine when the output SeqCouple was created. */646 if ((ptArg2->_length >= ptArg2->_maximum) &&647 (ptArg2->_maximum != 0UL)) {648 return VESP_SUCCESS;649 }650 /* Create a temporary sequence of couples. */651 ptTmpSeq = vesp_couple_seq_create ();

Page 76: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

76 IC Client and Server Programmer�s Design Guide

652 /* Loop through each entry in each record and fill in the temporary653 sequence of couples. */654 for (j = 0; j < ptArg1->_buffer[i]._length; j++) {655 vesp_couple_seq_add_couple_values (ptTmpSeq,656 ptArg1->_buffer[i]._buffer[j].name,657 ptArg1->_buffer[i]._buffer[j].value);658 }659 /* Copy contents of the temporary sequence to the output sequence. */660 vesp_couple_seqseq_add_seq (ptArg2, ptTmpSeq);661 /* Free up the temp sequence. */662 vesp_couple_seq_delete (ptTmpSeq);663 }

664 if ((vesp_get_trace_level () & VESP_TRACE_USR1)) {665 log_unparsable ("vesp_general_echo3:");666 /* Notice that the type here is SeqSeqCouple and not SeqCouple. It's667 important that you tell vesp_print_any exactly which data type you668 expect it to print out. */669 vesp_print_any ("SeqSeqCouple", ptArg1);670 vesp_print_any ("SeqSeqCouple", ptArg2);671 }672 return VESP_SUCCESS;673 }

674 /*********************************************************************/675 /* This method will always return an exception to the client */676 /*********************************************************************/677 /*ARGSUSED */678 ORBStatus679 TEST_Exception (Object oObject, Environment * ptEnv)680 {681 vesp_set_exception (ptEnv, USER_EXCEPTION, VESP_FAILURE,682 "my test exception");683 return VESP_SUCCESS;684 }

685 /*********************************************************************/686 /* This method demonstrates deferring the response to a client while the687 server asynchronously makes a request to another server.

688 The client invoking this request expects output data. We will be making an689 Alarm.GetStatus request and passing a copy of the returned sequence of690 couples back to the client.

691 This method returns void instead of ORBStatus. For an example that returns692 ORBStatus, see TEST_Assign.693 */694 /*********************************************************************/695 /*ARGSUSED */696 void697 TEST_DeferRequest (Object tObj, Environment * ptEnv, SeqCouple * ptOutputData)698 {699 Environment tMyEnv;700 ORBStatus mMyStatus;

Page 77: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 77

701 struct saved_for_callback *ptSaveInfo;

702 /* This has to be static for the callback to work. It will only be703 filled in and meaningful in the callback to this function, so it704 doesn't matter that it will be overwritten by subsequent function705 calls. */706 static SeqCouple tSeqCouple;

707 /* Initialize the structure to NULL - the information in this struct will708 be sent to the server that you are making a request of, so you're709 better off knowing what you are sending */710 tSeqCouple._length = 0;711 tSeqCouple._maximum = 0;712 tSeqCouple._buffer = NULL;

713 /* Allocate space for saving the request, the session, and the output714 data to be used by the callback function to send the deferred715 response. */716 ptSaveInfo = vesp_calloc (1, sizeof (struct saved_for_callback));

717 /* Save the request - we use it in the callback to retrieve the client718 environment. */719 ptSaveInfo->oRequest = Object_duplicate (ptEnv->request, &tMyEnv);

720 if (tMyEnv._major != NO_EXCEPTION) {721 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_duplicate");722 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);

723 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,724 tMyEnv.vesp_error_description);725 vesp_free (ptSaveInfo);726 return;727 }728 /* Save the session - we use it in the callback to check that the client729 still exists. */730 ptSaveInfo->oSession = Object_duplicate (ptEnv->session, &tMyEnv);731 if (tMyEnv._major != NO_EXCEPTION) {732 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_duplicate");733 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);

734 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,735 tMyEnv.vesp_error_description);

736 Object_release (ptSaveInfo->oRequest, &tMyEnv);737 if (tMyEnv._major != NO_EXCEPTION) {738 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");739 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);740 }741 vesp_free (ptSaveInfo);742 return;743 }744 /* Save the output data pointer passed to the function with the745 duplicated session and request objects. This will be used in the746 callback. */747 ptSaveInfo->pxUserData = (void *) ptOutputData;

Page 78: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

78 IC Client and Server Programmer�s Design Guide

748 mMyStatus = Vesp_Request ("Alarm.GetStatus", defer_request_callback,749 (unsigned long) ptSaveInfo, oMySession_gbl,750 &tSeqCouple);

751 if (mMyStatus != VESP_SUCCESS) {752 /* Return an error to the client immediately if there's a problem753 with the request. */754 vesp_log_info (VESP_CAT_ALL, "Problem", "Vesp_Request");755 log_unparsable ("Status: %s", vesp_find_error (mMyStatus));

756 vesp_set_exception (ptEnv, SYSTEM_EXCEPTION, VESP_FAILURE,757 "defer_request method request failed");758 vesp_free (ptSaveInfo);759 return;760 }761 /* Now defer the request - after this is successfully called, no762 response will be sent to the client until we send one. Normally, a763 response would be sent to the client when this function returns. */764 mMyStatus = Request_defer (ptEnv->request, &tMyEnv);765 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {766 /* We were unable to defer the request for some reason. */767 vesp_log_info (VESP_CAT_ALL, "Problem", "Request_defer");768 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,769 vesp_find_error (mMyStatus));

770 /* Clean up of our duplicated objects will happen in the callback. We771 could release them here if we wanted to, then in the callback we'd772 have to check that the saved objects were non-null.

773 Since the Request_defer failed, the response will be sent to the774 client when this function returns. However, the callback will still775 be invoked when the request we made in this function returns a776 response.

777 We'll end up with a situation where there will be no778 outstanding request associated with our stored request object. We779 use Request_get_ev to detect this situation when it retrieves the780 original request environment. */781 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,782 tMyEnv.vesp_error_description);783 }784 /* If we get to this point, we should be good to go - the session, the785 request, and the output data pointer are saved, and the original786 request has been deferred. */787 }

788 /*********************************************************************/789 /* Send the results of the deferred request to the client. In this case,790 we pass along the result returned by the toolkit, but that's not791 necessary - you can send the client any status you want to.792 */793 /*********************************************************************/794 /*ARGSUSED */795 static ORBStatus

Page 79: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Example Server

Issue 1.0 June 2002 79

796 defer_request_callback (Identifier tInterface, ORBStatus mStatus,797 Environment * ptEnv, long lUserData,798 Session oSession, SeqCouple * ptOutputData)799 {800 Environment tMyEnv;

801 struct saved_for_callback *ptSavedInfo;

802 ORBStatus mMyStatus;

803 int i;

804 any tReturnToClient;805 Environment *ptRequestEnv;806 SeqCouple *ptRequestData;

807 /* Make the user data look like a pointer again. */808 ptSavedInfo = (struct saved_for_callback *) lUserData;

809 /* Get the client environment first - this is mostly to check that our810 request is still valid. If you're working with a toolkit older than811 3.5.9 you have to add the following line before making the812 Request_get_ev function call.

813 tMyEnv._major = NO_EXCEPTION;

814 This is because of a toolkit bug that was not properly initializing815 the environment before doing its stuff. */816 mMyStatus = Request_get_ev (ptSavedInfo->oRequest, &tMyEnv,817 &ptRequestEnv);

818 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {819 vesp_log_info (VESP_CAT_ALL, "Problem", "Request_get_ev");820 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,821 vesp_find_error (mMyStatus));

822 Object_release (ptSavedInfo->oRequest, &tMyEnv);823 if (tMyEnv._major != NO_EXCEPTION) {824 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");825 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);826 }827 Object_release (ptSavedInfo->oSession, &tMyEnv);828 if (tMyEnv._major != NO_EXCEPTION) {829 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");830 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);831 }832 vesp_free (ptSavedInfo);

833 /* No request, can't send anything to client. Any return from inside834 this function goes to the toolkit, not the client. */835 return VESP_SUCCESS;836 }837 /* Check that the client session still exists before sending a response.838 Bad things will happen if you try to send a response using a client839 session that's already been cleaned up by the toolkit. */

Page 80: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

80 IC Client and Server Programmer�s Design Guide

840 mMyStatus = Session_exist (ptSavedInfo->oSession, &tMyEnv);841 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {842 vesp_log_info (VESP_CAT_ALL, "Problem", "Session_exist");843 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,844 vesp_find_error (mMyStatus));

845 Object_release (ptSavedInfo->oRequest, &tMyEnv);846 if (tMyEnv._major != NO_EXCEPTION) {847 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");848 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);849 }850 Object_release (ptSavedInfo->oSession, &tMyEnv);851 if (tMyEnv._major != NO_EXCEPTION) {852 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");853 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);854 }855 vesp_free (ptSavedInfo);856 return VESP_SUCCESS;857 }858 /* OK - so we have a valid environment and a valid client session let's859 send the response. Here's where the result of the request comes into860 play - if the environment has an exception set, we can't use any of861 the output values, but our user data is unmodified.

862 Notice that we're sending a response to a method that returns863 something other than ORBStatus, so the values that we're assigning to864 tReturnToClient._type and tReturnToClient._value change accordingly.865 */

866 tReturnToClient._type = "void";867 tReturnToClient._value = NULL;

868 /* The important thing is that the toolkit checks the type you are trying869 to return against the return type that is expected in the original870 request, so they have to match. */

871 if (NO_EXCEPTION == ptEnv->_major) {

872 /* Fill in the output data using the pointer we saved from earlier. */873 ptRequestData = (SeqCouple *) ptSavedInfo->pxUserData;

874 for (i = 0; i < ptOutputData->_length; i++) {875 char *pcName = ptOutputData->_buffer[i].name;876 char *pcValue = ptOutputData->_buffer[i].value;

877 vesp_couple_seq_add_couple_values (ptRequestData, pcName, pcValue);878 }

879 } else {880 vesp_set_exception (ptRequestEnv, ptEnv->_major, ptEnv->_minor,881 ptEnv->vesp_error_description);882 }

883 mMyStatus = Request_send_deferred_response (ptSavedInfo->oRequest,884 &tMyEnv,

Page 81: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Servicing Requests

Issue 1.0 June 2002 81

885 &tReturnToClient);

886 /* There's not much we can do if this fails. */887 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {888 vesp_log_info (VESP_CAT_ALL, "Problem",889 "Request_send_deferred_response");890 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,891 vesp_find_error (mMyStatus));892 }893 /* We're done with these now. */894 Object_release (ptSavedInfo->oRequest, &tMyEnv);895 if (tMyEnv._major != NO_EXCEPTION) {896 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");897 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);898 }899 Object_release (ptSavedInfo->oSession, &tMyEnv);900 if (tMyEnv._major != NO_EXCEPTION) {901 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");902 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);903 }904 vesp_free (ptSavedInfo);

905 /* Thank you, drive through. */906 return VESP_SUCCESS;907 }

Servicing RequestsMethod invocation from the point of view of the invoking client or server is discussed in detail in �The Hybrid Interface,� on page 33. This section demonstrates a method invocation from the point of view of the server invoked.

The Toolkit function (BOA_set_method) must be called to register the name of the function that runs when a particular method is invoked.

Method FunctionsMethod functions are called automatically by the Toolkit when a method is invoked from a client application. The general form of a method function is:

ORBStatusServer_Method (Object object, /* Global object for this server */Environment *env, /* Environment structure */arg1, /* Input arguments to the method... */arg2,arg3,arg4,...);{...}

Page 82: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

82 IC Client and Server Programmer�s Design Guide

The function name is arbitrary, but by convention is composed of the server name, an underscore, and the method name.

Source Code Sample 1 shows the method function for the Dummy Server Reverse method:

Source Code Sample 1: Method functionORBStatus Dummy_Reverse(Object object,Environment *env,char *in_string,char **out_string){char *iptr, *optr;

/* Check for bad input argument, return an exception */if (in_string == NULL || strlen (in_string) == 0){vesp_set_exception (env, USER_EXCEPTION,VESP_BAD_PARAMETER,"Bad Parameter passed to Dummy.Reverse");return (VESP_BAD_PARAMETER);}/* Allocate space for the output */*out_string = vesp_malloc (strlen (in_string) + 1);

/* Generate the reverse string, store in output */iptr = in_string + (strlen (in_string) - 1);optr = *out_string;while (iptr >= in_string) {*optr++ = *iptr--;*optr = ’\0’; /* Terminate the new string */

return VESP_SUCCESS}

Argument Purpose

env Pointer to an Environment structure. It should be filled in with any exception information or error conditions encountered while executing the method. This data structure will be passed to the calling client and replicated in the local client environment for error processing. If an error occurs in the Toolkit layer that prevents successful method invocation and response, the Toolkit will use this structure to report that error. The definition of the Environment type is in idlpk.h and is described in �The Environment Variable,� on page 19. The structure can be modified directly, or by calling vesp_set_exception.

arg1... The arguments for the method, as defined in the IDL specification. These are the arguments that the calling client used in its local call to Vesp_Request or Vesp_Request_Sync. Output arguments should be filled in by the method for return to the client.

Page 83: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Callback Functions

Issue 1.0 June 2002 83

Memory Allocation for Output ParametersRules for memory allocation of output data parameters are, as expected, based on those for the calling party.

Type: longunsigned long

These types are allocated by the Toolkit on behalf of the calling client and passed by pointer to the method function. The method merely fills in the values. Memory is freed by the Toolkit.

Type: string

A pointer is allocated by the Toolkit on behalf of the calling client, and its address (char **) is passed to the method function. The method must use vesp_malloc, vesp_strdup or a similar function to allocate memory (see example in Source Code Sample 1). Memory for the string and the pointer are both freed by the Toolkit.

Type: sequence

The sequence structure is allocated by the Toolkit on behalf of the calling client, and the _maximum is filled in with the value the client specified. A pointer to the sequence is passed to the method function. The method must allocate space for members added to the sequence, usually using Avaya IC convenience routines like vesp_couple_seq_add_couple_values, etc. (see the Core Services Programmer�s Guide for details). Memory for all added members of the sequence, and for the sequence structure itself, is freed by the Toolkit.

Type: structure

The data structure is allocated by the Toolkit on behalf of the calling client. A pointer to the structure is passed to the method function. The method must allocate space for members added to the structure, using vesp_malloc, etc. Memory for all added members of the structure and for the structure itself is freed by the Toolkit.

Callback FunctionsWhen a server makes an asynchronous call to another server, any work depending on the results of that call must be performed in the callback function. The following example illustrates a schematic diagram of two servers. Each set of large curly braces {} inside a server represents a functional block of source code, labeled with the name of the function (or the general type of function).

Page 84: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

84 IC Client and Server Programmer�s Design Guide

The following diagram illustrates Asynchronous System Dynamics.

The flow depicted in this example is as follows:1 Server1 receives an external event from some object in the system.

2 The event handling code in Server1 processes the event. This involves completing some task that requires the help of Server2. Server1 calls Vesp_Request to invoke a method (Sever2.MethodA) asynchronously on Server2.

3 Server2 sends a response (Server2.MethodA.response) to Server1. The Server1 Toolkit layer automatically invokes the callback function specified in the argument list to Vesp_Request (Server2_MethodA_callback). The callback function continues processing the initial event. (Note that no response is returned to the sender of an event.)

Through the use of this asynchronous mechanism, Server1 first services the event in the event handler code and then in the callback function. When a task requires calling methods on other servers, much or even most of the work of the calling server is generally completed in one or more callback functions. This allows many separate tasks to be performed simultaneously on behalf of many different entities or events, without the presence of a true threading environment.

If another event is received by Server1 while Server2 is processing MethodA, Server1 will process the event immediately. Server1 may send several requests to Server2 before any responses are received. The asynchronous mechanism in the hybrid interface automatically matches each response to the correct request regardless of timing or sequence of responses.

Server1

...Vesp_Request (

"Server2.MethodA",Server2_MethodA_callback,(ULONG)0, session,input, ..., output, ...);

...

(Event Handler Function)

[Process output from Server2,take appropriate action onbehalf of the initial event]

(Server2_MethodA_callback)

Server2

[Process input...][Create output...]return VESP_SUCCESS;

(Server2_MethodA)

(1) (2)

(3)

END

START(External Event)

Page 85: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Callback Functions

Issue 1.0 June 2002 85

Passing Data to the Callback Function: user_dataThe callback function argument list contains the arguments passed to Vesp_Request, plus a filled-in environment structure and a return result. The input arguments for the specific method appear exactly as they did in the call to Vesp_Request, and the output arguments are filled in with data returned by the invoked server.

This argument list may or may not contain the data necessary to continue processing. If a variable available to the calling function is not in the argument list for the invoked method, that variable will not be passed automatically to the callback function.

For example, the EDUID of a call is needed to route a phone call. This is usually the final step in responding to an incoming call event. It is often preceded by one or more asynchronous calls to various servers. If the last asynchronous method invocation in the flow does not include EDUID in its argument list, the EDUID is not available to the final callback function where the route should occur. This illustrates the need for a facility for passing data from the calling function to the callback function.

The user_data parameter in the argument list to Vesp_Request provides a means of passing arbitrary data to the callback function. This unsigned long is held by the Toolkit layer until the response is received, at which time it is added to the callback function argument list. A pointer to any desired data element or structure can be cast as an unsigned long and passed to Vesp_Request as user_data. The user_data parameter in the callback function argument list can then be recast to the original type.

Deferred RequestsWhen a server receives a method request, the registered function is run automatically by the Toolkit (see �Servicing Requests,� on page 81). At the conclusion of this function, a response is automatically returned to the calling client.

If an asynchronous call to a second server is required to service the method request, the response to the client would generally be returned before the response from the second server is received. The data received from the second server and the subsequent processing in the callback function cannot contribute to the client response. This demonstrates the need for a mechanism to defer the response until a later time.

The Telephony hybrid interface includes a function for deferring a response: Request_defer. The prototype of this function is:

ORBStatus Request_defer (Request request, Environment *ev);

The request object is available from the environment structure in the argument list of the function servicing the method. Before calling Request_defer, the server must save a copy of the request and a copy of the session associated with the client making the request, as demonstrated in lines 719 through 743 in the example in �Deferred Request Example: Source Code,� on page 86. This prevents memory conflicts later if an error causes the initial Request object to be deleted before the deferred response is sent. The environment structure itself is also passed to Request_defer.

Page 86: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

86 IC Client and Server Programmer�s Design Guide

When Request_defer is called, the response to the method will not be sent to the client when the function ends. The server is free to make asynchronous requests on behalf of the client. Note that a callback structure is necessary in this case. It provides a way for callback functions to access the Request object, the session object, and any output parameters. These will be used when the deferred response is sent.

One or more levels of callback function later, when the server is ready to return a response to the client, the deferred response is sent by calling Request_send_deferred_response. Before attempting to send the response it must check that the request is still valid (using Request_get_ev), and check that the client session still exists. This is demonstrated in lines 816 through 857 in the example in �Deferred Request Example: Source Code,� on page 86.

Deferred Request Example: Source CodeThe following code fragments from the example server demonstrate use of a deferred request.

. . .62 /* This is the declaration for a structure that will be used to hold the63 information about the request, the session, and a pointer to the output64 data associated with a deferred request in TEST_DeferRequest.65 */66 struct saved_for_callback {67 Request oRequest;68 Session oSession;69 void *pxUserData;70 };

. . .78 static ORBStatus79 defer_request_callback (Identifier, ORBStatus, Environment *, long,80 Session, SeqCouple *);. . .

685 /******************************************************************/686 /* This method demonstrates deferring the response to a client while the687 server asynchronously makes a request to another server.

688 The client invoking this request expects output data. We will be making an689 Alarm.GetStatus request and passing a copy of the returned sequence of690 couples back to the client.

691 This method returns void instead of ORBStatus. For an example that returns692 ORBStatus, see TEST_Assign.693 */694 /*********************************************************************/695 /*ARGSUSED */696 void697 TEST_DeferRequest (Object tObj, Environment * ptEnv, SeqCouple * ptOutputData)698 {699 Environment tMyEnv;700 ORBStatus mMyStatus;

701 struct saved_for_callback *ptSaveInfo;

702 /* This has to be static for the callback to work. It will only be703 filled in and meaningful in the callback to this function, so it

Page 87: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Callback Functions

Issue 1.0 June 2002 87

704 doesn't matter that it will be overwritten by subsequent function705 calls. */706 static SeqCouple tSeqCouple;

707 /* Initialize the structure to NULL - the information in this struct will708 be sent to the server that you are making a request of, so you're709 better off knowing what you are sending */710 tSeqCouple._length = 0;711 tSeqCouple._maximum = 0;712 tSeqCouple._buffer = NULL;

713 /* Allocate space for saving the request, the session, and the output714 data to be used by the callback function to send the deferred715 response. */716 ptSaveInfo = vesp_calloc (1, sizeof (struct saved_for_callback));

717 /* Save the request - we use it in the callback to retrieve the client718 environment. */719 ptSaveInfo->oRequest = Object_duplicate (ptEnv->request, &tMyEnv);

720 if (tMyEnv._major != NO_EXCEPTION) {721 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_duplicate");722 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);

723 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,724 tMyEnv.vesp_error_description);725 vesp_free (ptSaveInfo);726 return;727 }728 /* Save the session - we use it in the callback to check that the client729 still exists. */730 ptSaveInfo->oSession = Object_duplicate (ptEnv->session, &tMyEnv);731 if (tMyEnv._major != NO_EXCEPTION) {732 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_duplicate");733 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);

734 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,735 tMyEnv.vesp_error_description);

736 Object_release (ptSaveInfo->oRequest, &tMyEnv);737 if (tMyEnv._major != NO_EXCEPTION) {738 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");739 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);740 }741 vesp_free (ptSaveInfo);742 return;743 }744 /* Save the output data pointer passed to the function with the745 duplicated session and request objects. This will be used in the746 callback. */747 ptSaveInfo->pxUserData = (void *) ptOutputData;

748 mMyStatus = Vesp_Request ("Alarm.GetStatus", defer_request_callback,749 (unsigned long) ptSaveInfo, oMySession_gbl,750 &tSeqCouple);

Page 88: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

88 IC Client and Server Programmer�s Design Guide

751 if (mMyStatus != VESP_SUCCESS) {752 /* Return an error to the client immediately if there's a problem753 with the request. */754 vesp_log_info (VESP_CAT_ALL, "Problem", "Vesp_Request");755 log_unparsable ("Status: %s", vesp_find_error (mMyStatus));

756 vesp_set_exception (ptEnv, SYSTEM_EXCEPTION, VESP_FAILURE,757 "defer_request method request failed");758 vesp_free (ptSaveInfo);759 return;760 }761 /* Now defer the request - after this is successfully called, no762 response will be sent to the client until we send one. Normally, a763 response would be sent to the client when this function returns. */764 mMyStatus = Request_defer (ptEnv->request, &tMyEnv);765 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {766 /* We were unable to defer the request for some reason. */767 vesp_log_info (VESP_CAT_ALL, "Problem", "Request_defer");768 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,769 vesp_find_error (mMyStatus));

770 /* Clean up of our duplicated objects will happen in the callback. We771 could release them here if we wanted to, then in the callback we'd772 have to check that the saved objects were non-null.

773 Since the Request_defer failed, the response will be sent to the774 client when this function returns. However, the callback will still775 be invoked when the request we made in this function returns a776 response.

777 We'll end up with a situation where there will be no778 outstanding request associated with our stored request object. We779 use Request_get_ev to detect this situation when it retrieves the780 original request environment. */781 vesp_set_exception (ptEnv, tMyEnv._major, tMyEnv._minor,782 tMyEnv.vesp_error_description);783 }784 /* If we get to this point, we should be good to go - the session, the785 request, and the output data pointer are saved, and the original786 request has been deferred. */787 }

788 /*********************************************************************/789 /* Send the results of the deferred request to the client. In this case,790 we pass along the result returned by the toolkit, but that's not791 necessary - you can send the client any status you want to.792 */793 /*********************************************************************/794 /*ARGSUSED */795 static ORBStatus796 defer_request_callback (Identifier tInterface, ORBStatus mStatus,797 Environment * ptEnv, long lUserData,798 Session oSession, SeqCouple * ptOutputData)799 {

Page 89: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Callback Functions

Issue 1.0 June 2002 89

800 Environment tMyEnv;

801 struct saved_for_callback *ptSavedInfo;

802 ORBStatus mMyStatus;

803 int i;

804 any tReturnToClient;805 Environment *ptRequestEnv;806 SeqCouple *ptRequestData;

807 /* Make the user data look like a pointer again. */808 ptSavedInfo = (struct saved_for_callback *) lUserData;

809 /* Get the client environment first - this is mostly to check that our810 request is still valid. If you're working with a toolkit older than811 3.5.9 you have to add the following line before making the812 Request_get_ev function call.

813 tMyEnv._major = NO_EXCEPTION;

814 This is because of a toolkit bug that was not properly initializing815 the environment before doing its stuff. */816 mMyStatus = Request_get_ev (ptSavedInfo->oRequest, &tMyEnv,817 &ptRequestEnv);

818 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {819 vesp_log_info (VESP_CAT_ALL, "Problem", "Request_get_ev");820 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,821 vesp_find_error (mMyStatus));

822 Object_release (ptSavedInfo->oRequest, &tMyEnv);823 if (tMyEnv._major != NO_EXCEPTION) {824 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");825 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);826 }827 Object_release (ptSavedInfo->oSession, &tMyEnv);828 if (tMyEnv._major != NO_EXCEPTION) {829 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");830 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);831 }832 vesp_free (ptSavedInfo);

833 /* No request, can't send anything to client. Any return from inside834 this function goes to the toolkit, not the client. */835 return VESP_SUCCESS;836 }837 /* Check that the client session still exists before sending a response.838 Bad things will happen if you try to send a response using a client839 session that's already been cleaned up by the toolkit. */840 mMyStatus = Session_exist (ptSavedInfo->oSession, &tMyEnv);841 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {842 vesp_log_info (VESP_CAT_ALL, "Problem", "Session_exist");843 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,

Page 90: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

90 IC Client and Server Programmer�s Design Guide

844 vesp_find_error (mMyStatus));

845 Object_release (ptSavedInfo->oRequest, &tMyEnv);846 if (tMyEnv._major != NO_EXCEPTION) {847 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");848 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);849 }850 Object_release (ptSavedInfo->oSession, &tMyEnv);851 if (tMyEnv._major != NO_EXCEPTION) {852 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");853 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);854 }855 vesp_free (ptSavedInfo);856 return VESP_SUCCESS;857 }858 /* OK - so we have a valid environment and a valid client session let's859 send the response. Here's where the result of the request comes into860 play - if the environment has an exception set, we can't use any of861 the output values, but our user data is unmodified.

862 Notice that we're sending a response to a method that returns863 something other than ORBStatus, so the values that we're assigning to864 tReturnToClient._type and tReturnToClient._value change accordingly.865 */

866 tReturnToClient._type = "void";867 tReturnToClient._value = NULL;

868 /* The important thing is that the toolkit checks the type you are trying869 to return against the return type that is expected in the original870 request, so they have to match. */

871 if (NO_EXCEPTION == ptEnv->_major) {

872 /* Fill in the output data using the pointer we saved from earlier. */873 ptRequestData = (SeqCouple *) ptSavedInfo->pxUserData;

874 for (i = 0; i < ptOutputData->_length; i++) {875 char *pcName = ptOutputData->_buffer[i].name;876 char *pcValue = ptOutputData->_buffer[i].value;

877 vesp_couple_seq_add_couple_values (ptRequestData, pcName, pcValue);878 }

879 } else {880 vesp_set_exception (ptRequestEnv, ptEnv->_major, ptEnv->_minor,881 ptEnv->vesp_error_description);882 }

883 mMyStatus = Request_send_deferred_response (ptSavedInfo->oRequest,884 &tMyEnv,885 &tReturnToClient);

886 /* There's not much we can do if this fails. */887 if (tMyEnv._major != NO_EXCEPTION || mMyStatus != VESP_SUCCESS) {

Page 91: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Callback Functions

Issue 1.0 June 2002 91

888 vesp_log_info (VESP_CAT_ALL, "Problem",889 "Request_send_deferred_response");890 log_unparsable ("Error: %s, Status: %s", tMyEnv.vesp_error_description,891 vesp_find_error (mMyStatus));892 }893 /* We're done with these now. */894 Object_release (ptSavedInfo->oRequest, &tMyEnv);895 if (tMyEnv._major != NO_EXCEPTION) {896 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");897 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);898 }899 Object_release (ptSavedInfo->oSession, &tMyEnv);900 if (tMyEnv._major != NO_EXCEPTION) {901 vesp_log_info (VESP_CAT_ALL, "Problem", "Object_release");902 log_unparsable ("Error: %s", tMyEnv.vesp_error_description);903 }904 vesp_free (ptSavedInfo);

905 /* Thank you, drive through. */906 return VESP_SUCCESS;907 }

Page 92: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Chapter 6 Server Development

92 IC Client and Server Programmer�s Design Guide

Page 93: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

93

APPENDIX AMEMORY ALLOCATION CODE SAMPLES

This appendix contains code samples illustrating memory allocation in synchronous and asynchronous method invocations. Refer to �The Hybrid Interface,� on page 33 for additional information.

Output Arguments to Vesp_Request_SyncSource Code Sample 1 shows an example of a synchronous request to the (invented) method �Dummy.Square�. This method takes a long as input and returns a long (the input squared) as output. Both the input and output parameters in this example are allocated as automatic variables by the caller.

You must initialize the output sequence _length to zero and _buffer to NULL before calling Vesp_Request_Sync.

Page 94: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix A Memory Allocation Code Samples

94 IC Client and Server Programmer�s Design Guide

Source Code Sample 1: synchronous request � output type long

void example(Session session){Environment env;Request request;long input; /* For input to method */long output = o; /* Output space allocated (automatically) here */unsigned long result;

input = 5;

result = Vesp_Request_Sync ("Dummy.Square", /* Server and method to invoke */&env, /* Pointer to an Environment structure */session, /* A valid session */&request, /* Pointer to a new request structure */input, /* Input argument */&output); /* Pointer to output argument */

if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS{vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.Square failure");log_unparsable ("Error was \%s\"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.Square");log_unparsable ("Dummy.Square returned: %1d", output);}

Vesp_Request_Delete (session, request);}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.Square

mymachine:8007 [generic.c:496]

Dummy.Square returned: 25

Type: string

Source Code Sample 2 shows a synchronous request to �Dummy.Reverse�. This method takes a string as input and returns a string (the input reversed) as output.

Source Code Sample 2: synchronous request � output type string

Page 95: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Source Code Sample 1: synchronous request � output type long

Issue 1.0 June 2002 95

void example(Session session){Environment env;Request request;char input[32]; /* String for input */char *output = NULL; /* Place to build output string*/unsigned long result;

strcpy (input, "321 gnitseT");

result = Vesp_Request_Sync ("Dummy.Reverse", /* Server and method to invoke */&env, /* Pointer to an Environment structure */session, /* A valid session */&request, /* Pointer to a new request structure */input, /* Input string */&output); /* Address of output string pointer */

if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS{vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.Reverse failure");log_unparsable ("Error was \%s\"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.Reverse");log_unparsable ("Dummy.Reverse returned: %1d", output);}

Vesp_Request_Delete (session, request);}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.Reverse

mymachine:8007 [generic.c:496]

"Dummy.Reverse returned: Testing 123:.

Type: sequence

Source Code Sample 3 shows a synchronous request to �Dummy.DataFetch�. This method takes a database criteria string as input and returns a sequence of couples for the matching data.

Source Code Sample 3: synchronous request � output type sequence

void example(Session session){Environment env;Request request;char input[32]; /* Input string (criteria) */SeqCouple *output; /* Pointer to output when allocated */unsigned long result;int i;

Page 96: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix A Memory Allocation Code Samples

96 IC Client and Server Programmer�s Design Guide

strcpy (input,"datakey=\"12345\""); /* Input parameter is a criteria string */

output = vesp_couple_seq_create(); /* Allocate the output sequence */output->_maximum = 10; /* Now initialize the sequence */output->_length = 0output->_buffer = NULL;

result = Vesp_Request_Sync ("Dummy.DataFetch", /* Server and method to invoke */&env, /* Pointer to an Environment structure */session, /* A valid session */&request, /* Pointer to a new request structure */input, /* Input string */output); /* Pointer to output sequence */

if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS{vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.DataFetch failure");log_unparsable ("Error was \%s\"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.DataFetch");log_unparsable ("Dummy.DataFetch returned:)for (i = 0; i <output->_length; i++)}log_unparsable (\t%s = %s, output->_buffer[1].nameoutput->_buffer)[i].value);}}

Vesp_Request_Delete (session, request);vsep_couple_seq_delete (output); /* Delete the sequence we allocated */}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.DataFetch

mymachine:8007 [generic.c:496]

"Dummy.DataFetch returned:

name = James

account = 12345678765432

acc_value = 87

ssn = 543323212

Page 97: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Source Code Sample 1: synchronous request � output type long

Issue 1.0 June 2002 97

The order in which Vesp_Request_Delete and vesp_couple_seq_delete are called is important. Vesp_Request_Delete will always try to free the memory for the couples it added to the output sequence; vesp_couple_seq_delete can then delete the empty sequence. If vesp_couple_seq_delete is called first, it will free the sequence and its contents, and Vesp_Request_Delete will fail, resulting in memory leaks and possibly other problems.

Note: Output sequences are handled in this same fashion regardless of content. For example, a sequence of longs, a sequence of couples, and a sequence of sequences are handled the same. One initial sequence structure is allocated (and freed) by the caller, and all members of the sequence are allocated (and freed) by the Toolkit, with calls to the hybrid API.

Type: structure

Source Code Sample 4 shows a synchronous request to �Dummy.DataFetch2�. This method takes a database criteria string as input and returns a custom data structure. Assume the IDL structure definition in vespidl.idl is as follows:

struct Cust_Data {char * name;char * account;long acc_value;char * ssn;};

The Telephony IDL compiler will translate this into the following C structure in vespidl.h:

typedef Cust_Data {char * name;char * account;long acc_value;char * ssn;} Cust_Data;

Source Code Sample 4: synchronous request � output type structure

void example(Session session){Environment env;Request request;char input[32]; /* Input string (criteria) */Cust_Data *output; /* Output struct */unsigned long result;

strcpy (input,"datakey=\"12345\""); /* Input parameter is a criteria string */output = vesp_calloc (sizeof (Cust_Detail)); /* Allocate & zero out output struct*/

result = Vesp_Request_Sync ("Dummy.DataFetch2", /* Server and method to invoke */&env, /* Pointer to an Environment structure */session, /* A valid session */&request, /* Pointer to a new request structure */input, /* Input string */output); /* Pointer to output sequence */

Page 98: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix A Memory Allocation Code Samples

98 IC Client and Server Programmer�s Design Guide

if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS{vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.DataFetch2 failure");log_unparsable ("Error was \%s\"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.DataFetch2");log_unparsable ("Dummy.DataFetch2 returned:)log_unparsable ("\tname = %s, output->name);log_unparsable ("\taccount = %s, output->account);log_unparsable ("\tacc_value = %s, output->acc_value);log_unparsable ("\tssn = %s, output->ssn);}

Vesp_Request_Delete (session, request);vsep_free (output);}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.DataFetch2

mymachine:8007 [generic.c:496]

"Dummy.DataFetch2 returned:

name = James

account = 12345678765432

acc_value = 87

ssn = 543323212

Memory Management for Asynchronous OperationsCalls to Vesp_Request allocate memory for output arguments and other purposes. Memory allocated by Vesp_Request is freed automatically after the callback function has been executed.

Input Arguments to Vesp_RequestThe caller is responsible for allocating memory for input arguments to Vesp_Request, and freeing it afterwards. Vesp_Request makes copies of all input arguments, so the caller may free this memory as soon as Vesp_Request returns.

Page 99: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Memory Management for Asynchronous Operations

Issue 1.0 June 2002 99

Output Arguments to Vesp_RequestThe caller must initialize all output parameters to zero or null before calling Vesp_Request.

Source Code Sample 5 shows an example of an asynchronous request to the (invented) method �Dummy.Square�, and the matching callback function. This method takes a long as input and returns a long (the input squared) as output. The input is an automatic variable, and the output is a static variable whose scope is the entire module.

Source Code Sample 5: asynchronous request � output type long

static long output; /* Space for output */

void example(Session session){long input; /* For input to method */

input = 5;output = 0;

Vesp_Request ("Dummy.Square",Dummy_Square_callback, /* Pointer to callback function */(ULONG) 0, /* Data to pass to callback (none in this case) */session, /* A valid session */input, /* Input argument */&output); /* Pointer to output argument */}

/* Callback function. This function will be invoked by the Toolkit* when the response from Dummy Server arrives.*/ORBStatus Dummy_Square_callback (Interface, interface,ORBStatus return_result,Environment *env,long user_data,Session, session,long data_in,long *data_out){if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS{vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.Square failure");log_unparsable ("Error was %s"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.Square");log_inparsable ("Dummy.Square returned: %1d", *data_out);}return VESP_SUCCESS;}

Page 100: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix A Memory Allocation Code Samples

100 IC Client and Server Programmer�s Design Guide

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.Square

mymachine:8007 [generic.c:496]

"Dummy.Square returned: 25

Type: string

Source Code Sample 6 shows an asynchronous request to �Dummy.Reverse�. This method takes a string as input and returns a string (the input reversed) as output.

Source Code Sample 6: asynchronous request � output type string

static char *output; /* Space for output */

void example(Session session){char input; /* String for input */

strcpy (input, *321 gnitseT");;output = NULL;

Vesp_Request ("Dummy.Reverse","Dummy_Reverse_callback", /* Pointer to callback function */(ULONG) 0, /* Data to pass to callback (none in this case) */session, /* A valid session */input, /* Input argument */&output); /* Pointer to output argument */}

/* Callback function. This function will be invoked by the Toolkit* when the response from Dummy Server arrives.*/

ORBStatus Dummy_Reverse_callback (Interface, interface,ORBStatus return_result,Environment *env,long user_data,Session, session,char data_in,char *data_out){if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS){vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.Reverse failure");log_unparsable ("Error was \%s\"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {

Page 101: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Memory Management for Asynchronous Operations

Issue 1.0 June 2002 101

vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.Reverse");log_inparsable ("Dummy.Reverse returned: %1d", *data_out);}return VESP_SUCCESS;}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.Reverse

mymachine:8007 [generic.c:496]

"Dummy.Reverse returned: 123

Type: sequence

Source Code Sample 7 shows an asynchronous request to �Dummy.DataFetch�. This method takes a database criteria string as input, and returns a sequence of couples for the matching data.

Source Code Sample 7: asynchronous request � output type sequence

static SeqCouple output; /* Pre-allocated output sequence */

void example(Session session){char input[32]; /* Input string criteria */int i;

strcpy (input, "datakey=\"12345\""); /* Input parameter is a criteria string */

output._maximum = 10; /* Now initialize the sequence */output._length = 0;output._buffer = NULL;

Vesp_Request ("Dummy.DataFetch","Dummy_Fetch_callback", /* Pointer to callback function */(ULONG) 0, /* Data to pass to callback (none in this case) */session, /* A valid session */input, /* Input argument */&output); /* Address of output sequence */}

/* Callback function. This function will be invoked by the Toolkit* when the response from Dummy Server arrives.*/ORBStatus Dummy_DataFetch_callback (Interface, interface,ORBStatus return_result,Environment *env,long user_data,Session, session,char *data_in,SeqCouple *data_out){if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS)vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.DataFetch failure");log_unparsable ("Error was %s"",(env->vesp_error_description) ?

Page 102: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix A Memory Allocation Code Samples

102 IC Client and Server Programmer�s Design Guide

env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.DataFetch");log_inparsable ("Dummy.DataFetch returned: %1d", *data_out);}Return VESP_SUCCESS;}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.DataFetch

mymachine:8007 [generic.c:496]

"Dummy.DataFetch returned:

name = James

account = 12345678765432

acc_value = 87

ssn = 543323212

Note: Output sequences are handled in this same fashion regardless of content. For example, a sequence of longs, a sequence of couples, and a sequence of sequences are handled the same. A static sequence structure is allocated by the caller, and all members of the sequence are allocated (and freed) by the Toolkit.

Type: structure

Source Code Sample 8 shows an asynchronous request to �Dummy.DataFetch2�. This method takes a database criteria string as input, and returns a custom data structure. Assume the IDL structure definition in vespidl.idl is as follows:

struct Cust_Data {string * name;string * account;long acc_value;string * ssn;};

The Telephony IDL compiler will translate this into the following C structure in vespidl.h:

typedef Cust_Data {char * name;char * account;long acc_value;char * ssn;} Cust_Data;static Cust_Data output; /* Pre-allocated output sequence */

void example(Session session){char input[32]; /* Input string (criteria) */

Page 103: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Memory Management for Asynchronous Operations

Issue 1.0 June 2002 103

strcpy (input, "datakey=\"12345\""); /* Input parameter is a criteria string */memset (output, 0, sizeof (Cust_Data)); /* Zero the output */

Vesp_Request ("Dummy.DataFetch2",Dummy_DataFetch2_callback, /* Pointer to callback function */(ULONG) 0, /* Data to pass to callback (none in this case) */session, /* A valid session */input, /* Input argument */&output); /* Address of output structure */}

/* Callback function. This function will be invoked by the Toolkit* when the response from Dummy Server arrives.*/ORBStatus Dummy_DataFetch2_callback (Interface, interface,ORBStatus return_result,Environment *env,long user_data,Session, session,char *data_in,Cust_Data *data_out){if (env->_major != NO_EXCEPTION|| result != VESP_SUCCESS)vsep_log_info(VESP_CAT_ALL, "Error", "Dummy.DataFetch2 failure");log_unparsable ("Error was %s"",(env->vesp_error_description) ?env->vesp_error_description :vesp_find_error (result));}else {vesp_log_info(VESP_CAT_ALL, "SUCCESS", "Dummy.DataFetch2");log_inparsable ("Dummy.DataFetch2 returned:");log_unparsable ("\tname = %s", output->name);log_unparsable ("\taccount = %s", output->account);log_unparsable ("\tacc_value = %s", output->acc_value);log_unparsable ("\tssn = %s", output->ssn);

}Return VESP_SUCCESS;}

If successful, this excerpt would print lines similar to the following in the server log file:

(1997-03-05 16:11:23 520 ) Info /SUCCESS Dummy.DataFetch2

mymachine:8007 [generic.c:496]

"Dummy.DataFetch2 returned:

name = James

account = 12345678765432

acc_value = 87

ssn = 543323212

Page 104: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix A Memory Allocation Code Samples

104 IC Client and Server Programmer�s Design Guide

Page 105: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

105

APPENDIX BCLIENT CODE EXAMPLE

This appendix contains an example client application. Refer to �Client Development,� on page 47 for information on client development.

Example of a Client ApplicationThis example client application shows how a client is initialized, messages processed, and callback routines run. This example does an assign, some requests, and a deassign. 1 Include Avaya IC ORB headers.

2 Declare callback routine.

3 Declare event handler.

4 Establish port number for incoming messages.

5 Login to Avaya IC ORB. This must be done before any calls are made to the ORB that call a server.

6 Set the tracing level to see requests and responses in the log.

7 Create a session to hold information about the servers to be used.

8 Establish log file name explicitly.

9 Call the DS.WhoIsYourParent method synchronously.

10 Use vesp convenience function to allocate a separate copy of the information retrieved by the DS.WhoIsYourParent request. The data returned by the request will be released when Vesp_Request_Delete is called.

11 Clean up/free structures associated with DS.WhoIsYourParent request.

12 Assign to the parent Directory Server synchronously.

13 Put a timestamped header in the log file.

14 Add printf formatted text to the log file.

Page 106: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix B Client Code Example

106 IC Client and Server Programmer�s Design Guide

15 Ιinitialize an empty sequence of sequence of couples.

16 Call the DS.GetFewRecords method synchronously to get a list of Directory Servers.

17 Use DS.Ping to determine if the children are running.

18 Clean up/free structures associated with DS.GetFewRecords request.

19 Change the time limit for message responses.

20 Set the trace level so that a minimum amount of information is written to the log.

21 Do a Deassign request to terminate the session on the server side.

22 Start of the callback routine used with DS.Ping requests.

23 Check the return result and environment. The environment is the primary error indication. VESP_SUCCESS here indicates that the method succeeded, meaning the server is running, which we don�t want in this situation.

24 Raise a low priority alarm.

25 Event handling routine. This function is associated with a server by the Vesp_Assign_Request function. This routine runs every time an event is generated for this client from the server specified in the assign function.

Custom Telephony Client: source code/********************************************************************* Copyright (c) 1998 Quintus Corporation USA* All Rights Reserved*********************************************************************** Name: ds_user_add.c - DS User Batch Add utility client** Revision History:* 19950919 itf Created to test Vesp_Request w/no callback* 19960417 itf Converted itestcli.c to vduos_purge.c 1.0.0* 19960503 itf Made code conformant with Jay's new build* procedure (corresponds with v1.2.0 of* vduossrv.c)* 19961011 itf Created ds_user_add.c from vduos_purge.c*********************************************************************/#include <orb.h> 1#include <stdio.h>#include <errno.h>#include <ctype.h>

#define NAME_STR "DS User Batch Add"static char version_string[] = NAME_STR " Version " VERS;

Page 107: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Client: source code

Issue 1.0 June 2002 107

#define INFILENAME "useradd.txt"#define DEF_LOGINID "vesp"#define DEF_PASSWD "vesp"

static int global_ds_events = 0;static char *myname;Object client_obj;

ORBStatus ds_ping_callback(Identifier interface, 2ORBStatus return_result,Environment *ev,long user_data,Session session);

ORBStatus ds_event_handler(Identifier inter_opt, 3Object obj,Session session,Event *event);

int rtrim(char *buf);void check_for_name(Couple *cp, char *name, char value[], int sz);

int main(int argc, char *argv[]){

Session session;Request request;ORBStatus create_res, request_res, err;char *out_id, *parent_id, err_desc[256], *login, *passwd,

buf[2048], buf2[2048], cname[64], *bstart, *bend, *c,*key;

char loginid[33], lname[33], fname[33], pname[33],phone[33], mname[33], password[64];

Environment ev;FILE *infp;

SeqSeqCouple *ds_list;

int users_added, buflen, lastbuflen, infile_line_no, i;Couple coup;SeqString *skills;SeqCouple *userrec;

/* say what this program is */printf("%s v%s (%s %s)\n",

NAME_STR,VERS,__DATE__,__TIME__);

/* validate parameter count */if (argc != 3 && argc != 1){

printf("Usage: %s [<loginid> <password>]\n"" loginid and password, if supplied, ""will be used by %s to\n"" log in to vesp. If they are omitted, "

Page 108: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix B Client Code Example

108 IC Client and Server Programmer�s Design Guide

"loginid = \"%s\"\n"" and password = \"%s\" will be used.\n"" All input is taken from the file \"./%s\" whose\n"" format is identical to that described in the ""ManCon manual\n"" for the ManCon User Batch Add function.\n",argv[0],argv[0],DEF_LOGINID,DEF_PASSWD,INFILENAME);

exit(1);}

/* Save user's name for this program for later use. */myname = argv[0];

/* 7000 should be the default, however, we do this explicitly so* we're sure of where we stand.*/Vesp_Set_Client_Port( 7000 ); 4

/* Log in to Vesp and get ready to communicate with other vesp* objects.*/if (argc == 3){

login = argv[1];passwd = argv[2];

}else{

login = DEF_LOGINID;passwd = DEF_PASSWD;

}if ( Vesp_Login( login, passwd, &client_obj ) != VESP_SUCCESS) 5{

printf("User \"%s\" could not log into Vesp with password \"%s\".\n",login,passwd);

exit(1);}

/* watch the idl messages for now */vesp_set_tracing(VESP_TRACE_FLUSH_LOG | VESP_TRACE_IDL_CODING); 6

create_res = Vesp_Session_Create( client_obj, &session ); 7

if (create_res != VESP_SUCCESS){

printf("Vesp_Session_Create failed with error %lx: %s\n",create_res,vesp_find_error(create_res));

exit(1);}

Page 109: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Client: source code

Issue 1.0 June 2002 109

/* use our own log file */sprintf(buf, "%s.log", argv[0]);vesp_set_log_name(buf); 8

/* open input file */if (!(infp = fopen(INFILENAME, "r"))){

printf("Error: Could not open \"%s\".\n", INFILENAME);exit(errno);

}

/* Get a list of Directory Servers, then fish out the ID of the* Parent DS, so we can talk to the boss.*/if ((err = Vesp_Request_Sync("DS.WhoIsYourParent", 9

&ev,session,&request,&out_id)) != VESP_SUCCESS)

{printf("Error: DS.WhoIsYourParent request failed (err = %lx).\n",

err);exit(1);

}parent_id = vesp_strdup(out_id); 10Vesp_Request_Delete(session, request); 11

/* Assign to the Parent, so there's no ambiguity and we can track* updates.*/sprintf(buf, "#%s.Assign", parent_id);if (Vesp_Assign_Request(buf, 12

&ev,NULL,0UL,ds_event_handler,session) != VESP_SUCCESS)

{vesp_log_info(VESP_CAT_ALL, "Warning", "Assign Failed"); 13log_unparsable("Warning: %s request failed.", buf); 14printf("Warning: DS.Assign request failed.\n");

}

/* The following is a somewhat contrived step for instructional* purposes.* We will Ping any children (asynchronously, because we don't want* to waste time on this) and send an alarm (in the callback) for* any that are running, because the system is better off if only* one DS (the Parent) is running during updates and the rest come* back later and get all the changes at once.*//* First query the DS for a list of Directory Servers */ds_list = vesp_couple_seqseq_create(); 15if ((err = Vesp_Request_Sync("DS.GetFewRecords", 16

&ev,

Page 110: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix B Client Code Example

110 IC Client and Server Programmer�s Design Guide

session,

&request,"","type = srv & name = DS",ds_list)) != VESP_PARTIAL_SUCCESS)

{printf("Error: DS.GetFewRecords request failed (err = %lx).\n",

err);exit(1);

}if (ev._major != NO_EXCEPTION){

printf("Error: DS.GetFewRecords request failed.\n");exit(1);

}

/* Now loop through the DS list, and ping all the ones that aren't* the parent.*/for (i = 0; i < ds_list->_length; i++){

char *uuid;

if (vesp_dup_seq_couple_value(ds_list->_buffer + i,"UUID",&uuid) == VESP_SUCCESS)

{if (strcmp(uuid, parent_id)){

if (Vesp_Request("DS.Ping", 17ds_ping_callback,(long)uuid,session) != VESP_SUCCESS)

{vesp_log_info(VESP_CAT_ALL, "Info", "Warning");log_unparsable("DS.Ping request rejected.\n");

}}else{

vesp_free(uuid);}

}else{

vesp_log_info(VESP_CAT_ALL, "Info", "Warning");log_unparsable("vesp_dup_seq_couple_value(UUID) failed.\n");

}}Vesp_Request_Delete(session, request); 18vesp_couple_seqseq_delete(ds_list);

/* If we're packing too many records in the DS, it will slow down,

Page 111: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Client: source code

Issue 1.0 June 2002 111

* so we increase our message timeouts.*/Session_set_message_timeout( session, &ev, 0x1000 ); 19

/* stop watching the idl messages now, because there's going to be* a lot of them*/vesp_set_tracing(VESP_TRACE_FLUSH_LOG); 20

/**** THE MAIN LOOP ****//* As long as there's data in the input file, add users to the DS.

*/buflen = lastbuflen = 0;users_added = 0;coup.name = cname; /* provide space for name field */while (!feof(infp)){

*loginid = *lname = *fname = *pname = '\0';*phone = *mname = *password = '\0';userrec = vesp_couple_seq_create();vesp_couple_seq_add_couple_values(userrec, "type", "per");while (!feof(infp)){

/* catch condition of multiple blank lines */lastbuflen = buflen;

/* get the next line of input */if (!fgets(buf, sizeof(buf), infp))

*buf = '\0';else

infile_line_no++;if (!(buflen = rtrim(buf)))

break;

/* name starts at first non-whitespace character */for (bstart = buf; isspace(*bstart); bstart++);

/* name ends with last non-whitespace before '=' */for (c = bstart, i = 0;

i < sizeof(cname) && *c && *c != '=';i++, c++)coup.name[i] = *c;

coup.name[i] = '\0';rtrim(coup.name);if (*c != '='){

vesp_log_info(VESP_CAT_ALL, "Warning", "Bad Line");log_unparsable("Invalid input on line #%d:",

infile_line_no);log_unparsable(buf);continue;

}

Page 112: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix B Client Code Example

112 IC Client and Server Programmer�s Design Guide

/* value starts with first non-white character after '='* and goes to end of buf.*/c++;while (isspace(*c)) c++;coup.value = c;

/* Check for special names we care about & save their* values.*/check_for_name(&coup, "loginid", loginid, sizeof(loginid));check_for_name(&coup, "lname", lname, sizeof(lname));check_for_name(&coup, "fname", fname, sizeof(fname));check_for_name(&coup, "mname", mname, sizeof(mname));check_for_name(&coup, "pname", pname, sizeof(pname));check_for_name(&coup, "password", password, sizeof(password));if (!strcmp(coup.name, "skills")){

/* parse the skills string */bstart = coup.value;skills = vesp_string_seq_create();err = 0;

while(*bstart){

while(isspace(*bstart))bstart++;

bend = bstart;while (*bend != '/' && *bend)

bend++;for (i = 0, c = bstart; c != bend; i++, c++)

buf2[i] = *c;buf2[i] = '\0';if (rtrim(buf2)){

vesp_string_seq_add_value(skills, buf2);if (*bend)

bend++;bstart = bend;

}else{

vesp_log_info(VESP_CAT_ALL,"Warning","Bad Line");

log_unparsable("Invalid skills on line #%d:",infile_line_no);

log_unparsable(buf);err = 1;break;

}}

if (!err)

Page 113: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Client: source code

Issue 1.0 June 2002 113

{sprintf(buf2, "{0,%d", skills->_length);for (i = 0; i < skills->_length; i++){

strcat(buf2, ",\"");strcat(buf2, skills->_buffer[i]);strcat(buf2, "\"");

}strcat(buf2, "}");coup.value = buf2;

}}

/* add any couples that aren't "configuration" or* "password" couples to the user record*/if (strcmp(coup.name, "configuration") &&

strcmp(coup.name, "password"))vesp_couple_seq_add_couple(userrec, &coup);

}

if (!lastbuflen && !buflen) /* ignore multiple blank lines */continue;

if (!*lname && !*fname) /* if the required fields are missing */{vesp_log_info(VESP_CAT_ALL, "Warning", "Bad Record");log_unparsable("No fname or lname (first, last name) for "

"user above line #%d",infile_line_no);

continue;}

/* if no pname given, use fname+" "+mname+" "+lname */

if (!*pname){

strcpy(pname, fname);if (*mname){

strcat(pname, " ");strcat(pname, mname);

}strcat(pname, " ");strcat(pname, lname);vesp_couple_seq_add_couple_values(userrec,

"pname",pname);

}

/* if no loginid given, use 1st initial + lname */if (!*loginid){

*loginid = *fname;strcpy(loginid + 1, lname);

Page 114: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix B Client Code Example

114 IC Client and Server Programmer�s Design Guide

vesp_couple_seq_add_couple_values(userrec,"loginid",loginid);

}

/* create the user record */if (Vesp_Request_Sync("DS.CreateRecord",

&ev,session,&request,"",userrec,&key) != VESP_SUCCESS)

{vesp_log_info(VESP_CAT_ALL, "Error", "Request Failed");log_unparsable("DS.CreateRecord failed for "

"user above line #%d",infile_line_no);

log_unparsable("(lname = \"%s\", fname = \"%s\")",lname,fname);

continue;}if (ev._major != NO_EXCEPTION)

{vesp_log_info(VESP_CAT_ALL, "Error", "Request Failed");log_unparsable("DS.CreateRecord failed for "

"user above line #%d",infile_line_no);

log_unparsable("(lname = \"%s\", fname = \"%s\")",lname,fname);

vesp_print_environment(&ev);continue;

}Vesp_Request_Delete(session, request);

/* if no password, use loginid */if (!*password){

strcpy(password, loginid);}

/* give the user a password */if (Vesp_Force_Password(session,

loginid,password) != VESP_SUCCESS)

{vesp_log_info(VESP_CAT_ALL, "Error", "Request Failed");log_unparsable("Assignment of password failed for "

"user above line #%d",infile_line_no);

log_unparsable("(loginid = \"%s\")",loginid);

Page 115: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Client: source code

Issue 1.0 June 2002 115

continue;}users_added++;vesp_couple_seq_delete(userrec);

}fclose(infp);

/* Deassign from Parent DS */if (Vesp_Deassign_Request("DS.Deassign", 21

&ev,NULL,0UL,session) != VESP_SUCCESS)

{vesp_log_info(VESP_CAT_ALL, "Warning", "Deassign Failed");log_unparsable("Warning: %s.Deassign request failed.", parent_id);printf("Warning: DS.Deassign request failed.\n");

}

/* report results */printf("\nBatch addition of users complete. "

"%d users added successfully.\n",users_added);

printf("Received a total of %d DS events.\n", global_ds_events);

return 0;}

/* This is the callback which is called when we get a response to a* DS.Ping request. This callback is a little unusual because it only* sends an alarm if there are no errors, and then does little else.* Typically we would check for errors, raise alarms (or simply write* to the log) in the event of an error, and then act on the results of* the request, but in this case, a successful Ping means something bad* is happening - a child DS is running and requesting updates from the* parent DS while we try to hammer it with a rapid flood of continuous* updates.*/ORBStatus ds_ping_callback(Identifier interface, 22

ORBStatus return_result,Environment *ev,long user_data,Session session)

{char fullname[64], buf[256];char *uuid = (char *)user_data;

if (ev->_major == NO_EXCEPTION && return_result == VESP_SUCCESS) 23{

sprintf(fullname, "%s.ExtraDS", myname);sprintf(buf,

"Child DS #%s is up. %s will run faster without it.",uuid,myname);

Page 116: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix B Client Code Example

116 IC Client and Server Programmer�s Design Guide

Vesp_Send_Alarm(client_obj, fullname, "low", buf); 24}

vesp_free(uuid);return VESP_SUCCESS;

}

/* This is the routine that will be called whenever we receive any* events from the DS. (This will be the parent DS, since that's the* only one we assign to.*/

ORBStatus ds_event_handler(Identifier inter_opt, 25Object obj,Session session,Event *event)

{global_ds_events++;return VESP_SUCCESS;

}

/* Trim all the whitespace off of the end (right) of a string and* return its length.*/

int rtrim(char *buf){

int buflen = strlen(buf);

while (buflen && isspace(buf[buflen - 1])){

buf[--buflen] = '\0'; /* remove trailing whitespace */}return buflen;

}

/* Check a couple for a specific name. If that name is present, copy* its value.*/

void check_for_name(Couple *cp, char *name, char value[], int sz){

if (!strcmp(cp->name, name)){

strncpy(value, cp->value, sz);value[sz - 1] = '\0';

}}

Page 117: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

117

APPENDIX CSERVER CODE EXAMPLE

This appendix contains an example of a server different from the example presented in �Server Development,� on page 59. The source code for this server is included with the Avaya IC Toolkit.

This appendix also provides instructions for building custom SDK servers in a Solaris 7 or Windows environment.

Server Source Code ExampleThis example server application shows how a server is initialized and run and how method requests are handled. 1 Include Avaya IC ORB headers.

2 Declare version string for later use with vesp_set_server_version().

3 Declare server hook routines to the compiler.

4 Pass pointers to server hook routines to the Telephony toolkit.

5 Convert the server's two command line arguments to Object data.

6 The server must be told its UUID to run.

7 Log the server into the Avaya IC system using the Object data that was passed to it at startup.

8 Vesp_poll() sends and receives requests, responses, and events in Avaya IC ORB. It must be called about 5 times a second. Synchronous methods call this routine automatically.

9 Server_user_init() is called at the end of Vesp_Server_Login().

10 Version information is used by the toolkit when the server's GetStatus method is invoked.

11 Get server configuration information. The configuration information is presented in the form of a sequence of couples.

12 Each method must be registered with a call to BOA_set_method (this does not include the generic methods provided by the Toolkit).

13 Server_user_poll() is called at the end of Vesp_poll().

Page 118: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

118 IC Client and Server Programmer�s Design Guide

14 If the server's Exit method is invoked, Server_user_exit() will be called before the process terminates.

15 Ιf a client assigned to the server terminates, Server_client_terminate() will be invoked. (AccStat does not have an Assign method, so Server_client_terminate is not really necessary here.)

16 If the server is terminated by some means other than its Exit method, the toolkit will attempt to call Server_user_exception() before the process ends.

17 Server_user_status() is called by the Generic.GetStatus method, to allow the server to add custom status information.

18 This function will be called by the toolkit whenever the AccStat.CheckAcc method is invoked.

19 The environment variable is used to return exception information in the event of an error.

Page 119: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Server Source Code

Issue 1.0 June 2002 119

Custom Telephony Server Source Code

/* ------------------------------------------------------------------------ *\** Description: Sample server code example (account status server)** Copyright (c) 1998 by Quintus Corporation* ---- change log ----* Revision 1.5.1 1996/1/18 ian* Made sess and configseq global for stylistic reasons, moved orb.h* line for same.** Revision 1.5 1995/10/28 ian* Added use of server configuration information in Server_user_init().** Revision 1.4 1995/09/24 ian* Comment and format cleanup, added Server_set_status_hook_routine()* call.** Revision 1.3 1995/07/26 greg* Made some changes in the way exceptions are constructed. We now use* the NabCTI toolkit call "vesp_set_exception" to construct the exception.** Revision 1.2 1995/07/25 greg* Cleaned up warnings and added some usage of the environment parameter.** Revision 1.1 1995/07/18 greg* Initial revision*\* ------------------------------------------------------------------------ */

/* This file implements an extremely simple NabCTI server. It has one* method, CheckAcc, which performs a simple account lookup based on* a character string passed in by a client program, then fills up a* sequence of couples with the account information.*/

/* This file must be included in order to use the NabCTI functions and* constructs.*/#include "orb.h" 1

/* This is the version string for the server. */static char *version = "1.5.1"; 2

/* These error codes are defined in the style of an ORBStatus error code.* They are used to indicate various problems when attempting to check* account status.*/#define VESP_DATABASE_EMPTY_ERROR 0x4000360#define VESP_UNKNOWN_ACCOUNT_ERROR 0x4000370

/* This is the operating mode of the AccStat Server - test or demo -

Page 120: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

120 IC Client and Server Programmer�s Design Guide

* which controls the behavior of Server_user_poll().*/

static enum {ASM_DEMO, ASM_TEST} AccStatMode = ASM_DEMO;

/* This is the server's default session, it is currently only used in* Server_user_init(), which is also where it is initialized, but we* make it global because it's frequently useful in more complex* servers.*/

Session sess;

/* This is the server's configuration, which is loaded at startup. As* with the session, this is merely made global because we may need it* if the server expands later.*/

SeqCouple *configseq;

/* Here are the prototypes for the functions that we provide to the* toolkit, so it can call us when it needs to.*/

ORBStatus Server_user_init(Object object); 3ORBStatus Server_user_poll(void);void Server_user_exit(void);ORBStatus Server_client_terminate(Object object);void Server_user_exception(void);void Server_user_status(SeqCouple *status_info);

int main(int argc, char *argv[]){

Environment local_env;Object boa_object = NULL;

/* Initialize server-defined routines */Server_set_user_init_routine (Server_user_init); 4Server_set_user_poll_routine (Server_user_poll);Server_set_user_exit_routine (Server_user_exit);Server_set_client_terminate_routine (Server_client_terminate);Server_set_user_exception_routine (Server_user_exception);Server_set_status_hook_routine(Server_user_status);

/** 1st arg in this object's UUID (object_gbl is declared in orb.h)* 2nd arg is BOA object's UUID*/if (argc >= 2) { 5

object_gbl = ORB_string_to_object (VESP_ORB, &local_env, argv[1]);if (argc >= 3)

boa_object = ORB_string_to_object (VESP_ORB, &local_env, argv[2]);} /* if */else

return VESP_ERROR; 6

/* If this call fails, the server will exit */

Page 121: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Server Source Code

Issue 1.0 June 2002 121

SCHECK (Vesp_Server_Login (object_gbl, boa_object); 7

/* Go into the polling loop here and process incoming requests */while (1)

Vesp_poll (20UL); 8} /* main */

/* Any user-specific initialization is performed in this function. It is* where methods are registered. Additional user memory can be allocated* in here and communication channels may be opened as well.*/ORBStatus Server_user_init(Object object) 9{

Environment env;Context ctx;char *value;

/* The server version string must be set, otherwise VESP will* complain. Keeping the version string up to date is a good* way to track changes and bug fixes in the server.*/vesp_set_server_version (version); 10/* Get default session, and config from that. */ 11SCHECK( Vesp_get_default_session(object, &sess));SCHECK( Session_get_context(sess, &env, &ctx));Context_get_configuration(ctx, &env, &configseq);if (configseq != NULL){

if (vesp_dup_seq_couple_value(configseq, "accstatmode",&value) == VESP_SUCCESS)

{if (strcmp(value, "test") == 0)

AccStatMode = ASM_TEST; vesp_free(value);}

}

/* Register the one method that this server publishes. */SCHECK (BOA_set_method (VESP_BOA, &env, object, "CheckAcc", 12

0, 0, (unsigned long)AccStat_CheckAcc));return VESP_SUCCESS;

} /* Server_user_init */

/* This function is called many times per second. It is an excellent place* to put any time-dependent code. For instance, if you need to poll an* incoming communications line (RS-232 interface or other), this would be* the place to do it.*/static unsigned int Successful_Requests = 0;static unsigned int Failed_Requests = 0;

/* Every 60 seconds, we'll print some request statistics to the log file. */#define PRINT_INTERVAL 60

Page 122: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

122 IC Client and Server Programmer�s Design Guide

ORBStatus Server_user_poll(void) 13{

static time_t now = 0;

/* Once the current time has exceeded the last update time + 60 seconds,* update the last update time marker and print the latest statistics.* Also do the same the first time we enter the function (now == 0).*/if (AccStatMode == ASM_DEMO){

if (now + PRINT_INTERVAL < time (NULL) || now == 0){

now = time (NULL);vesp_log_info (VESP_CAT_ALL, "Info", "Request Information");log_unparsable ("%d \tsuccessful account requests have "

"been processed",Successful_Requests);log_unparsable ("%d \tunsuccessful account requests have "

"been processed", Failed_Requests);log_unparsable("");} /* if time to print*/

} /* if Demo Mode*/return VESP_SUCCESS;} /* Server_user_poll */

/* Any user-specific cleanup code can go here. If memory needs to be* deallocated or files need to be closed, do that here so it happens before* the process exits.*/

void Server_user_exit(void) 14{

return;} /* Server_user_exit */

/* If any special handling needs to be done when a client terminates, the* code can do it in this function.*/

ORBStatus Server_client_terminate(Object object) 15{

return VESP_SUCCESS;} /* Server_client_terminate */

/* If any code needs to be executed before the server crashes due to a* segmentation violation or bus error (memory problems), it can go here.*/

void Server_user_exception(void) 16{

return ;} /* Server_user_exception */

/* Add any relevant status information to the generic information* provided by the Generic.GetStatus method.*/

Page 123: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Server Source Code

Issue 1.0 June 2002 123

void Server_user_status(SeqCouple *status_info) 17{

char value_str[32];

sprintf(value_str, "%d", Successful_Requests);vesp_couple_seq_add_couple_values(status_info,

"Successful_Requests",value_str);

sprintf(value_str, "%d", Failed_Requests);vesp_couple_seq_add_couple_values(status_info,

"Failed_Requests",value_str);

}

/* This dummy structure stores some fake account data for the purpose* of our example server.*/static struct accinfo {

char *accnum;char *fname;char *lname;char *accstatus;

} AccountInfo[] = {{ "45676-00", "Jonathan", "Public", "Overdrawn" },{ "12393-23", "Mary", "Jones", "OK" },{ "29484-98", "Peter", "Pan", "Terminated" },{ "12932-93", "Heeby", "Jeeby", "Unknown" }

};

/* This variable will be initialized with the number of entries in* the AccountInfo array.*/static unsigned int NumAccounts = sizeof (AccountInfo) /

sizeof (AccountInfo[0]);

/* The CheckAcc method.*/ORBStatus AccStat_CheckAcc(Object object, 18

Environment *env,char *account,SeqCouple *record)

{unsigned int i;

vesp_log_info (VESP_CAT_ALL, "Info", "CheckAcc");log_unparsable ("Checking the account #%s\n", account);

if (AccountInfo == NULL) {vesp_set_exception (env, SYSTEM_EXCEPTION,VESP_DATABASE_EMPTY_ERROR, 19"Database is empty!");Failed_Requests++;return VESP_FAILURE;

} /* if */

Page 124: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

124 IC Client and Server Programmer�s Design Guide

/* When we get called, we simply loop through the AccountInfo array,* looking for an account number match. If we find one, we load up the* sequence of couples with all of the account information. If not,* we just print a message to the server log file.*/for (i = 0; i < NumAccounts; i++) {

if (!strcmp (AccountInfo[i].accnum, account)) {log_unparsable ("Account information for #%s "

"has been retrieved.\n",account);

vesp_couple_seq_add_couple_values (record, "AccountNumber",AccountInfo[i].accnum);

vesp_couple_seq_add_couple_values (record, "FirstName",AccountInfo[i].fname);

vesp_couple_seq_add_couple_values (record, "LastName",AccountInfo[i].lname);

vesp_couple_seq_add_couple_values (record, "AccountStatus",AccountInfo[i].accstatus);

env->_major = NO_EXCEPTION;Successful_Requests++;

return VESP_SUCCESS;

} /* if */} /* for */

if (record->_length == 0) {log_unparsable ("No account information for #%s\n", account);vesp_set_exception (env, USER_EXCEPTION, VESP_UNKNOWN_ACCOUNT_ERROR,

"Unknown account number");Failed_Requests++;return VESP_FAILURE;

} /* if */

return VESP_SUCCESS;} /* AccStat_CheckAcc */

Page 125: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Server : Server makefile

Issue 1.0 June 2002 125

Custom Telephony Server : Server makefile

###################################################################### VESP AccStat Server Makefile## @(#)makefile.sysv 1.0 10/2/95#####################################################################

CCFLAGS= -g -DUNIX=1 -v -XcCC=cc

RELEASE = /NAB/release/localTEST = /NAB/release/testINCLUDE=-I. -I$(RELEASE)OBJ_DIR = objs_$(MACHINE)VESP_LIB = $(RELEASE)/orb.a $(RELEASE)/tools.a \

$(RELEASE)/vnet.a -lsocket \-lnsl -lgen -lx

VESP_LIB2 = -lvesporb -lsocket -lnsl -lgen -lx

###########################################################accstatsrv: $(OBJ_DIR)/accstatsrvminsrv: $(OBJ_DIR)/minsrv###########################################################$(OBJ_DIR)/accstatsrv: $(OBJ_DIR)/accstat.o $(OBJ_DIR)/vespidl.o

$(CC) -o $@ $(OBJ_DIR)/accstat.o $(OBJ_DIR)/vespidl.o \$(VESP_LIB)@-chmod 777 $@

$(OBJ_DIR)/minsrv: $(OBJ_DIR)/minsrv.o $(OBJ_DIR)/vespidl.o$(CC) -o $@ $(OBJ_DIR)/minsrv.o $(OBJ_DIR)/vespidl.o \$(VESP_LIB)@-chmod 777 $@

###########################################################

$(OBJ_DIR)/vespidl.o: vespidl.c$(CC) $(CCFLAGS) -c $(INCLUDE) $?@-mv *.o $(OBJ_DIR)@-chmod 666 $@

$(OBJ_DIR)/accstat.o: accstat.c$(CC) $(CCFLAGS) -c $(INCLUDE) $?@-mv *.o $(OBJ_DIR)@-chmod 666 $@

$(OBJ_DIR)/minsrv.o: minsrv.c$(CC) $(CCFLAGS) -c $(INCLUDE) $?@-mv *.o $(OBJ_DIR)@-chmod 666 $@

clean:rm -f $(OBJ_DIR)/*.o

Page 126: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

126 IC Client and Server Programmer�s Design Guide

test:cp $(OBJ_DIR)/accstatsrv $(TEST)cp $(OBJ_DIR)/minsrv $(TEST)

all:make -f makefile.sysv accstatsrvmake -f makefile.sysv minsrv

Building SDK Custom ServersThis section provides instructions for building OOTB (out-of-the-box) SDK custom servers on either a Solaris 8 or Windows O/S. These custom servers can be designed to meet some of the needs of your environment that are not addressed by the CORBA servers provided OOTB with Avaya IC.

Solaris 8 EnvironmentThe Sun® Forte Developer 6, Update 2 (C compiler) must be installed on the system to build SDK custom servers on Solaris 8.

The IC 6.0 Software Development Kit (SDK) for Solaris 8 must also be installed on the system. Refer to the IC Installation and Configuration Guide for instructions.

To build custom servers on Solaris 8:1 Navigate to the <AVAYA_IC_HOME>\IC60\examples directory.

2 Make backup copies of the following executable binary files in the directory as a safety precaution.

� ctest.exe� test_server.exe� accstat.exe� minsrv.exe� ds_user_add.exe

3 Run the make program with the option clean at the system prompt.

Note: You may have to specify the full path of your make program if the path <AVAYA_IC_HOME>\IC60\bin\make clean is not included in your $PATH environment variable.

4 Run the make program with no option to compile the OOTB SDK Servers.

Page 127: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Testing OOTB SDK Custom Servers

Issue 1.0 June 2002 127

Windows NT or 2000 EnvironmentThe Microsoft® Visual Studio 6, SP 5 (C compiler) must be installed on the system to build SDK custom servers on Windows.

The IC 6.0 Software Development Kit (SDK) for Windows must also be installed on the system. Refer to the IC Installation and Configuration Guide for instructions.

To build custom servers on Windows NT or 2000:1 Start the MS Visual Studio program.

2 Navigate to the <AVAYA_IC_HOME>\IC60\examples directory.

3 Open servers.dsw.

4 Build the projects as required. Refer to your MS Visual Studio documentation for instructions.

Testing OOTB SDK Custom ServersAfter building the OOTB SDK custom servers:1 Move the test_server.exe file from the <AVAYA_IC_HOME>\IC60\examples directory to

the <AVAYA_IC_HOME>\IC60\bin directory.

2 Start IC Manager and follow these procedures to test them.

Make sure the ORB Server is running.1 Click on the Server tab.

2 Select the ORB Server from the list on the Server Manager.

3 Select the Server>Status menu option to display the ORB Server�s status on the Server Manager. If the server is running, the status is Up.

To start an ORB Server that is Down:1 Open the command line window for your Operating System.

2 Navigate to the <AVAYA_IC_HOME>\IC60\etc directory.

3 Type ..\bin\icadmin so at the command line.

4 Return to IC Manager and select Server>Status to display the ORB Server�s status. If the server is running, the status is Up.

Create a new server with the server type of TEST.1 Select the Server>New menu option to display the Select or enter server type dialog.

2 Type TEST the Server Type field. This is case sensitive, be sure to enter in uppercase.

3 Click the Ok button to display General tab of the Server Editor.

Page 128: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

128 IC Client and Server Programmer�s Design Guide

a Enter TEST in the Name field.

b Enter the appropriate IP address of the host in the Host Field.

c Select the domain to which you want to assign the server in the Domain field.

d Enter <AVAYA_IC_HOME>\IC60\bin\test_server.exe in the Executable field.

e Click the Ok button to add the server and return to the Server Manager.

4 Click on the parent Directory Server and select the Server>Update menu option to update it.

5 Click on all the ORB Servers and select the Server>Update menu option to update it.

6 Select the new TEST server and click on the Start Server button. The status of the server should be Up.

You should now be able to:� Display the status of the server through the Server>Status menu option and � Stop the server through the to Server>Stop menu option.

Page 129: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Testing OOTB SDK Custom Servers

Issue 1.0 June 2002 129

TroubleshootingThe following table provides troubleshooting tips for some of the common problems that occur when building SDK custom servers.

Problem Check for

Can�t build the custom server Make sure you are using the correct version of the compiler for the O/S in which you are building the server. � Solaris 7 - Sun® Forte Developer 6, Update 2

� Windows - Microsoft® Visual Studio 6, SP 5

An error is returned if you are not using this version of the compiler.

Problem running the test_server � Make sure the executable path is correct.

� Make sure the ORB Server is running on the machine where test_server.exe is installed.

� Make sure the test_server.exe file that was shipped with the SDK runs properly.

� Check the status of the TEST server on IC Manager. It should be Up with the correct Uptime.

� Try to run the test_server from the UNIX command line:

� Navigate to: <AVAYA_IC_HOME>/IC60/bin� Enter: run_util vespadmin ss <login> <pwd> TEST� Displays information on why the server is not running

The test_server crashes Contact Avaya Technical Support and email the core and log files to [email protected].

Page 130: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

130 IC Client and Server Programmer�s Design Guide

Custom Telephony Server : vespidl.idl file

/* ------------------------------------------------------------------------ *\* $Id: vespidl.idl,v 1.1 1995/07/18 21:58:32 greg Exp $** Description: Sample server IDL code** Copyright (c) 1998 by Quintus Corporation* ---- change log ----* $Log: vespidl.idl,v $* Revision 1.1 1995/07/18 21:58:32 greg* Initial revision*

\* ------------------------------------------------------------------------ */

#include "generic.idl"

interface AccStat : General {ORBStatus CheckAcc(in string account, out SeqCouple record);

};

Page 131: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Custom Telephony Server: IDL makefile

Issue 1.0 June 2002 131

Custom Telephony Server: IDL makefile

# Copyright 1998 (c) Quintus Corporation. All rights reserved.## This makefile should be executed whenever the user has added new# methods to vespidl.idl. It will regenerate vespidl.c, vespidl.h, and# other associated files.

# The following section defines some different directories where we# find files that we need. These variables should be tweaked on a# site-by-site basis. INCDIR2 should be set to the directory where orb.h# can be found. LIBDIR should be set to the directory where orb.a, tools.a# and vnet.a can be found. EXEDIR should be set to the directory where# idl, idlcgen, and idltype can be found. OBJDIR tells the compiler where# to put platform-dependent object files. This will allow multi-platform# builds to occur without wiping out object files from a previous compilation# on a different platform. The MACHINE environment variable is required to# be set to the following values depending on the platform:## Platform MACHINE value# Alpha alpha# SysV386 sysv386# Solaris sol# Stratus FTX ftx

RELDIR = /NAB/release/localINCDIR1 = .INCDIR2 = $(RELDIR)LIBDIR = $(RELDIR)EXEDIR = $(RELDIR)OBJDIR = objs_$(MACHINE)

# Convenience definitionsRM = rm -fLN = ln -s

# The "idlcgen" program needs to be in the current directory in order to# be accessed by "idl". We'll just do a symbolic link for the duration# of the compilation, then remove it. Just added the first line to remove# the idlcgen link if it is already there. If there is no link there,# then the rm command will not complain (-f flag does this).## WARNING: If a local copy of idlcgen has been installed into the source# directory, it will be removed by this target.all: vespidl.c

vespidl.c: vespidl.idl

vespidl.idl: generic.idl

vespidl.c:$(RM) ./idlcgen$(LN) $(EXEDIR)/idlcgen .

Page 132: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

Appendix C Server Code Example

132 IC Client and Server Programmer�s Design Guide

$(EXEDIR)/idl -c vespidl$(RM) ./idlcgen

# Invoke "make -f makefile.idl" to get rid of files that were generated# during the IDL compilation.clean::

$(RM) vespidl.c vespidl.h$(RM) vespidl.pk vespidl.pkt vespidl.pkh

Page 133: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

133

AADU (Agent Data Unit Server) 16ALARM (Alarm Server) 16Alarms 21appendix 93, 105, 117Asynchronous requests 39Avaya 9Avaya Interaction Center

overview 11servers, list of 14

BBinding, dynamic and static 33

CCallback functions 83

described 42passing data to 85

CI Repository 16Client development 47Client, example of 48Compiler, described 31Constants, describing 29Creating new data types 27

DData types 26

creating 27unsupported 28

Data types, adding 32Debugging techniques 23Deferred requests 85Describing constants 29Describing interfaces 28DS (Directory Server) 15

EEDU (Electronic Data Unit Server) 15Environment variable 19Events 20Examples

client 48deferred request 91

IDL makefile 131memory allocation 93, 105, 117server 62server makefile 125vespidl.idl 130

Exceptions 20

HHybrid interface, described 33

IIC Manager 16IDL Compiler 31Inheriting an interface 29Interface

describing 28inheriting 29virtual 29

Interface repository 18

MMakefile, IDL, example of 131Makefile, server, example of 125Memory allocation 83Memory management

asynchronous operations 43synchronous operations 37

Method functions 81Methods, described 28

OORBServer (Object Request Broker Server) 15

PPoll loop 60Preprocessing directives 30

RRequests

asynchronous 39deferred 85on behalf of clients 61

INDEX

Page 134: Avaya™ Interaction Center · Avaya™ Interaction Center Release 6.0 IC Client and Server Programmer’s Design Guide DXX-1026-02 Issue 1.0 June 2002 2002, Avaya Inc

134 IC Client and Server Programmer�s Design Guide

Index

servicing 81synchronous 34timing of 45

SScope rules in an IDL file 30Script (Workflow Designer ) 15Security levels 21Server

adding to Avaya IC 31application layer 61architecture of 59development 59example 62steps to building 31

Servicing requests 81Sessions 18Structures, adding 32Synchronous requests 34

TThe 18, 26, 33

Timeouts 21Timing of requests 45Toolkit

components 13description of 12

TS (Telephony Server) 14

UUnsupported data types 28User_data 85

VVesp_Request 41Vesp_Request_Sync 36Vespidl.idl

customizing 32vespidl.idl

example of 130vespidl.pk 18Virtual interface 29VOX (Voice Response Unit Server) 15VTel Engine 16