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++.
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.
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:
There are three types of calls to CICS_ExternalCall():
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.
In addition to the categorization in TABLE 8-1, a distinction must be made between synchronous and asynchronous call types:
Note - Because of their behavior, synchronous calls are not recommended. |
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 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 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 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.
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
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.
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.
This section describes programming methods that work best in a Solaris environment.
There are two choices for application design:
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.
The tables in this section define the following ECI data structures:
Sun MTP server is currently connected and available for work. |
||
This section lists and describes the syntax of the two ECI functions.
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.
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.
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.
cics_sshort_t CICS_EciListSystems(cics_char_t *NameSpace,cics_ushort_t *Systems,CICS_EciSystem_t *List);
The following table describes the fields within the CICS_EciSystem_t structure.
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.
cics_sshort_t KixCli_QueryFD( int *pFD );
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.
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 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.
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.
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.
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:
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 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.
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:
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 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.
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:
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 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.
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:
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.
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.
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.
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.
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.
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.
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.
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.
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.
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():
After this is done, a notification is sent when the system state changes from that specified in the eci_commarea fields.
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 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:
Same interface as ECI_VERSION_1 but with enhancements to the reply message formats, as described in Reply Message Formats. |
|
Same interface as ECI_VERSION_1A but with enhancements to the reply message formats, as described in 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
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
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.
Copyright © 2003, Sun Microsystems, Inc. All rights reserved.