IWAYEVT1 Program

The IWAYEVT1 sample program demonstrates sending an XML document to the iWay Transaction Adapter for CICS from a CICS/TX sockets interface. The program will echo the return document to the CICS terminal.

On Windows, the IWAYEVT1 sample program is located in:

C:\Program Files\iWay60\etc\samples\cics\iwayevt1

The following supporting file is provided:

#include <cics_api.h>
#include <cics_eib.h>
/***********************************************************************/
/* IWYEVT1 - This sample program demonstrates sending an xml           */
/* document to the iWay CICS adapter from CICS/TX.  The program will   */
/* echo the return document to the CICS terminal.                      */
/*                                                                     */
/* Author John Schlesinger                                             */
/* Version 1.0                                                         */
/***********************************************************************/
/* Updated 22-Feb-2006 - Lori Pieper                                   */
/* Changes include:                                                    */
/*                                                                     */
/* 1)  In main, removed the declaration of                             */ 
/* int cics_api_temp_var = cics_api_edf_init_c_extended(0, &CicsArgs); */
/*     since it seemed to be generated for us which caused a syntax    */
/*     error when compiling the code.                                  */
/*                                                                     */
/* 2)  Also in main, changed:                                          */
/*        // SendData("168.135.63.14", 4773);                          */
/*     to use the proper C language comment syntax as the former was   */
/*     causing syntax errors.                                          */
/*                                                                     */
/* 3)  To the includes section, added                                  */
/*        #include<netinet/in.h>                                       */
/*     since this is needed in order to define sockaddr_in, which is   */
/*     being used in the SendData subroutine.                          */
/*                                                                     */
/***********************************************************************/
/* #includes */
/********************************************************************/
#include <cicstype.h>
#include <string.h>
#include <stdlib.h>
#include <stdio.h>
#include <ctype.h>
#include <errno.h>
/* Include the right sockets headers */
#ifdef _MSC_VER
#include <winsock2.h>
#else
#include<netinet/in.h>
#include<arpa/inet.h>
#include<sys/socket.h>
#endif
/********************************************************************/
/* #defines */
/********************************************************************/
#define InsertCursor '\x13' /* 3270 Insert cursor */
#define ebcdic_ProtectAttribute '\xe4' /* 3270 Protected Attr */
#define ascii_ProtectAttribute '\x55' /* 3270 Protected Attr */
#define MSG_SIZE 32500 /* */
/********************************************************************/
/* Procedure Declarations */
/********************************************************************/
void Output_Text (char*);
void Log_Text (char*);
void cics_time (cics_char_t []);
void Process_Startup_Parameters (void);
void return_to_cics (void);
void SendData(char *, short);
int  writen(int, const void *, size_t);
int  readn(int, void *, size_t);
/********************************************************************/
/* Structures */
/********************************************************************/
struct screen_struct
{
       cics_char_t sf;
       cics_char_t attr;
       cics_char_t display [160];
;
struct log_struct
{
       ics_char_t program [8];
       cics_char_t filler0;
       cics_char_t applid [8];
       cics_char_t filler1;
       cics_char_t msg [80];
;
/********************************************************************/
/* Global Variables */
/********************************************************************/
cics_char_t Term_Code [2] = "00"; /* Terminal Code */
cics_char_t sba [4];              /* 3270 set buffer address */
cics_char_t ProtectAttribute ;    /* 3270 Protect Attribute */
cics_sshort_t scrnwd = 80;        /* Width of the screen */
struct screen_struct output_screen = {'\x1d', ' ', ""};
struct log_struct CSMT_log = {"CICSDEXI", ' ', "", ' ', ""};
/********************************************************************/
/* Procedure : Main */
/* Function : To call all sub-procedures */
/* Input : None */
/* Returns : Nothing */
/********************************************************************/
void main( void )
{
     Process_Startup_Parameters();
     Output_Text("Starting the test");
     /*****************************************/
     /* Add site specific host and port below */
     /*****************************************/
     SendData("172.30.244.81", 8182);
     Output_Text("Test completed");
     return_to_cics();
} 
/* End of main */
/********************************************************************/
/* Procedure : Process_Startup_Parameters */
/* Function : To Determine how the transaction was initiated */
/* and process any parameters supplied */
/* Input : None */
/* Returns : Nothing */
/********************************************************************/
void Process_Startup_Parameters()
{
     cics_sshort_t len_out;
     cics_char_t ascii_sba [4] = {'\x11', '\x20', '\x41', '\x13'};
     cics_char_t ebcdic_sba [4] = {'\x11', '\x40', '\xC1', '\x13'};
     cics_char_t Start_Code [2] = "00"; /* Start Code */
     cics_sshort_t Text_Length = 80;
     cics_char_t Text_Buffer [80];
     cics_ubyte_t This_OPSYS = '\0'; /* local OPSYS */
     cics_char_t This_RELEASE [5] = "" ; /* local cics release */
     char * pch;
     /* initialise storage */
     memset(Text_Buffer, ' ', 79);
     Text_Buffer [79] = '\0';
/* EXEC CICS ADDRESS EIB(dfheiptr); */ \
     { \
     CicsArgs.ArgCode[0] = 77; \
     CicsArgs.ArgData[0].PointerRef = &dfheiptr; \
     CicsArgs.ArgMask = 0x20000000; \
     CicsArgs.ArgCount = 1; \
     CicsArgs.FnCode = 2; \
     CicsArgs.DebugLine = -1; \
     cics_api_exec_c_extended(&CicsArgs); \
     dfheiptr = (dfheiptr); \
	}
/* EXEC CICS INQUIRE SYSTEM
OPSYS(&This_OPSYS)
RELEASE(This_RELEASE); 	*/ \
      { \
      CicsArgs.ArgCode[0] = 325; \
      CicsArgs.ArgData[0].StringArea = This_RELEASE; \
      CicsArgs.ArgCode[1] = 252; \
      CicsArgs.ArgData[1].ByteArea = &This_OPSYS; \
      CicsArgs.ArgMask = 0x20000000; \
      CicsArgs.ArgCount = 2; \
      CicsArgs.FnCode = 42; \
      CicsArgs.DebugLine = -1; \
      cics_api_exec_c_extended(&CicsArgs); \
      }
      /* if ASCII opsys use ASCII 3270 cursor positioning*/
      if ((This_OPSYS == 'P') || (This_OPSYS == 'A') ||
           (This_OPSYS == 'H') || (This_OPSYS == 'O') ||
           (This_OPSYS == 'S') || (This_OPSYS == 'L') ||
           (This_OPSYS == 'N'))
      {
           strncpy(sba, ascii_sba, 4);
           output_screen.attr = '\x48';
           ProtectAttribute = ascii_ProtectAttribute;
      }
      else
      {
           strncpy(sba, ebcdic_sba, 4);
           output_screen.attr = '\xc8';
           ProtectAttribute = ebcdic_ProtectAttribute;
       }
/* EXEC CICS ASSIGN
APPLID(CSMT_log.applid)
SCRNWD(scrnwd)
STARTCODE(Start_Code)
TERMCODE(Term_Code); */ \
       { \
       CicsArgs.ArgCode[0] = 18; \
       CicsArgs.ArgData[0].StringArea = CSMT_log.applid; \
       CicsArgs.ArgCode[1] = 351; \
       CicsArgs.ArgData[1].ShortArea = &scrnwd; \
       CicsArgs.ArgCode[2] = 373; \
       CicsArgs.ArgData[2].StringArea = Start_Code; \
       CicsArgs.ArgCode[3] = 397; \
       CicsArgs.ArgData[3].StringArea = Term_Code; \
       CicsArgs.ArgMask = 0x20000000; \
       CicsArgs.ArgCount = 4; \
       CicsArgs.FnCode = 5; \
       CicsArgs.DebugLine = -1; \
       cics_api_exec_c_extended(&CicsArgs); \
       }
       /* Handle input from terminal or from a START */
       if (Start_Code [0] == 'S')
       {
/* EXEC CICS RETRIEVE INTO(Text_Buffer) LENGTH(Text_Length); */ \
       { \
       CicsArgs.ArgData[8].DataArea = Text_Buffer; \
       CicsArgs.ArgData[2].ShortArea = &Text_Length; \
       CicsArgs.ArgMask = 0x20000104; \
       CicsArgs.FnCode = 71; \
       CicsArgs.DebugLine = -1; \
       cics_api_exec_c_extended(&CicsArgs); \
       }
   }
   else
   {
/* EXEC CICS RECEIVE INTO(Text_Buffer) LENGTH(Text_Length); */ \
       { \
       CicsArgs.ArgData[8].DataArea = Text_Buffer; \
       CicsArgs.ArgData[2].ShortArea = &Text_Length; \
       CicsArgs.ArgMask = 0x20000104; \
       CicsArgs.FnCode = 67; \
       CicsArgs.DebugLine = -1; \
       cics_api_exec_c_extended(&CicsArgs); \
       }
   }
   /* Check if screen input is new or modified */
   /* If modified need to jump 3 bytes to skip sba */
   if (!(memcmp(Text_Buffer, sba, 3)))
   {
          memcpy(Text_Buffer, Text_Buffer+3, (size_t)Text_Length);
   }
   /* if a 3270 terminal resend hostid back to the screen */
   /* and position InsertCursor for new line */
   if ((Term_Code [0] > '\x90') &&
          (Term_Code [0] < '\xa0'))
   {
       strncpy(output_screen.display, Text_Buffer,(size_t)Text_Length);
       len_out = (cics_sshort_t) (scrnwd + 3);
       output_screen.display [scrnwd - 2] = InsertCursor;
/* EXEC CICS SEND FROM(&output_screen) LENGTH(len_out) ERASE; */ \
		{ \
		CicsArgs.ArgData[4].DataArea = &output_screen; \
		CicsArgs.ArgData[2].ShortValue = len_out; \
		CicsArgs.ArgMask = 0x20000414; \
		CicsArgs.FnCode = 74; \
		CicsArgs.DebugLine = -1; \
		cics_api_exec_c_extended(&CicsArgs); \
		}
	}
} /* End of Process_Startup_Parameters */
/********************************************************************/
/* Procedure : Output_Text */
/* Function : To Display text to Terminal (if appropiate) */
/* Input : Text to be displayed */
/* Returns : Nothing */
/********************************************************************/
void Output_Text(char* Text)
{
	cics_sshort_t len_out;
	char Temp_Text [92]; /* text buffer */
	cics_char_t time_msg [9];
	cics_time(time_msg);
	sprintf (Temp_Text, "%s %s",time_msg,Text);
	len_out = (cics_sshort_t) (scrnwd + 3);
	if ((Term_Code [0] > '\x90') &&
		(Term_Code [0] < '\xa0'))
	{
		strncpy(output_screen.display, Temp_Text, 92);
		memset(output_screen.display+92, ' ',
		sizeof(output_screen.display)-92);
		output_screen.display [scrnwd - 1] = InsertCursor;
		output_screen.attr = ProtectAttribute;
/* EXEC CICS SEND FROM(&output_screen) LENGTH(len_out) WAIT; */ \
		{ \
		CicsArgs.ArgData[4].DataArea = &output_screen; \
		CicsArgs.ArgData[2].ShortValue = len_out; \
		CicsArgs.ArgMask = 0x20800014; \
		CicsArgs.FnCode = 74; \
		CicsArgs.DebugLine = -1; \
		cics_api_exec_c_extended(&CicsArgs); \
		}
	}
	/* clear screen structure */
	memset(output_screen.display, ' ', 159);
	output_screen.display [159]='\0';
} /* End of Output_Text */
/********************************************************************/
/* Procedure : Log_Text */
/* Function : To send text to CICS CSMT log */
/* Input : Text to be displayed */
/* Returns : Nothing */
/********************************************************************/
void Log_Text(char* Text)
{
	cics_sshort_t Text_Length = 105;
	cics_char_t time_msg [9];
	cics_time(time_msg);
	sprintf (CSMT_log.msg, "%s %s",time_msg,Text);
/* EXEC CICS WRITEQ TD QUEUE("CSMT") FROM(&CSMT_log)
LENGTH(Text_Length); */ \
	{ \
	cics_api_strncpy(CicsArgs.ArgData[9].StringValue, "CSMT", (short)4); \
	CicsArgs.ArgData[4].DataArea = &CSMT_log; \
	CicsArgs.ArgData[2].ShortValue = Text_Length; \
	CicsArgs.ArgMask = 0x20000214; \
	CicsArgs.FnCode = 106; \
	CicsArgs.DebugLine = -1; \
	cics_api_exec_c_extended(&CicsArgs); \
	}
	/* clear log structures */
	memset(CSMT_log.msg, ' ', 79);
	CSMT_log.msg [79]='\0';
} /* End of Output_Text */
/**********************************************************************
* Function name: return_to_cics *
* Description: Return to CICS and exit program *
* Parameters: None *
* Returns: None *
**********************************************************************/
void return_to_cics(void)
{
	cics_char_t blank_log [80] = "" ;
	/* write blank line to log */
/* EXEC CICS WRITEQ TD QUEUE("CSMT") FROM(blank_log) LENGTH(80); */ \
	{ \
	cics_api_strncpy(CicsArgs.ArgData[9].StringValue, "CSMT", (short)4); \
	CicsArgs.ArgData[4].DataArea = blank_log; \
	CicsArgs.ArgData[2].ShortValue = 80; \
	CicsArgs.ArgMask = 0x20000214; \
	CicsArgs.FnCode = 106; \
	CicsArgs.DebugLine = -1; \
	cics_api_exec_c_extended(&CicsArgs); \
	}
	
/* EXEC CICS RETURN; */ \
	{ \
	CicsArgs.ArgMask = 0x20000000; \
	CicsArgs.FnCode = 72; \
	CicsArgs.DebugLine = -1; \
	cics_api_exec_c_extended(&CicsArgs); \
	}
}
/**********************************************************************
* Function name: SendData *
* Description: Sends the data to the host and port *
* Inputs: Host id and port number *
* Returns: None *
**********************************************************************/
void SendData(char * Host_Id, short Port_Num)
{
	char * pch;
	static char Temp_Text [80]; /* text buffer */
	int connfd, crc, i, BytesRead;
	struct sockaddr_in servaddr;
	char RcvBuf[MSG_SIZE+1];
	char MsgBuf[] = \
		"<?xml version='1.0' encoding='UTF-8'?> \
		<ZPBT_IN> \
		<in> \
		<ORDER_NUM/> \
		<ITEM_NUM>00000</ITEM_NUM> \
		<BANK_CODE/> \
		<BANK_ACCT/> \
		</in> \
		<in> \
		<ORDER_NUM>2015689292</ORDER_NUM> \
		<ITEM_NUM>00001</ITEM_NUM> \
		<BANK_CODE>123456789</BANK_CODE> \
		<BANK_ACCT>9753124680</BANK_ACCT> \
		</in> \
		<in> \
		<ORDER_NUM>2025689393</ORDER_NUM> \
		<ITEM_NUM>00001</ITEM_NUM> \
		<BANK_CODE/> \
		<BANK_ACCT>1345678920</BANK_ACCT> \
		</in> \
		<in> \
		<ORDER_NUM>2025689393</ORDER_NUM> \
		<ITEM_NUM>00006</ITEM_NUM> \
		<BANK_CODE/> \
		<BANK_ACCT/> \
		</in> \
		<in> \
		<ORDER_NUM>2025689393</ORDER_NUM> \
		<ITEM_NUM>00000</ITEM_NUM> \
		<BANK_CODE/> \
		<BANK_ACCT/> \
		</in> \
		</ZPBT_IN>";
		
	connfd = socket(AF_INET, SOCK_STREAM, 0);
	if (connfd < 0) {
		Output_Text("Error creating socket");
		return_to_cics();
	}
	sprintf (Temp_Text, "Trying to connect to host %s and port %d",
	Host_Id, Port_Num);
	Output_Text(Temp_Text);
	servaddr.sin_family = AF_INET;
	servaddr.sin_port = htons(Port_Num);
	servaddr.sin_addr.s_addr = inet_addr(Host_Id); /*Use quad 4 notation*/
	if ((crc = connect(connfd, (struct sockaddr *) &servaddr,
		sizeof(servaddr))) < 0) {
		Output_Text("Connect Error");
		return_to_cics();
	}
	sprintf (Temp_Text, "Number of bytes to send is %d bytes",
	strlen(MsgBuf));
	Output_Text(Temp_Text);
	writen(connfd, MsgBuf, strlen(MsgBuf));
	BytesRead = readn(connfd, RcvBuf, sizeof(RcvBuf));
	sprintf (Temp_Text, "Number of bytes read is %d bytes", BytesRead);
	Output_Text(Temp_Text);
	Output_Text("First ten lines of payload are:");
	for (i=519;i<1220;i+=70) {
		strncpy(Temp_Text,&RcvBuf[i],70);
		Output_Text(Temp_Text);
	}
	for (i=0;i<BytesRead;i+=78) {
		pch = RcvBuf + i;
		strncpy(Temp_Text, pch, 78);
		Log_Text(Temp_Text);
	}
#ifdef _MSC_VER
	closesocket(connfd);
#else
	close(connfd);
#endif
	return;
} /* End send data */
/**********************************************************************
* Function name: cics_time *
* Description: gets the time *
* Returns: time_msg as 8 cics_char_t string *
**********************************************************************/
void cics_time (cics_char_t time_msg[])
{
	cics_char_t abstime [8];
/* EXEC CICS ASKTIME ABSTIME(abstime); */ \
	{ \
	CicsArgs.ArgData[0].DataArea = abstime; \
	CicsArgs.ArgMask = 0x20000001; \
	CicsArgs.FnCode = 4; \
	CicsArgs.DebugLine = -1; \
	cics_api_exec_c_extended(&CicsArgs); \
	}
/* EXEC CICS FORMATTIME ABSTIME(abstime) TIME(time_msg) TIMESEP; */
\
	{ \
	CicsArgs.ArgData[0].DataArea = abstime; \
	CicsArgs.ArgData[15].StringArea = time_msg; \
	CicsArgs.ArgMask = 0x20018001; \
	CicsArgs.FnCode = 22; \
	CicsArgs.DebugLine = -1; \
	cics_api_exec_c_extended(&CicsArgs); \
	}
	time_msg [8]='\0';
}
/**********************************************************************
* Function name: readn *
* Description: Utility function to read a socket *
* Inputs: fd - socket number, *
* vptr - buffer to read into *
* n - length of the data read *
* Returns: int number of bytes read *
**********************************************************************/
int readn(int fd, void *vptr, size_t n)
{
	size_t nleft;
	size_t nread;
	char *ptr;
	ptr = vptr;
	nleft = n;
	while (nleft > 0)
	{
		if ( (nread = recv(fd, ptr, nleft, 0)) < 0)
		{
			if (errno == EINTR)
				nread = 0;
			else
				return (-1);
		}
		else if (nread == 0)
			break;
		nleft -= nread;
		ptr += nread;
	}
	return (n - nleft);
}
/**********************************************************************
* Function name: writen *
* Description: Utility function to write a socket *
* Inputs: fd - socket number, *
* vptr - buffer to write from *
* n - length of the data to write *
* Returns: int number of bytes not written *
**********************************************************************/
int writen(int fd, const void *vptr, size_t n)
{
	size_t nleft;
	size_t nwritten;
	const char *ptr;
	ptr = vptr;
	nleft = n;
	while (nleft > 0)
	{
		if ( (nwritten = send(fd, ptr, nleft, 0)) <= 0)
		{
		if (errno == EINTR)
			nwritten = 0;
		else
			return (-1);
		}
		nleft -= nwritten;
		ptr += nwritten;
	}
	return (nleft);
}

iWay Software