Douglas Connolly is a Professional Staff Member of the Senate Democratic Policy Committee of the U.S. Senate. He has been programming in C for two and one half years and has written HLLAPI programs that are used by Democratic offices throughout the U.S. Senate to access the Senate mainframe computer. He graduated from the University of Michigan with high honors for research in the history of science. Mr. Connolly can be reached at 419 Hart Office Building, Washington, D.C. 20510. (202) 224- 5554.
Introduction
The popularity of using PCs to access mainframe computers offers new opportunities for the C programmers, as well as the promise of better software for users. With the right 3270 emulation software, it is now possible to write programs that communicate directly with a mainframe computer and take advantage of the mainframe's vast resources. This communication is provided by HLLAPI, IBM's High Level Language Application Program Interface (pronounced "hi-happy" at IBM).HLLAPI handles the interface between programs written in high-level languages such as C and the 3270 emulation software running on a PC. HLLAPI allows a C program to perform the same functions that an operator can perform on a 3270 terminal, such as:
Such programs can simplify a user's tasks at a terminal, or fully automate a task replacing the user interaction altogether. Because any operation carried out at a terminal can be controlled from C, the programmer can even create a user-friendly frontend for an organization's mainframe, allowing programs to be selected from a menu and seamlessly integrating mainframe operations with those performed on a PC. All these objectives can be accomplished with surprising ease using HLLAPI.
- logging on to a mainframe application
- transferring a file
- updating a database record
- performing a query
HLLAPI is valuable not only for the level of control it offers but also for its portability. Though created by IBM, HLLAPI is also supported by a number of other vendor's 3270 emulation packages, including some that run under Windows 3.0. HLLAPI is also available under OS/2 Extended Edition's Communication Manager, making it relativity painless to port an application written in C to OS/2.
This article describes the basics of writing C programs that use HLLAPI. A set of C utility functions simplify getting started with HLLAPI and solve some commonly encountered mainframe problems. These functions form the foundation of a program called HOSTCOM, which provides the routine functions of a 3270 terminal. HOSTCOM demonstrates how to write a HLLAPI program and serves as a platform for developing more complex programs.
All the code presented here was developed using Borland's Turbo C 2.0 and has been tested with the following emulation software:
(1) IBM 3270/Personal Communications
(2) IBM Entry Level Emulation Program
(3) Attachmate Extra! for DOS
(4) RabbitGATE from Rabbit Software.
There should be few, if any, problems in using this code with other emulation software packages that support HLLAPI.
The Programmed Operator
A HLLAPI program carries out the same activities as a person sitting at a 3270 terminal. The functions available in HLLAPI so closely parallel the actions of an operator that, according to IBM's guidelines, you can think of a HLLAPI program as a "programmed terminal operator." A HLLAPI program establishes a session (i.e., a connection) with a host (a mainframe computer) and then carries out its operations. The exact same steps a human operator takes are followed by a HLLAPI program.Instead of using the keyboard, the HLLAPI program sends keystrokes to the mainframe in the form of null-terminated strings. In place of the screen, the program has access to a string containing the presentation space, which directly matches the information displayed for a human operator. A program can check its connection with a mainframe using HLLAPI functions that report the connection status. The mainframe does not know and does not need to know whether it is receiving commands from a person sitting at a terminal or from a HLLAPI program.
HLLAPI Program Organization
The three basic parts of a HLLAPI program are:(1) establishing the connection between a program and the host
(2) obtaining and analyzing the presentation space
(3) sending keystrokes
The functions in the accompanying listings, while modular in design, are directed toward developing the sample program HOSTCOM.
Mainframe applications are notoriously inconsistent in their behavior. A successful HLLAPI program depends not only on how well you define your objective but on how thoroughly you identify inconsistencies in the mainframe application you are using. Your program's reliability will ultimately depend on how well it interacts with the mainframe application.
HLLAPI consists of 36 functions, each of which is accessed by specifying a function number along with the other required parameters. (See Table 1. ) This article focuses on just nine of these functions the minimum you need to know, but enough to achieve fairly sophisticated results. These functions are described in Table 2.
The prototype for a function call is:
void HLLC(int &func, char *data_string, int &string_length, int &parm_4);These parameters are used as follows:func one of the 36 HLLAPI function numbers.
data_string a pointer to the presentation space. Some functions (not covered in this article) use this parameter to point to data items (e.g., to copy a string to and from a field in the presentation space).
string_length the length of the string pointed to by data_string. Function 6, Search_Presentation_Space, uses this parameter to return the offset of the supplied string in the presentation space.
parm_4 on a function call, the fourth parameter used only by function 99, Convert_Position_or_RowCol, to specify the offset of the cursor in the presentation space. Every HLLAPI function uses the fourth parameter to return a code reporting the success of the function. A return code of zero indicates the function was executed successfully. A value greater than zero indicates either detection of an error condition which prevented the function from being carried out or information about the host state that was detected after the function was executed.
Not all four parameters are used by every function. In some cases assigning a value is irrelevant because a value is implied by the function call. You must always supply all four parameters when making a call, however.
Listing 1 contains a separate C function for each HLLAPI function used here, except for the HLLAPI functions Query_Cursor_Location and Convert_Position_or_RowCol, which are both used in the function dspy_cursor. The listing also documents the return codes for each HLLAPI function and details how each of the four parameters is used. The functions used directly by HOSTCOM are in Listing 2, which contains more complex functions that are built upon individual HLLAPI calls. These functions return values that are used by process_error to index into the error message array in Listing 4, which is fully described below.
The Host Connection
The first step in any HLLAPI program is to establish a connection between the program and the host. This connection is created by a call to connect_ps_space, as shown in Listing 2. This function calls connect_ps, in Listing 1, and uses a switch statement to translate the return value to an index, which can be used with the error message array. This organization is used throughout the code presented here.Once a connection is established, a program can proceed with its operations. But before using a HLLAPI function, you should verify that the communication line (the connection between your PC and the mainframe) is not busy. During the time a function is executing and again when the host responds, the communication line is busy. (The time between these two events is a kind of "no man's land" which will be discussed below.) A call made during this time would either fail or yield misleading results. HLLAPI provides the Wait function which indicates when the communication line is not busy. This function is implemented as host_wait in Listing 2. Calling host_wait before any other HLLAPI function will ensure that the function executes successfully.
The last step your program should take is to call the function reset_connection, in Listing 2. This function uses the HLLAPI function Reset to break the connection between your program and the host and to reset the HLLAPI interface to its default settings. (Functions that modify the defaults are outside the scope of this article.)
A program that simply makes and breaks a host connection looks like this:
main() { int err; err = connect_ps_space(); if (!err) /* connect successful? */ err = reset_connection(); if (err) /* any errors? */ process_error(err); }The Presentation Space
The presentation space is an area in memory whose contents correspond to the information that would appear on a terminal screen. The HLLAPI function Copy_Presentation_Space transfers this data to an area of memory pointed to by a specified pointer. Once your program obtains this data, you can search the presentation data for mainframe prompts, extract information from it, or, as is done by HOSTCOM, display the data. By searching the presentation space for prompts, you can determine when and how the mainframe has responded to an action initiated by your program.Two functions show how to use the presentation space. update_ps in Listing 2 obtains a copy of the current presentation space and displays it on the screen. update_ps relies on the HLLAPI function Copy_Presentation_Space and requires a pointer to an area the size of the presentation space 1,920 bytes (24 lines by 80 characters) plus one additional byte to serve as a NUL terminator. This last byte is required because of the way HOSTCOM displays the presentation space. For each line in the presentation space, the characters leading up to the first alphanumeric character are ASCII spaces, 0x20, and the characters following the last alphanumeric character to the end of the line are NULs, 0x00. There are no newline characters. update_ps converts all the NUL characters to spaces. Thus the presentation space can be treated as a single string, and can be displayed with one function call. Further, you can search the presentation space using the string functions in the Standard C library.
You need not rely on the standard library to search the presentation space, however. The function find_msg in Listing 2 uses a HLLAPI function that returns the offset in the presentation space of a specified string. For example, to determine whether the host will allow you to sign on, you might write:
int rtn; rtn = find_msg("READY FOR SIGN ON"); switch(rtn) { case (0): /* msg not found */ puts("Host is not ready\n"); break; case (-1): /* msg found */ /* your sign on func */ your_sign_on(); break; default: process_error(rtn); }find_msg returns -1 if it finds the search string. A positive number indicates an error condition, and can be used to index into the error message array.
Sending Keystrokes
Keystrokes are sent to the host in the form of a NUL-terminated string. The function keys and various special keys are represented as two characters: @ (at sign) followed by the key code. A listing of these keys is in Table 3.There are two kinds of input:
An AID key can cause the mainframe application to be busy for some time (retrieving a database record, for example). During this time, which could be seconds or minutes, an attempt to send additional input would be rejected. Calling host_wait does not indicate when it is safe to send additional input because host_wait only indicates the status of the communication line not the mainframe application.
- the standard alphanumeric characters, along with the keys that position the cursor tab, return, backspace and delete
- the Attention Identifier (AID) keys, which cause the host to carry out some action. These include the enter key and the function keys.
Two input functions are provided for greater flexibility:
Both functions call host_wait to verify that the communication line is clear. input_to_host also detects when the host will accept another AID key, and uses the same procedure a human operator would. A human would hit the reset key, wait a few seconds, then retype the AID key until successful. input_to_host repeats the same steps until successful, an error is detected, or the user hits the escape key.
- keys_to_host sends a string of keystrokes to the host
- input_to_host sends a single AID key to the host
For many mainframe applications you can detect when the host has completed an operation by looking for confirmation in the presentation space but you cannot depend on this. I have dealt with mainframe applications that are occupied for minutes on end without providing any indication in the presentation space when they are ready for additional input. This problem is typical of the difficulties you may run into when controlling a mainframe application from a HLLAPI program.
A Sample HLLAPI Program
HOSTCOM is a sample HLLAPI program designed to emulate a terminal: its two primary tasks are to display the contents of the presentation space (simulating a terminal screen) and to handle input from the keyboard. In addition, HOSTCOM implements a simple error reporting function and provides certain enhancements over a 3270 terminal. The code for HOSTCOM is in Listing 3 and Listing 4. Listing 5 is the header file.To complete the terminal-emulation environment, HOSTCOM displays a status indicator on the left side of the 25th line that notifies the user when the host is ready for keyboard input. Rather than the usual status indicator symbols used by 3270 terminals, HOSTCOM displays Ready when the keyboard may be used, Sending when a command is being transmitted to the mainframe, and TIME n, with n incrementing every two seconds, to indicate that HOSTCOM is trying to resend an AID key. The sending and time messages are controlled by input_to_host. host_wait displays a Waiting message while the communication line is busy.
When a key is waiting in the keyboard buffer, HOSTCOM sends the key to either keys_to_host or input_to_host, depending on the type of the key. Then the display is updated and the cursor positioned by a call to display_cursor. Two HLLAPI functions are required to position the cursor:
HOSTCOM keeps track of the position of the cursor to protect the user from backspacing into a protected field a useful feature not found on a 3270 terminal.
- Query_Cursor_Location reports the position of the cursor in the presentation space as a single offset
- Convert_Position_or_RowCol converts this offset to a row/column expression.
HOSTCOM uses the direct video function write_string for all screen output. The function set_vid detects the active video mode and sets a pointer to the active video memory. set_vid also determines the screen attributes for color or monochrome.
Error Reporting
The function process_error is called when any function in Listing 2 returns a value greater than zero. process_error displays a message describing the error and provides a menu from which to select one of four actions. Simple user-caused errors can be corrected by entering a 3270 clear or reset command, options 1 or 2. A major problem, such as a faulty communication line, requires exiting the program, option 4. Because HOSTCOM was designed with development in mind, option 3 permits ignoring the error and continuing the program.
Making A Graceful Exit
Before terminating a program, you should log out of the mainframe application you are using. Failure to do so can create annoying problems, such as being unable to log back into an application since it has no record of your exit. When you try to exit HOSTCOM, the function check_signon determines whether you are signed on to an application, by analyzing information contained in the OIA.
The OIA
The 25th line of a 3270 terminal displays information about the connection between the terminal and the mainframe and is called the Operator Information Area (OIA). This information is accessible to a program through the HLLAPI function Copy_OIA, which returns a 103-character string containing the data. The full extent of the OIA is outside the scope of this article, but is described in most emulation software documentation. Only the fourth byte of the OIA is used by HOSTCOM. This byte indicates whether the host is signed on to an application. A HEX dump of the OIA string can be viewed in HOSTCOM by pressing the key F7.
Running HOSTCOM
If you are using one of the four supported emulation packages, you can run HOSTCOM by entering (at the MS-DOS prompt):
HOSTCOM nwhere n is 0 for IBM Personal Communications/3270, 1 for IBM Entry Level Emulator Program, 2 for Attachmate, and 3 for RabbitGATE. Specifying 4 will run the program in simulated mode for testing purposes and using 5 will run it in simulated mode and display test data on the screen.
Adding Your Own Options
As presented, HOSTCOM is only a slight improvement over the mainframe session provided directly by your terminal emulation software. But using HOSTCOM to automate some mainframe tasks can make it quite useful. With HOSTCOM you can automate many mainframe tasks using just the functions keys_to_host, input_to_host, and find_msg.Consider signing on to a mainframe. I will assume that signing on requires entering an application name, waiting for the mainframe to request a password, depressing the tab key twice (to move the cursor to a password field), then typing the password, followed by enter. Assuming the application is called MYAPP and your password is ROSEBUD, you could automate the task of signing on as shown in Listing 6.
sign_on will return zero on success, -1 if the application is not available, and a value greater than zero if an error is encountered. find_msg searches for either a confirmation of the sign on request or an indication that the application is not available. You will have to change the function to correspond to the prompts and messages used in your organization. You could call this function from HOSTCOM by adding the following lines to the switch statement in main in Listing 3, assuming it would be invoked by depressing the key F2:
case K_F2: err = sign_on(); if (err == -1) { write_string(1, 1, "App not Available",stat_attr); while (!receive_esc()) ; /* wait for escape */ } break;When this function is executed, the status indicator will indicate Ready/Sending/Waiting as each part of the sign on operation is carried out.
Compiling And Running
The connection between a program and the emulation software is made with a Language Interface Module (LIM). A LIM is a small object file that is linked with your C object files to form an executable program. LIMs are included with IBM's emulation software and with some other packages as well. IBM includes a separate LIM for small, medium, and large C model programs: hllc_s.obj, hllc_m.obj, and hllc_l.obj, respectively. (IBM also supplies LIMS for Pascal, BASIC, and COBOL, along with guidelines for writing a LIM.) When your program makes a HLLAPI call, the LIM generates a software interrupt and passes the function number and parameters to the emulation software.Be sure your emulation software is configured to support HLLAPI. This requires running a program that becomes memory resident or specifying an option during program installation. Once the emulation software is configured and loaded, you need only enter the name of your HLLAPI program at the MS-DOS prompt.
Emulation Software Considerations
RabbitGATE
This package consists of hardware (a controller and gateway) and software to bring 3270 emulation to PC-based networks. The RabbitGATE emulation software requires that a HLLAPI program power-on a session before using it. This is accomplished by sending a special power-on string using the Send_Key function. (See rabbit_power[] in Listing 3. ) Sending the same string a second time powers the session off. It is necessary to power a session off before terminating a program in order to prevent leaving the connection in a "bound" (locked up) state. HOSTCOM handles this automatically.
Attachmate Extra! for DOS
This highly-rated program is completely compatible with HLLAPI and works with a variety of 3270 cards. However, I have experienced one problem with v2.0. If a HLLAPI program sends two consecutive clear commands to the host, subsequent attempts to send input result in a "keyboard locked" error message, and all attempts to clear the condition fail. HOSTCOM uses the variable clear_key to prevent this situation.
IBM Entry Level Emulator
This program does not support some of the more advanced HLLAPI functions and supports only one session, but runs on PCs with as little as 128K of RAM.
Other Emulation Software Packages
The code presented here should work with any emulation software that supports HLLAPI. The only modification you may have to make involves the session identification. Every mainframe session has associated with it what is called the short name of the host presentation space, or the Presentation Space Identification (PSID). This is a single character or number that must be supplied when using the functions Connect_Presentation_Space and Query_Cursor_Location. Each of the emulation packages discussed previously uses a different default PSID. connect_ps and dspy_cursor in Listing 1 select the correct PSID for the active emulation software. If you are writing a program that supports multiple sessions or a different emulation package, check the emulation software documentation to determine how the PSID is assigned. You will have to modify connect_ps and dspy_cursor. In addition, you will have to change the line in Listing 3 that assigns argcv[1] to hllapi_level.
Where To Go From Here
The code presented here has introduced the basics of HLLAPI programs and successful interaction with mainframes. While other functions are available in HLLAPI, you can accomplish a lot using the nine functions described here. Using just these functions, I have written HLLAPI programs that use a pop-up menu interface to select mainframe applications, cut and paste text between a mainframe and WordPerfect, download text from a mainframe to an ASCII file, and print text on standard and PostScript printers. Here are some ideas you might explore using HOSTCOM:
- Add detection and display of the Host screen attributes. (Use Function 14, Query Field Attribute.)
- Add a pop-up menu interface.
- Print screens of text or capture to a file. You could create what amounts to a file transfer (to capture e-mail messages, for example) without making any changes to the mainframe application by (1) saving the data contained in the presentation space, (2) sending the appropriate key to get the next screen of data, and (3) testing each screen with find_msg to determine if the last screen of text has been reached.
- Use Send File (Function 90) and Receive File (Function 91) to pass data between PC and mainframe applications.
Table 4