Write theCICS ONC RPC converter

This section describes how you can write a converter to perform various tasks. Some of these tasks are required for all 4-tuples, others only for some.

The section describes in turn each of the tasks, indicating the converter function (Getlengths, Decode, or Encode) used.

The parameter details and responses of each of the converter functions are given at the end of the section in Getlengths, Decode, and Encode.

Tasks that can be performed by a converter

The tasks to be performed are:

Lengths of the CICS program input and output data

CICS ONC RPC needs to know the length of the CICS program input and output data for each 4-tuple. For each 4-tuple, the lengths may be defined in one of three places:

Setting the CICS program data format

CICS ONC RPC needs to know the CICS program data format for each 4-tuple. The data format defines how the input and output data is arranged in the CICS program communication area. You can set this either in Getlengths or in the connection manager. If you choose Getlengths, use the output field glength_server_data_format. The value specified with the connection manager is supplied as input to Getlengths in this field.

Mapping data between client and CICS program formats

You need to map the incoming data intended for the CICS program only if it is not in the format required by the CICS program. This is typically for:

The mapping is always done by Decode for the input data for the CICS program. In most cases, the output data needs to be mapped in the opposite direction by Encode.

On input, the client data is pointed to by the Decode input field decode_client_data_ptr. Decode maps this data into the form which the CICS program requires.

To achieve the mapping, Decode must allocate an area of CICS storage, using EXEC CICS GETMAIN SHARED. Decode must set the output field decode_returned_data_ptr to the address returned by the GETMAIN command, and put the input data passed from the client into the storage, making changes where applicable.

Changing the alias and CICS program

You can use Decode to redirect a client request to another CICS program. CICS ONC RPC then ignores the original program name that was defined in the connection manager for the requested 4-tuple. To reroute a client request, specify a new CICS program name in the decode_server_program field in Decode. This facility allows a client to pass a CICS program name in the data it sends in the remote procedure call. The new CICS program must work with the same communication area format, converter, and XDR output routine as the original program.

You can use Decode to change the name of the alias transaction to run the CICS program by setting the decode_alias_transid output field. CICS ONC RPC then ignores the transaction ID that was defined in the connection manager for the requested 4-tuple. This facility allows a client to pass the alias transaction ID in the data it sends with the remote procedure call.

Changing security information

You may want your CICS ONC RPC system to implement security checking on incoming client requests. Such checking usually involves checks on the client user ID and password. One of the ways the client can provide these is by including them in the data structure it sends.

Decode can retrieve this information from the incoming data, and return it in the output fields. The user ID should be returned in the output field decode_userid; the password should be returned as part of the data pointed to by the decode_returned_data_ptr field. These outputs can either be passed by the client or generated by Decode in whatever way you want. For instance, Decode can derive the CICS user ID and password for the client request by using the decode_client_address field, or the authentication fields decode_aup_... that identify the client.

Organizing the converter

You can write converters for any CICS-supported compiler. If you choose a language other than C or COBOL, you must write your own header files to define the CICS ONC RPC data structures and constants.

A converter is passed a communication area that contains a parameter that specifies which of the three functions Getlengths, Decode, or Encode is required, and parameters for the particular function, as described in the reference material: Getlengths, Decode, and Encode.

The following C header files (in the SDFHC370 target library) and COBOL copybooks (in the SDFHCOB target library) are provided to help with writing the converter:

You need a header file produced by RPCGEN only if you used RPCL to define the data structures, and you are writing Decode or Encode. If you are writing your converter in a language other than C, you need to rewrite the header file in your chosen language, since RPCGEN produces its output only in C.

You need definitions of the CICS structures that you use, and the definition of the CICS program communication area.

Writing a converter in C

The following discussion is based on a converter that consists of four main parts:

Figure 59 shows how you can route control to the appropriate function.

Figure 59. Routing control to the functions in C
  EXEC CICS ADDRESS EIB(dfheiptr);      /*Get addressability of EIB*/
 
  EXEC CICS ADDRESS COMMAREA(converter_parms_ptr);
 
  switch(converter_parms_ptr->converter_function) {
 
   case URP_GETLENGTHS:
   {
     converter_getlengths();
     break;
   }
   case URP_DECODE:
   {
     converter_decode();
     break;
   }
   case URP_ENCODE:
   {
     converter_encode();
     break;
   }
 
   default:
   {
     converter_parms_ptr->converter_response = URP_INVALID;
   }
 
  }   /* end switch */
 
  EXEC CICS RETURN;
 
}  /* end main */

In this program fragment, converter_parms_ptr is a locally declared pointer to the converter_parms structure declared in DFHRPCDH. All the other names beginning converter_ are names from this structure.

The processing is as follows:

  1. The converter_parms_ptr pointer is set by using EXEC CICS ADDRESS COMMAREA.
  2. The switch statement is used to select the function to be called. If you are not providing all the functions, you need fewer case statements.
  3. If the function is not valid, the response URP_INVALID is returned from the converter. This test is always advised, especially if the converter does not provide all three functions.

Figure 60 is an example of a Decode function.

Figure 60. Example of a Decode function in C
 void converter_decode(void)
 {
   decode_parms *decode_parms_ptr;
 
   decode_parms_ptr = (decode_parms *)converter_parms_ptr;
 
   if (strncmp
   (decode_parms_ptr->decode_eyecatcher,DECODE_EYECATCHER_INIT,8)
   == 0)
   {
     EXEC CICS GETMAIN
       SET(decode_parms_ptr->decode_returned_data_ptr)
       FLENGTH(sizeof(rem_proc_parms_103) + PW_LEN)
       SHARED
       NOSUSPEND
       CICSDATAKEY
       RESP(response)
       RESP2(response2);
 
     if (response != DFHRESP(NORMAL))
     {
       memcpy(outline,errmsg1,strlen(errmsg1));
       EXEC CICS WRITEQ TD QUEUE(tdq) FROM(outline) LENGTH(30);
       decode_parms_ptr->decode_response = URP_EXCEPTION;
       decode_parms_ptr->decode_reason = NO_STORAGE;
     }
     else
     {
       /* move password and data to decode_password and
       decode_server_input_data */
 
       decode_parms_ptr->decode_response = URP_OK;
     };
   }
   else
     decode_parms_ptr->decode_response = URP_INVALID;
 }

In this program fragment, names beginning decode_, except decode_parms_ptr, are names from the decode_parms structure defined in DFHRPCDH.

The processing is as follows:

  1. The pointer decode_parms_ptr is set from converter_parms_ptr.
  2. The eyecatcher is checked to see if it agrees with the function code. If it does:
    1. EXEC CICS GETMAIN is used to get storage for the password and for the communication area to be passed to the CICS program. The value of PW_LEN is set elsewhere in the program to 8 by #define. The output parameter decode_returned_data_ptr is used directly in the GETMAIN. In this case there is no conversion of data to be done, and the communication area size is the same as the size of the client data structure. (rem_proc_parms_103 is a structure that defines the input data after XDR conversion.)
    2. If the response to the EXEC CICS GETMAIN is not NORMAL, an error message is directed to a transient data queue, the converter response is set to URP_EXCEPTION, and the reason code is set to NO_STORAGE, which is locally declared.
    3. If the response to the EXEC CICS GETMAIN is NORMAL, the data and password are transferred to the storage acquired by GETMAIN (not shown), and the converter response is set to URP_OK.
  3. If the eyecatcher is not the one for the function being called, the converter response is set to URP_INVALID.

Writing a converter in COBOL

In the working storage section of the data division, you should use the COPY statement to copy the copybook DFHRPUCO, and any other copybooks you need. You should also define any other data items you need in working storage.

You use the COPY statement to include the definition of the communication area in the linkage section of the data division.

Figure 61 shows the layout of the data division. Comments, which would be part of a well-documented converter, are omitted.

The following discussion is based on a converter that consists of four main parts:

Figure 62 shows how you can route control to the appropriate function.

Figure 61. Layout of data division in COBOL
       DATA DIVISION.
 
       WORKING-STORAGE SECTION.
 
           COPY DFHRPUCO.
 
       01  RESP                          PIC S9(8) COMP.
       01  RESP2                         PIC S9(8) COMP.
       01  REM-PROC-COMMSIZE             PIC S9(8) COMP VALUE +12.
       01  CLIENT-OUT-SIZE               PIC S9(8) COMP VALUE +8.
 
       LINKAGE SECTION.
 
        01 DFHCOMMAREA.
          02 COMM-PARMLIST PIC X(1).
 
        01 CONVERTER-PARMS REDEFINES DFHCOMMAREA.
          02 CONVERTER-EYECATCHER PIC X(8).
          02 CONVERTER-FUNCTION PIC 9(8) COMP.
          02 CONVERTER-RESPONSE PIC 9(8) COMP.
          02 CONVERTER-REASON PIC 9(8) COMP.
          02 CONVERTER-PARMLIST PIC X(1).
 
        01 GLENGTH-PARMS REDEFINES DFHCOMMAREA.
          02 GLENGTH-EYECATCHER PIC X(8).
          02 GLENGTH-FUNCTION PIC 9(8) COMP.
          02 GLENGTH-RESPONSE PIC 9(8) COMP.
          02 GLENGTH-REASON PIC 9(8) COMP.
          02 GLENGTH-SERVER-INPUT-DATA-LEN PIC S9(8) COMP.
          02 ...
 
        01 DECODE-PARMS REDEFINES DFHCOMMAREA.
          02 ...
 
        01 DECODE-RETURNED-DATA.
          02 DECODE-PASSWORD PIC X(8).
          02 DECODE-SERVER-INPUT-DATA PIC X(1).
 
        01 ENCODE-PARMS REDEFINES DFHCOMMAREA.
          02 ...

Figure 62. Routing control to the functions in COBOL
       PROCEDURE DIVISION.
 
       A-CONTROL SECTION.
 
       A-0000-MAIN-TASK.
 
           MOVE URP-INVALID TO DECODE-RESPONSE.
 
           IF CONVERTER-FUNCTION = URP-GETLENGTHS
           PERFORM B-0000-GETLENGTHS END-IF.
 
           IF CONVERTER-FUNCTION = URP-DECODE THEN
           PERFORM C-0000-DECODE END-IF.
 
           IF CONVERTER-FUNCTION = URP-ENCODE THEN
           PERFORM D-0000-ENCODE END-IF.
 
       A-9999-EXIT.
 
           EXEC CICS RETURN END-EXEC.
           GOBACK.

In this program fragment:

  1. The response URP-INVALID is set.
  2. The IF statements examine the function code in the communication area, and pass control to the appropriate function.
  3. The converter returns to the program that called it. (If the IF statements selected a function, the DECODE-RESPONSE value returned is the response from that function.)

Figure 63 is an example of a Decode function.

Figure 63. Example of a Decode function in COBOL
       C-0000-DECODE.
 
           IF DECODE-EYECATCHER IS NOT = DECODE-EYECATCHER-INIT
             MOVE URP-INVALID TO DECODE-RESPONSE
           ELSE
             SET ADDRESS OF CLIENT-IN-DATA TO DECODE-CLIENT-DATA-PTR
             ADD 8 TO REM-PROC-COMMSIZE
             EXEC CICS GETMAIN
                              SET(DECODE-RETURNED-DATA-PTR)
                              FLENGTH(REM-PROC-COMMSIZE)
                              SHARED
                              NOSUSPEND
                              CICSDATAKEY
                              RESP(RESP)
                              RESP2(RESP2)
                              END-EXEC
           SET ADDRESS OF DECODE-RETURNED-DATA
                       TO DECODE-RETURNED-DATA-PTR
           MOVE "PASSWD" TO DECODE-PASSWORD
           SET ADDRESS OF REM-PROC-DATA
                       TO ADDRESS OF DECODE-SERVER-INPUT-DATA
           MOVE CLIENT-IN-U-CHAR TO REM-PROC-U-CHAR
           MOVE CLIENT-IN-CHAR TO REM-PROC-CHAR
           MOVE URP-OK TO DECODE-RESPONSE.

In this program fragment, the names beginning DECODE- (except DECODE-PASSWORD) are fields in the communication area for the Decode function. DECODE-PASSWORD is the field at the beginning of the returned data. The processing is as follows:

  1. The eyecatcher is checked to see if it agrees with the function code. If it does not, the URP-INVALID response is returned.
  2. If it does:
    1. The structure CLIENT-IN-DATA is overlaid on the data coming from the inbound XDR routine addressed by DECODE-CLIENT-DATA-PTR.
    2. The communication area size is increased by 8 to allow for the password field.
    3. EXEC CICS GETMAIN is used to get storage for the password and for the communication area. REM-PROC-COMMSIZE is the size of the structure REM-PROC-DATA, which defines the format of the communication area. The address of the storage is put directly into DECODE-RETURNED-DATA-PTR.
    4. The structure DECODE-RETURNED-DATA is overlaid on the newly-acquired storage addressed by DECODE-RETURNED-DATA-PTR.
    5. The password is moved into DECODE-PASSWORD.
    6. The data is moved from CLIENT-IN-DATA to REM-PROC-DATA, and the response is set to URP-OK.

Using converters

Converters run as CICS programs under the connection manager, server controller, and aliases. Converters must reside in the same CICS system as CICS ONC RPC.

Preparation

Before using a converter, you must:

  1. Translate the converter using the appropriate CICS translator. If it is a COBOL program, you must use the QUOTE translator directive.
  2. Compile the output from the translator.
  3. Link the converter as a standard CICS application program into a CICS load library used by the CICS system on which CICS ONC RPC is installed.
  4. Define the converter to CICS as a program.
  5. Use the connection manager to specify the converter in one of the 4-tuple definitions, and define which of the converter functions are required for that 4-tuple.

Related concepts
ONC RPC concepts
ONC RPC remote procedures and CICS programs
CICS ONC RPC user-replaceable programs
Related tasks
Developing an ONC RPC application for CICS ONC RPC
Related reference
Reference information for the converter functions
[[ Contents Previous Page | Next Page Index ]]