/*------------------------------------------------------------------*/
/* SUESAMP1 EXEC */
/* */
/* This EXEC is the source program for the demonstration of the */
/* CPI Communications VM extension routine Signal_User_Event */
/* (XCSUE). It NUCXLOADs and calls SUESAMP3 MODULE (sample */
/* ASSEMBLE provided for this) to set a timer and handle the */
/* subsequent interrupt. It establishes a CPI Communications */
/* conversation, and SUESAMP2 EXEC handles the partner side of */
/* the conversation. A CMS communications directory entry for */
/* nickname SUESAMP2 is required by SUESAMP1. */
/* */
/* Because this program is for demonstration purposes, only */
/* minimal error checking is included. */
/* */
/* Main logic of SUESAMP1: */
/* */
/* Initialize program constants */
/* Start a conversation with the partner */
/* Execute nucleus extension program to set a timer for */
/* 10 seconds. Its interrupt handler, driven when the */
/* timer "pops", will issue Signal_User_Event (XCSUE). */
/* Do forever */
/* Wait (XCWOE) for XCSUE user_event or data from partner */
/* If data is available, receive it */
/* Else if a user_event occurred then leave */
/* End */
/* Show the results of the XCWOE (user_data from XCSUE) */
/* End the conversation with the partner */
/*------------------------------------------------------------------*/
arg args
call Initialize
call Main_Prog
Get_Out:
say
Exit
/*------------------------------------------------------------------*/
/* INITIALIZE: Set up program variables and constants */
/*------------------------------------------------------------------*/
Initialize:
address command 'ESTATE CMREXX COPY *'
if (rc ¬= 0) then call error 'CMREXX COPY file not found.'
else do
'execio * diskr CMREXX COPY * (finis stem PSEUDONYM.'
do i = 1 to pseudonym.0
interpret pseudonym.i
end
end
say
say '*'copies('-', 78)'*'
msg = 'SUESAMP1: CPI Communications XCSUE Sample Source Program'
say ' ' msg
say '*'copies('-', 78)'*'
say
return
/*------------------------------------------------------------------*/
/* MAIN_PROG: Call Get_Conversation to start the conversation */
/* Call Set_Timer to start the timer program */
/* Do Forever */
/* Call Wait_on_Event (XCWOE) */
/* If more data, call Receive_And_Confirmed */
/* Else leave */
/* End */
/* Show XCSUE user_data reported on XCWOE */
/* Call End_Conversation to end the conversation */
/*------------------------------------------------------------------*/
Main_Prog:
call Get_Conversation
call Set_Timer
say 'XCWOE loop is beginning'
loop_count = 0
do forever
x = 'XCWOE -- Wait_on_Event'
address cpicomm 'XCWOE res_id conv event_type' ,
'event_info_len event_buf cm_rc'
if (cm_rc ¬= cm_ok) then
call error x, 'cm_rc', cm_return_code.cm_rc, ,
cm_return_code.cm_ok
if (event_type = xc_information_input) then call Receive_And_Confirmed
else if (event_type = xc_user_event) then leave
else call error x, 'event_type', xc_event_type.event_type, ,
xc_event_type.xc_user_event
end
say 'XCWOE loop is complete, performed' loop_count 'times'
say
say 'User_Event received by XCWOE:'
say ' Event_ID parameter =' res_id
say ' User_Data parameter =' left(event_buf, event_info_len)
say
call End_Conversation
return
/*------------------------------------------------------------------*/
/* SET_TIMER: Nucxload SUESAMP3, which calls STIMER macro to set */
/* a timer for 10 seconds. Its interrupt handler gets */
/* control when the timer "pops" and issues XCSUE */
/*------------------------------------------------------------------*/
Set_Timer:
'nucxload suesamp3 (system'
'suesamp3'
say 'SUESAMP3 called, timer set for 10 seconds'
return
/*------------------------------------------------------------------*/
/* GET_CONVERSATION: Issue CMINIT, CMSSL, CMALLC, and CMPTR to */
/* start a CPI Communications conversation. */
/* The CMINIT sets up conversation */
/* characteristics and gives us the */
/* conversation_id, the CMSSL sets the */
/* sync_level of this conversation to */
/* cm_confirm, and the CMALLC requests a */
/* session for the conversation. The CMPTR */
/* will switch the conversation from send to */
/* receive state, and also flow a confirmation */
/* request to the partner since the sync_level */
/* of the conversation is cm_confirm. */
/*------------------------------------------------------------------*/
Get_Conversation:
x = 'CMINIT -- Initialize_Conversation'
sym_dest_name = 'SUESAMP2'
address cpicomm 'CMINIT conv_id sym_dest_name cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
x = 'CMSSL -- Set_Sync_Level'
sync_level = cm_confirm
address cpicomm 'CMSSL conv_id sync_level cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
x = 'CMALLC -- Allocate'
address cpicomm 'CMALLC conv_id cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
x = 'CMPTR -- Prepare_To_Receive'
address cpicomm 'CMPTR conv_id cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
m = 'CMINIT, CMSSL, CMALLC, and CMPTR complete for conversation'
say m conv_id
return
/*------------------------------------------------------------------*/
/* RECEIVE_AND_CONFIRMED: Issue CMRCV. If confirm status is */
/* received, then we have received a */
/* complete data record so we'll respond */
/* CMCFMD and increment the loop counter. */
/*------------------------------------------------------------------*/
Receive_And_Confirmed:
reql = event_info_len
x = 'CMRCV -- Receive'
address cpicomm 'CMRCV conv_id buf reql datr recl stat rts cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
if (stat = cm_confirm_received) then do
x = 'CMCFMD -- Confirmed'
address cpicomm 'CMCFMD conv_id cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
loop_count = loop_count + 1
end
return
/*------------------------------------------------------------------*/
/* END_CONVERSATION: Issue CMSERR to reject any data that might */
/* have been sent but not received yet. That */
/* will switch the conversation to send state. */
/* Issue CMSDT to set the deallocate_type to */
/* cm_deallocate_flush, then CMDEAL to */
/* deallocate the conversation. */
/*------------------------------------------------------------------*/
End_Conversation:
x = 'CMSERR -- Send_Error'
address cpicomm 'CMSERR conv_id rts_rec cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
x = 'CMSDT -- Set_Deallocate_Type'
address cpicomm 'CMSDT conv_id cm_deallocate_flush cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
x = 'CMDEAL -- Deallocate'
address cpicomm 'CMDEAL conv_id cm_rc'
if (cm_rc ¬= cm_ok) then ,
call error x, 'cm_rc', cm_return_code.cm_rc, cm_return_code.cm_ok
say 'CMSERR, CMSDT and CMDEAL complete for conversation' conv_id
return
*------------------------------------------------------------------*/
/* ERROR: Display input error message and exit SUESAMP1. */
/*------------------------------------------------------------------*/
Error:
parse arg message, parm_name, act_val, exp_val
parm_msg = ' (Unexpected' parm_name 'value)'
x = 'Error:' message
if (parm_name ¬= '') then x = x parm_msg
say
say x
if (parm_name ¬= '') then do
say
say ' Expected value:' exp_val
say ' Received value:' act_val
end
signal Get_Out
return