ibm-information-center/dist/eclipse/plugins/i5OS.ic.apiref_5.4.0.1/apiexustran.htm

2105 lines
91 KiB
HTML
Raw Normal View History

2024-04-02 14:02:31 +00:00
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE html
PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html lang="en-us" xml:lang="en-us">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<meta name="security" content="public" />
<meta name="Robots" content="index,follow" />
<meta http-equiv="PICS-Label" content='(PICS-1.1 "http://www.icra.org/ratingsv02.html" l gen true r (cz 1 lz 1 nz 1 oz 1 vz 1) "http://www.rsac.org/ratingsv01.html" l gen true r (n 0 s 0 v 0 l 0) "http://www.classify.org/safesurf/" l gen true r (SS~~000 1))' />
<meta name="DC.Type" content="reference" />
<meta name="DC.Title" content="Example: Using the user-defined communications programs for file transfer" />
<meta name="abstract" content="This example shows how X.25-oriented applications use the user-defined communications support to connect to remote systems." />
<meta name="description" content="This example shows how X.25-oriented applications use the user-defined communications support to connect to remote systems." />
<meta name="DC.Relation" scheme="URI" content="apiexmp.htm" />
<meta name="DC.Relation" scheme="URI" content="../apis/qolsetf.htm" />
<meta name="copyright" content="(C) Copyright IBM Corporation 1998, 2006" />
<meta name="DC.Rights.Owner" content="(C) Copyright IBM Corporation 1998, 2006" />
<meta name="DC.Format" content="XHTML" />
<meta name="DC.Identifier" content="apiexustran" />
<meta name="DC.Language" content="en-us" />
<!-- All rights reserved. Licensed Materials Property of IBM -->
<!-- US Government Users Restricted Rights -->
<!-- Use, duplication or disclosure restricted by -->
<!-- GSA ADP Schedule Contract with IBM Corp. -->
<link rel="stylesheet" type="text/css" href="./ibmdita.css" />
<link rel="stylesheet" type="text/css" href="./ic.css" />
<title>Example: Using the user-defined communications programs for file transfer</title>
</head>
<body id="apiexustran"><a name="apiexustran"><!-- --></a>
<!-- Java sync-link --><script language="Javascript" src="../rzahg/synch.js" type="text/javascript"></script>
<h1 class="topictitle1">Example: Using the user-defined communications programs for file transfer</h1>
<div><p>This example shows how X.25-oriented applications use the user-defined
communications support to connect to remote systems.</p>
<div class="section"><p>Two user-defined application programs written in the ILE C programming
language are used to illustrate a simple file transfer between two systems
over an X.25 packet-switching data network (PSDN). Although an X.25 example
is shown, many of the same concepts can be applied to applications running
over token-ring and Ethernet local area networks (LANs). For the purposes
of the examples, the APIs are referred to by their call names. The includes <em>header</em>, <em>hexconv</em>,
and <em>typedefs</em> are not in QSYSINC. These includes are only documented
in the examples.</p>
<p>For this example, the following network configuration
will be used.</p>
<br /><img src="RBAFX652.gif" alt="Example&#xA;X.25 network" /><br /><div class="note"><span class="notetitle">Note:</span> Read the <a href="codedisclaimer.htm">Code license and disclaimer information</a> for
important legal information.</div>
</div>
<div class="section"><h4 class="sectiontitle">X.25 overview</h4><p>In this example X.25 network, the
source application on System A is responsible for establishing a switched
virtual circuit, or connection to the target application running on System
B. This is done by using the remote network address (System B's address) of
X'0000652'. When the target application on System B is initialized, it waits
for notification of an incoming call packet before proceeding. Once the virtual
circuit is established, the source application reads records from a file into
its output buffer and sends them to the target application using normal X.25
data transfer procedures. While receiving the file data, the target application
writes the data to a local file on System B. When the file transfer completes,
the source application closes the connection by issuing an X.25 clear request
packet and ends. When receiving the clear indication packet, the target application
also ends.</p>
</div>
<div class="section"><h4 class="sectiontitle">User-defined communications support overview</h4><p>Both
the source and target applications call the Query Line Description (QOLQLIND)
API to obtain information about the local X.25 line being used. This information
is stored in a local control block for use in establishing the peer connection
during X.25 connection processing. Both applications also call the Enable
Link (QOLELINK) API to enable the link for future communications. The iSeries™ server
line name, communications handle, and remote DTE address are passed to both
programs as arguments to the C function main(). For simplicity, the user space
names and data queue name on the call to the QOLELINK API are coded directly
in the applications.</p>
<div class="note"><span class="notetitle">Note:</span> Keyed data queue support is used by both applications.
The key length is 3 and the keys used are source (SRC) and target (TGT) for
the source and target applications, respectively.</div>
<p id="apiexustran__Header_38"><a name="apiexustran__Header_38"><!-- --></a><strong>Activating
filters</strong></p>
<p>Once the links have been enabled and both applications have
read their respective enable-complete entries from their data queues, the
target application program calls the Set Filter (QOLSETF) API to activate
a filter. The filter activated then identifies the protocol of the local X.25
service user. This filter is used by the user-defined communications support
on System B to route incoming calls. The actual filter type activated is X'00'
(for X.25 PID) and its associated value is X'21'. For more information concerning
filters, see Set Filter (QOLSETF) API. After activating the X'21' filter,
the target application waits for the source application to request a connection.</p>
<p id="apiexustran__Header_39"><a name="apiexustran__Header_39"><!-- --></a><strong>Establishing a connection</strong></p>
<p>The source application
calls the Send Data (QOLSEND) API with a X'B000' operation in its output data
buffer to establish a switched virtual circuit (SVC) to the target application.
Included in the first byte of the call user data is the protocol ID of the
target application, or X'21'. When the user-defined communications support
on System B sees the incoming call packet with the first byte of user data
equal to a previously activated filter, the call is routed to the process
responsible for activating that filter. In this case, the target application
will receive notification of an incoming call since it previously activated
filter X'21'.</p>
<p>While waiting for the incoming call, the target application
calls the Receive Data (QOLRECV) API to receive a X'B201' operation with incoming
call data. After doing so, the target application accepts the X.25 connection
by calling the QOLSEND API with a X'B400' operation in its output data buffer.
See for more information.</p>
<p id="apiexustran__Header_40"><a name="apiexustran__Header_40"><!-- --></a><strong>Sending data</strong></p>
<p>Once
the peer connection is established between the source and target applications
running on System A and System B respectively, the file transfer takes place.
The source application reads records from a local file and calls the QOLSEND
API with X'0000' operations in its output data buffer to transfer the file
data to System B. This process continues until the entire contents of the
source file has been sent to System B.</p>
<p id="apiexustran__Header_41"><a name="apiexustran__Header_41"><!-- --></a><strong>Receiving data</strong></p>
<p>After
accepting the X.25 connection, the target application waits until its data
queue receives incoming-data entries. When the first entry is read from the
queue, the QOLRECV API is called to determine which operation was received.
Barring failure, the target application should receive a X'0001' operation
as a result of the QOLRECV API call. The data contained in the input data
buffer is the file data received from System A. While receiving the file data,
the target application writes the data to a local file. This process continues
until the entire contents of the file is received from System A. The target
application then assumes the file transfer is complete when an operation other
than a X'0001' operation is received after a successful call to the QOLRECV
API. Most likely, the first non-X'0001' operation received will be X'B301'
operation, signalling that the user-defined communications support running
on System B received an SVC clear indication.</p>
<p id="apiexustran__Header_42"><a name="apiexustran__Header_42"><!-- --></a><strong>Clearing
the connection and disabling links</strong></p>
<p>Once the entire contents of the
file has been read and sent to System B, the source application calls the
QOLSEND API with a X'B100' operation in its output data buffer to clear the
X.25 connection. Afterwards, the source application closes its local file,
disables its local link by calling the QOLDLINK API, and ends.</p>
<p>When
the source application program sends a X'B100' operation, it causes the target
application to receive a X'B301' operation. After receiving this operation,
the target application program calls the QOLSEND API with a X'B100' operation
to locally close the connection between itself and the user-defined communications
support. Afterwards, the target application closes its local file, disables
its local link by calling the QOLDLINK API, and ends.</p>
<p id="apiexustran__Header_43"><a name="apiexustran__Header_43"><!-- --></a><strong>Using
timers and the data queue support</strong></p>
<p>Both the source and target application
programs use the user-defined communications support timer service to manage
the reception of certain operations. This is done by setting a timer before
checking the data queue for an entry. For example, the target application
sets a timer to manage the reception of file data from the source application.
If the timer expires, the user-defined communications support places a timer-expired
entry on the application's data queue. The target application then assumes
when receiving this entry that the source application ended abnormally. The
target application can then take the appropriate action to end itself.</p>
</div>
<div class="section"><h4 class="sectiontitle">ILE C compiler listings</h4><p>Below are the listings for
the source and target applications described in the previous paragraphs. Note
the reference numbers (for example, <span class="uicontrol">(1)</span>) in the listings.
Detailed explanations of each reference number block are found in <a href="#apiexustran__SPTCSOUR">Source application program listing references</a> and <a href="#apiexustran__SPTCTARG">Target application program listing references</a>.</p>
<p>The target application compiler
listing can be found in <a href="#apiexustran__HDRTARGET">Target application
on System B listing</a>.</p>
<p id="apiexustran__Header_45"><a name="apiexustran__Header_45"><!-- --></a><strong>Source application on
System A listing</strong></p>
<p>In this example, the source application is the
initiator of all meaningful work. In summary, the source program listed on
the following pages does the following:</p>
<ul><li>Calls the QOLQLIND API to get local X.25 line information</li>
<li>Opens the local file</li>
<li>Calls the QOLELINK API to establish a link for communications</li>
<li>Calls the QOLSEND API with X'B000' operation to establish a peer (SVC)
connection</li>
<li>Sends the local file to the target system using X'0000' operations </li>
<li>Calls the QOLSEND API with X'B100' operation to clear the peer (SVC) connection</li>
<li>Calls the QOLDLINK API to disable the link</li>
<li>Calls the QOLTIMER API to manage the reception of data queue entries</li>
</ul>
<p>To create the program using ILE C, use the Create Bound C (CRTBNDC)
command.</p>
<pre> Program name . . . . . . . . . :
<span class="uicontrol">(SOURCE)</span>
Library name . . . . . . . . : UDCS_APPLS
Source file . . . . . . . . . . : QCSRC
Library name . . . . . . . . : UDCS_APPLS
Source member name . . . . . . : SOURCE
Text Description . . . . . . . : Source Application Example
Output . . . . . . . . . . . . : *NONE
Compiler options . . . . . . . : *SOURCE *NOXREF *SHOWUSR
: *SHOWSYS *NOSHOWSKP *NOEXPMAC
: *NOAGR *NOPPONLY *NODEBUG
: *GEN *NOSECLVL *PRINT *LOGMSG
: *USRINCPATH
Checkout Options . . . . . . . : *NOAGR
Optimization . . . . . . . . . : *NONE
Inline Options:
Inliner . . . . . . . . . . . : *OFF
Mode . . . . . . . . . . . . : *NOAUTO
Threshold . . . . . . . . . . : 250
Limit . . . . . . . . . . . . : 2000
Debugging View . . . . . . . . : *NONE
Define Names . . . . . . . . . : *NONE
Language Level . . . . . . . . : *SOURCE
Source Margins:
Left margin . . . . . . . . . : 1
Right margin . . . . . . . . : 32754
Sequence columns:
Left column . . . . . . . . . : *NONE
Right column . . . . . . . . :
Message flagging level . . . . : 0
Compiler messages:
Message limit . . . . . . . . : *NOMAX
Message limit severity . . . : 30
Replace Program Object . . . . : *YES
User Profile . . . . . . . . . : *USER
Authority . . . . . . . . . . . : *LIBCRTAUT
Target Release . . . . . . . . : *CURRENT
System includes . . . . . . . . : *YES
/*******************************************************************/
/** Program Name: Source Application Program Example **/
/** **/
/** **/
/** Function: **/
/** This is the source application program example that uses **/
/** X.25 services provided by the user-defined communications **/
/** support to transfer a simple file to the target application **/
/** program running on system B. This program performs the **/
/** following: **/
/** 01. Open the source file name INFILE. **/
/** 02. Call QOLQLIND API to obtain local line information. **/
/** 03. Enable a link. **/
/** 04. Send a 'B000'X operation (call request). **/
/** 05. Receive a 'B001'X operation (call confirmation). **/
/** 06. Read record(s) from the file opened in step 1). and **/
/** send '0001'X operation(s) to transfer the file to **/
/** the target application program. **/
/** 07. Send a 'B100'X operation (clear call request). **/
/** 08. Receive a 'B101'X operation. **/
/** 09. Disable the link enabled in step 3). **/
/** **/
/** A data queue will be actively used to manage the operation **/
/** of this program. Data queue support will be used to monitor **/
/** for the completion of the enable and disable routines, as **/
/** well as timer expirations and incoming data. Timers are **/
/** used to ensure that there will never be an infinite wait on **/
/** the data queue. If a timer expires, the link enabled will **/
/** be disabled and the program will stop. **/
/** **/
/** Inputs: **/
/** The program expects the following input parameters **/
/** Line Name: This is the name of the line description **/
/** that will be used to call the QOLELINK API. **/
/** The line must be an X.25 line with at least **/
/** one SVC of type *SVCBOTH or *SVCOUT. **/
/** **/
/** CommHandle: This is the logical name that will be used **/
/** to identify the link enabled. **/
/** **/
/** Remote DTE Address: The is the Local Network Address **/
/** of System B. **/
/** **/
/** **/
/** Outputs: **/
/** Current status of the file transfer will be provided when **/
/** running this program. If an error should occur, then a **/
/** message will be displayed indicating where the error occurred **/
/** and the program will end. If the program completes **/
/** successfully, a "successful completion" message will be **/
/** posted. **/
/** **/
/** Language: ILE C **/
/** **/
/** APIs used: QOLELINK, QUSPTRUS, QOLRECV, QOLSEND, QOLDLINK, **/
/** QOLTIMER, QRCVDTAQ **/
/** **/
/*******************************************************************/
/*******************************************************************/
/*******************************************************************/
#include "header"
#include "typedef"
#include "hexconv"
<span class="uicontrol">(1)</span>
/************ Typedef Declarations *******************/
<span class="uicontrol">(2)</span>
void senddata(sendparms *a, char *b, desc *c, char *d, char *e, int f);
void sndformat1(sendparms *a,char *b, char *c, char *d, qlindparms *f);
void sndformat2 (sendparms *a, char *b, char *c);
void setfilters (hdrparms *a);
void byte (char *a, int b, char *c, int d);
void printespec (espec *a);
void settimer(unsigned short *a,char *b,qentry *c,usrspace *d,char *e);
void dequeue (int a, char *b, qentry *c, usrspace *d);
void x25lind (qlindparms *a, char *b);
int getline (char *a, int b, FILE *c);
void disablelink (disableparms *a, char *b, usrspace *c);
void handler (disableparms a, usrspace *b);
void _GetExcData(_INTRPT_Hndlr_Parms_T *parms);
/**********************************************************/
/*************** Start Main Program *******************/
/**********************************************************/
main (int argc, char *argv[])
{
/************ Variable Declarations *******************/
usrspace inbuff, /* Input Data Buffer */
indesc, /* Input Buffer Descriptor */
outbuff, /* Output Data Buffer */
outdesc, /* Output Buffer Descriptor */
qname; /* Data Queue */
int length, /* Data Queue key length */
linesiz, /* Length of line that is read in */
i= 0; /* counter */
unsigned short expctid; /* Message ID that is expected */
char commhandle[10], /* Command Line Parameter */
*buffer, /* Pointer to buffer */
rmtdte[18], /* Remote DTE read in */
line[132], /* Line to read in */
key[256]; /* Data Queue key identifier */
desc *descriptor; /* Pointer to buffer descriptor */
/** definitions for the API functions **/
enableparms enable;
disableparms disable;
sendparms send;
recvparms recv;
setfparms setf;
timerparms timer;
qlindparms qlind;
qentry dataq;
hdrparms *header;
<span class="uicontrol">(3)</span>
/***--- Open the file to send to remote side ----**/
if ((fptr = fopen("UDCS_APPLS/INFILE(INFILE)", "r")) == NULL)
{
printf("Unable to open source input file in UDCS_APPLS LIB.\n");
printf("The Program was terminated.\n\n");
return;
}
/***--- Open the display file as our input screen. ----**/
if ((screen = fopen("ERRORSPEC", "ab+ type=record")) == NULL)
{
printf("Unable to open display file.\n");
printf("The Program was terminated.\n\n");
return;
}
/** set the exception handler **/
signal(SIGALL,SIG_DFL);
/** Clear the command line Parameters **/
strncpy(enable.linename, " ", 10); /* Clear linename */
strncpy(commhandle, " ", 10); /* Clear Commhandle*/
strncpy(rmtdte, " ", 17); /* Clear Remote DTE*/
/** Receive command line Parameters **/
strncpy(enable.linename, argv[1], strlen(argv[1]));
strncpy(commhandle, argv[2], strlen(argv[2]));
strncpy(rmtdte, argv[3], strlen(argv[3]));
rmtdte[strlen(argv[3])] = '\0';
/** Initialize the user spaces **/
strncpy(inbuff.library, "UDCS_APPLS", 10); /* Input Buffer */
strncpy(inbuff.name, "SOURCEIBUF", 10);
strncpy(indesc.library, "UDCS_APPLS", 10); /* Input B Desc */
strncpy(indesc.name, "SOURCEBDSC", 10);
strncpy(outbuff.library, "UDCS_APPLS", 10); /* Output Buffer*/
strncpy(outbuff.name, "SOURCEOBUF", 10);
strncpy(outdesc.library, "UDCS_APPLS", 10); /* Output B Desc */
strncpy(outdesc.name, "SOURCEODSC", 10);
strncpy(qname.library, "UDCS_APPLS", 10); /* Data queue */
strncpy(qname.name, "X25DTAQ ", 10);
/***** retrieve the line description information ******/
x25lind (&amp;qlind, enable.linename);
if ((qlind.retcode != 0) || (qlind.reason != 0))
{
printf("Query line description failed.\n");
printf("Return code = %d\n", qlind.retcode);
printf("Reason code = %d\n\n", qlind.reason);
return;
}
/***** Hard Code the QOLELINK Input Parameters ******/
enable.maxdtax25 = 512;
enable.keylength = 3;
strncpy (enable.keyvalue, "SND", 3);
<span class="uicontrol">(4)</span>
/**************************************************/
/************ Enable the line *******************/
/**************************************************/
QOLELINK (&amp;(enable.retcode), &amp;(enable.reason), &amp;(enable.tdusize),\
&amp;(enable.numunits), &amp;(enable.maxdtalan), &amp;(enable.maxdtax25),\
(char *)&amp;inbuff, (char *)&amp;indesc, (char *)&amp;outbuff,\
(char *)&amp;outdesc, &amp;(enable.keylength), enable.keyvalue,\
(char *)&amp;qname, enable.linename, commhandle);
if ((enable.retcode != 0) || (enable.reason != 0))
{
printf("Line %.10s with Commhandle %.10s was NOT ENABLED.\n",\
enable.linename, commhandle);
printf("Return code = %d\n", enable.retcode);
printf("Reason code = %d\n\n", enable.reason);
return;
}
<span class="uicontrol">(5)</span>
/*-------- Set a timer for Enable Link ---------**/
expctid = 0xF0F0;
settimer(&amp;expctid, "Enable", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F0)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
<span class="uicontrol">(6)</span>
/******************************************************************/
/************** Set up a Call Request Packet *******************/
/******************************************************************/
/**** Get pointers to the user spaces. ******/
QUSPTRUS(&amp;outbuff, &amp;buffer);
QUSPTRUS(&amp;outdesc, &amp;descriptor);
send.ucep = 26; /* set the UCEP number */
send.operation = 0xB000; /* send a call request */
send.numdtaelmnts = 1; /* send one data unit */
/**----------- Send the packet ---------**/
sndformat1 (&amp;send, buffer, rmtdte, commhandle, &amp;qlind);
if ((send.retcode != 0) || (send.reason != 0))
{
printf("Call request packet not sent\n");
printf("Return code = %d\n", send.retcode);
printf("Reason code = %d\n", send.reason);
printf("new pcep %d\n", send.newpcep);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
<span class="uicontrol">(7)</span>
/*****************************************************************/
/*********** Receive the Call CONFIRMATION packet ********/
/*****************************************************************/
/*-------- Set a timer to receive a message ---------**/
expctid = 0xF0F3;
settimer(&amp;expctid, "Rcv Call", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F3)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
QOLRECV (&amp;(recv.retcode), &amp;(recv.reason), &amp;(recv.ucep),\
&amp;(recv.pcep), &amp;(recv.operation), &amp;(recv.numdtaunits),\
&amp;(recv.dataavail), &amp;(recv.errorspecific), commhandle);
if ((recv.retcode != 0) || (recv.reason != 0))
{
printf("Recv Call reqst resp failed\n");
printf("return code %d\n", recv.retcode);
printf("reason code %d\n", recv.reason);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/* Interpret the Received Operation */
if (recv.operation != 0xB001)
{
printf("Recvd opr %x instead of opr B001\n", recv.operation);
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
printf("We have an X.25 SVC connection\n\n");
<span class="uicontrol">(8)</span>
/*****************************************************************/
/*************** Send the file to the target application *******/
/*****************************************************************/
send.pcep = send.newpcep; /* set the PCEP number */
/*************** Send the Mbr LGRF in file DOC ****************/
linesiz = getline(line, 92, fptr); /* Get first record **/
while (linesiz != 0)
{
/*************** Send a Packet of Data ***************/
/**** Get pointers to the user spaces. ******/
QUSPTRUS(&amp;outbuff, &amp;buffer);
QUSPTRUS(&amp;outdesc, &amp;descriptor);
send.operation = 0x0000;
send.numdtaelmnts = 1;
/**----- Send the packet -------------**/
senddata (&amp;send, buffer, descriptor, commhandle, line, linesiz);
if ((send.retcode != 0) || (send.reason != 0))
{
printf("Data NOT sent for commhandle %.9s\n", commhandle);
printf("Return code = %d\n", send.retcode);
printf("Reason code = %d\n", send.reason);
printf("new pcep %d\n", send.newpcep);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
i = i + 1;
printf("Data %d Sent for commhandle %.9s.\n\n", i, commhandle);
linesiz = getline(line, 92, fptr); /** Get next record **/
} /*** End While loop ***/
/***************************************************************/
/*************** Set up a Clear Request Packet **************/
/***************************************************************/
<span class="uicontrol">(9)</span>
/**** Get pointers to the user spaces. ******/
QUSPTRUS(&amp;outbuff, &amp;buffer);
QUSPTRUS(&amp;outdesc, &amp;descriptor);
send.operation = 0xB100; /** send clear request **/
send.numdtaelmnts = 1; /** send one data unit **/
/**----------- Send the packet ---------**/
sndformat2 (&amp;send, buffer, commhandle);
if ((send.retcode != 0) || (send.reason != 0))
{
printf("Clear request packet not sent\n");
printf("Return code = %d\n", send.retcode);
printf("Reason code = %d\n", send.reason);
printf("new pcep %d\n", send.newpcep);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
<span class="uicontrol">(10)</span>
/***************************************************************/
/*********** Receive the Clear Request Response packet *****/
/***************************************************************/
/*-------- Set a timer to receive a message ---------**/
expctid = 0xF0F3;
settimer(&amp;expctid, "Rv Clr Rqt", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F3)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/*********** Call QOLRECV to Receive the Clear Response *****/
/**** Get pointers to the user spaces. ******/
QUSPTRUS (&amp;inbuff, &amp;buffer);
QUSPTRUS (&amp;indesc, &amp;descriptor);
QOLRECV (&amp;(recv.retcode), &amp;(recv.reason), &amp;(recv.ucep),\
&amp;(recv.pcep), &amp;(recv.operation), &amp;(recv.numdtaunits),\
&amp;(recv.dataavail), &amp;(recv.errorspecific), commhandle);
if ((recv.retcode != 0) || (recv.reason != 0))
{
printf("Recv clear response failed\n");
printf("return code %d\n", recv.retcode);
printf("reason code %d\n", recv.reason);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/* Interpret the Received Operation */
if (recv.operation != 0xB101)
{
printf("Recvd opr %x instead of opr B101\n", recv.operation);
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/***********************************************/
/*** Disable the link and end the program ****/
/***********************************************/
disablelink (&amp;disable, commhandle, &amp;qname);
printf("****** SOURCE completed successfully ******\n\n");
} /* End Main */
/*****************************************************************/
/************** Start Subroutine Section **********************/
/*****************************************************************/
/*************************************************************/
/*************** Send a Packet of Data ******************/
<span class="uicontrol">(11)</span>
void senddata (sendparms *send,
char *buffer,
desc *descriptor,
char *commhandle,
char *line,
int linesiz)
{
descriptor-&gt;length = linesiz;
descriptor-&gt;more = 0;
descriptor-&gt;qualified = 0;
descriptor-&gt;interrupt = 0;
descriptor-&gt;dbit = 0;
strncpy (buffer, line, linesiz);
QOLSEND (&amp;(send-&gt;retcode), &amp;(send-&gt;reason),
&amp;(send-&gt;errorspecific),\
&amp;(send-&gt;newpcep), &amp;(send-&gt;ucep), &amp;(send-&gt;pcep), \
commhandle, &amp;(send-&gt;operation), &amp;(send-&gt;numdtaelmnts));
} /* End senddata Subroutine */
/*********************************************************/
/************ Routine to fill X.25 Format I ***********/
void sndformat1 (sendparms *send,
char *buffer,
char *rmtdte,
char *commhandle,
qlindparms *qlind)
{
format1 *output = (format1 *) buffer;
register int counter;
register querydata *qd;
qd = (querydata *)&amp;(qlind-&gt;userbuffer);
output-&gt;type = 2; /* SVC used */
output-&gt;logchanid = 0x0;
output-&gt;sendpacksize = qd-&gt;x25data.defsend;
output-&gt;sendwindsize = qd-&gt;x25data.windowsend;
output-&gt;recvpacksize = qd-&gt;x25data.defrecv;
output-&gt;recvwindsize = qd-&gt;x25data.windowrecv;
output-&gt;dtelength = strlen(rmtdte);
byte(output-&gt;dte, 16, rmtdte, strlen(rmtdte));
output-&gt;dbit = 0;
output-&gt;cug = 0;
output-&gt;cugid = 0;
output-&gt;reverse = 0;
output-&gt;fast = 0;
output-&gt;faclength = 0;
byte(output-&gt;facilities, 109, "", 0);
output-&gt;calllength = 1;
byte(output-&gt;callud, 128, "21", 2); /* Contains Remote PID */
output-&gt;misc[0] = 0; /* change to 0x80 for reset support */
output-&gt;misc[1] = 0;
output-&gt;misc[2] = 0;
output-&gt;misc[3] = 0;
output-&gt;maxasmsize = 16383;
output-&gt;autoflow = 32;
QOLSEND (&amp;(send-&gt;retcode), &amp;(send-&gt;reason),
&amp;(send-&gt;errorspecific),\
&amp;(send-&gt;newpcep), &amp;(send-&gt;ucep), &amp;(send-&gt;pcep),\
commhandle, &amp;(send-&gt;operation), &amp;(send-&gt;numdtaelmnts));
} /* End sndformat1 Subroutine */
/**********************************************************/
/************ Routine to fill X.25 Format II ***********/
void sndformat2 (sendparms *send,
char *buffer,
char *commhandle)
{
format2 *output = (format2 *) buffer;
output-&gt;type = 1;
output-&gt;cause = 'FF';
output-&gt;diagnostic = 'FF';
output-&gt;faclength = 0;
byte(output-&gt;facilities, 109, "", 0);
output-&gt;length = 0;
byte(output-&gt;userdata, 128, "", 0);
QOLSEND (&amp;(send-&gt;retcode), &amp;(send-&gt;reason),
&amp;(send-&gt;errorspecific),\
&amp;(send-&gt;newpcep), &amp;(send-&gt;ucep), &amp;(send-&gt;pcep),\
commhandle, &amp;(send-&gt;operation), &amp;(send-&gt;numdtaelmnts));
} /* End sndformat2 Subroutine */
<span class="uicontrol">(12)</span>
/********************************************/
/******** Routine to disable ***********/
void disablelink (disableparms *disable,
char *commhandle,
usrspace *qname)
{
unsigned short expctid;
qentry dataq;
disable-&gt;vary = 1; /* Hard coded to be varied off */
QOLDLINK (&amp;(disable-&gt;retcode), &amp;(disable-&gt;reason),\
commhandle, &amp;(disable-&gt;vary));
if ((disable-&gt;retcode != 0) &amp;&amp; (disable-&gt;reason != 00))
{
printf ("Link %.10s did not disabled.\n", commhandle);
printf ("return code = %d\n", disable-&gt;retcode);
printf ("reason code = %d\n\n", disable-&gt;reason);
}
/**------- Set a timer to receive disable complete msg --------**/
expctid = 0xF0F1;
settimer(&amp;expctid, "Disable", &amp;dataq, qname, commhandle);
if (expctid != 0xF0F1)
{
printf("Disable link did not complete successfully");
return;
}
printf ("%.10s link disabled \n", commhandle);
/** close the files **/
fclose(fptr);
fclose(screen);
} /* End disablelink Subroutine */
/**************************************************************/
/** Routine to convert string to Hexadecimal format ******/
void byte (char *dest,
int dlength,
char *source,
int slength)
{
register int counter;
char holder[2];
for (counter=0;counter&lt;dlength;counter++)
dest[counter]=0;
for (counter=slength-1;counter&gt;=0;counter--)
if (isxdigit(source[counter]))
{
holder[0]=source[counter];
holder[1]='\0';
if (counter % 2 == 0)
dest[counter/2] += (char) hextoint(holder)*16;
else dest[counter/2] += (char) hextoint(holder);
}
} /* End byte Subroutine */
/**************************************************************/
/** Routine to display the ErrorSpecific output ******/
void printespec(espec *errorspecific)
{
especout outparms;
sprintf(outparms.hwecode, "%.8X", errorspecific-&gt;hwecode);
sprintf(outparms.timestamp, "%.8X%.8X", errorspecific-&gt;timestamphi,\
errorspecific-&gt;timestamplo);
sprintf(outparms.elogid, "%.8X", errorspecific-&gt;elogid);
if (errorspecific-&gt;flags &amp; 0x40)
outparms.fail = 'Y';
else outparms.fail = 'N';
if (errorspecific-&gt;flags &amp; 0x20)
outparms.zerocodes = 'Y';
else outparms.zerocodes = 'N';
if (errorspecific-&gt;flags &amp; 0x10)
outparms.qsysopr = 'Y';
else outparms.qsysopr = 'N';
sprintf(outparms.cause,"%.2X", errorspecific-&gt;cause);
sprintf(outparms.diagnostic, "%.2X", errorspecific-&gt;diagnostic);
sprintf(outparms.erroffset, "%.6d", errorspecific-&gt;erroroffset);
fwrite(&amp;outparms, 1, sizeof(especout), screen);
fread("", 0, 0, screen);
} /* End printespec Subroutine */
<span class="uicontrol">(13)</span>
/************* Set a timer and dequeue next entry ******/
void settimer (unsigned short *expctid,
char *process,
qentry *dataq,
usrspace *qname,
char *commhandle)
{
timerparms timer;
disableparms disable;
int length;
char key[6];
timer.interval = 20000; /* Set timer for 20 seconds */
timer.establishcount = 1;
timer.keylength = 3; /* Set key value */
strncpy(timer.keyvalue, "SRC", 3);
timer.operation = 1; /* Set a timer */
QOLTIMER (&amp;(timer.retcode), &amp;(timer.reason), timer.handleout,\
timer.handlein, (char *)qname, &amp;(timer.operation),\
&amp;(timer.interval), &amp;(timer.establishcount),\
&amp;(timer.keylength), timer.keyvalue, timer.userdata);
if ((timer.retcode != 0) || (timer.reason != 0))
{
printf("%s timer failed while being set.\n", process);
printf("Return code = %d\n", timer.retcode);
printf("Reason code = %d\n\n", timer.reason);
}
/**------- Dequeue an entry --------**/
strncpy(key, "SRC",3);
length = 3;
dequeue (length, key, dataq, qname);
/*** Cancel timer ***/
if (dataq-&gt;msgid != 0xF0F4)
{
strncpy(timer.handlein, timer.handleout, 8);
timer.operation = 2; /* Set one timer */
QOLTIMER (&amp;(timer.retcode), &amp;(timer.reason), timer.handleout,\
timer.handlein, (char *)qname, &amp;(timer.operation),\
&amp;(timer.interval), &amp;(timer.establishcount),\
&amp;(timer.keylength), timer.keyvalue, timer.userdata);
if ((timer.retcode != 0) || (timer.reason != 0))
{
printf("%s timer failed while being canceled\n", process);
printf("Return code = %d\n", timer.retcode);
printf("Reason code = %d\n\n", timer.reason);
}
}
if (dataq-&gt;msgid != *expctid)
{
printf ("A %.4X message ID was received instead of %.4X\n",\
dataq-&gt;msgid, *expctid);
printf ("%s completion message was not received\n", process);
*expctid = dataq-&gt;msgid;
}
} /* End settimer Subroutine */
/***************************************************************/
/******* Dequeues the Incoming Message and processes it ******/
void dequeue (int length,
char *key,
qentry *dataq,
usrspace *qname)
{
char fldlen[3],
waittime[3],
keylen[2],
senderid[2],
*pointer,
order[2];
register int counter;
waittime[0] = 0;
waittime[1] = 0;
waittime[2] = 0x1D; /* Hard code a delay of infinite */
keylen[0] = 0;
keylen[1] = 0x3F; /* Hard code a keylength of 3 */
senderid[0] = 0;
senderid[1] = 0x0F;
strncpy(order, "EQ", 2);
fflush(stdin);
pointer = (char *)dataq;
for (counter = 0; counter &lt; 336; counter++)
pointer[counter] = 0;
strncpy (dataq-&gt;type, " ", 7);
while ((strncmp(dataq-&gt;type, "*USRDFN", 7) != 0) || (fldlen == 0))
QRCVDTAQ(qname-&gt;name, qname-&gt;library, fldlen, dataq, waittime,\
order, keylen, key, senderid,"");
} /* End dequeue Subroutine */
<span class="uicontrol">(14)</span>
/************************************************************/
/** x25lind: Retrieve X.25 line description information **/
void x25lind (qlindparms *qlind, char *linename)
{
register int counter;
for(counter=0;counter&lt;256;counter++)
qlind-&gt;userbuffer[counter]=0;
qlind-&gt;format = 0x01;
QOLQLIND (&amp;(qlind-&gt;retcode), &amp;(qlind-&gt;reason), &amp;(qlind-&gt;nbytes),\
qlind-&gt;userbuffer, linename, &amp;(qlind-&gt;format));
} /* End x25lind Subroutine */
/*******************************************************/
/** Getline: Read a record into line and return length **/
int getline (char *line, int max, FILE *fptr)
{
if (fgets(line, max, fptr) == NULL)
return 0;
else
return strlen(line);
} /* End getline Subroutine */
/***************************************************/</pre>
</div>
<div class="section" id="apiexustran__SPTCSOUR"><a name="apiexustran__SPTCSOUR"><!-- --></a><h4 class="sectiontitle">Source application program listing references</h4><p>The
following reference numbers and explanations correspond to the reference numbers
in the source application's program listing.</p>
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all"><tbody><tr><th valign="top" class="firstcol" id="d0e187">(1)</th>
<td valign="top" headers="d0e187 ">Some general C structure declarations used by both the source and target
application programs.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e192">(2)</th>
<td valign="top" headers="d0e192 ">Function prototypes of the internal functions used in this program.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e197">(3)</th>
<td valign="top" headers="d0e197 ">Call the C library routines fopen() and signal() to open the source
file and set up a signal handler to process <span class="keyword">i5/OS™</span> exceptions,
respectively. An example of an exception would be accessing a data area with
a NULL pointer. If an exception situation is encountered, SIG_DFL, the default
handler, will be called in order for the program to end.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e206">(4)</th>
<td valign="top" headers="d0e206 ">Call the QOLQLIND API to retrieve local configuration information from
the iSeries server
line description about that will be used for communications. Next, call the
QOLELINK API to enable the line description using the line name and communications
handle passed as input parameters to this program.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e214">(5)</th>
<td valign="top" headers="d0e214 ">Call the QOLTIMER API to time the completion of the enable link operation.
If the timer expires before the enable-complete entry is posted on the this
program's data queue, then this program will end.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e219">(6)</th>
<td valign="top" headers="d0e219 ">Call the QOLSEND API with a X'B000' operation to establish a connection
to the target application program.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e224">(7)</th>
<td valign="top" headers="d0e224 ">Monitor the source program's data queue for the call confirmation.
The source program will be notified of the call confirmation by call the QOLRECV
API and receiving a X'B001' operation in the program's input buffer.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e229">(8)</th>
<td valign="top" headers="d0e229 ">This is the main send loop for the source program. The data from the
source file is placed one line at a time in the output buffer and then the
QOLSEND API is called to send one data unit of the file to System B. This
process repeats until the contents of the entire file have been transmitted
to the target application.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e234">(9)</th>
<td valign="top" headers="d0e234 ">Call the QOLSEND API with a X'B100' operation to clear the peer connection.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e239">(10)</th>
<td valign="top" headers="d0e239 ">The source program will check its data queue for a response to the
clear packet sent to the target system. Once the response is received, the
program will clean up, call the QOLDLINK API to disable the link previously
enabled, and end.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e244">(11)</th>
<td valign="top" headers="d0e244 ">The following C functions illustrate the various user-defined communications
support APIs.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e249">(12)</th>
<td valign="top" headers="d0e249 ">This procedure illustrates a call to the QOLDLINK API. Note the vary
option is set to vary off the associated iSeries server *USRDFN network device.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e257">(13)</th>
<td valign="top" headers="d0e257 ">The settimer() calls the QOLTIMER API requesting timers for 20000 milliseconds,
or twenty seconds. After setting a timer, the settimer() will call the dequeue()
to remove an entry from the program's data queue.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e262">(14)</th>
<td valign="top" headers="d0e262 ">The x25lind() illustrates calling the QOLQLIND API.</td>
</tr>
</tbody>
</table>
</div>
<p id="apiexustran__HDRTARGET"><a name="apiexustran__HDRTARGET"><!-- --></a><strong>Target application on System B listing</strong></p>
<p>The
target application waits for the source application to initiate the file transfer.
The following list summarizes the actions of the target application:</p>
<ul><li>Calls the QOLQLIND API to get local X.25 line information</li>
<li>Opens the local file</li>
<li>Calls the QOLELINK API to establish a link for communications</li>
<li>Calls the QOLSETF API to activate an X.25 protocol ID filter</li>
<li>Calls the QOLRECV API to receive the X'B201' operation (incoming call)</li>
<li>Calls the QOLSEND API with a X'B400' operation to accept the SVC connection</li>
<li>Receives the file from the target system using X'0001' operations</li>
<li>Calls the QOLRECV API to receive the X'B301' (connection failure notification)</li>
<li>Call the QOLSEND API with 'B100' operation to locally close the SVC connection</li>
<li>Calls the QOLDLINK API to disable the link</li>
<li>Calls the QOLTIMER API to manage the reception of data queue entries</li>
</ul>
<p>To create the program using ILE C, use the Create Bound C (CRTBNDC)
command.</p>
<p>Explanations of the reference numbers in the listing can be
found in <a href="#apiexustran__SPTCTARG">Target application program listing references</a>.</p>
<pre> Program name . . . . . . . . . :
<span class="uicontrol">(TARGET)</span>
Library name . . . . . . . . : UDCS_APPLS
Source file . . . . . . . . . . : QCSRC
Library name . . . . . . . . : UDCS_APPLS
Source member name . . . . . . : TARGET
Text Description . . . . . . . : Target Application Example
Output . . . . . . . . . . . . : *NONE
Compiler options . . . . . . . : *SOURCE *NOXREF *NOSHOWUSR
: *NOSHOWSYS *NOSHOWSKP *NOEXPMAC
: *NOAGR *NOPPONLY *NODEBUG
: *GEN *NOSECLVL *PRINT *LOGMSG
: *USRINCPATH
Checkout Options . . . . . . . : *NOAGR
Optimization . . . . . . . . . : *NONE
Inline Options:
Inliner . . . . . . . . . . . : *OFF
Mode . . . . . . . . . . . . : *NOAUTO
Threshold . . . . . . . . . . : 250
Limit . . . . . . . . . . . . : 2000
Debugging View . . . . . . . . : *NONE
Define Names . . . . . . . . . : *NONE
Language Level . . . . . . . . : *SOURCE
Source Margins:
Left margin . . . . . . . . . : 1
Right margin . . . . . . . . : 32754
Sequence columns:
Left column . . . . . . . . . : *NONE
Right column . . . . . . . . :
Message flagging level . . . . : 0
Compiler messages:
Message limit . . . . . . . . : *NOMAX
Message limit severity . . . : 30
Replace Program Object . . . . : *YES
User Profile . . . . . . . . . : *USER
Authority . . . . . . . . . . . : *LIBCRTAUT
Target Release . . . . . . . . : *CURRENT
System includes . . . . . . . . : *YES
/*******************************************************************/
/** **/
/** Program Name: Target Application Program Example **/
/** **/
/** **/
/** Function: **/
/** This is the target application program example that uses **/
/** X.25 services provided by the user-defined communications **/
/** support to receive a simple file from the source application **/
/** program running on System A. This program performs the **/
/** following: **/
/** 01. Open the target file named OUTFILE. **/
/** 02. Call QOLQLIND to obtain local line information. **/
/** 03. Enable a link. **/
/** 04. Set a Filter on the enabled link. **/
/** 05. Receive a 'B101'X operation (incoming call). **/
/** 06. Send a 'B400'X operation (accept call). **/
/** 07. Receive '0001'X operation(s) (incoming data) from **/
/** the source application program and write it to the **/
/** file opened in step 1). **/
/** 08. Receive a 'B301'X operation (clear call indication). **/
/** 09. Send a 'B100'X operation to respond locally to the **/
/** clearing of the connection. **/
/** 10. Disable the link enabled in step 3). **/
/** **/
/** A data queue will be actively used to manage the operation **/
/** of this program. Data queue support will be used to monitor **/
/** for the completion of the enable and disable routines, as **/
/** well as timer expirations and incoming data. Timers are **/
/** used to ensure that there will never be an infinite wait on **/
/** the data queue. If a timer expires, the link enabled will **/
/** be disabled and the program will stop. **/
/** **/
/** **/
/** Inputs: **/
/** The program expects the following input parameters: **/
/** Line Name: This is the name of the line description **/
/** that will be used to call the QOLELINK API. **/
/** The line must be an X.25 line with at least **/
/** one SVC of type *SVCBOTH or *SVCIN. **/
/** **/
/** CommHandle: This is the logical name that will be used **/
/** to identify the link enabled. **/
/** **/
/** Remote DTE Address: The is the Local Network Address **/
/** of system A. **/
/** **/
/** **/
/** Outputs: **/
/** Current status of the file transfer will be provided when **/
/** running this program. If an error should occur, then a **/
/** message will be displayed indicating where the error occurred **/
/** and the program will end. If the program completes **/
/** successfully, a "successful completion" message will be **/
/** posted. **/
/** **/
/** Language: ILE C **/
/** **/
/** APIs used: QOLELINK, QUSPTRUS, QOLRECV, QOLSEND, QOLDLINK, **/
/** QRCVDTAQ, QOLTIMER **/
/** **/
/*******************************************************************/
/*******************************************************************/
/*******************************************************************/
/*******************************************************************/
#include "header"
#include "typedef"
#include "hexconv"
void senddata(sendparms *a, char *b, desc *c, char *d, char *e, int f);
void sndformat1(sendparms *a,char *b, char *c, char *d, qlindparms *e);
void sndformat2 (sendparms *a, char *b, char *c);
void setfilters (hdrparms *a);
void byte (char *a, int b, char *c, int d);
void printespec (espec *a);
void settimer(unsigned short *a,char *b,qentry *c,usrspace *d,char *e);
void dequeue (int a, char *b, qentry *c, usrspace *d);
void putdata (char *a, int b, FILE *c);
void x25lind (qlindparms *a, char *b);
void disablelink (disableparms *a, char *b, usrspace *c);
void handler (disableparms a, usrspace *b);
void _GetExcData(_INTRPT_Hndlr_Parms_T *parms);
/**********************************************************/
/*************** Start Main Program *******************/
/**********************************************************/
main (int argc, char *argv[])
{
/************ Variable Declarations *******************/
usrspace inbuff, /* Input Data Buffer */
indesc, /* Input Buffer Descriptor */
outbuff, /* Output Data Buffer */
outdesc, /* Output Buffer Descriptor */
qname; /* Data Queue */
int length, /* Data Queue key length */
inc, i, j; /* counters */
unsigned short expctid; /* Message ID that is expected */
char commhandle[10], /* Command Line Parameter */
rmtdte[17], /* Remote DTE Address */
*buffer, /* Pointer to buffer */
key[256]; /* Data Queue key identifier */
desc *descriptor; /* Pointer to buffer descriptor */
/** definitions for API functions **/
enableparms enable;
disableparms disable;
sendparms send;
recvparms recv;
setfparms setf;
timerparms timer;
qlindparms qlind;
qentry dataq;
hdrparms *header;
/****** Annndddddd.... they're off!! ***********/
<span class="uicontrol">(1)</span>
/***--- Open the file to put the received data. ----**/
if ((fptr = fopen("UDCS_APPLS/OUTFILE))", "w")) == NULL)
{
printf("Unable to open target output file in UDCS_APPLS LIB.\n");
printf("The Program was terminated.\n\n");
return;
}
/***--- Open the display file for error handling. ----**/
if ((screen = fopen("ERRORSPEC", "ab+ type = record")) == NULL)
{
printf("Unable to open display file.\n");
printf("The Program was terminated.\n\n");
return;
}
/***--- Set the Exception Handler ----**/
signal(SIGALL,SIG_DFL);
/** Clear the command line parameters **/
strncpy(enable.linename, " ", 10); /* Clear linename */
strncpy(commhandle, " ", 10); /* Clear Commhandle */
strncpy(rmtdte, " ", 17); /* Clear Remote DTE */
/** Receive command line Parameters **/
strncpy(enable.linename, argv[1], strlen(argv[1]));
strncpy(commhandle, argv[2], strlen(argv[2]));
strncpy(rmtdte, argv[3], strlen(argv[3]));
rmtdte[strlen(argv[3])] = '\0';
/** Initialize the user spaces **/
strncpy(inbuff.library, "UDCS_APPLS", 10); /* Input Buffer */
strncpy(inbuff.name, "TARGETIBUF", 10);
strncpy(indesc.library, "UDCS_APPLS", 10); /* Input B Desc */
strncpy(indesc.name, "TARGETIDSC", 10);
strncpy(outbuff.library, "UDCS_APPLS", 10); /* Output Buffer*/
strncpy(outbuff.name, "TARGETOBUF", 10);
strncpy(outdesc.library, "UDCS_APPLS", 10); /* Output B Desc */
strncpy(outdesc.name, "TARGETODSC", 10);
strncpy(qname.library, "UDCS_APPLS", 10); /* Data queue */
strncpy(qname.name, "X25DTAQ ", 10);
/***** retrieve the line description information ******/
x25lind (&amp;qlind, enable.linename);
if ((qlind.retcode != 0) || (qlind.reason != 0))
{
printf("Query line description failed.\n");
printf("Return code = %d\n", qlind.retcode);
printf("Reason code = %d\n\n", qlind.reason);
return;
}
/***** Hard Code the QOLELINK Input Parameters ******/
enable.maxdtax25 = 512;
enable.keylength = 3;
strncpy(enable.keyvalue, "RCV", 3);
<span class="uicontrol">(2)</span>
/**------- Enable the link -----------**/
QOLELINK (&amp;(enable.retcode), &amp;(enable.reason), &amp;(enable.tdusize),\
&amp;(enable.numunits), &amp;(enable.maxdtalan), &amp;(enable.maxdtax25),\
(char *)&amp;inbuff, (char *)&amp;indesc, (char *)&amp;outbuff,\
(char *)&amp;outdesc, &amp;(enable.keylength), enable.keyvalue,\
(char *)&amp;qname, enable.linename, commhandle);
if ((enable.retcode != 0) || (enable.reason != 0))
{
printf("Line %.10s with Commhandle %.10s was NOT ENABLED.\n",\
enable.linename, commhandle);
printf("Return code = %d\n", enable.retcode);
printf("Reason code = %d\n\n", enable.reason);
return;
}
<span class="uicontrol">(3)</span>
/**------- Set a timer for Enable link --------**/
expctid = 0xF0F0;
settimer(&amp;expctid, "Enable", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F0)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/*************************************************************/
/*******---- Set a Filter for the Link --------*********/
/*************************************************************/
<span class="uicontrol">(4)</span>
QUSPTRUS(&amp;outbuff, &amp;header); /* get the output buffer pointer */
header-&gt;function = 1; /* add a filter */
header-&gt;type = 0; /* X.25 PID only */
header-&gt;number = 1; /* set 1 filter */
header-&gt;length = 16; /* X.25 filter length */
setfilters(header); /* Fill in the filter format */
/*******---- Set the filter for the Link --------*********/
QOLSETF (&amp;(setf.retcode), &amp;(setf.reason), &amp;(setf.erroffset),\
commhandle);
if ((setf.retcode != 0) || (setf.reason != 0))
{
printf("Set Filters Return Code = %.2d\n", setf.retcode);
printf("Set Filters Reason Codes = %.4d\n", setf.reason);
printf("Set Filters Error Offset = %.4d\n", setf.erroffset);
return;
}
/*************************************************************/
/**** Receive the incoming call packet and accept the call **/
/*************************************************************/
/**------- Set a timer to receive data --------**/
expctid = 0xF0F3;
settimer(&amp;expctid, "Inc Call ", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F3)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
<span class="uicontrol">(5)</span>
/********** Receive the Incoming Data **********/
QUSPTRUS (&amp;inbuff, &amp;buffer);
QUSPTRUS (&amp;indesc, &amp;descriptor);
QOLRECV (&amp;(recv.retcode), &amp;(recv.reason), &amp;(recv.ucep),\
&amp;(recv.pcep), &amp;(recv.operation), &amp;(recv.numdtaunits),\
&amp;(recv.dataavail), &amp;(recv.errorspecific), commhandle);
if ((recv.retcode != 0) || (recv.reason != 0))
{
printf("Recv incoming call packet failed\n");
printf("return code %d\n", recv.retcode);
printf("reason code %d\n", recv.reason);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/*** Interpret the Received Operation ***/
if (recv.operation != 0xB201)
{
printf("Recvd operation %x instead of B201", recv.operation);
disablelink (&amp;disable, commhandle, &amp;qname);
return; /**** End the program ***/
}
<span class="uicontrol">(6)</span>
/******************************************************************/
/** Send a response to accept the call and establish a connection */
/******************************************************************/
/**** Get pointers to the user spaces. ******/
QUSPTRUS(&amp;outbuff, &amp;buffer);
QUSPTRUS(&amp;outdesc, &amp;descriptor);
/******* Set up Send Packet *********/
send.ucep = 62; /* set UCEP to be 62 */
send.pcep = recv.pcep; /* get the PCEP number */
send.operation = 0xB400; /* send a call request response*/
send.numdtaelmnts = 1; /* send one data unit */
/**----- Send the packet ----------------**/
sndformat1 (&amp;send, buffer, rmtdte, commhandle, &amp;qlind);
if ((send.retcode != 0) || (send.reason != 0))
{
printf("Data NOT sent for commhandle %.9s\n", commhandle);
printf("Return code = %d\n", send.retcode);
printf("Reason code = %d\n", send.reason);
printf("new pcep %d\n\n", send.newpcep);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
printf("An X.25 SVC connection was completed\n\n");
<span class="uicontrol">(7)</span>
/**********************************************************/
/**** Receive Incoming Data *************************/
/**********************************************************/
/**------- Set a timer to receive data --------**/
expctid = 0xF0F3;
settimer(&amp;expctid, "Inc Data ", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F3)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/*******--- Receive the Incoming Data ----******/
/** Get pointer to user space **/
QUSPTRUS (&amp;inbuff, &amp;buffer);
QUSPTRUS (&amp;indesc, &amp;descriptor);
/** Receive the data **/
QOLRECV (&amp;(recv.retcode), &amp;(recv.reason), &amp;(recv.ucep),\
&amp;(recv.pcep), &amp;(recv.operation), &amp;(recv.numdtaunits),\
&amp;(recv.dataavail), &amp;(recv.errorspecific), commhandle);
if ((recv.retcode != 0) || (recv.reason != 0))
{
printf("Recv op for first data unit failed\n");
printf("return code %d\n", recv.retcode);
printf("reason code %d\n", recv.reason);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
<span class="uicontrol">(8)</span>
/**************************************************************/
/******* Start a loop to read in all the incoming data ***/
/**************************************************************/
i = 1;
while (recv.operation == 0x0001)
{
printf("%d Data Recvd {%.4x}.\n\n", i++, recv.operation);
/** Store all the data units in the file **/
for (j = 1; j &lt;= recv.numdtaunits; j++) {
putdata (buffer + (j - 1)*enable.tdusize,\
descriptor-&gt;length, fptr);
descriptor = (desc *)((char *)descriptor + sizeof(desc));
} /* for */
/**------- Set a timer to wait for more data -------**/
if (recv.dataavail == 0)
{
/** Set timer **/
expctid = 0xF0F3;
settimer(&amp;expctid, "Wt Inc Dta", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F3)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
}
/** Get pointer to user space **/
QUSPTRUS (&amp;inbuff, &amp;buffer);
QUSPTRUS (&amp;indesc, &amp;descriptor);
/** Receive the data **/
QOLRECV (&amp;(recv.retcode), &amp;(recv.reason), &amp;(recv.ucep),\
&amp;(recv.pcep), &amp;(recv.operation), &amp;(recv.numdtaunits),\
&amp;(recv.dataavail), &amp;(recv.errorspecific), commhandle);
} /** End Receive data while loop ******/
<span class="uicontrol">(9)</span>
/****************************************************/
/*********** Receive the Clear indication ***********/
/****************************************************/
if ((recv.retcode != 83) || (recv.reason != 4002))
{
printf("Recv opr for clear request failed\n");
printf("return code %d\n", recv.retcode);
printf("reason code %d\n", recv.reason);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/* Interpret the Received Operation */
if (recv.operation != 0xB301)
{
printf("Recvd operation %x instead of B301", recv.operation);
disablelink (&amp;disable, commhandle, &amp;qname);
return; /**** end the program ***/
}
<span class="uicontrol">(10)</span>
/****************************************************************/
/*********** Send local response to clear indication ***********/
/****************************************************************/
/**** Get pointers to the user spaces. ******/
QUSPTRUS(&amp;outbuff, &amp;buffer);
QUSPTRUS(&amp;outdesc, &amp;descriptor);
/******* Set up the packet ****************/
send.operation = 0xB100; /* send a clear request packet */
send.numdtaelmnts = 1; /* send one data unit */
/**----- Send the packet ----------------**/
sndformat2 (&amp;send, buffer, commhandle);
if ((send.retcode != 0) &amp;&amp; (send.reason != 0))
{
printf("Response not sent for clear connection\n");
printf("Return code = %d\n", send.retcode);
printf("Reason code = %d\n", send.reason);
printf("new pcep %d\n\n", send.newpcep);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/******************************************************/
/*********** Receive the Clear Confirmation **********/
/******************************************************/
/**------- Set a timer to receive data --------**/
expctid = 0xF0F3;
settimer(&amp;expctid, "Clr Cnfrm", &amp;dataq, &amp;qname, commhandle);
if (expctid != 0xF0F3)
{
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
if ((recv.retcode != 00) || (recv.reason != 0000))
{
printf("Recv failed for clear confirmation\n");
printf("return code %d\n", recv.retcode);
printf("reason code %d\n", recv.reason);
printespec(&amp;(send.errorspecific));
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
/* Interpret the Received Operation */
if (recv.operation != 0xB101)
{
printf("Recvd opr %x instead of opr B301\n", recv.operation);
disablelink (&amp;disable, commhandle, &amp;qname);
return;
}
<span class="uicontrol">(11)</span>
/****************************************/
/** disable the link and end program **/
/****************************************/
disablelink (&amp;disable, commhandle, &amp;qname);
printf("TARGET application completed OK!\n\n");
} /* End Main */
/*****************************************************************/
/************** Start Subroutine Section **********************/
/*****************************************************************/
/*****************************************************************/
/************ Routine to fill X.25 Format I ***********/
void sndformat1 (sendparms *send,
char *buffer,
char *rmtdte,
char *commhandle,
qlindparms *qlind)
{
format1 *output = (format1 *) buffer;
register int counter;
register querydata *qd;
qd = (querydata *)&amp;(qlind-&gt;userbuffer);
output-&gt;type = 0; /* not used */
output-&gt;logchanid = 0x0;
output-&gt;sendpacksize = qd-&gt;x25data.defsend;
output-&gt;sendwindsize = qd-&gt;x25data.windowsend;
output-&gt;recvpacksize = qd-&gt;x25data.defrecv;
output-&gt;recvwindsize = qd-&gt;x25data.windowrecv;
output-&gt;dtelength = strlen(rmtdte); /* not used */
byte(output-&gt;dte, 16, rmtdte, strlen(rmtdte)); /* not used */
output-&gt;dbit = 0;
output-&gt;cug = 0; /* not used */
output-&gt;cugid = 0; /* not used */
output-&gt;reverse = 0; /* not used */
output-&gt;fast = 0; /* not used */
output-&gt;faclength = 0;
byte(output-&gt;facilities, 109, "", 0);
output-&gt;calllength = 0;
byte(output-&gt;callud, 128, "00", 2);
output-&gt;misc[0] = 0;
output-&gt;misc[1] = 0;
output-&gt;misc[2] = 0;
output-&gt;misc[3] = 0;
output-&gt;maxasmsize = 16383;
output-&gt;autoflow = 32;
QOLSEND (&amp;(send-&gt;retcode), &amp;(send-&gt;reason),
&amp;(send-&gt;errorspecific),\
&amp;(send-&gt;newpcep), &amp;(send-&gt;ucep), &amp;(send-&gt;pcep),\
commhandle, &amp;(send-&gt;operation), &amp;(send-&gt;numdtaelmnts));
} /* End sndformat1 Subroutine */
/*****************************************************************/
/************ Routine to fill X.25 Format II ***********/
void sndformat2 (sendparms *send,
char *buffer,
char *commhandle)
{
format2 *output = (format2 *) buffer;
output-&gt;type = 1;
output-&gt;cause = 'FF';
output-&gt;diagnostic = 'FF';
output-&gt;faclength = 0;
byte(output-&gt;facilities, 109, "", 0);
output-&gt;length = 0;
byte(output-&gt;userdata, 128, "", 0);
QOLSEND (&amp;(send-&gt;retcode), &amp;(send-&gt;reason),
&amp;(send-&gt;errorspecific),\
&amp;(send-&gt;newpcep), &amp;(send-&gt;ucep), &amp;(send-&gt;pcep),\
commhandle, &amp;(send-&gt;operation), &amp;(send-&gt;numdtaelmnts));
} /* End sndformat2 Subroutine */
/********************************************************************/
/************** Fill in the Buffer for the Filter ****************/
void setfilters (hdrparms *header)
{
x25filter *filters;
filters = (x25filter *)header-&gt;filters;
filters[0].pidlength = 1;
filters[0].pid = 0x21; /* set the protocol ID */
filters[0].dtelength = 0; /* no DTE used in filter */
byte(filters[0].dte, 12, "", 0);
filters[0].flags = 0x0;
filters[0].flags += 0x80; /* Set Reverse Charging to no */
filters[0].flags += 0x40; /* Set Fast Select to no */
} /* End setfilters Subroutine */
/********************************************/
/******** Routine to disable ***********/
void disablelink (disableparms *disable,
char *commhandle,
usrspace *qname)
{
qentry dataq;
unsigned short expctid;
disable-&gt;vary = 1; /* Hard code device to vary off */
/** Call disable link **/
QOLDLINK (&amp;(disable-&gt;retcode), &amp;(disable-&gt;reason),\
commhandle, &amp;(disable-&gt;vary));
if ((disable-&gt;retcode != 0) &amp;&amp; (disable-&gt;reason != 00))
{
printf ("Link %.10s did not disabled.\n", commhandle);
printf ("return code = %d\n", disable-&gt;retcode);
printf ("reason code = %d\n\n", disable-&gt;reason);
}
else
printf ("%.10s link disabled \n", commhandle);
/**------- Set a timer to receive message --------**/
expctid = 0xF0F1;
settimer(&amp;expctid, "Disable ", &amp;dataq, qname, commhandle);
if (expctid != 0xF0F1)
{
printf("Disable link did not complete successfully");
return;
}
/** close the files **/
fclose(fptr);
fclose(screen);
} /* End disablelink Subroutine */
/**************************************************************/
/** Routine to convert string to Hexadecimal format ******/
void byte (char *dest,
int dlength,
char *source,
int slength)
{
register int counter;
char holder[2];
for (counter=0;counter&lt;dlength;counter++)
dest[counter]=0;
for (counter=slength-1;counter&gt;=0;counter--)
if isxdigit(source[counter])
{
holder[0]=source[counter];
holder[1]='\0';
if (counter % 2 == 0)
dest[counter/2] += (char) hextoint(holder)*16;
else dest[counter/2] += (char) hextoint(holder);
}
} /* End byte Subroutine */
/**************************************************************/
/** Routine to display the ErrorSpecific output ******/
/**************************************************************/
void printespec(espec *errorspecific)
{
especout outparms;
sprintf(outparms.hwecode, "%.8X", errorspecific-&gt;hwecode);
sprintf(outparms.timestamp, "%.8X%.8X", errorspecific-&gt;timestamphi,\
errorspecific-&gt;timestamplo);
sprintf(outparms.elogid, "%.8X", errorspecific-&gt;elogid);
if (errorspecific-&gt;flags &amp; 0x40)
outparms.fail = 'Y';
else outparms.fail = 'N';
if (errorspecific-&gt;flags &amp; 0x20)
outparms.zerocodes = 'Y';
else outparms.zerocodes = 'N';
if (errorspecific-&gt;flags &amp; 0x10)
outparms.qsysopr = 'Y';
else outparms.qsysopr = 'N';
sprintf(outparms.cause,"%.2X", errorspecific-&gt;cause);
sprintf(outparms.diagnostic, "%.2X", errorspecific-&gt;diagnostic);
sprintf(outparms.erroffset, "%.6d", errorspecific-&gt;erroroffset);
fwrite(&amp;outparms, 1, sizeof(especout), screen);
fread("", 0, 0, screen);
} /* End printespec Subroutine */
/***************************************************************/
/******* Dequeues the Incoming Message and processes it ******/
void dequeue (int length,
char *key,
qentry *dataq,
usrspace *qname)
{
char fldlen[3],
waittime[3],
keylen[2],
senderid[2],
*pointer,
order[2];
register int counter;
waittime[0] = 0;
waittime[1] = 0;
waittime[2] = 0x1D; /* Hard code a delay of infinite */
keylen[0] = 0;
keylen[1] = 0x3F; /* Hard code a keylength of 3 */
senderid[0] = 0;
senderid[1] = 0x0F;
strncpy(order, "EQ", 2);
/* Clear the data structures **/
fflush(stdin);
pointer = (char *)dataq;
for (counter = 0; counter &lt; 336; counter++)
pointer[counter] = 0;
strncpy (dataq-&gt;type, " ", 7);
while ((strncmp(dataq-&gt;type, "*USRDFN", 7) != 0) || (fldlen == 0))
QRCVDTAQ(qname-&gt;name, qname-&gt;library, fldlen, dataq, waittime,\
order, keylen, key, senderid,"");
} /* End dequeue Subroutine */
/**********************************************************/
/************* Set a timer and dequeue next entry ******/
void settimer (unsigned short *expctid,
char *process,
qentry *dataq,
usrspace *qname,
char *commhandle)
{
timerparms timer;
disableparms disable;
int length;
char key[6];
timer.interval = 20000; /* set timer for 20 seconds */
timer.establishcount = 1; /* set establish count to 1 */
timer.keylength = 3; /* key value */
strncpy(timer.keyvalue, "TGT", 3); /* set key value /
timer.operation = 1; /* set a timer */
/* Call QOLTIMER */
QOLTIMER (&amp;(timer.retcode), &amp;(timer.reason), timer.handleout,\
timer.handlein, (char *)qname, &amp;(timer.operation),\
&amp;(timer.interval), &amp;(timer.establishcount),\
&amp;(timer.keylength), timer.keyvalue, timer.userdata);
if ((timer.retcode != 0) || (timer.reason != 0))
{
printf("%s timer failed while being set.\n", process);
printf("Return code = %d\n", timer.retcode);
printf("Reason code = %d\n\n", timer.reason);
}
/**------- Dequeue an entry --------**/
strncpy(key, "TGT", 3);
length = 3;
dequeue (length, key, dataq, qname);
/***---- Cancel timer -----***/
if (dataq-&gt;msgid != 0xF0F4)
{
strncpy(timer.handlein, timer.handleout, 8);
timer.operation = 2; /* Cancel one timer */
QOLTIMER (&amp;(timer.retcode), &amp;(timer.reason), timer.handleout,\
timer.handlein, (char *)qname, &amp;(timer.operation),\
&amp;(timer.interval), &amp;(timer.establishcount),\
&amp;(timer.keylength), timer.keyvalue, timer.userdata);
if ((timer.retcode != 0) || (timer.reason != 0))
{
printf("%s timer failed while being canceled\n", process);
printf("Return code = %d\n", timer.retcode);
printf("Reason code = %d\n\n", timer.reason);
}
}
if (dataq-&gt;msgid != *expctid)
{
printf ("A %.4X message ID was received instead of %.4X\n",\
dataq-&gt;msgid, *expctid);
printf ("%s completion message was not received\n", process);
*expctid = dataq-&gt;msgid;
}
} /* End settimer Subroutine */
/************************************************************/
/** x25lind: Read a record into buf and return length **/
void x25lind (qlindparms *qlind, char *linename)
{
register int counter;
for(counter=0;counter&lt;256;counter++)
qlind-&gt;userbuffer[counter]=0;
qlind-&gt;format = 0x01;
QOLQLIND (&amp;(qlind-&gt;retcode), &amp;(qlind-&gt;reason), &amp;(qlind-&gt;nbytes),\
qlind-&gt;userbuffer, linename, &amp;(qlind-&gt;format));
} /* End x25lind Subroutine */
/************************************************************/
/** putdata: Read a record into buf and return length **/
void putdata (char *buf,
int dtalen,
FILE *fptr)
{
int i;
for (i = 0; i &lt; dtalen; i++)
fwrite(buf + i, 1, 1, fptr);
} /* End putdata Subroutine */</pre>
</div>
<div class="section" id="apiexustran__SPTCTARG"><a name="apiexustran__SPTCTARG"><!-- --></a><h4 class="sectiontitle">Target application program listing references</h4><p>The
following reference numbers and explanations correspond to the reference numbers
in the target application's program listing.</p>
<div class="tablenoborder"><table cellpadding="4" cellspacing="0" summary="" frame="border" border="1" rules="all"><tbody><tr><th valign="top" class="firstcol" id="d0e350">(1)</th>
<td valign="top" headers="d0e350 ">Call the C library routines fopen() and signal() to open the target
file and set up a signal handler to process <span class="keyword">i5/OS</span> exceptions,
respectively. If an exception situation is encountered, the handler() will
be called to perform clean-up in order for the program to end.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e359">(2)</th>
<td valign="top" headers="d0e359 ">Call the QOLELINK API to enable the line description using the line
name and communications handle passed as input parameters to this program.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e364">(3)</th>
<td valign="top" headers="d0e364 ">Call the QOLTIMER API to time the completion of the enable link operation.
If the timer expires before the enable-complete message is posted on the this
program's data queue, then this program will end.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e369">(4)</th>
<td valign="top" headers="d0e369 ">Call the QUSPTRUS API to obtain a pointer to the beginning of the output
buffer user space. The output buffer will be used to construct a filter list
for the call to the QOLSETF API.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e374">(5)</th>
<td valign="top" headers="d0e374 ">Call the QOLRECV API to receive inbound data after reading an incoming
data message that was posted on the program's data queue by the user-defined
communications support. Since these programs are operating using the communications
services of X.25, the first data unit the target program should see is a X'B201'
operation signalling an incoming call was received.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e379">(6)</th>
<td valign="top" headers="d0e379 ">Call the QOLSEND API with a X'B400' operation to accept the incoming
X.25 call. A connection is now established between the source and target application
programs.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e384">(7)</th>
<td valign="top" headers="d0e384 ">The target program will now set a timer by calling the QOLTIMER API
and wait for incoming data. If the timer expires before any incoming data
is received, then this program will call the QOLDLINK API, and end.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e389">(8)</th>
<td valign="top" headers="d0e389 ">This is the main receive loop for the target program. When data is
received from the source program, it will be written to the target file opened
during the initialization of this program. The loop will process until a message
other than incoming-data entry is read from the program's data queue.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e394">(9)</th>
<td valign="top" headers="d0e394 ">Call the QOLSEND API with a X'B001' operation to locally close the
connection.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e399">(10)</th>
<td valign="top" headers="d0e399 ">Receives a X'B101' operation from the user-defined communications support.
This is a local confirmation of X'B100' operation.</td>
</tr>
<tr><th valign="top" class="firstcol" id="d0e404">(11)</th>
<td valign="top" headers="d0e404 ">Call the QOLDLINK API to disable the link previously enabled and end.</td>
</tr>
</tbody>
</table>
</div>
<p id="apiexustran__Header_47"><a name="apiexustran__Header_47"><!-- --></a><strong>Includes for source and target programs</strong></p>
<p>The
following three includes are used by both the preceding source and target
programs. They are not in an <span class="keyword">i5/OS</span> library.</p>
<pre>/*******************************************************************/
/*******************************************************************/
/* Include Name: Header */
/* */
/* */
/* Function: */
/* Type define and declare the structures used to interface */
/* to the user-defined communications APIs. These structures */
/* are used by both the source and target application. */
/* */
/* */
/* LANGUAGE: ILE C */
/* */
/* APIs USED: QOLDLINK, QOLELINK, QOLSEND, QOLRECV, QOLSETF, */
/* QOLTIMER, QUSPTRUS, QRCVDTAQ, QCLRDTAQ, QOLQLIND */
/* */
/*******************************************************************/
/*******************************************************************/
FILE *screen;
FILE *rptr;
FILE *fptr;
#include &lt;qoldlink.h&gt;
#include &lt;qolelink.h&gt;
#include &lt;qolsend.h&gt;
#include &lt;qolrecv.h&gt;
#include &lt;qolsetf.h&gt;
#include &lt;qoltimer.h&gt;
#include &lt;qusptrus.h&gt;
#include &lt;qrcvdtaq.h&gt;
#include &lt;qclrdtaq.h&gt;
#include &lt;qolqlind.h&gt;
/************ Typedef Declarations *******************/
typedef struct usrspace
{
char name[10];
char library[10];
} usrspace;
typedef struct enableparms /* Enable parameters */
{
int retcode, /* Output */
reason, /* Output */
tdusize, /* Output */
numunits, /* Output */
maxdtalan, /* Output */
maxdtax25, /* Input */
keylength; /* Input */
char keyvalue[256], /* Input */
linename[10]; /* Input */
} enableparms;
typedef struct disableparms /* Disable parameters */
{
int retcode, /* Output */
reason; /* Output */
char vary; /* Input */
} disableparms;
typedef struct setfparms /* Set Filters parameters */
{
int retcode, /* Output */
reason, /* Output */
erroffset; /* Output */
} setfparms;
typedef _Packed struct hdrparms /* Filter header */
{
char function;
char type;
unsigned short number;
unsigned short length;
char filters[1];
} hdrparms;
typedef _Packed struct x25filter /* X.25 filter */
{
char pidlength;
char pid;
char dtelength;
char dte[12];
char flags;
} x25filter;
typedef struct sendparms /* Send parameters */
{
espec errorspecific; /* Output */
int retcode, /* Output */
reason, /* Output */
newpcep, /* Output */
ucep, /* Input */
pcep, /* Input */
numdtaelmnts; /* Input */
unsigned short operation; /* Input */
} sendparms;
typedef struct recvparms /* Receive parameters */
{
espec errorspecific; /* Output */
int retcode, /* Output */
reason, /* Output */
newpcep, /* Output */
ucep, /* Output */
pcep, /* Output */
numdtaunits; /* Output */
char dataavail; /* Output */
unsigned short operation; /* Output */
} recvparms;
typedef struct timerparms /* Timer parameters */
{
int retcode, /* Output */
reason, /* Output */
interval, /* Input */
establishcount, /* Input */
keylength; /* Input */
char handleout[8], /* Output */
handlein[8], /* Input */
operation, /* Input */
keyvalue[256], /* Input */
userdata[60]; /* Input */
} timerparms;
typedef struct especout
{
char hwecode[8];
char timestamp[16];
char elogid[8];
char fail;
char zerocodes;
char qsysopr;
char cause[2];
char diagnostic[2];
char erroffset[6];
} especout;
typedef struct qlindparms /* Query line parameters */
{
int retcode, /* Output */
reason, /* Output */
nbytes; /* Output */
char userbuffer[256];
char format;
} qlindparms;
typedef _Packed union content /* Queue support parameters */
{
_Packed struct other
{
char commhandle[10];
char reserved[58];
} other;
_Packed struct enable
{
char commhandle[10];
char status;
char reserved[57];
} enable;
_Packed struct timer
{
char timerhandle[8];
char userdata[60];
} timer;
} content;
typedef _Packed struct qentry /* Queue parameters */
{
char type[10];
unsigned short msgid;
content message;
char key[256];
} qentry;
</pre>
<p>The following typedef include has new type declarations used
by both source and target programs.</p>
<pre>/*******************************************************************/
/*******************************************************************/
/* Include Name: Typedef */
/* */
/* Function: */
/* Define the buffer spaces used to pass the data to the */
/* APIs. */
/* */
/* */
/* LANGUAGE: ILE C */
/* */
/*******************************************************************/
/*******************************************************************/
/*These definitions and C library #include files are either global, or
are used by multiple modules in the Open FM API driver.*/
#include &lt;stdio.h&gt;
#include &lt;stdlib.h&gt;
#include &lt;signal.h&gt;
#include &lt;xxcvt.h&gt;
#include &lt;string.h&gt;
#include &lt;ctype.h&gt;
#include &lt;recio.h&gt;
typedef struct queuein
{
char library[10];
char name[10];
char option;
} queuein;
typedef struct namelib
{
char library[10];
char name[10];
} namelib;
typedef _Packed struct format1
{
char type;
char reserved1;
unsigned short logchanid;
unsigned short sendpacksize;
unsigned short sendwindsize;
unsigned short recvpacksize;
unsigned short recvwindsize;
char reserved2[7];
char dtelength;
char dte[16];
char reserved3[8];
char dbit;
char reserved4[7];
char cug;
char cugid;
char reverse;
char fast;
char faclength;
char facilities[109];
char reserved5[48];
unsigned short calllength;
char callud[128];
char reserved6[128];
unsigned char misc[4]; /* control flags */
unsigned int maxasmsize;
unsigned short autoflow;
} format1;
typedef _Packed struct format2
{
unsigned short type;
char cause;
char diagnostic;
char reserved[4];
char faclength;
char facilities[109];
char reserved2[48];
unsigned short length;
char userdata[128];
} format2;
typedef _Packed struct desc
{
unsigned short length;
char more; /*These 4 char's are only used for X.25.*/
char qualified;
char interrupt;
char dbit;
char reserved[26];
} desc;
typedef _Packed struct llcheader
{
unsigned short headerlength;
char macaddr[6];
char dsap;
char ssap;
char priority;
char priorctl;
unsigned short routlen;
unsigned short userdtalen;
char data[1];
} llcheader;
typedef _Packed struct espec
{
char reserved[2];
unsigned int hwecode;
unsigned int timestamphi;
unsigned int timestamplo;
unsigned int elogid;
char reserved2[10];
char flags;
char cause;
char diagnostic;
char reserved3;
unsigned int erroroffset;
char reserved4[4];
} espec;
typedef struct tableentry
{
char handle[10];
char type;
char inbuff[20];
char indesc[20];
char outbuff[20];
char outdesc[20];
unsigned int totaldusize;
struct tableentry *next;
} tableentry;
/******* Data structure for X.25 line ********/
/******* descriptions as returned by QOLQLIND. ******/
typedef struct x25info
{
char addrlen;
char addr[9];
char addrtype;
char insert;
char modulus;
char dtedce;
unsigned short maxsend;
unsigned short maxrecv;
unsigned short defsend;
unsigned short defrecv;
char windowsend;
char windowrecv;
unsigned short numlc;
char lcinfo[4];
} x25info;
typedef struct querydata
{
char header[12]; /* line header info */
x25info x25data; /* preliminary data */
} querydata;</pre>
<pre>/*******************************************************************/
/*******************************************************************/
/* Include Name: Hexconv */
/* */
/* Function: */
/* This include brings in procedures to convert hexadecimal */
/* to integer values and vice versa. */
/* */
/* */
/* LANGUAGE: ILE C */
/* */
/*******************************************************************/
/*******************************************************************/
#include &lt;stdio.h&gt;
unsigned int hextoint(char *);
char *inttohex(decimal,hex) /*Converts a 4-byte integer into a
string of 2 uppercase hex characters.*/
unsigned int decimal;
char *hex;
{
sprintf(hex,"%.2X",decimal);
return(hex);
}
unsigned int hextoint(hex) /*Converts a string containing hex
digits into a 4-byte integer. */
char *hex;
{
int decimal;
sscanf(hex,"%x",&amp;decimal);
return(decimal);
}</pre>
</div>
</div>
<div>
<div class="familylinks">
<div class="parentlink"><strong>Parent topic:</strong> <a href="apiexmp.htm" title="Contains example programs that use APIs and exit programs.">Examples: APIs</a></div>
</div>
<div class="relref"><strong>Related reference</strong><br />
<div><a href="../apis/qolsetf.htm">Set Filter (QOLSETF) API</a></div>
</div>
</div>
</body>
</html>