| There does seem to one bug in the configurator where the PVC access is set for
none, but that is easily corrected by editing the x25$configure.ncl script and
changing the Access = NONE to Access = ALL.
As a test I compiled, linked, and ran this crude, sample program on my
DEC3000-300 w/ OpenVMS Alpha V7.1, DECnet-Plus V7.1, and X.25 V1.1A. It uses
only the psi$c_ncb_pvcnam and psi$c_ncb_dteclass ncb items and it worked.
$cc pvc_receive
$link pvc_receive
--------------------------------------------
#module PSI$X25_SEND_C PSI Example Program
/*
* COPYRIGHT (C) 1987
* DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASSACHUSETTS, USA
*
* THIS SOFTWARE IS FURNISHED UNDER A LICENSE AND MAY BE USED AND COPIED
* ONLY IN ACCORDANCE WITH THE TERMS OF SUCH LICENCE AND WITH THE INCLUSION
* OF THE ABOVE COPYRIGHT NOTICE. THIS SOFTWARE, OR ANY OTHER COPIES
* THEREOF, MAY NOT BE PROVIDED OR OTHERWISE MADE AVAILABLE TO ANY OTHER
* PERSON. NO TITLE TO AND OWNERSHIP OF THE SOFTWARE IS HEREBY TRANSFERRED.
*
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT NOTICE
* AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL EQUIPMENT
* CORPORATION.
*
* DIGITAL ASSUMES NO RESPONSIBILITY FOR THE USE OR THE RELIABILITY OF ITS
* SOFTWARE ON EQUIPMENT WHICH IS NOT SUPPLIED BY DIGITAL.
*
*
**++
**
** FACILITY:
**
** VAX P.S.I. Example Program
**
** ABSTRACT:
**
** SEND PROGRAM
** This program is one of a pair of demonstration programs which will
** transfer data entered at the terminal from one VAX to another over
** a Packet Switching Data Network. This program sends messages
** entered at the terminal to a remote process run as an object.
**
** ENVIRONMENT:
**
** Native mode VAX processor, User mode.
**
** COMPILATION/LINKAGE:
**
** $ CC this_prog
** $ LINK this_prog, sys$library:vaxcrtl/lib
** $ RUN this_prog
**
** FUNCTIONAL DESCRIPTION:
**
** * Include external macro and constant definitions
** and define local macros and constants
** * Declare the NCB structure and fill with call connect information
** * Declare structures for NCB descriptor, mailbox message and IOSB
** * Create a mailbox for the network device
** * Assign an input/output (I/O) channel to the network
** device (NWA0:)
** * Set up a virtual circuit
** * Read the mailbox to obtain the status of the connection
** * Loop reading data from keyboard and sending to remote
** process until control-z received
** * Clear the call
** * Deassign the mailbox and I/O channels
**
**--
**/
/*
* Included macros and definitions
*/
#include stdio /* Standard C i/o */
#include ssdef /* VAX/VMS System services */
#include descrip /* VAX-11 Calling std. descriptors */
#include iodef /* VAX/VMS i/o definitions */
#include <psilib> /* PSI constants */
/*
* Local macros and definitions
*/
#define check_status(x) if (!((x) &1)) SYS$EXIT(x) /* Error handler */
#define IOBSZ 128
#define CTRLZ 26
/*
* Define the following two constants as required,
* REMDTE is the remote DTE address and
* REMDTESUB is the remote DTE sub-address
*/
#define PVCNAM "X25-PVC"
#define DTECLASS "HOLSTN_TELENET"
/*
* Entry point
*/
exa$psi_send()
MAIN_PROGRAM
{
/*
* Local storage
*/
int status; /* Service return status */
short psi_channel, mbx_channel; /* Channel numbers for i/o */
char iobuf[IOBSZ]; /* I/o buffer */
/*
* Network connect block
*/
static struct ncb {
struct rem_pvc { /* DTE Address */
short len;
short code;
char s_siz; /* Counted ascii string */
char s[sizeof(PVCNAM)-1];
} rem_pvc;
struct rem_net { /* DTE Subaddress */
short len;
short code;
char s_siz;
char s[sizeof(DTECLASS)-1];
} rem_net;
} ncb = { { sizeof(struct rem_pvc),
psi$c_ncb_pvcnam,
sizeof(ncb.rem_pvc.s),
PVCNAM },
{ sizeof(struct rem_net),
psi$c_ncb_DTECLASS,
sizeof(ncb.rem_net.s),
DTECLASS }
};
/*
* NCB Descriptor
*/
static struct dsc$descriptor ncb_desc = { sizeof(ncb),
DSC$K_DTYPE_VT,
DSC$K_CLASS_VS,
&ncb };
/*
* Mailbox message buffer
*/
static struct mbx_mess {
short msgtype;
short unit;
char name_siz;
char name[15];
char info_siz;
char info[15];
} mbx_mess;
/*
* IO Status block definition
*/
volatile struct {
unsigned short status; /* Final io status */
unsigned short dlen; /* Usually data length */
unsigned short devdep1, devdep2; /* Device dependent */
} iosb;
/*
* Static string descriptors for mailbox and network device
*/
static $DESCRIPTOR(mbx_name, "X25S_MBX");
static $DESCRIPTOR(dev_name, "_NWA0:");
/*
* Create network device mailbox and assign network channel
*/
status = SYS$CREMBX(0, /* Create mailbox */
&mbx_channel, /* channel */
0,
0,
0,
0,
&mbx_name); /* logical name */
check_status(status); /* Check for error */
/* Assign a channel */
status = SYS$ASSIGN(&dev_name, /* to network device */
&psi_channel, /* channel number */
0,
&mbx_name); /* mailbox logical name */
check_status(status); /* Check for error */
/*
* Set up a virtual call to receive program and get connect information
* from the mailbox
*/
status = SYS$QIOW( 0, /* Issue QIO and wait */
psi_channel, /* to network device */
IO$_ACCESS, /* funtion is make call */
&iosb, /* I/O status block */
0,
0,
0,
&ncb_desc, /* call NCB descriptor */
0,
0,
0,
0);
check_status(status); /* Check for error */
check_status(iosb.status);
status = SYS$QIOW( 0, /* Issue QIO and wait */
mbx_channel, /* to mailbox channel */
IO$_WRITEVBLK, /* function is read */
&iosb, /* I/O status block */
0,
0,
&mbx_mess, /* mailbox buffer */
sizeof(struct mbx_mess),/* and its size */
0,
0,
0,
0);
check_status(status);
check_status(iosb.status); /* Check for I/O error */
status = SYS$QIOW( 0, /* Issue QIO and wait */
psi_channel, /* to network device */
IO$_NETCONTROL, /* funtion is make call */
&iosb, /* I/O status block */
0,
0,
0,
0, /* call NCB descriptor */
0,
psi$k_reset,
0,
0);
check_status(status); /* Check for error */
check_status(iosb.status);
/*
* Code to decode call accept mailbox message
*/
/* ... */
/*
* Enter mainloop to read from stdin stream and send it over the network
* to the remote process. When end of file is reached call will be
* cleared.
*/
/*
* Read lines from stdin until EOF
*/
while(((char *)gets(iobuf)) != NULL) {
status = SYS$QIOW(0, /* Issue QIO and wait */
psi_channel, /* to network device */
IO$_WRITEVBLK, /* function is write */
&iosb, /* I/O status block */
0,
0,
iobuf, /* buffer address */
strlen(iobuf) + 1, /* and size incldng '/0'*/
0,
0,
0,
0);
check_status(status);
check_status(iosb.status); /* Check for I/O error */
}
/*
* End of file was encountered. Send control-Z to remote process, clear
* the call and deassign the I/O channels.
*/
iobuf[0] = CTRLZ; /* I/O buffer is ctl-Z */
status = SYS$QIOW( 0, /* Issue QIO and wait */
psi_channel, /* to the network device*/
IO$_WRITEVBLK, /* function is write */
&iosb, /* I/O status block */
0,
0,
iobuf, /* I/O buffer */
1, /* and its length */
0,
0,
0,
0);
check_status(status);
check_status(iosb.status); /* Check for I/O error */
status = SYS$QIOW( 0, /* Issue QIO and wait */
psi_channel, /* to network device */
IO$_DEACCESS, /* functn is clear call */
&iosb, /* I/O status block */
0,
0,
0,
0,
0,
0,
0,
0);
check_status(status);
check_status(iosb.status); /* Check for I/O error */
status = SYS$DASSGN(psi_channel); /* Deassign netwk device*/
check_status(status); /* Check for error */
status = SYS$DASSGN(mbx_channel); /* Deassign mailbox */
check_status(status); /* Check for error */
SYS$EXIT(SS$_NORMAL); /* Exit with success */
}
|