═══ 1. (C) Copyright IBM Corp. 1992 ═══ ═══ 2. Installation ═══ ═══ 2.1. REXXAPPC Installation ═══ Copy SAAAPPC.DLL to a LIBPATH directory Start Communications Manager Add a modified version of the following TP definition for TP2 to your Communications Manager NDF file in \CMLIB\APPN DEFINE_TP TP_NAME(TP2) FILESPEC(idrive\os2\cmd.exe) PARM_STRING(/c [fdrive\fpath\]tp2.cmd) CONVERSATION_TYPE(EITHER) CONV_SECURITY_RQD(NO) SYNC_LEVEL(EITHER) TP_OPERATION(NONQUEUED_AM_STARTED) PROGRAM_TYPE(VIO_WINDOWABLE) RECEIVE_ALLOCATE_TIMEOUT(INFINITE); where idrive is the drive OS/2 is installed on and fdrive\fpath are the drive and path where TP2.CMD exists if it is NOT in a directory in the PATH= environment variable type APPNV configname /E to update the active Communications Manager configuration where configname is the name of the NDF file modified above Add the following line to all REXXAPPC execs to insure the function is registered If rxfuncquery('Appc') then call rxfuncadd 'APPC','SAAAPPC','APPCSRV' ═══ 3. REXXAPPC Programming Interface ═══ The REXXAPPC function package provides two sets of functions: 1. Control Verbs o Receive_allocate o Tp_started o Tp_ended 2. Conversation Verbs o Allocate o Confirm o Confirmed o Convert o Deallocate o Flush o Get_attributes o Prepare_to_receive o Receive_wait o Request_to_send o Send_Conversation o Send_data o Send_error o Test_rts Note: These verbs are supported in both Basic and Mapped formats thru a function parameter rather than separate functions. The basic format of the APPC service function is as follows: APPC( function [ , function specific data ] ) REXXAPPC Function syntax ═══ 3.1. Basic Return codes ═══ In addition to specific return codes for each function, there is a set of values that can be returned for any of the functions. These are called Basic return codes and are documented here to simplify the document. Syntax related Basic return codes o BAD_CONV_ID 0x02000000 o BAD_CONV_TYPE 0x11000000 o BAD_LL 0xF1000000 o BAD_LU_ALIAS 0x03000000 o BAD_RETURN_CONTROL 0x14000000 o BAD_SECURITY 0x13000000 o BAD_SYNC_LEVEL 0x12000000 o BAD_TP_ID 0x01000000 Operation Related Basic return codes o TP_BUSY 0x02F0 o COMM_SUBSYSTEM_ABENDED 0x03F0 o COMM_SUBSYSTEM_NOT_LOADED 0x04F0 o INVALID_VERB_SEGMENT 0x08F0 o UNEXPECTED_DOS_ERROR 0x11F0 o CONVERSATION_TYPE_MIXED 0x1900 o CANCELLED 0x2100 o DEALLOC_ABEND 0x0500 o DEALLOC_ABEND_PROG 0x0600 o DEALLOC_ABEND_SVC 0x0700 o DEALLOC_ABEND_TIMER 0x0800 o DEALLOC_NORMAL 0x0900 o PROG_ERROR_NO_TRUNC 0x0C00 o PROG_ERROR_PURGING 0x0E00 o PROG_ERROR_TRUNC 0x0D00 o UNSUCCESSFUL 0x1400 o STACK_TOO_SMALL 0x15F0 o ALLOCATION_FAILURE_NO_RETRY 0x04000000 o ALLOCATION_FAILURE_RETRY 0x05000000 o CONVERSATION_TYPE_MISMATCH 0x34600810 o ALLOCATE_NOT_PENDING 0x09050000 o ATTACH_MANAGER_INACTIVE 0x08050000 o CONFIRM_BAD_STATE 0x32000000 o CONFIRM_NOT_LL_BDY 0x33000000 o CONFIRM_ON_SYNC_LEVEL_NONE 0x31000000 o CONFIRMED_BAD_STATE 0x41000000 o DEALLOC_BAD_TYPE 0x51000000 o DEALLOC_CONFIRM_BAD_STATE 0x53000000 o DEALLOC_FLUSH_BAD_STATE 0x52000000 o DEALLOC_LOG_LL_WRONG 0x57000000 o DEALLOC_NOT_LL_BDY 0x55000000 o FLUSH_NOT_SEND_STATE 0x61000000 o INVALID_DATA_SEGMENT 0x06000000 o INVALID_PROCESS 0x25050000 o INVALID_SEMAPHORE_HANDLE 0xD6000000 o NO_USE_OF_SNASVCMG 0x17000000 o P_TO_R_INVALID_TYPE 0xA1000000 o P_TO_R_NOT_LL_BDY 0xA2000000 o P_TO_R_NOT_SEND_STATE 0xA3000000 o PIP_LEN_INCORRECT 0x16000000 o PIP_NOT_ALLOWED 0x31600810 o PIP_NOT_SPECIFIED_CORRECTLY 0x32600810 o RCV_AND_POST_NOT_LL_BDY 0xD2000000 o R_T_S_BAD_STATE 0xE1000000 o RCV_AND_POST_BAD_FILL 0xD5000000 o RCV_AND_POST_BAD_STATE 0xD1000000 o RCV_AND_WAIT_BAD_FILL 0xB5000000 o RCV_AND_WAIT_BAD_STATE 0xB1000000 o RCV_AND_WAIT_NOT_LL_BDY 0xB2000000 o RCV_IMMD_BAD_FILL 0xC4000000 o RCV_IMMD_BAD_STATE 0xC1000000 o SEND_ERROR_BAD_TYPE 0x03010000 o SECURITY_NOT_VALID 0x51600F08 o SEND_DATA_BAD_MAP_NAME 0xF3000000 o SEND_DATA_NOT_SEND_STATE 0xF2000000 o SEND_ERROR_LOG_LL_WRONG 0x02010000 o SYNC_LEVEL_NOT_SUPPORTED 0x41600810 o TOO_MANY_TPS 0x43020000 o TP_NAME_NOT_RECOGNIZED 0x21600810 o TRANS_PGM_NOT_AVAIL_NO_RETRY 0x00004C08 o TRANS_PGM_NOT_AVAIL_RETRY 0x31604B08 o UNKNOWN_PARTNER_MODE 0x18000000 o UNDEFINED_TP_NAME 0x06050000 ═══ 3.1.1. APPC Conversations and general information ═══ APPC provides two general types of conversations, (i.e., peer-to-peer communication sessions): o Basic A basic conversation provides low level control of the data being transmitted. A sending program (Transaction Program or TP) can build a buffer of logical records, with a length for each logical record, and transmit the entire buffer. The receiving TP can choose to process the buffer as a single buffer, or to receive ONLY one logical records worth of data. This provides a great deal of flexibility and power. The receiving program need not KNOW or CARE how the sending program packaged a particular transmission. It can choose to process only individual logical records. The receiving TP would not know how many records were to be processed or their layout in the buffer, or in fact whether the entire record was sent in a single or multiple transmissions. The APPC subsystem will do the unblocking as part of the transmission service. This is known as 'LL' type reception, and can be specified on any of the Receive data functions described later. The other Basic conversation receive option is called 'Buffer'. Using this option, the receiving TP must provide code to extract a logical record from the buffer received. To use either basic conversation reception type requires BOTH the sender AND receiver TPs to perform special processing. For each logical record in a transmission buffer, a 2 byte length field must precede the actual data of the logical record. The length field MUST include the length of the length field itself. Therefore the minimum logical record size (including length field) is 2 bytes. In addition, (including this REXX adapter) the layout of the length field is required to be in 370 data format (i.e., the high-order byte of the length (in binary) must be at the lowest memory address, this is backwards from the way it normally is stored on the INTEL architecture machines.) A length value of 258 decimal would be x'0102' in hex, and should be stored that way immediately in front of the data. The INTEL layout that we are all used to would have the data in memory like this x'0201' Example: x'0102'data correct layout x'0201'data incorrect layout You can use the D2X built-in function to convert a REXX whole number into a hexadecimal string with the correct layout. As you will see later, the receive functions return a value called 'what_received'. This value indicates the state of the current logical record or buffer. Data_complete A complete logical record has been received. Please note that this does NOT mean that ALL data sent has been received, only that the CURRENT logical record has been moved into the TPs application buffer space by the communications subsystem. Data_incomplete There was insufficient room in the TPs application buffer space for the entire logical record. More data for this record will be received on subsequent receive call(s). There is no way to determine how many receive calls are required to receive ALL the data in this logical record, unless the TPs involved have some prearranged protocol. Data If you use the 'Buffer' option, this means that data has been received. How much of the actual transmission is unknown. When no more data is available, Data_complete will be returned. o Mapped A mapped conversation supports transmission and reception of blocks of data. The receive function used specifies how much data can be received at one time. There is no logical record format, and the APPC subsystem will not perform any processing of the data itself. This makes transmission of complete blocks of data (file copies etc) easy. For mapped conversations you can not receive 'Data'. There are additional 'what_received' values when no data has been received, that indicate the state of the conversation. These are described here for clarity. SEND This TP is now in SEND state CONFIRM The other TP has requested that you confirm its last transmission. You may use either the 'Confirmed' verb to confirm reception, or 'Send_error' to deny confirmation. CONFIRM_SEND The remote TP has issued a 'Prepare_to_receive' verb with in 'Confirm' level conversation. You can confirm it (by using the 'Confirmed' verb), and this TP will be placed in SEND state. Otherwise, this TP will remain in receive state. CONFIRM_DEALLOCATE The remote TP has requested that the conversation be terminated. If this TP used 'Confirmed', the session will be ended. Otherwise the session will continue. The send/receive state of this TP depends on many things, but can be determined by using the 'Get_attributes' verb. The Values returned for 'what_received' are: DATA '256' DATA_COMPLETE '512' DATA_INCOMPLETE '1024' SEND '1' CONFIRM '2' CONFIRM_SEND '3' CONFIRM_DEALLOCATE '4' These values are the decimal representation of the binary values returned by the APPC subsystem. ═══ 3.2. REXXAPPC Control Verb Functions ═══ ═══ 3.2.1. Receive_allocate ═══ APPC( 'Receive_allocate', tpname, stemname ) Allows a 'server' LU to wait for a session request from a 'requester' system. tpname is the name this server program will be known by. A requester must use tpname when an Allocate request is made to connect to this server. to supply a service tp name, enter the EBCDIC value in hex. '06F3F0F1'x stemname is the name of a REXX stem variable where info returned from the Receive_allocate call will be placed. This function will return one of the following values: 0 Function completed ok Additional info will be in the variable stemname in the following order: stemname.0 tp_ID to be used in subsequent functions on this conversation stemname.1 conv_ID to be used on subsequent functions on this conversation stemname.2 sync_level, synchronization level 'N' = None 'C' = Confirm stemname.3 Conversation Type 'B' = Basic 'M' = Mapped stemname.4 user_ID, Conversation level user ID of the conversation initiating program. stemname.5 LU_alias, Local LU alias name or '' if none. stemname.6 Partner_LU name, Local name of LU from which the Allocate request was received. stemname.7 mode_name, the mode name used on the allocate request. not 0 error return code from Receive_allocate request. Note: stemname will be dropped ═══ 3.2.2. Tp_started ═══ APPC( 'Tp_started' , [ LU_alias ] , tpname, stemname ) Establishes a server program on this system with name tpname. If LU_alias is supplied it must be one of the LU_alias names established during system configuration. If LU_alias is not supplied, the configured default LU will be used. to supply a service tp name, enter the EBCDIC value in hex. '06F3F0F1'x This function returns one of two values: 0 Function Completed ok Additional info will be in the variable stemname in the following order: stemname.0 tp_ID to be used in subsequent functions on this conversation not 0 error return code from Tp_started request. Note: stemname will be dropped ═══ 3.2.3. Tp_ended ═══ APPC( 'Tp_ended' , tp_ID [ , type ] ) Terminates the server program on this system with name tp_ID. the tp_ID value is returned on the 'Received_allocate' or 'Tp_started' functions. type can be either of the following, of which only the first character is significant 'Soft' Ends the TP, but does NOT terminate any active sessions between the partners 'Hard' Ends the TP, AND terminates any active sessions between the partners. This function returns one of two values: 0 Function Completed ok not 0 error return code from Tp_ended request. ═══ 3.3. REXXAPPC Conversation Verb Functions ═══ ═══ 3.3.1. Allocate Conversation ═══ APPC( 'Allocate' , tp_ID , Partner_LU , Modename , tpname , type , Return_control , sync_level , security , stemname ) Create a conversation with server tpname on system Partner_LU using tp_ID as this applications name in mode Modename. Partner_LU may be a Local LU Alias, an implicit LU, or a Fully Qualified Partner LU name (i.e., contains Network_name.LU_name). to supply a service tp name, enter the EBCDIC value in hex. '06F3F0F1'x type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation Return_control can contain any of the following values (of which only the first character is significant) 'Allocated' Return from the function when the conversation is established. 'Immediate' Returns control immediately whether or not the conversation was established. 'Free' Returns control when a conversation is available, whether or not the conversation was established. Sync_level can contain one of the following values (of which only the first character is significant): 'None' No synchronization verbs are allowed during this conversation 'Confirm' Synchronization verbs ARE allowed during this conversation. Security may contain one of the following values, which must be complete: 'None' No conversation level Security 'Same' The user ID was verified when the local transaction program was initiated. 'Pgm U P' The remote LU validates access by examining the Userid string (up to 10 characters with no imbedded spaces) and the Password (up to 10 characters with no imbedded spaces) Example 'Pgm SOMEUSER SOMEPWD' Note: The Userid and Password strings should be in upper case. This can be done with the Translate built-in function. stemname is the name of a REXX stem variable that will contain additional information if the allocate request succeeds. This function returns one of two values: Note: stemname will be dropped before the call is executed 0 Function Completed ok stemname.1 conv_ID to be used on subsequent functions on this conversation not 0 error return code from Allocate request. additional info is provided as follows: stemname.2 primary return code stemname.3 secondary return code stemname.4 sense data ═══ 3.3.2. Confirm ═══ APPC( 'Confirm' , tp_ID , conv_ID , type ) Requests the remote application program to confirm (synchronize) the last transmission. This function will force any buffered data to be sent, and then wait for a reply from the remote application. To use this function request, then conversation must have been allocated with a Sync_level of 'Confirm'. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation This function returns one of two values: 0 Function Completed ok not 0 error return code from Confirm request. ═══ 3.3.3. Confirmed ═══ APPC( 'Confirmed' , tp_ID , conv_ID , type ) Sends a positive response to a 'Confirm' request issued by the remote transaction program. This function request can be used only when a 'Confirm' request has been received. (see the Receive_ function request) type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation This function returns one of two values: 0 Function Completed ok not 0 error return code from Confirmed request. ═══ 3.3.4. Convert ═══ APPC( 'Convert' , direction , table , expression ) Converts data from one type to another direction must be one of the following (of which only the first character is significant) 'Ascii' Convert data from EBCDIC to ASCII 'Ebcdic' Convert data from ASCII to EBCDIC table must be one of the following 'A' Use the Communications Manager 'A' translate table 'E' Use the Communications Manager 'AE' translate table 'G' Use the Communications Manager 'G' translate table. This table is user supplied, and MUST be specified as part of the Workstation Parameters in the Communications Manager Profile. expression is the data to convert, for example left(data_receive_from_host,10) or data_received_from_host This function returns either the converted data, or '' in case of error ═══ 3.3.5. Deallocate ═══ APPC( 'Deallocate' , tp_ID , conv_ID , type, dtype ) Ends the conversation conv_ID. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation dtype must be one of the following (of which only the first character is significant) Sync_level the conversation will be deallocated based on the Sync_level setting. If Sync_level is 'None' a 'Flush' function will be executed and the conversation will be ended. If Sync_level is 'Confirm', a 'Confirm' function will be executed and the conversation will be terminated only if 'Confirmed'. Otherwise an error results and the conversation is NOT ended. 'Flush' A 'Flush' function will be executed and the conversation will be ended. 'Abend' The conversation will be ended abnormally. If the conversation was in send state, a 'Flush' function will be executed. If in receive state, data may be purged and/or logical records may be terminated. If this is a Basic conversation type, 'Abend' is equivalent to 'Abend-Pgm' in the APPC Programmers Reference. Note: The 'Abend-SVC' and 'Abend-Timer' Basic conversation options are not supported. This function returns one of two values: 0 Function Completed ok not 0 error return code from Deallocate request. ═══ 3.3.6. Flush ═══ APPC( 'Flush' , tp_ID , conv_ID , type ) Forces any data buffered by the local LU to be sent to the remote LU. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation This function returns one of two values: 0 Function Completed ok not 0 error return code from Flush request. ═══ 3.3.7. Get_attributes ═══ APPC( 'Get_attributes' , tp_ID , conv_ID , type , stemname ) Provides attribute of the specified conversation. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation stemname is the name of a REXX stem variable that will contain additional information if the allocate request succeeds. This function returns one of two values: 0 Function Completed ok stemname.0 net_name The name of the network containing the local LU stemname.1 LU_name The name of the local LU stemname.2 LU_alias name The alias name of the local LU stemname.3 partner_LU_localname The name the partner LU is known by on this system stemname.4 partner_LU_netname The name the partner LU is known by on this network stemname.5 partner_full_name The fully qualified name of the partner LU stemname.6 mode_name The mode_name in use by this conversation stemname.7 sync_level in use during this conversation 'N' = None 'C' = Confirm stemname.8 user_ID The conversation level userid name (if any) or '' if none not 0 error return code from Get_attributes request. Note: stemname will be dropped ═══ 3.3.8. Prepare_to_receive ═══ APPC( 'Prepare_to_receive' , tp_ID , conv_ID , type , rtype , locks ) Used to change from send state to receive state, in anticipation of data. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation rtype must be one of the following (of which only the first character is significant) 'Sync_level' the function will be performed based on the synchronization level set for this conversation. None A 'Flush' function will be executed prior to entering receive mode. Confirm A 'Confirm' function (which includes a Flush function, will be executed. If the partner confirms receipt, the function will return in receive mode. If the confirm fails, the return code determines the state of the conversation. 'Flush' A 'flush' function will be performed prior to entering receive mode. locks specifies when to return control after executing the Confirm function of this verb. If Sync_level for this conversation is None, then this parameter is ignored. locks must be one of the following (of which only the first character is significant) 'Short' Control is returned immediately after the 'Confirm' function of this verb is executed. 'Long' Control is returned upon receipt of information or data from the partner. This function will return one of two values: 0 Function completed ok not 0 error return code from Prepare_to_receive request. ═══ 3.3.9. Receive_wait ═══ APPC( 'Receive_wait' , tp_ID , conv_ID , type , stemname , maxlen ) Used to receive data from the other partner in this conversation. stemname is the name of a REXX stem variable where info returned from the Receive_wait call will be placed. type must be one of the following (of which only the first character is significant) 'Mapped' Mapped Conversation 'Buffer' Basic conversation with 'Buffer' receive option. 'LL' Basic conversation with 'Logical' record receive option. This function will return one of two values: 0 Function completed ok Additional info will be in the variable stemname in the following order: stemname.0 a value to indicate what was received. stemname.1 a value to indicate whether the remote partner sent a 'Request to Receive' direction change request as well as data. stemname.2 the data received if stemname.0 indicates either Data (for basic conversations only) Data_complete Data_incomplete not 0 error return code from Receive_wait request. ═══ 3.3.10. Receive_immediate ═══ APPC( 'Receive_immediate' , tp_ID , conv_ID , type , stemname , maxlen ) Used to receive data from the other partner in this conversation. stemname is the name of a REXX stem variable where info returned from the Receive_immediate call will be placed. type must be one of the following (of which only the first character is significant) 'Mapped' Mapped Conversation 'Buffer' Basic conversation with 'Buffer' receive option. 'LL' Basic conversation with 'Logical' record receive option. This function will return one of two values: 0 Function completed ok Additional info will be in the variable stemname in the following order: stemname.0 a value to indicate what was received. stemname.1 a value to indicate whether the remote partner sent a 'Request to Receive' direction change request as well as data. stemname.2 the data received if stemname.0 indicates either Data (for basic conversations only) Data_complete Data_incomplete not 0 error return code from Receive_immediate request. type must be one of the following (of which only the first character is significant) 'Mapped' Mapped Conversation 'Buffer' Basic conversation with 'Buffer' receive option. 'LL' Basic conversation with 'Logical' record receive option. queue_name is the name of an external data queue where info returned from the Receive_post call will be placed. This function will return one of two values: 0 Function processing started when this function completes, the following info will be placed on the external data queue queue_name: a line consisting of the following data conv_ID what_received request_to_receive_requested where conv_ID is the conversation ID that returned this information what_received indicates what information was received either '0' or '1' to indicate if the partner has requested to receive information. If what_received indicates Data (for basic conversations only), Data_complete or Data_incomplete, then an additional record will be placed on the queue following (fifo) the information recorded above. not 0 error return code from Receive_post request. ═══ 3.3.11. Request_to_send ═══ APPC( 'Request_to_send' , tp_ID , conv_ID , type ) Requests permission to send data to the remote LU. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation This function returns one of two values: 0 Function Completed ok not 0 error return code from Request_to_send request. ═══ 3.3.12. Send_Conversation ═══ APPC( 'Send_Conversation' , tp_ID , Partner_LU , Modename , tpname , type, Return_control , security , data, [ Conv_Group_Id ] , stemname) Create a conversation with server tpname on system Partner_LU using tp_ID in Mode Modename, sends data and then deallocates the conversation without confirmation. Partner_LU may be a Local LU Alias, an implicit LU, or a Fully Qualified Partner LU name (i.e., contains Network_name.LU_name). to supply a service tp name, enter the EBCDIC value in hex. '06F3F0F1'x type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation Return_control can contain any of the following values (of which only the first character is significant) 'Allocated' Return from the function when the conversation is established. 'Immediate' Returns control immediately whether or not the conversation was established. 'Free' Returns control when a conversation is available, whether or not the conversation was established. 'ConWinner' Returns control when the first contention-winner session becomes available 'Group' Allocates a specific session specified by the Conv_Group_Id parameter Note: If 'Group' is specified then Conv_Group_Id MUST be supplied Security may contain one of the following values, which must be complete: 'None' No conversation level Security 'Same' The user ID was verified when the local transaction program was initiated. 'Pgm U P' The remote LU validates access by examining the Userid string (up to 10 characters with no imbedded spaces) and the Password (up to 10 characters with no imbedded spaces) Example 'Pgm SOMEUSER SOMEPWD' Note: The Userid and Password strings should be in upper case. This can be done with the Translate built-in function. stemname is the name of a REXX stem variable that will contain additional information if the allocate request succeeds. This function returns one of two values: Note: stemname will be dropped before the call is executed 0 Function Completed ok stemname.1 Conv_Group_ID if Return_type is NOT 'Group' not 0 error return code from Allocate request. additional info is provided as follows: stemname.2 primary return code stemname.3 secondary return code stemname.4 sense data ═══ 3.3.13. Send_data ═══ APPC( 'Send_data' , tp_ID , conv_ID , type , data) Sends data to the remote application program. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation This function returns one of two values: 0 Function Completed ok not 0 error return code from Send_data request. ═══ 3.3.14. Send_error ═══ APPC( 'Send_error' , tp_ID , conv_ID , type , layer ) Sends an error indication to the remote LU. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation layer must be one of the following (of which only the first characteis significant) 'Program' This error was detected by the application programming level 'Service' This error was detected by the LU service program layer An LU Service Program is a transaction program that is written to provide services to other programs at your LU. Example LU service programs include the SNA distribution system (SNA/DS), the APPC Mapped Conversation Support, and Distributed Data Management (DDM). The basic conversation interface is intended for LU service programs. It has extended features that are very valuable in this environment. o You can build architected records called general data stream (GDS) variables. o You can send or receive more than one data record in a single buffer with a single verb. o You can provide a unique or optimized mapped conversation interface (good for protocol converters). o You can provide a log data GDS variable when reporting an error (aids in problem determination). o You can distinguish between errors detected by your program and errors detected by your program's user. The LAYER parameter of SEND_ERROR is intended to provide this last feature. It indicates where the error was detected. If the error was detected by the program that uses your LU service program, specify Program. If the error was detected by your LU service program, specify Service. The intent is to control the error recovery procedures at the partner LU. If the error was detected by the program that uses your LU service program, the error was in something outside the scope of your program. Therefore, the error recovery is also outside the scope of your program. At the partner LU, the error indication is passed up to the program which is using the partner LU service program. If the error was detected by your LU service program, the error and its recovery are within the scope of the service. The error can be reported and recovery procedures completed without bothering the users at either LU. When you want to inform the partner program about the type of error detected (internal programming error, invalid request, unrecognized parameter, e.t.c), build a special data record which contains this information and use SEND_DATA to send it as the first data record after a SEND_ERROR request. This function returns one of two values: 0 Function Completed ok not 0 error return code from Send_error request. ═══ 3.3.15. Test_rts ═══ APPC( 'Test_rts' , tp_ID , conv_ID , type ) Used to determine if the remote LU has requested to send data. type must be one of the following (of which only the first character is significant) 'Basic' Basic conversation 'Mapped' Mapped Conversation This function returns one of two values: 0 Function Completed ok not 0 error return code from Test_rts request. ═══ 3.3.16. Trans_table ═══ APPC( 'Trans_table', table_type ) Used to set different translate tables to be used for any data translations required internally. The default Table is 'E' (AE). table_type must be one of the following 'A' Use the Communications Manager 'A' translate table 'E' Use the Communications Manager 'AE' translate table (DEFAULT) 'G' Use the Communications Manager 'G' translate table. This table is user supplied, and MUST be specified as part of the Workstation Parameters in the Communications Manager Profile. This function returns one value: 0 Function Completed ok ═══ 3.4. Sample Programs ═══ ═══ 3.4.1. Client ═══ This is a sample 'requester' TP program in REXX. /* */ /* REXX/APPC transaction program sample (requester) */ /* */ trace off /* */ /* Tell Rexx that there is a new function available */ /* */ CALL RXFUNCADD APPC,SAAAPPC,APPCSRV /* */ /* start a Transaction Pgm (i.e., tell APPC we're here and running)*/ /* */ rc=appc('Tp_started',,'TP1','Lu1s.') if rc=0 then do tpid=lu1s.0 /* save the transaction pgm id */ /* */ /* Open (allocate) a conversation with Transaction pgm (TP) TP2 */ /* which is located on Node prompted for */ /* Note the Userid and Password data format. */ /* */ say 'Enter Partner LU name' pull plu . rc=appc('Allocate',lu1s.0,plu,'#BATCH','TP2','MAPPED','A','N', 'N','Lu1P.') if rc=0 then do convid=lu1p.1 /* save the conversation id */ /* */ /* Lets send some data ('Hello from tp1') to our partner */ /* */ /* Note: as this is a 'Mapped' conversations, the length info */ /* is NOT part of the actual data. */ /* */ rc=appc('Send_data',tpid,convid,'Mapped','Hello from tp1') /* */ /* Now Lets receive send some data from our partner */ /* Our partner will have to turn the conversation around */ /* */ rc=appc('Receive_wait',tpid,convid,'Mapped','data.',1000) say data.2 end else Say 'Allocate failed rc=' c2x(Lu1P.2) 'Secondary rc=' c2x(Lu1P.3) 'Sense=' c2x(Lu1p.4) /* */ /* Well, we're done now. So tell APPC we're done. APPC */ /* will close the conversation. */ /* */ rc=appc('Tp_ended',tpid) end else do say 'Communications manager has not been started' say 'or is not configured for APPC' end ═══ 3.4.2. Server ═══ This is a sample 'server'TP program in REXX. /* */ /* REXX/APPC transaction program sample (server) */ /* */ trace off /* */ /* Tell Rexx that there is a new function available */ /* */ CALL RXFUNCADD APPC,SAAAPPC,APPCSRV /* */ /* Tell APPC that we are TP2 and we're ready to talk to any other */ /* TP that calls us. */ /* */ rc=appc('Receive_allocate','TP2','Lu2s.') tpid=lu2s.0 /* save the TP ID */ convid=lu2s.1 /* and conversation ID */ ConvType=Lu2s.3 /* get Conversation type (Basic/Mapped) */ /* */ /* Lets receive some data from our partner. */ /* */ /* Note: This is a 'Mapped' Conversation. */ /* */ rc=appc('Receive_wait',tpid,convid,ConvType,'data.',1000) say data.2 /* */ /* We have the data. In this sample, we know there is no more */ /* data coming, so a receive_immediate will turn the line around. */ /* In reality one should check the state after the receive_wait */ /* to see if all the data was received, and check again after */ /* the receive_immediate. */ /* */ /* But were skimping here, cause its only a sample */ /* */ rc=appc('Receive_immediate',tpid,convid,ConvType,'data1.',1000) /* */ /* We should be in 'SEND' state now, that means WE can SEND */ /* data1.0 should contain 'SEND' as what_received */ /* */ rc=appc('Send_data',tpid,convid,ConvType,'Hello from tp2') /* */ /* OK, data sent. Now we are done. */ /* Tell APPC that this transaction is complete. */ /* */ /* This could be a 'do forever' loop processing single */ /* transmissions from multiple requestors one at a time. */ /* */ /* */ rc=appc('Tp_ended',tpid) 'exit'