C H A P T E R  8

External Call Interface (ECI)

This chapter describes the Sun MTP Client External Call Interface (ECI) as used with the C programming language. The C function calls and defines are usable from C++.


ECI Example Code

You can find example code illustrating the use of ECI from the C programming language in $INSTROOT\EXAMPLES. $INSTROOT indicates the name of the directory where Sun MTP Client was installed.


How Does the Sun MTP ECI Work?

The Sun MTP ECI allows applications to call Sun MTP programs in a Sun MTP server. ECI is a method of gaining access to Sun MTP programs; it does not issue EXEC CICS commands, but instructs Sun MTP to execute programs to do the processing. The Sun MTP program then appears to have been called by EXEC CICS LINK with the COMMAREA option.

An ECI application can call any Sun MTP program as long as the program is written to follow the rules for Distributed Program Link (DPL):

An application can run multiple Sun MTP programs concurrently; either on the same or different Sun MTP regions.

When considering the use of ECI, note the following points

The complete ECI functionality comes from two API function calls:

CICS_ExternalCall()
Provides most of the functionality of ECI, as described in CICS_ExternalCall Call Types. The function takes a single parameter, which is a pointer to an ECI_PARMS block. It is the fields within this control structure that determine what functionality is performed. CICS_ExternalCall() describes this function.
CICS_EciListSystems()
Provides an interface for the programmer to inquire as to which server systems are configured for use. CICS_EciListSystems() describes the syntax.


CICS_ExternalCall Call Types

There are three types of calls to CICS_ExternalCall():

Program link
Causes program execution of the Sun MTP server.
Status information
Obtains connection information about specific systems.
Reply solicitation
Obtains results and status from previous program link calls.

In order to perform any of the above tasks, the eci_call_type field of the ECI_PARMS control block must be set to one of the required values. The values available are listed in TABLE 8-1.

TABLE 8-1 eci_call_type for Functions

Function

eci_call_type Values

Program link

ECI_SYNC

ECI_ASYNC

ECI_ASYNC_NOTIFY_MSG (Windows only)

ECI_ASYNC_NOTIFY_SEM (Windows only)

Status request

ECI_STATE_SYNC

ECI_STATE_ASYNC

ECI_STATE_ASYNC_MSG (Windows only)

ECI_STATE_ASYNC_SEM (Windows only)

Reply solicitation

ECI_GET_REPLY

ECI_GET_REPLY_WAIT

ECI_GET_SPECIFIC_REPLY

ECI_GET_SPECIFIC_REPLY_WAIT


In addition to the categorization in TABLE 8-1, a distinction must be made between synchronous and asynchronous call types:

Synchronous calls

The function does not return control to the application until the request has completed. This means that the request traveled over the network to the Sun MTP region, the program was scheduled, completed and the response is available. This may take considerable time, especially on busy systems and networks with a narrow bandwidth. During this time, the application making the synchronous call is unable to service requests; therefore, it cannot perform other tasks.


Note - Because of their behavior, synchronous calls are not recommended.



Asynchronous calls

On Windows, the ECI is thread safe. In this case, processing could continue on another thread, if required.
The function returns to the application as soon as the request is scheduled. This means that the application gets control back before the request is given to the network. The application can perform other work and is informed asynchronously when the request has completed. The result of the request is obtained using a reply solicitation call.

Program Link Calls

Program link calls are either synchronous or asynchronous. For asynchronous calls, it is the responsibility of the calling application to solicit the reply using one of the reply solicitation calls. See Reply Solicitation Calls.

Program link calls either initiate a program as part of a unit-of-work or to complete a unit-of-work. The functions that a program link call can perform are as follows:

Reply Solicitation Calls

Reply solicitation calls get information back after asynchronous program link or asynchronous status information calls. There are two types of reply solicitation calls:

An application that uses the asynchronous method of calling may have several program link and status information calls outstanding at any time. The eci_message_qualifier parameter in the ECI parameter block is used on an asynchronous call to provide a user-defined identifier for the call.



Note - The use of different identifiers for different asynchronous calls within a single application is the programmer's responsibility.



When a general reply solicitation call is made, ECI uses the eci_message_qualifier field to return the name of the call to which the reply belongs. When a specific reply solicitation call is made, it is necessary to supply a value in the eci_message_qualifier field to identify the asynchronous call about which information is being sought.

Within the Windows programming environment, the use of specific reply solicitation calls is recommended because when an ECI request is made, the application can be told when the reply for that request is ready. Therefore, there is enough information to specify which request to handle.

Status Information Calls

Status information calls can be either synchronous or asynchronous. For asynchronous calls, it is the responsibility of the calling application to obtain the reply using a reply solicitation call. See Reply Solicitation Calls.

Status information is supplied in the ECI status block (ECI_STATUS), which is passed across the interface in the eci_commarea parameter.

The ECI status block contains the following status information

The status information calls allow you to perform these tasks

The format of the status request block is described in ECI Data Structures.


Application Design

Application design is different between Solaris and Windows environments because of the different paradigms that are usually followed for applications in those environments. This section describes the management of logical units-of-work, which is common to all platforms, and provides guidelines for programming in the Windows and Solaris environments.

Managing Logical Units-of-Work

An ECI application is often concerned with updating recoverable resources on the server. The application programmer must understand the facilities that ECI provides for managing logical units-of-work. A logical unit-of-work is all the processing in the server that is needed to establish a set of updates to recoverable resources. When the logical unit-of-work ends normally, the changes are all committed. When the logical unit-of-work ends abnormally, for instance because a program abends, the changes are all backed out. You can use ECI to start and end logical units-of-work on the server.

The changes to recoverable resources in a logical unit-of-work are affected by



caution icon

Caution - Be careful when extending a logical unit-of-work across multiple program link calls that may span a long time. Logical units-of-work hold locks and other Sun MTP resources on the server; this may cause delays to other users who are waiting for those same locks and resources.



When a logical unit-of-work ends, the Sun MTP server attempts to commit the changes. The last, or only, program link call of a logical unit-of-work is advised if the attempt was successful.

Only one program link call per logical unit-of-work can be outstanding at any time. (An asynchronous program link call is outstanding until a reply solicitation call has processed the reply.)

The techniques required to manipulate units-of-work from ECI are illustrated in Common ECI Scenarios. Using these techniques, an application can manage the control flow within the unit-of-work to perform the tasks required.

Each logical unit-of-work ties up one Sun MTP non-facility task for the duration of its execution. This means that you must define enough free tasks in the Sun MTP server to service the maximum expected number of concurrent calls. The number of tasks is affected by the TCPRTERM environment variable described in Configuring Sun MTP for a TCP/IP Connection to Sun MTP Client and by the number of transaction servers created when Sun MTP is started. For example, if you need six concurrent units-of-work to the same Sun MTP region, set $TCPRTERM to at least six; the number of transaction servers must also be set to at least six in the VSAM Configuration Table (VCT).

An ECI application is not restricted to running a single unit-of-work at any one time. An application can perform many simultaneous units-of-work directed at one or many Sun MTP regions. These units-of-work are independent of each other, and can be controlled by the application so that they work in harmony. For example, an application may need to obtain data from two different regions for display on the screen. Obtaining the data would be done with an ECI call to each of the regions, both running simultaneously but within separate units-of-work. The data is then received by the application and displayed to the end user as required.

As described in How Does the Sun MTP ECI Work? and CICS_ExternalCall Call Types, ECI provides a series of methods for performing the same user functionality.

Designing an Application for Windows

This section describes programming methods that work best in a Windows environment.

Since Windows is a multi-threaded environment, it is possible, and in some cases desirable, to design applications using synchronous ECI calls. When these calls are executed from multiple threads, it is possible to have multiple synchronous units-of-work active at any one time. However, the creation of multi-threaded applications is problematic since it normally requires a lot of work to synchronize multiple threads.

It is easier, and more effective to use the notification facilities available on asynchronous calls within the Windows environment. This enables the application to be written as a normal Windows application and to have notification of completion of DPLs done via a variety of mechanisms. Thus, ECI can easily be fitted into the design of the rest of the application.

The most important of the notification mechanisms is the Windows message. When using this mechanism, the application is notified that work has completed by posting a Windows message. The message parameters informs the application what has happened to each ECI request. The application then uses the reply solicitation calls to obtain the completed results of the work. This message posting method fits normal Windows programming modes where an application is mainly concerned with the presentation to the user. The message posted to the application concerning ECI completion is the same as all other Windows messages.

There are two other notification mechanisms the semaphore and the callback. Semaphore notification is a misnomer because the notification is actually via a Windows Event.

An application creates an Event, and when an ECI request completes, ECI signals the Event. Then the application can use the WaitForSingleObject() and WaitForMultipleObjects() system calls to wait for the completion of the request.

The callback notification mechanism is less useful but may be what an application requires. Using this mechanism, a user-defined function is executed when an ECI request completes. The callback routine should not perform large amounts of work. An application must not call ECI in that callback, so the callback normally just notifies the rest of the application that there is work to be done to receive the reply. On Windows, this callback is made on a separate thread that is owned by ECI.

ECI is not used to notify the application about the completion of the call. Here, it is the responsibility of the application to solicit the reply when it is appropriate. If there is no reply ready, the relevant return code is returned from the ECI solicitation call.

Designing an Application for Solaris

This section describes programming methods that work best in a Solaris environment.

There are two choices for application design:

The application blocks during the processing of a DPL. In many cases, this is satisfactory.
Some applications require many units-of-work active at any one time. On the Solaris implementation, there is only one method of asynchronous request notification, the callback. However, there are several design issues with this callback mechanism.

Sun MTP Client communicates with an application via named pipes. Since Sun MTP Client is single threaded, data can only be read from the pipe when an application calls into the ECI/EPI interface. It is only at this point that any callbacks can be performed. Thus, notification callbacks are only performed while processing other ECI/EPI functions. These limitations can cause problems when designing an application that works effectively. To simplify this process, use the KixCli_QueryFD() function, which returns a standard UNIX file descriptor that is the pipe used for communications. An application can use the select() function call to wait until there is information for the ECI/EPI to process. When the application is told that there is data, it should call into the ECI/EPI APIs to ensure any callbacks are performed.

The supplied sample ECIEX2 shows how this mechanism can be fitted into a curses application that performs multiple concurrent units-of-work, while simultaneously servicing user input.


ECI Data Structures

The tables in this section define the following ECI data structures:

TABLE 8-3 ECI_PARMS Structure Fields

Field

Type

Description

eci_call_type

sshort

The primary call type that is modified by the eci_extend_mode field, which together define the call being requested.

eci_program_name

char[8]

Name of the program to execute on the Sun MTP server.

eci_userid

char[8]

User ID for server security checking.

eci_password

char[8]

Password for server security checking.

eci_transid

char[4]

The transaction name under which the program will run, as available to the Sun MTP program via the EIBTRNID field.

eci_abend_code

char[4]

The abend code that is returned from a failed program. This can also be set for some ECI Client side errors.

eci_commarea

char *

A pointer to the COMMAREA. Data is either sent from, or placed into this area (or both), depending on the call type.

eci_commarea_length

sshort

The length of the eci_commarea block.

eci_timeout

sshort

A timeout in seconds for a request. This is normally set to 0 to indicate no timeout; only set to other values in rare instances.

eci_sys_return_code

sshort

A return code that provides extended information about a failure. This field is never set by the ECI Client.

eci_extend_mode

sshort

A modifier to the eci_call_type field. Together with eci_call_type, this field fully defines the functionality required.

eci_window_handle

HWND

Window handle of a window that receives posted messages upon completion of asynchronous calls. (Windows Only)

eci_hinstance

HINSTANCE

Ignored by the ECI Client.

eci_message_id

ushort

ID of the message that is sent to the eci_window_handle window upon completion of asynchronous calls.

eci_message_qualifier

sshort

User-defined value that is used to identify different asynchronous calls.

eci_luw_token

slong

A token returned by some ECI calls and used as input by others, to identify the unit-of-work that is being acted on.

eci_sysid

char[4]

Ignored by the ECI Client.

eci_version

sshort

The version of ECI in use. For new applications, set to ECI_UNIKIX_VERSION_1. However, Sun MTP Client also supports ECI_VERSION_1 for compatibility with the IBM Client ECI.

eci_system_name

char[8]

Name of the Sun MTP server, which are any of the values specified in the [Systems] section of the INI file (obtained with the CICS_EciListSystems() call). Alternatively, you can use the default system by specifying NULLs in this parameter. Note that this parameter is ignored on some calls.

eci_callback

func*

A pointer to a callback routine that may be called on completion of an asynchronous request.

eci_userid2

char[16]

Ignored.

eci_password2

char[16]

Ignored.

eci_tpn

char[4]

The transaction ID under which the program actually runs instead of CPMI. This value is ignored for ECI_VERSION_1 and ECI_UNIKIX_VERSION_1.



ECI Functions

This section lists and describes the syntax of the two ECI functions.

CICS_ExternalCall()

CICS_ExternalCall() gives access to the program link calls, status information calls, and reply solicitation calls described in the previous section. The eci_call_type field in the ECI parameter block controls the function performed.

Format

cics_sshort_t CICS_ExternalCall(ECI_PARMS *EciParms);

where EciParms is a pointer to an ECI parameter block. Different fields within this block are required for the different call types. Later sections describe those required for the normal usage of the CICS_ExternalCall().

Before calling this function, set the entire block to NULL before setting the relevant fields. See TABLE 8-3 for a description of the ECI_PARMS structure fields.

Common ECI Scenarios contains examples of the CICS_ExternalCall() and describes which calls and control block values are needed for a particular use.

Return Codes

ECI_NO_ERROR
The call to CICS_ExternalCall() was successful.
ECI_ERR_INVALID_DATA_LENGTH
The eci_commarea length is invalid and is caused by one of the following
eci_commarea length < 0
eci_commarea length > 32500
eci_commarea length = 0 and
eci_commarea is not a NULL pointer
eci_commarea length > 0 and
eci_commarea is a NULL pointer
ECI_ERR_INVALID_EXTEND_MODE
The value of eci_extend_mode is either invalid, or not appropriate to the value of eci_call_type.
ECI_ERR_NO_CICS
Either the ECI Client is unavailable, or the server is not available.
ECI_ERR_CICS_DIED
The Sun MTP Server that is servicing an extended unit-of-work is no longer available. When this occurs, it is not possible to determine if the resource changes were committed or backed out. Log this event to aid in manual recovery of the resources involved.
ECI_ERR_NO_REPLY
A reply solicitation has asked for a reply when none is available.
ECI_ERR_RESPONSE_TIMEOUT
The request has timed out before completion. When this occurs, it is not possible to determine if resource changes were committed or backed out. Log this event to aid in manual recovery of the resources involved.
ECI_ERR_TRANSACTION_ABEND
The request to which this call refers has caused the Sun MTP transaction to abend. The abend code is returned in the eci_abend_code field of the ECI_PARMS structure.
ECI_ERR_LUW_TOKEN
The eci_luw_token field contains an invalid value.
ECI_ERR_SYSTEM_ERROR
An internal error has occurred.
ECI_ERR_NULL_WIN_HANDLE
The eci_window_handle field specified does not refer to an existing window.
ECI_ERR_NULL_SEM_HANDLE
The eci_sem_handle field specified is NULL.
ECI_ERR_NULL_MESSAGE_ID
The eci_message_id field is 0.
ECI_ERR_INVALID_CALL_TYPE
The eci_call_type field contains an invalid value.
ECI_ERR_ALREADY_ACTIVE
An attempt was made to continue a unit-of-work while an existing request for that unit-of-work was active.
ECI_ERR_RESOURCE_SHORTAGE
There were insufficient system resources to satisfy the request.
ECI_ERR_NO_SESSIONS
The application attempted to create a new unit-of-work when the ECI Client had reached its maximum allowed number of concurrent units-of-work.
ECI_ERR_INVALID_DATA_AREA
Either the pointer to the ECI_PARMS structure is NULL, or the eci_commarea pointer is NULL when it is not expected to be NULL.
ECI_ERR_INVALID_VERSION
The eci_version field is not one of ECI_UNIKIX_VERSION_1, ECI_UNIKIX_VERSION_1A, ECI_VERSION_1 or ECI_VERSION_1A.
ECI_ERR_UNKNOWN_SERVER
The eci_system_name field contains an unknown system.
ECI_ERR_CALL_FROM_CALLBACK
A call to CICS_ExternalCall() was made from inside a callback routine. This is not allowed.
ECI_ERR_INVALID_TRANSID
The value in eci_transid is different from the one specified in previous calls in the same unit-of-work.
ECI_ERR_SECURITY_ERROR
The eci_userid/eci_password pair that was supplied were invalid.
ECI_ERR_MAX_SYSTEMS
The number of systems that the ECI Client can talk to concurrently is reached.
ECI_ERR_ROLLEDBACK
When attempting to commit a unit-of-work, the Sun MTP region was unable to do so, and rolled the changes back.

CICS_EciListSystems()

The CICS_EciListSystems() function enables the programmer to obtain a list of remote systems at which ECI requests can be directed. The list of systems returned is the set of systems defined in the KIXCLI.INI file (see Adding Systems to the KIXCLI.INI File). A system appearing in the list does not mean that a connection exists to the remote system; it only indicates that the system is defined in the KIXCLI.INI file.

On successful return from this function, the array pointed to by the List parameter contains details of the systems; the Systems parameter is updated to reflect the number of systems that are available.

The systems returned by this function allow an application to provide a valid Systems parameter to the CICS_ExternalCall() function. The only valid values for the Systems parameter are those returned by this call and a special value consisting of eight spaces.

Format

cics_sshort_t CICS_EciListSystems(cics_char_t *NameSpace,cics_ushort_t *Systems,CICS_EciSystem_t *List);

where:

NameSpace

Must be set to a NULL pointer; it is ignored.

Systems

Pointer to a number. On entry, it contains the number of CICS_EciSystem_t structures that can fit into the area of storage pointed to by the List parameter. On return, it contains the number of systems that exist, regardless of how many were requested.

List

Pointer to an area of storage that contains details of the systems defined. It only contains the information found in the Systems area.


The following table describes the fields within the CICS_EciSystem_t structure.

TABLE 8-4 CICS_EciSystem_t Structure Fields

Field

Type

Description

SystemName

char[9]

Name of the remote system, which is a NULL- terminated character string obtained from the KIXCLI.INI file. Also used in the CICS_ExternalCall() function to perform remote requests.

Description

char[61]

Textual description of the system obtained from the KIXCLI.INI file.


Return Codes

ECI_NO_ERROR
The call to CICS_EciListSystems() was successful.
ECI_ERR_INVALID_DATA_LENGTH
The value of Systems is such that the amount of storage in the List parameter exceeds 32767 bytes.
ECI_ERR_NO_CICS
The ECI Client is unavailable.
ECI_ERR_SYSTEM_ERROR
An internal error has occurred.
ECI_ERR_INVALID_DATA_AREA
The List parameter is NULL, and the Systems parameter is non-zero.
ECI_ERR_CALL_FROM_CALLBACK
A call to CICS_EciListSystems() was made from inside a callback routine. This is not allowed.
ECI_ERR_NO_SYSTEMS
The number of systems defined in the KIXCLI.INI file is 0.
ECI_ERR_MORE_SYSTEMS
The number of systems in the KIXCLI.INI file is greater than the number requested in the List parameter. In this case, the value in the List parameter is the number of systems that exist.

KixCli_QueryFD()

This function is only available on Solaris and enables the programmer to determine the file descriptor (FD) that is being used for communications between the application process and the Client process. It is an extension to enable the writing of efficient ECI and EPI applications.

When asynchronous API calls are made, there is no way for the application to know when a reply is available. The application process is single threaded, so the only way that the ECI/EPI APIs can know when data is ready is for the application is to make calls into the APIs. In addition, the application does not know when data is ready to be received.

The KixCli_QueryFD() function allows an application to obtain the FD that is used for communications. Giving this to the application allows it to use the system select() function call to determine when there is work for the ECI/EPI APIs to perform. After an application finds that there is incoming data on the FD, it should make a call into the ECI/EPI APIs to enable the data to be read and processed. The type of call does not matter; the purpose of the call is to allow the data to be read and any callbacks to occur. For example, the application could call KixCli_QueryFD() again, which has no real effect, but allows the callbacks to occur.

The supplied samples, ECIEX2 and EPIEX2, demonstrate the use of this call to enable the processing of curses I/O while concurrently performing ECI and EPI requests.

Format

cics_sshort_t KixCli_QueryFD( int *pFD );

where:

pFD
Pointer to an FD that is returned by this call.

Return Codes

ECI_NO_ERROR
The call to KixCli_QueryFD() was successful.
ECI_ERR_FROM_CALLBACK
The call to KixCli_QueryFD() was made while processing a callback.
ECI_ERR_NO_CICS
Could not contact the Sun MTP Client.


Common ECI Scenarios

This section describes the sample applications supplied with Sun MTP Client and demonstrate some methods for using ECI. Only those relevant to your platform are provided.

ECI provides a variety of mechanisms to create and use units-of-work. The first thing you must do when designing an application is to decide on the requirements for reply notification.



Note - Since some methods only apply to certain platforms, read the guidelines in Application Design before using this section.



When deciding which of these scenarios most closely matches your requirements, consider the programs that you are going to execute on the Sun MTP server.

Answering these questions should enable you to chose the appropriate programming model.

Performing a One-Shot DPL

The most frequently required functionality available from ECI is to perform a unit-of-work that consists of a single DPL to a Sun MTP region. It is normally used for a single set of updates or a single set of queries directed at a single region. Many applications require this functionality.

Performing a One-shot Asynchronous DPL Using Message Notification



Note - This is only available on Windows platforms.



Performing an asynchronous DPL consists of three actions:

1. The application must first call CICS_ExternalCall(), telling it to perform the work, and informing it how to notify the application program of any reply.

2. It must wait until it receives notification that the request is complete.

3. It must call CICS_ExternalCall() again to perform a reply solicitation call to obtain the results of the request.

The first part of the process gets ECI to perform the request. This is done with the CICS_ExternalCall() function with the ECI_PARMS block set with the values listed in TABLE 8-5. Set all other parameters to NULL.

TABLE 8-5 ECI_PARMS Values for One-Shot Asynchronous DPL Using Message Notification

Field

Value

eci_call_type

ECI_ASYNC_NOTIFY_MSG

eci_program_name

Name of the program to execute as specified in the PPT of the Sun MTP region.

eci_userid

User ID under which to execute the program.

eci_password

Password corresponding to the eci_userid.

eci_commarea

Pointer to the space allocated within the application for the data to pass to the Sun MTP region.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field.

eci_extend_mode

ECI_NO_EXTEND

eci_message_qualifier

User-defined value that you can specify so that, upon receipt of notification messages, the application can determine to which unit-of-work the notification corresponds.

eci_version

UNIKIX_ECI_VERSION_1

eci_system_name

Name of the system that is the destination for this request. This name is either one of the names returned from the CICS_EciListSystems() call, or set it to all NULLs, in which case, the default server is used (as defined in KIXCLI.INI).

eci_window_handle

Window handle of a window that receives posted messages upon completion of this request.

eci_message_id

ID of the message that is sent to the eci_window_handle window upon completion of this request.


After this call completes, the ECI Client fills the eci_luw_token field in the ECI_PARMS structure. This field contains an ECI Client LUW token, which serves no purpose for this type of request.

The eci_call_type value specified in TABLE 8-5 means that a message with the identifier eci_message_id is posted to the window specified in the eci_window_handle field.

Format

wParam

Return code of the asynchronous call.

lParam

Low order 16 bits contain the eci_message_qualifier specified on the asynchronous call.


On receipt of this message, the application should perform the ECI request to obtain the results of the DPL. This is done by another call to CICS_ExternalCall(), but this time with the parameter block set with the values shown in TABLE 8-6. Set all other fields to NULL.

TABLE 8-6 ECI_PARMS Value for Obtaining a Specific Reply

Field

Value

eci_call_type

ECI_GET_SPECIFIC_REPLY

eci_commarea

Pointer to space allocated within the application for the data that the Sun MTP region returns. This data must be the same length as the original data sent on the DPL.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field.

eci_message_qualifier

Message qualifier that was specified on the original DPL call.

eci_version

ECI_UNIKIX _VERSION_1


After this call completes, the comm area specified in the eci_commarea field contains the returned data. The unit-of-work, as far as the Sun MTP server is concerned, is complete; any changes are committed.

This call may have modified the following field:

eci_abend_code

If the transaction running this unit-of-work abended, the abend code is placed in this field.


After this reply is received, the unit-of-work is complete.

Performing a One-Shot Asynchronous DPL Using Semaphore Notification



Note - This is only available on Windows platforms.



Performing an asynchronous DPL consists of three actions:

1. The first part of the process gets ECI to perform the request. This is done with the CICS_ExternalCall() function with the ECI_PARMS block set up with the values listed in TABLE 8-7. Set all other parameters to NULL.

TABLE 8-7 ECI_PARMS Values for One-Shot Asynchronous DPL Using Semaphore Notification

Field

Description

eci_call_type

ECI_ASYNC_NOTIFY_SEM

eci_program_name

Name of the program to execute as specified in the PPT of the Sun MTP region.

eci_userid

User ID under which to execute the program.

eci_password

Password corresponding to the eci_userid.

eci_commarea

Pointer to space allocated within the application for the data to pass to the Sun MTP region.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field.

eci_extend_mode

ECI_NO_EXTEND

eci_message_qualifier

User-defined value that you can specify so that, upon receipt of notification messages, the application can determine to which unit-of-work the notification corresponds.

eci_version

UNIKIX_ECI_VERSION_1

eci_system_name

Name of the system that is the destination for this request. This name is either one of the names returned from the CICS_EciListSystems() call, or set it to all NULLs, in which case, the default server is used (as defined in KIXCLI.INI).

eci_sem_handle

Handle of a system Event that is set when the request is complete.


After this call completes, the ECI Client fills the eci_luw_token field in the ECI_PARMS structure, which contains an ECI Client LUW token. This serves no purpose for this type of request.

The eci_call_type value specified in TABLE 8-7 means that the Event specified in the eci_sem_handle parameter is set when the request completes. An application can use the Windows functions WaitForMultipleObjects() and WaitForSingleObject() to wait for this to happen.

When an application receives notification of completion, it should perform the ECI request to obtain the results of the DPL. This is done by another call to CICS_ExternalCall(), but this time with the parameter block set with the values shown in TABLE 8-6. Set all other fields to NULL.

After this call completes, the comm area specified in the eci_commarea field contains the returned data. The unit-of-work, as far as the Sun MTP server is concerned, is complete, and any changes made are committed.

This call may have modified the following field:

eci_abend_code

If the transaction running this unit-of-work abended, then the abend code is placed in here.


After this reply is received, the unit-of-work is complete.

Performing a One-Shot Asynchronous DPL Using Callback Notification

Performing an asynchronous DPL consists of three actions:

1. The application must first call CICS_ExternalCall(), telling it to perform the work, and informing it how to notify the application program of any reply.

2. It must wait until it receives notification that the request is complete.

3. It must call CICS_ExternalCall() again to obtain the results of the request.

There are two areas of added complexity for callback notification:

For Windows, the callback is called on a different thread than the rest of the application. Thus, the callback can happen at any point in the processing of the applications other threads. Therefore, it is important that any work done inside the callback is thread-safe.

For the Solaris environment, the Sun MTP Client communicates with an application via named pipes. Since the application is single-threaded, data can only be read from the pipe when the application calls into the ECI interface. It is only at this point that any callbacks can be performed. Therefore, notification callbacks are only performed while processing other ECI functions.

These limitations can cause problems when designing an application on Solaris that works effectively. In order to simplify this process, you can use the KixCli_QueryFD() function, which returns a standard UNIX file descriptor that is the pipe that is used for the communications. An application can use the select() function call to wait until there is information for the ECI to process. When the application is told that there is data, it should call into the ECI interface to get any necessary callbacks processed. The supplied samples show how you can use this method to enable curses applications to work cleanly with the ECI. The first part of the process is to get ECI to perform the request. This is done with the CICS_ExternalCall() function with the ECI_PARMS block set up with the values listed in TABLE 8-8. Set all other parameters to NULL.

TABLE 8-8 ECI_PARMS Values for One-Shot Asynchronous DPL Using Callback Notification

Field

Value

eci_call_type

ECI_ASYNC

eci_program_name

Name of the program to execute as specified in the PPT of the Sun MTP region.

eci_userid

User ID under which to execute the program.

eci_password

Password corresponding to the eci_userid.

eci_commarea

Pointer to the space allocated within the application for the data to pass to the Sun MTP region.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field.

eci_extend_mode

ECI_NO_EXTEND

eci_message_qualifier

User-defined value you can specify so that, upon receipt of notification messages, the application can determine to which unit-of-work the notification corresponds.

eci_version

UNIKIX_ECI_VERSION_1

eci_system_name

Name of the system that is the destination for this request. This name is either one of the names returned from the CICS_EciListSystems() call, or it set to all NULLs, in which case the default server is used (as defined in KIXCLI.INI).

eci_callback

Pointer to a function to call when a response is ready.


After this call completes, the ECI Client fills the eci_luw_token field in the ECI_PARMS structure, which contains an ECI Client LUW token. This serves no purpose for this type of request.

The eci_call_type value specified in TABLE 8-8 means that the callback specified in the eci_callback parameter is executed when the request completes.

When an application receives notification of completion, it should perform the ECI request to obtain the results of the DPL. This is done by another call to CICS_ExternalCall(), but with the parameter block set with the values shown in TABLE 8-6. Set all other fields to NULL.

After this call completes, the memory location specified in the eci_commarea field contains the returned data. The unit-of-work, as far as the Sun MTP server is concerned, is complete; any changes made are committed.

The following field may have been modified by this call:

eci_abend_code

If the transaction running this unit-of-work abended, then the abend code is placed in here.


After this reply is received, the unit-of-work is complete.

Performing a One-Shot Synchronous DPL

Performing a synchronous DPL consists of a single action. The application must make a single call to CICS_ExternalCall(), telling it to perform the work. The call to CICS_ExternalCall() is done with the ECI_PARMS block set with the values listed in TABLE 8-9. Set all other parameters to NULL.

TABLE 8-9 ECI_PARMS Values for One-Shot Synchronous DPL

Field

Value

eci_call_type

ECI_SYNC

eci_program_name

Name of the program to execute as specified in the PPT of the Sun MTP region.

eci_userid

User ID under which to execute the program.

eci_password

Password corresponding to the eci_userid.

eci_commarea

Pointer to space allocated within the application for the data to pass to the Sun MTP region.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field.

eci_extend_mode

ECI_NO_EXTEND

eci_version

UNIKIX_ECI_VERSION_1

eci_system_name

Name of the system that is the destination for this request. This name is either one of the names returned from the CICS_EciListSystems() call, or it set it to all NULLs, in which case, the default server is used (as defined in KIXCLI.INI).


After this call completes, the memory location specified in the eci_commarea field contains the returned data. The unit-of-work, as far as the Sun MTP server is concerned, is complete, and any changes made are committed.

The call may have modified the following field:

eci_abend_code

If the transaction running this unit-of-work abended, then the abend code is placed in here.


After this call returns, the unit-of-work is complete.

Starting a Multiple Part Unit-of-Work

The method for starting a multiple part unit-of-work is similar to that of starting a unit-of-work consisting of a single program. For asynchronous, the application must perform the same steps for issuing the request, waiting for notification of the results, and obtaining the results. The most significant difference is that after obtaining the results, the unit-of-work is not over, and it can be extended to the users requirements.

Therefore, to initiate a long running unit-of-work, follow the same steps as a one-shot DPL, with the exception that you must set the eci_extend_mode parameter on the initial call to CICS_ExternalCall() to ECI_EXTEND instead of ECI_NO_EXTEND. On return from the initiating call to CICS_ExternalCall(), the eci_luw_token contains a value that must be supplied to later calls. You should store this value to facilitate the completion of the unit-of -work.

After the reply is received, the unit-of-work is ready to be extended or completed.



caution icon

Caution - At this point, an Sun MTP transaction server process is tied-up awaiting a reply. Therefore, it is unavailable to run other Sun MTP transactions. Do not leave a transaction processor in this state any longer than necessary.



Continuing a Long Running Unit-of-Work

To continue a long running unit-of-work, you must have initiated a unit-of-work, using methods similar to those described in Starting a Multiple Part Unit-of-Work. You must retain the eci_luw_token returned by the call to CICS_ExternalCall() that initiated the unit-of-work to use in these extensions to the unit-of-work.

The steps required for continuing a unit-of-work are the same as those for initiating one. A call to CICS_ExternalCall() must be made to run a program. These is either synchronous or asynchronous. The only significant difference between continuing a unit-of-work and initiating one is that the eci_luw_token field in the ECI_PARMS structure must contain the value that was returned on the original initiating program call. If the eci_no_extend of the latest DPL initiating call is set to ECI_EXTEND, then after the reply is received, the unit-of-work is complete, and the eci_luw_token that was stored away is no longer valid. If the eci_extend_mode is ECI_EXTEND, the unit-of-work is ready to have more action applied to it after the reply is received.

Explicitly Syncpointing a Unit-of-Work

To syncpoint a unit-of-work, you must have initiated a unit-of-work, using the methods described in Starting a Multiple Part Unit-of-Work. You must retain the eci_luw_token returned by the call to CICS_ExternalCall() that initiated the unit-of-work for use in these extensions to the unit-of-work.

The steps required for syncpointing a unit-of-work are the same as those for initiating one. You must make a call to CICS_ExternalCall() to syncpoint the unit-of-work, and if necessary, the application then waits until a reply is ready; then, it gets the reply. The significant difference is that the eci_luw_token field in the ECI_PARMS structure must contain the value that was returned on the original program call.

The first part of the process is to get ECI to perform the request. This is done with the CICS_ExternalCall() function with the ECI_PARMS block set up with the values given in TABLE 8-10. Set all other parameters to NULL.

TABLE 8-10 ECI_PARMS Values for Syncpointing a Unit-of-Work

Field

Value

eci_call_type

ECI_ASYNC_NOTIFY_MSG, ECI_ASYNC_NOTIFY_SEM, or ECI_SYNC

eci_commarea

NULL pointer because no program is to be run.

eci_commarea_length

0 because no program is to be run.

eci_extend_mode

ECI_COMMIT

eci_luw_token

Token returned by the initial ECI call in this unit-of-work.

eci_message_qualifier

User-defined value you can specify so that, upon receipt of notification messages, the application can determine to which unit-of-work the notification corresponds. This value does not have to be the same as the value for the original request.

eci_version

ECI_UNIKIX_VERSION_1

eci_window_handle

Window handle of a window that received posted messages upon completion of this request. (For ECI_ASYNC_NOTIFY_MSG.)

eci_message_id

ID of the message that is sent to the eci_window_handle window upon completion of this request. (For ECI_ASYNC_NOTIFY_MSG.)

eci_sem_handle

Handle of a system Event that is set when the request is complete. (For ECI_ASYNC_NOTIFY_SEM.)


After this call is complete and the reply received, if necessary, the unit-of-work, as far as the Sun MTP server is concerned, is complete, and any changes made are committed.

Rolling Back a Unit-of-Work

In order to roll back a unit-of-work, you must have initiated a unit-of-work, using methods similar to those described in Starting a Multiple Part Unit-of-Work. You must retain the eci_luw_token returned by the call to CICS_ExternalCall() that initiated the unit-of-work for use in these extensions to the unit-of-work.

The basic steps required for rolling back a unit-of-work are the same as those for syncpointing one. A call to CICS_ExternalCall() must be made to roll back the unit-of-work, the application then waits until a reply is ready, then it receives the reply.

The first part of the process is to get ECI to perform the request. This is done with the CICS_ExternalCall() function with the ECI_PARMS block set up with the values given in TABLE 8-11. Set all other parameters to NULL.

TABLE 8-11 ECI_PARMS Values for Rolling Back a Unit-of-Work

Field

Value

eci_call_type

ECI_ASYNC_NOTIFY_MSG

eci_commarea

NULL pointer because no program is to be run.

eci_commarea_length

0 because no program is to be run.

eci_extend_mode

ECI_BACKOUT

eci_luw_token

Token returned by the initial ECI call in this unit-of-work.

eci_message_qualifier

User-defined value you can specify so that, upon receipt of notification messages, the application can determine to which unit-of-work the notification corresponds. This value does not have to be the same as the value for the original request.

eci_version

ECI_UNIKIX_VERSION_1

eci_window_handle

Window handle of a window that receives posted messages upon completion of this request. For ECI_ASYNC_NOTIFY_MSG.

eci_message_id

ID of the message that is sent to the eci_window_handle window upon completion of this request. For ECI_ASYNC_NOTIFY_MSG.

eci_sem_handle

Handle of a system Event that is set when the request is complete. For ECI_ASYNC_NOTIFY_SEM.


After this call is complete and the reply is received, if necessary, the unit-of-work, as far as the Sun MTP server is concerned, is over; any changes made have been rolled back.

Interrogating Connections to a Remote System

Using the ECI, it is possible to make a call to interrogate the ECI Client as to whether there is a connection to a specified Sun MTP region. To do this, the application must call CICS_ExternalCall() with the parameters set as shown in TABLE 8-12. Set all other parameters to NULL.

TABLE 8-12 ECI_PARMS Values for ECI_STATE_ASYNC Call

Field

Value

eci_call_type

ECI_STATE_ASYNC_MSG

eci_commarea

Pointer to a space allocated within the application for a structure of type ECI_STATUS.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field (size of ECI_STATUS).

eci_extend_mode

ECI_STATE_IMMEDIATE

eci_message_qualifier

User-defined value you can specify so that, upon receipt of notification messages, the application can determine to which unit-of-work the notification corresponds.

eci_version

ECI_UNIKIX_VERSION_1

eci_window_handle

Window handle of a window that receives posted messages upon completion of this request.

eci_message_id

ID of the message that is sent to the eci_window_handle window upon completion of this request.


After ECI has completed the request, a notification message is posted to the eci_window_handle window. On receipt of this message, the application should solicit the results of the request using a call to CICS_ExternalCall() with the values listed in TABLE 8-13 set within the ECI_PARMS structure.

TABLE 8-13 ECI_PARMS Values for STATE_ASYNC_MESSAGE Reply Solicitation

Field

Value

eci_call_type

ECI_GET_SPECIFIC_REPLY

eci_commarea

Pointer to a space allocated within the application for a structure of type ECI_STATUS.

eci_commarea_length

Length of the data block pointed to by the eci_commarea field; size of ECI_STATUS.

eci_message_qualifier

Message qualifier that was specified on the original call and returned as part of the notification function.

eci_version

ECI_UNIKIX_VERSION_1


The ECI_STATUS structure now contains the values. For the meanings of these fields, see TABLE 8-2.

In addition to this basic status request, it is possible to have ECI notify the application when the status of a particular system changes. or example, you can use this to alert you when a system is ready for work. Set the following parameters to issue a call to CICS_ExternalCall():

eci_call_type

ECI_STATE_ASYNC_MSG

eci_extend_mode

ECI_STATE_CHANGED


After this is done, a notification is sent when the system state changes from that specified in the eci_commarea fields.

Using Callbacks

You can call ECI to generate callbacks instead of Windows messages. Performing a One-Shot DPL through Interrogating Connections to a Remote System detail how to generate notification via Windows messages using the eci_window_handle parameter of the ECI_PARMS structure.

To generate callbacks instead of Windows messages, set the eci_window_handle parameter to NULL, and set the eci_callback parameter as a pointer to a callback function. After this is set up and an ECI request completes, the callback function is called. The callback function receives a single value as its parameter, the eci_message_qualifier field, as specified on the original call.

Within the callback function, the application must not call any ECI functionality. If it does, these calls return the ECI_ERR_IN_CALLBACK return code. Because of this restriction, the callback function must find some way to communicate the notification to the main section of the Windows program. This is normally done by posting a Windows message.


Sun MTP ECI Interface Enhancements

Sun MTP Client has four different versions of the ECI API. These are obtained by setting the eci_version field of the ECI parameter block to any one of the following:

ECI_VERSION_1

IBM compatible version of the ECI API Version 1.

ECI_VERSION_1A

IBM compatible version of the ECI API Version 1A.

ECI_UNIKIX_VERSION_1

Same interface as ECI_VERSION_1 but with enhancements to the reply message formats, as described in Reply Message Formats.

ECI_UNIKIX_VERSION_1A

Same interface as ECI_VERSION_1A but with enhancements to the reply message formats, as described in Reply Message Formats.


Reply Message Formats

When an application makes an asynchronous ECI call and has requested notification by a message, a message is delivered to the specified window as follows:

ECI_VERSION_1 and ECI_VERSION_1A

wParam

The return code of the asynchronous call.

lParam

The four-character abend code of the asynchronous call. (This may be four spaces if no abend occurred).


ECI_UNIKIX_VERSION_1 and ECI_UNIKIX_VERSION_1A

wParam

The return code of the asynchronous call.

lParam

The low-order 16 bits contain the eci_message_qualifier specified on the asynchronous call.


The message qualifier is usually more important information than the abend code. You can also obtain the abend code by performing an ECI_GET_SPECIFIC_REPLY, specifying the message qualifier.