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:
The text version of the source code file is included below for your review:
#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 |