 /* REXX */
 /*********************************************************************/
 /* Licensed Material - Property of IBM                               */
 /* 5639-B92 , 5648-A25 , 5688-197 , 5639-D65 , 5688-235              */
 /* (C) Copyright IBM Corp., 1997, 1998                               */
 /* All rights reserved.                                              */
 /* US Government Users Restricted Rights - Use, duplication or       */
 /* disclosure restricted by GSA ADP Schedule Contract with IBM Corp. */
 /*********************************************************************/
 trace off;
 signal on novalue;
/*---------------------------------------------------------------
 *
 *  Name:  IGYFINIT
 *
 *  Description:
 *
 *    This MVS based EXEC starts the IGYFSERV server. This is
 *    invoked via REXEC.
 *
 *  Function:
 *
 *    - Initiates APPC convseration with IGYFSERV.
 *    - Sends workstation IP address.
 *    - Receives Host IP address, port and ID token from IGYFSERV.
 *    - "Says" Host IP address, port and ID token. This is will
 *      be captured by invoking EXEC iwzmVSR.
 *
 *  Operation:
 *
 *    - Explicitly invoked via REXEC.  Will normally be started
 *      as part of the iwzmVSR EXEC on the workstation.
 *
 *  Parameters:
 *    1. Workstation IP address.
 *
 *  Security:
 *
 *    - Runs under the TSO ID that has been authorized via REXEC.
 *
 *  Installation:
 *
 *    - Put this EXEC in a library that can be called by the
 *      TSO command sent to MVS by iwzmVSR (via RSH).
 *      Probably SIGYCLST.
 *
 *  Changes:
 *    JCH 970325 Removed trailing blanks from mode name.
 *
 *
 *  What it doesn't do yet:
 *
 *---------------------------------------------------------------
 *  IGYFINIT - IGYFSERV APPC Conversation Flow
 *---------------------------------------------------------------
 *
 *     IGYFINIT                       IGYFSERV
 *
 *   Get WS IP
 *   Init conversation
 *   Allocate
 *   Confirm      --------------->
 *     .                            Accept Conversation
 *     .                            Receive (Looking for Confirm)
 *     .          <---------------  Confirmed
 *   Send data                        .
 *     (WS IP address)                .
 *   Prepare to Rec                   .
 *     .            ------------->    .
 *     .                            Receive (WS IP address)
 *     .                            Receive (Send state)
 *     .                          --- Initialize TCP/IP server ---
 *     .                            Send data (Host IP, port, token)
 *     .                            Deallocate conversation
 *     .          <---------------    .
 *   Receive (Host IP, port)          .
 *   Receive (confirm)                .
 *   Confirmed    --------------->    .
 *
 *                                --- Receive commands from
 *                                    workstation and return results
 *                                    via TCP/IP
 *
 *
 *---------------------------------------------------------------*/
 
trc=1                   /* 1=enable trace, 0=disable trace           */
 
/*---------------------------------------------------------------
 * Get passed workstation IP address
 *---------------------------------------------------------------*/
parse arg wsip .
 
 OK=1
/*---------------------------------------------------------------
 * Set standard CPIC pseudonyms
 *---------------------------------------------------------------*/
 call CPIC_Const
 
 call LogMsg 'OUTPUT from IGYFINIT'
 
/*---------------------------------------------------------------
 * Check for OK looking IP address
 *---------------------------------------------------------------*/
 call ArgChk wsip
 if OK=0 then exit 8
 
/*---------------------------------------------------------------
 * Initializations
 *---------------------------------------------------------------*/
 
      TP_name                = 'IGYFSERV'
      TP_Name_Length         = length(tp_name)
      sym_dest_name          = '        '
 
      mode_name              = '#INTER'
      Mode_Name_Length       = length(mode_name)
 
      Partner_LU_Name        = '        '
      Partner_LU_Name_Length = length(partner_lu_name)
      /* When Partner_LU_Name is left blank, then the TP runs on the
         partner LU specified in the side-information file.  if
         a value for partner LU is hardcoded here it will override
         any conflicting information that may be specified in the
         side information file.                              */
 
      Return_Code            = 99999
      Conv_ID                = '00000000'
 
      requested_length   = 255
 
     Buffer                   = 'THIS IS TEST DATA';
     Conversation_Type        = CM_mapped_conversation;
     Deallocate_Type          = CM_deallocate_confirm
     Error_Direction          = CM_receive_error;
     Fill                     = CM_fill_ll;
 
     Prepare_To_Receive_Type  = CM_prep_to_receive_flush;
     Return_Control           = CM_when_session_allocated;
 
     Send_Type                = CM_buffer_data;
     Sync_Level               = CM_confirm;
     Request_To_Send_Received_Value = CM_req_to_send_not_received;
 
      Log_Data               = 'This is log data';
      Log_Data_Length        = length(log_data);
 
      Data_Received           = 0;
      Status_Received         = 0;
      Received_Length         = 0;
 
 
/*---------------------------------------------------------------
 *
 *   Mainline
 *
 *---------------------------------------------------------------*/
 
    CALL Conv_Init;                 /*  Initialize Conversation      */
 
/*---------------------------------------------------------------
 * Set Conversation Type
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Conv_Type;
 
/*---------------------------------------------------------------
 * Set Mode Name
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Mode_Name;
 
/*---------------------------------------------------------------
 * Set Partner LU name
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Part_LUname;
 
/*---------------------------------------------------------------
 * Set Return Control
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Ret_Cntl;
 
/*---------------------------------------------------------------
 * Set Sync Level
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Sync_Level;
 
/*---------------------------------------------------------------
 * Set TP Name
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_TP_Name;
 
/*---------------------------------------------------------------
 * Allocate Conversation
 *---------------------------------------------------------------*/
    if OK then
      CALL Alloc;
 
/*---------------------------------------------------------------
 * Set Send Type
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Send_Type;
 
/*---------------------------------------------------------------
 * Request a confirmation from partner
 *---------------------------------------------------------------*/
    if OK then
      CALL Confirm
 
/*---------------------------------------------------------------
 * Send workstation IP address to server
 *---------------------------------------------------------------*/
    Buffer = ":IP:" wsip
    if OK then
      CALL Send_data
 
/*---------------------------------------------------------------
 * Set prepare to receive type
 *---------------------------------------------------------------*/
    if OK then
      CALL Set_Prep_To_Rec_Type
 
/*---------------------------------------------------------------
 * Prepare to receive
 *---------------------------------------------------------------*/
    if OK then
      CALL Prep_To_Rec
 
/*---------------------------------------------------------------
 * Receive server RC, Host IP, port and token
 *         -or-   RC, error message
 *---------------------------------------------------------------*/
    if OK then
      CALL Receive
 
/*---------------------------------------------------------------
 * Send back :IP: message or :ERR: message
 *---------------------------------------------------------------*/
    conf=0
    if OK then
      do
        if substr(buffer,1,4)=':IP:' then
          do
            say substr(buffer,1,received_length)
            conf=1
          end
        else
          do
            say ":ERR: Host IP, port and token not received",
                "from IGYFSERV"
          end
      end
    else
      do
        say ":ERR: Receive of Host IP, port and token failed"
      end
 
/*---------------------------------------------------------------
 * Receive Expected Confirmation Request
 *
 * Note: This explicit receive of the confirm state is only required
 *   if no status was received on the previous receive. Data and
 *   the status may or may not come in on the same receive.
 *---------------------------------------------------------------*/
    if OK & status_received=CM_NO_STATUS_RECEIVED then
      CALL Receive_Confirm
 
/*---------------------------------------------------------------
 * Return a positive confirmation
 *---------------------------------------------------------------*/
    if OK then
      do
        if conf then
          CALL Confirmed
        else
          CALL Send_Error
      end
 
exit 0
 
 
/*---------------------------------------------------------------
 *
 *   Initialize Conversation
 *
 *---------------------------------------------------------------*/
 Conv_Init: PROCEDURE ,
  EXPOSE conv_id sym_dest_name return_code cm_ok ok trc
  ADDRESS CPICOMM
     'CMINIT CONV_ID SYM_DEST_NAME RETURN_CODE'
                        /* Initialize the conversation */
 
  CALL LOGMSG 'APPC: CONV INIT return_code is ' return_code
    if Return_Code <> CM_OK then    /*  if init was unsuccessful     */
      do                            /*  Send message and return code */
        CALL LOGMSG 'APPC: Conversation Initialization failed'
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      do                            /*  Send message and return code */
        CALL LOGMSG 'APPC: Conversation Initialization succeeded'
        CALL LOGMSG ' Conversation id is 'C2X(conv_id)
      end;
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Conversation Type
 *
 *---------------------------------------------------------------*/
 Set_Conv_Type: PROCEDURE ,
    EXPOSE conv_id conversation_type return_code cm_ok ok trc
    ADDRESS CPICOMM 'CMSCT CONV_ID CONVERSATION_TYPE RETURN_CODE '
                /*  Set conversation type        */
 
    if Return_Code <> CM_OK then    /*  if typing was unsuccessful   */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Conversation Type failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
        CALL LOGMSG 'APPC: Set Conversation Type succeeded';
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Mode Name
 *
 *---------------------------------------------------------------*/
 Set_Mode_Name:  PROCEDURE ,
    EXPOSE conv_id mode_name mode_name_length return_code cm_ok ok trc
 
    ADDRESS CPICOMM ' CMSMN CONV_ID MODE_NAME MODE_NAME_LENGTH',
                 ' RETURN_CODE '
                /*  Set Mode Name  */
 
 
    if Return_Code <> CM_OK then    /*  if Mode name setting was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Mode Name failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
        CALL LOGMSG 'APPC: Set Mode Name succeeded';
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Partner LU Name
 *
 *---------------------------------------------------------------*/
 Set_Part_LUname:  PROCEDURE EXPOSE conv_id partner_lu_name cm_ok ,
    partner_lu_name_length return_code ok trc
 
    ADDRESS CPICOMM 'CMSPLN CONV_ID PARTNER_LU_NAME',
                'PARTNER_LU_NAME_LENGTH RETURN_CODE'
            /*  Set Partner LU Name          */
 
    if Return_Code <> CM_OK then    /*  if Partner LU name set was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Partner LU Name failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
        CALL LOGMSG 'APPC: Set Partner LU Name succeeded';
 
 return;  /*  end of SET_PART_LUname  */
 
/*---------------------------------------------------------------
 *
 *   Set Return Control
 *
 *---------------------------------------------------------------*/
 Set_Ret_Cntl: PROCEDURE ,
    EXPOSE conv_id return_control return_code cm_ok ok trc
    ADDRESS CPICOMM 'CMSRC  CONV_ID RETURN_CONTROL RETURN_CODE'
                 /*    Set Return Control           */
 
    if Return_Code <> CM_OK then    /*  if Set Return Control was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Return Control failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Set Return Control succeeded';
 
 return;    /*    Set_Ret_Cntl   */
 
/*---------------------------------------------------------------
 *
 *   Set Sync Level
 *
 *---------------------------------------------------------------*/
 Set_Sync_Level: PROCEDURE ,
 EXPOSE conv_id sync_level return_code cm_ok ok trc
 
   ADDRESS CPICOMM 'CMSSL CONV_ID SYNC_LEVEL RETURN_CODE '
     /*  Set Sync Level               */
 
    if Return_Code <> CM_OK then    /*  if Set Sync Level was bad    */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Sync Level failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
     CALL LOGMSG 'APPC: Set Sync Level succeeded';
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set TP Name
 *
 *---------------------------------------------------------------*/
 SET_TP_NAME:  PROCEDURE ,
  EXPOSE conv_id tp_name tp_name_length return_code cm_ok ok trc
 
  ADDRESS CPICOMM 'CMSTPN CONV_ID TP_NAME TP_NAME_LENGTH RETURN_CODE'
            /*  Set TP Name                  */
 
    if Return_Code <> CM_OK then    /*  if TP Name set was bad       */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set TP Name failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Set TP Name succeeded';
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Allocate Conversation
 *
 *---------------------------------------------------------------*/
 Alloc: procedure ,
 expose   conv_id return_code cm_ok ok trc
 
  ADDRESS CPICOMM 'CMALLC CONV_ID RETURN_CODE'
              /*  Allocate conversation        */
 
    if Return_Code <> CM_OK then    /*  if allocate was bad          */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Allocate failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Allocate succeeded';
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Fill
 *
 *---------------------------------------------------------------*/
 Set_Fill: procedure,
 EXPOSE conv_id fill return_code cm_ok cm_program_parameter_check ok,
   trc
 ADDRESS CPICOMM
    'CMSF CONV_ID FILL RETURN_CODE'
                                    /*  Set Fill                     */
 
    if Return_Code <> CM_program_parameter_check then  /* if bad     */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Fill failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      do;
        return_code = cm_ok;
        CALL LOGMSG 'APPC: Set Fill succeeded';
      end;
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Send Type
 *
 *---------------------------------------------------------------*/
 Set_Send_Type: procedure,
 EXPOSE conv_id send_type return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMSST CONV_ID SEND_TYPE RETURN_CODE'
                                    /*  Set Send Type                */
 
    if Return_Code <> CM_OK then    /*  if Set Send Type was bad     */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Send Type failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Set Send Type succeeded';
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Confirm - request confirmation from partner
 *
 *---------------------------------------------------------------*/
 Confirm: PROCEDURE,
 EXPOSE conv_id request_to_send_received_value return_code cm_ok ok,
   trc
 ADDRESS CPICOMM
 
    'CMCFM CONV_ID REQUEST_TO_SEND_RECEIVED_VALUE RETURN_CODE'
                                    /*  Confirm                      */
 
    if Return_Code <> CM_OK then    /*  if confirmation was bad      */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Confirmation failed'
        call CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was Successful     */
      do
        CALL LOGMSG 'APPC: Confirm succeeded'
        CALL LOGMSG ' Req to send recd value is ',
          request_to_send_received_value
      end
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Confirmation - positively respond to CONFIRM request
 *
 *---------------------------------------------------------------*/
 Confirmed: PROCEDURE,
 EXPOSE conv_id return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMCFMD CONV_ID RETURN_CODE'    /*  Confirm                      */
 
    if Return_Code <> CM_OK then    /*  if confirmation was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: CONFIRMED failed'
        call CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
     CALL LOGMSG 'APPC: CONFIRMED succeeded'
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Send Data
 *
 *---------------------------------------------------------------*/
 Send_Data: procedure,
 EXPOSE conv_id buffer send_length request_to_send_received_value,
        return_code cm_ok ok trc
 
 send_length = length(buffer)
 ADDRESS CPICOMM
    'CMSEND CONV_ID BUFFER SEND_LENGTH',
            'REQUEST_TO_SEND_RECEIVED_VALUE RETURN_CODE'
                                    /*  Send Data                    */
 
    CALL LOGMSG 'APPC: SEND_DATA return_code = 'return_code;
    CALL LOGMSG ' request_to_send_received = ',
        request_to_send_received_value;
 
    if Return_Code <> CM_OK then    /*  if Send Data was bad         */
      do;                           /*  Send message and return code */
        CALL LOGMSG ' Send Data failed';
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      do;
        CALL LOGMSG ' Send Data succeeded';
      end;
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Extract Conversation State
 *
 *---------------------------------------------------------------*/
 Ext_Conv_State: procedure,
 EXPOSE conv_id conv_state return_code OK CM_OK ok,
    request_to_send_received_value trc
 
 ADDRESS CPICOMM
    'CMECS CONV_ID CONV_STATE RETURN_CODE'
 
    if Return_Code <> CM_OK then    /*  if ext conv  was bad         */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Conversation state extract failed'
        CALL LOGMSG ' Ext_Conv_State return_code = 'return_code;
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      do;
        CALL LOGMSG 'APPC: Conversation state is' conv_state
      end;
 
 return
 
/* *******************************************************************/
/*                                                                   */
/*   Flush                                                           */
/*                                                                   */
/* *******************************************************************/
 
 Flush: procedure,
 EXPOSE conv_id return_code cm_ok ok trc
 ADDRESS CPICOMM
 
    'CMFLUS CONV_ID RETURN_CODE'    /*  Flush                        */
 
    if Return_Code <> CM_OK then    /*  if Flush was unsuccessful    */
      do;                           /*  Send message and return code */
        SAY 'APPC: Flush failed';
        CALL CheckRC return_code
      end;
    ELSE                            /*  operation was successful     */
     SAY 'APPC: Flush succeeded';
 
 return;
 
/* *******************************************************************/
/*                                                                   */
/*   Test Request to Send Received                                   */
/*                                                                   */
/* *******************************************************************/
 
 Test_Req_To_Send_Recd: procedure,
 EXPOSE conv_id request_to_send_received_value return_code,
        cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMTRTS CONV_ID REQUEST_TO_SEND_RECEIVED_VALUE RETURN_CODE'
                                    /*  Test request to send rec'd   */
 
    if Return_Code <> CM_OK then    /*  if TRTS was unsuccessful     */
      do;                           /*  Send message and return code */
        SAY 'APPC: Test Req to Send Received failed';
        CALL CheckRC return_code
      end;
    ELSE                            /*  operation was successful     */
    do;
     SAY 'APPC: Test Req to Send Received succeeded';
     SAY ' Request to send received is 'request_to_send_received_value;
    end;
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Prepare to Receive Type
 *
 *---------------------------------------------------------------*/
 Set_Prep_To_Rec_Type: PROCEDURE,
 EXPOSE conv_id prepare_to_receive_type return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMSPTR CONV_ID PREPARE_TO_RECEIVE_TYPE RETURN_CODE'
                                    /*  Set Prepare to Receive type  */
 
    if Return_Code <> CM_OK then    /*  if Set prep to rec type was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Prepare to Receive Type failed'
        CALL CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Set Prepare to Receive type succeeded'
 
 return
 
/*---------------------------------------------------------------
 *
/*   Prepare to Receive                                              */
 *
 *---------------------------------------------------------------*/
 Prep_To_Rec: PROCEDURE,
 EXPOSE conv_id return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMPTR CONV_ID RETURN_CODE'     /*  Prepare to Receive           */
 
    if Return_Code <> CM_OK then    /*  if Prepare to receive was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Prepare to Receive failed'
        call CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
     CALL LOGMSG 'APPC: Prepare to Receive succeeded'
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Receive Data
 *
 *---------------------------------------------------------------*/
 Receive: PROCEDURE,
 EXPOSE conv_id buffer requested_length data_received received_length,
        status_received request_to_send_received_value,
        return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMRCV  CONV_ID BUFFER REQUESTED_LENGTH DATA_RECEIVED',
            'RECEIVED_LENGTH STATUS_RECEIVED',
            'REQUEST_TO_SEND_RECEIVED_VALUE RETURN_CODE'
                                    /*  Receive                      */
 
     call logmsg 'APPC: Receive data'
     call logmsg ' RCV return_code = 'return_code
     call logmsg ' RCV data_received= 'data_received
     call logmsg ' RCV received_length=' received_length
     call logmsg ' RCV status_received= 'status_received
     call logmsg ' RCV req_to_send=',
       request_to_send_received_value
 
    if Return_Code <> CM_OK then    /*  if Receive was unsuccessful  */
      do;                           /*  Send message and return code */
        CALL LOGMSG ' Receive failed'
        call CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG ' Receive succeeded'
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Receive expected confirmation request
 *
 *---------------------------------------------------------------*/
 
 Receive_Confirm: PROCEDURE,
 EXPOSE conv_id buffer requested_length data_received received_length,
        status_received request_to_send_received_value return_code,
        cm_ok cm_deallocated_normal cm_request_to_send_not_received,
        cm_no_status_received cm_complete_data_received,
        cm_send_received ok cm_confirm_received,
        cm_confirm_dealloc_received trc
 ADDRESS CPICOMM
    'CMRCV CONV_ID BUFFER REQUESTED_LENGTH DATA_RECEIVED',
          'RECEIVED_LENGTH STATUS_RECEIVED',
          'REQUEST_TO_SEND_RECEIVED_VALUE RETURN_CODE'
 
    call logmsg 'APPC: Receive Confirm procedure'
    call logmsg ' RCV return_code = 'return_code
    call logmsg ' RCV data_received= 'data_received
    call logmsg ' RCV status_received= 'status_received
    call logmsg ' RCV req_to_send=',
      request_to_send_received_value
 
    SELECT
      WHEN (Return_Code = CM_OK) then
        call logmsg ' RCV Inbound Receive succeeded'
      WHEN (Return_Code = CM_deallocated_normal) then
        do
          call logmsg ' RCV Inbound Receive succeeded'
          ok=0
        end
      OTHERWISE
        do
          call logmsg ' RCV Inbound Receive failed'
          call CheckRC return_code
          ok=0
        end
    end
 
    if Return_code <> cm_deallocated_normal & ok=1 then
     /*  if the TP is deallocated don't do the following checks    */
       do;
         /*  Make sure a CONFIRM was received      */
          if Status_Received <> CM_CONFIRM_RECEIVED &,
             Status_Received <> CM_CONFIRM_DEALLOC_RECEIVED then
            do
              call logmsg ' Expected CONFIRM request not received'
              ok=0
            end
       end;
 
 return;
 
/* *******************************************************************/
/*                                                                   */
/*   Set Error Direction                                             */
/*                                                                   */
/* *******************************************************************/
 
 Set_Err_Dir: PROCEDURE,
 EXPOSE conv_id error_direction return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMSED CONV_ID ERROR_DIRECTION RETURN_CODE'
                                    /*  Set Error direction          */
 
    if Return_Code <> CM_OK then    /*  if Set Error direction was   */
                                    /*  unsuccessful                 */
      do;                           /*  Send message and return code */
        SAY 'APPC: Set Error Direction failed'
        call CheckRC return_code
      end;
    ELSE                            /*  operation was successful     */
     SAY 'APPC: Set Error Direction succeeded'
 
 return;
/* *******************************************************************/
/*                                                                   */
/*   Set Log Data                                                    */
/*                                                                   */
/* *******************************************************************/
 
 Set_Log_Data: PROCEDURE,
 EXPOSE conv_id log_data log_data_length return_code ,
        cm_program_parameter_check ok trc
 
 ADDRESS CPICOMM
    'CMSLD CONV_ID LOG_DATA LOG_DATA_LENGTH RETURN_CODE'
                                    /*  Set Log Data                 */
 
   /*  Set Log Data should give a program_parameter_check since
       the conversation_type is cm_mapped_conversation.        */
    if Return_Code <> cm_program_parameter_check then
      do;                           /*  Send message and return code */
        SAY 'APPC: Set Log Data failed'
        call CheckRC return_code
      end;
    ELSE                            /*  operation was successful     */
     SAY 'APPC: Set Log Data - expected return code 24 '
 
 return;
 
/*---------------------------------------------------------------
 *
/*   Send Error                                                      */
 *
 *---------------------------------------------------------------*/
 Send_Error: PROCEDURE,
 EXPOSE conv_id request_to_send_received_value return_code cm_ok ok,
   trc
 
 ADDRESS CPICOMM
    'CMSERR CONV_ID REQUEST_TO_SEND_RECEIVED_VALUE RETURN_CODE'
                                    /*  Send Error                   */
 
    if Return_Code <> CM_OK then    /*  if Send Error was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Send Error failed'
        call CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
     CALL LOGMSG 'APPC: Send Error succeeded'
     CALL LOGMSG ' Req to send rec''d value is',
       request_to_send_received_value
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Set Deallocation type
 *
 *---------------------------------------------------------------*/
 Set_Dealloc_Type: PROCEDURE,
 EXPOSE conv_id deallocate_type return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMSDT CONV_ID DEALLOCATE_TYPE RETURN_CODE'
                                    /*  Set Deallocate type          */
 
    if Return_Code <> CM_OK then    /*  if Set Deallocate type was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Set Deallocate type failed'
        call CheckRC return_code
        OK=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Set Deallocate type was successful'
 
 return;
 
/*---------------------------------------------------------------
 *
 *   Deallocate conversation
 *
 *---------------------------------------------------------------*/
 Deallocate: PROCEDURE,
 EXPOSE conv_id return_code cm_ok ok trc
 
 ADDRESS CPICOMM
    'CMDEAL CONV_ID RETURN_CODE'    /*  Deallocate                   */
 
    if Return_Code <> CM_OK then    /*  if Deallocate was
                                        unsuccessful                 */
      do;                           /*  Send message and return code */
        CALL LOGMSG 'APPC: Deallocate failed'
        call CheckRC return_code
        ok=0
      end;
    ELSE                            /*  operation was successful     */
      CALL LOGMSG 'APPC: Deallocate succeeded'
 
 return;
 
/*---------------------------------------------------------------
 * Check return code and log message
 *---------------------------------------------------------------*/
CheckRC:
 parse arg ChkRC
 
 SELECT
 
   WHEN (ChkRC=0)
     then do                            /* OK                        */
      CALL LOGMSG ' Return code 0 - OK'
     end;
 
   WHEN (ChkRC=1)
    then do                            /* Allocate Failure no retry  */
      CALL LOGMSG ' Return code 1 - Allocate Failure no retry'
     end;
 
   WHEN (ChkRC=2)
    then do;                           /* Allocate Failure retry     */
      CALL LOGMSG ' Return code 2 - Allocate Failure retry'
     end;
 
   WHEN (ChkRC=3)
    then do                            /* Conversation Type mismatch */
      CALL LOGMSG ' Return code 3 - Conversation Type mismatch'
     end;
 
   WHEN (ChkRC=6)
    then do                            /* Security not valid         */
      CALL LOGMSG ' Return code 6 - Security not valid'
     end;
 
   WHEN (ChkRC=8)
    then do                            /* Sync Level not supported   */
      CALL LOGMSG ' Return code 8 - Sync Level not supported'
     end;
 
   WHEN (ChkRC=9)
    then do                            /* TP Name not recognized     */
      CALL LOGMSG ' Return code 9 - TP Name not recognized'
     end;
 
   WHEN (ChkRC=10)
    then do                            /* TP not avail no retry      */
      CALL LOGMSG ' Return code 10 - TP not avail no retry'
     end;
 
   WHEN (ChkRC=11)
    then do                            /* TP not avail retry         */
      CALL LOGMSG ' Return code 11 - TP not avail retry'
     end;
 
   WHEN (ChkRC=17)
    then do                            /* Deallocated Abend          */
      CALL LOGMSG ' Return code 17 - Deallocated Abend'
     end;
 
   WHEN (ChkRC=30)
    then do                            /* Deallocated Abend Svc      */
      CALL LOGMSG ' Return code 30 - Deallocated Abend Svc'
     end;
 
   WHEN (ChkRC=31)
    then do                            /* Deallocated Abend Timer    */
      CALL LOGMSG ' Return code 31 - Deallocated Abend Timer'
     end;
 
   WHEN (ChkRC=32)
    then do                            /* SVC Error no truncation    */
      CALL LOGMSG ' Return code 32 - SVC Error no Truncation'
     end;
 
   WHEN (ChkRC=33)
    then do                            /* SVC Error Purging          */
      CALL LOGMSG ' Return code 33 - SVC Error Purging'
     end;
 
   WHEN (ChkRC=34)
    then do                            /* SVC Error Truncated        */
      CALL LOGMSG ' Return code 34 - SVC Error Truncated'
     end;
 
   WHEN (ChkRC=18)
    then do                            /* Deallocated Normal         */
      CALL LOGMSG ' Return code 18 - Deallocated Normal'
     end;
 
   WHEN (ChkRC=19)
    then do                            /* Parameter Error            */
      CALL LOGMSG ' Return code 19 - Parameter Error'
     end;
 
   WHEN (ChkRC=20)
    then do                            /* Product specific error     */
      CALL LOGMSG ' Return code 20 - Product specific error'
     end;
 
   WHEN (ChkRC=21)
    then do                            /* Program error no trunc     */
      CALL LOGMSG ' Return code 21 - Program error no trunc'
     end;
 
   WHEN (ChkRC=22)
    then do                            /* Program error purging      */
      CALL LOGMSG ' Return code 22 - Program error purging'
     end;
 
   WHEN (ChkRC=23)
    then do                            /* Program error trunc        */
      CALL LOGMSG ' Return code 23 - Program error trunc'
     end;
 
   WHEN (ChkRC=24)
    then do                            /* Program parameter check    */
      CALL LOGMSG ' Return code 24 - Program parameter check'
     end;
 
   WHEN (ChkRC=25)
    then do                            /* Program state check        */
      CALL LOGMSG ' Return code 25 - Program state check'
      call Ext_Conv_State
     end;
 
   WHEN (ChkRC=26)
    then do                            /* Resource failure no retry  */
      CALL LOGMSG ' Return code 26 - Resource failure no retry'
     end;
 
   WHEN (ChkRC=27)
    then do                            /* Resource failure retry     */
      CALL LOGMSG ' Return code 27 - Resource failure retry'
     end;
 
   WHEN (ChkRC=28)
    then do                            /* Unsuccessful               */
      CALL LOGMSG ' Return code 28 - Unsuccessful'
     end;
 
   OTHERWISE
     do                            /* unknown                    */
      CALL LOGMSG ' Unknown return code = 'CheckRC
     end;
 END;                                  /* End SELECT                 */
 
return
 
/*---------------------------------------------------------------
 * Set standard CPIC pseudonyms
 *---------------------------------------------------------------*/
CPIC_Const:
  CM_INITIALIZE_STATE             = 2
  CM_SEND_STATE                   = 3
  CM_RECEIVE_STATE                = 4
  CM_SEND_PENDING_STATE           = 5
  CM_CONFIRM_STATE                = 6
  CM_CONFIRM_SEND_STATE           = 7
  CM_CONFIRM_DEALLOCATE_STATE     = 8
  CM_DEFER_RECEIVE_STATE          = 9
  CM_DEFER_DEALLOCATE_STATE       = 10
  CM_SYNC_POINT_STATE             = 11
  CM_SYNC_POINT_SEND_STATE        = 12
  CM_SYNC_POINT_DEALLOCATE_STATE  = 13
                                         /* conversation_type      */
  CM_BASIC_CONVERSATION           = 0
  CM_MAPPED_CONVERSATION          = 1
                                         /* data_received          */
  CM_NO_DATA_RECEIVED             = 0
  CM_DATA_RECEIVED                = 1
  CM_COMPLETE_DATA_RECEIVED       = 2
  CM_INCOMPLETE_DATA_RECEIVED     = 3
                                         /* deallocate_type        */
  CM_DEALLOCATE_SYNC_LEVEL        = 0
  CM_DEALLOCATE_FLUSH             = 1
  CM_DEALLOCATE_CONFIRM           = 2
  CM_DEALLOCATE_ABEND             = 3
                                         /* error_direction        */
  CM_RECEIVE_ERROR                = 0
  CM_SEND_ERROR                   = 1
                                         /* fill                   */
  CM_FILL_LL                      = 0
  CM_FILL_BUFFER                  = 1
                                         /* prepare_to_receive_type */
  CM_PREP_TO_RECEIVE_SYNC_LEVEL   = 0
  CM_PREP_TO_RECEIVE_FLUSH        = 1
  CM_PREP_TO_RECEIVE_CONFIRM      = 2
                                         /* receive_type           */
  CM_RECEIVE_AND_WAIT             = 0
  CM_RECEIVE_IMMEDIATE            = 1
                                         /* request_to_send_received */
  CM_REQ_TO_SEND_NOT_RECEIVED     = 0
  CM_REQ_TO_SEND_RECEIVED         = 1
                                         /* return_code            */
  CM_OK                           = 0
  CM_ALLOCATE_FAILURE_NO_RETRY    = 1
  CM_ALLOCATE_FAILURE_RETRY       = 2
  CM_CONVERSATION_TYPE_MISMATCH   = 3
  CM_PIP_NOT_SPECIFIED_CORRECTLY  = 5
  CM_SECURITY_NOT_VALID           = 6
  CM_SYNC_LVL_NOT_SUPPORTED_LU    = 7
  CM_SYNC_LVL_NOT_SUPPORTED_PGM   = 8
  CM_TPN_NOT_RECOGNIZED           = 9
  CM_TP_NOT_AVAILABLE_NO_RETRY    = 10
  CM_TP_NOT_AVAILABLE_RETRY       = 11
  CM_DEALLOCATED_ABEND            = 17
  CM_DEALLOCATED_NORMAL           = 18
  CM_PARAMETER_ERROR              = 19
  CM_PRODUCT_SPECIFIC_ERROR       = 20
  CM_PROGRAM_ERROR_NO_TRUNC       = 21
  CM_PROGRAM_ERROR_PURGING        = 22
  CM_PROGRAM_ERROR_TRUNC          = 23
  CM_PROGRAM_PARAMETER_CHECK      = 24
  CM_PROGRAM_STATE_CHECK          = 25
  CM_RESOURCE_FAILURE_NO_RETRY    = 26
  CM_RESOURCE_FAILURE_RETRY       = 27
  CM_UNSUCCESSFUL                 = 28
  CM_DEALLOCATED_ABEND_SVC        = 30
  CM_DEALLOCATED_ABEND_TIMER      = 31
  CM_SVC_ERROR_NO_TRUNC           = 32
  CM_SVC_ERROR_PURGING            = 33
  CM_SVC_ERROR_TRUNC              = 34
  CM_TAKE_BACKOUT                 = 100
  CM_DEALLOCATED_ABEND_BO         = 130
  CM_DEALLOCATED_ABEND_SVC_BO     = 131
  CM_DEALLOCATED_ABEND_TIMER_BO   = 132
  CM_RESOURCE_FAIL_NO_RETRY_BO    = 133
  CM_RESOURCE_FAILURE_RETRY_BO    = 134
  CM_DEALLOCATED_NORMAL_BO        = 135
                                         /* return_control         */
  CM_WHEN_SESSION_ALLOCATED       = 0
  CM_IMMEDIATE                    = 1
                                         /* send_type              */
  CM_BUFFER_DATA                  = 0
  CM_SEND_AND_FLUSH               = 1
  CM_SEND_AND_CONFIRM             = 2
  CM_SEND_AND_PREP_TO_RECEIVE     = 3
  CM_SEND_AND_DEALLOCATE          = 4
                                         /* status_received        */
  CM_NO_STATUS_RECEIVED           = 0
  CM_SEND_RECEIVED                = 1
  CM_CONFIRM_RECEIVED             = 2
  CM_CONFIRM_SEND_RECEIVED        = 3
  CM_CONFIRM_DEALLOC_RECEIVED     = 4
  CM_TAKE_COMMIT                  = 5
  CM_TAKE_COMMIT_SEND             = 6
  CM_TAKE_COMMIT_DEALLOCATE       = 7
 
  CM_NONE                         = 0    /* sync_level             */
  CM_CONFIRM                      = 1
  CM_SYNC_POINT                   = 2
 
return
 
/*---------------------------------------------------------------
 * Message logging routine
 *---------------------------------------------------------------*/
LogMsg:
  if trc=0 then return
 
  PARSE ARG MSG
  SAY DATE('S') TIME('L') MSG
  VAC_Err_Msg = MSG
return
 
/*---------------------------------------------------------------
 * Check for valid arguments
 *---------------------------------------------------------------*/
ArgChk: procedure,
  expose OK trc
 
  parse arg addr
  parse var addr a.1 '.' a.2 '.' a.3 '.' a.4
 
  do i = 1 to 4
    if datatype(a.i,'W')=0 | length(a.i)>3 then
      do
        OK=0
        call LogMsg "ArgChk: Invalid IP address:" addr
        leave
      end
  end
return
