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.
The tasks to be performed are:
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:
In either of these first two cases, if Decode is specified for the 4-tuple, the Decode function can change the lengths.
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.
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.
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.
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.
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:
The format of the rest of the communication area depends on the converter function requested.
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.
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.
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:
Figure 60 is an example of a Decode function.
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:
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.
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 ...
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:
Figure 63 is an example of a Decode function.
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:
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.
Before using a converter, you must: