/****************************************************************************** * * (c) Copyright 1992, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS. * ALL RIGHTS RESERVED * * THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT * NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY DIGITAL * OR ITS THIRD PARTY SUPPLIERS * * DIGITAL AND ITS THIRD PARTY SUPPLIERS, ASSUME NO RESPONSIBILITY FOR * THE USE OR INABILITY TO USE ANY OF ITS SOFTWARE . THIS SOFTWARE IS PROVIDED * "AS IS" WITHOUT WARRANTY OF ANY KIND, AND DIGITAL EXPRESSLY DISCLAIMS ALL * IMPLIED WARRANTIES, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. * * Notice: Notwithstanding any other lease or license that may pertain to, * or accompany the delivery of, this computer software, the rights of the * Government regarding its use, reproduction and disclosure are as set * forth in Section 52.227-19 of the FARS Computer Software-Restricted * Rights clause. * * (c) Copyright 1992. Unpublished - all * rights reserved under the Copyright laws of the United States. * * RESTRICTED RIGHTS NOTICE: Use, duplication, or disclosure by the * Government is subject to the restrictions as set forth in subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software clause * at DFARS 52.227-7013. * * DIGITAL EQUIPMENT CORP. * 550 KING ST. * LITTLETON, MA * (508)486-5330 * * RESTRICTED RIGHTS LEGEND: This computer software is submitted with * "restricted rights." Use, duplication or disclosure is subject to the * restrictions as set forth in NASA FAR SUP 18-52.227-79 (April 1985) * "Commercial Computer Software- Restricted Rights (April 1985)." * * * DEC is a registered trademark of Digital Equipment Corporation * DIGITAL is a registered trademark of Digital Equipment Corporation * * DIGITAL distributes this software as a sample program for a remote * source to inter-operate with DECmcc Data Collector AM. Digital expects * no revenue from this program, and grants the rights to anyone who * has licenses for DECmcc to copy, distribute, or modify this program * at their risk. Digital retains the rights of authorship of the * program with its current functionality. It can not be resold without * the obtaining permission from Digital Equipment Corp. * Digital does not claim the rights of derivative works * which substantially alter the functionality of the original program. * Although this program works with the V1.2 release of DECmcc, Digital * makes no claims that it will perform any particular function, will * perform a similar function with another release of DECmcc, that * DECmcc future versions will interoperate with this sample, or that * a similar sample will be made available in any future releases. * The user of the sample is responsible to modify and test it adequately * for any desired functions that they desire. * * Access to this sample in no way implies a limit to Digital's ownership * of the Data Collector AM, any DECmcc software component, or DECmcc * as a whole. Nor does access to this sample imply any current or * future rights to use DECmcc. All rights to use DECmcc and/or any * of its componenents are detailed in the various licenses of those * components and are in no way abrogated by access to this sample. * ******************************************************************************/ /*********************************************************************** * * MODULE NAME: mcc_evc_api_dna.c (VMS) * * FACILITY: * MCC -- Management Control Center * * ABSTRACT: * * DECmcc Event Collection AM (COLLECTION_AM) provides an application the * capability of sending its event and event arguments to a selected * DECmcc event sink. At the DECmcc, the event report can be presented * and consumed. The goal of COLLECITON_AM is to support open platforms * and open transport mechanisms. However, in V1.2, COLLECTION_AM only * supports VMS and ULTRIX platforms. It only support DECnet task-to-task * and DECmsgQ Bus transport protocol to deliver the events in V1.2. * * ENVIRONMENT: * VAX/VMS. * Using the "C" programming language. * No compilation assumptions. * No execution assumptions. * * AUTHOR: * J. L. * * CREATION DATE: * 1-sept-1991 * * MODIFICATION HISTORY: * * See CMS history for details... * T1.4.0 Sept-1994 F. Amrani Back porting from OSF to VMS/ULTRIX ************************************************************/ #include "da_include.h" #include #include #include #include #include #include #include #include "mcc_evc_api_def.h" /* internal routines */ #include "mcc_evc_api_dna.h" /************************************************************************* * * Routine: mcc_evc_dna_connect_accept * * Functional Description: * * This routine accepts as input the address of an I/O block, * the address of a descriptor pointing to the incoming NCB; * and, optionally, the address of a descriptor pointing to * from 1 to 16 bytes of optional data. If there is optional * data, the NCB is modified to include such. Finally a connect * accept is queued via mcc_qiow and the I/O block is updated. * * Pseudo-code: * * if necessary update NCB * issue connect accept mcc_qiow * update I/O block * return I/O block on the stack * completion status in R0 * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * iob modify MCC_R_DA_IOB reference I/O block * ncb read dsc_descriptor descriptor NCB * opt read dsc_descriptor descriptor optional connect * data * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * MCC_S_NORMAL - Successful normal completion * MCC_S_INV_NCB - Invalid Network Connect Block * Any status returned by: * STR$FIND_FIRST_IN_SET * STR$COPY_R * STR$CONCAT * mcc_qiow * * Side Effects: * none * **************************************************************/ MCC_T_CVR mcc_evc_dna_connect_accept (struct MCC_R_DA_IOB *iob, struct dsc_descriptor *ncb, struct dsc_descriptor *opt) { MCC_T_CVR rs = MCC_S_NORMAL ; MCC_T_Integer32 pos = 0; MCC_T_BYTE chr_cnt = 0; _DESCRIPTOR(slash,"/"); _DESCRIPTOR(dbl_quote,"\""); _DECL_DESC_S(count); _DECL_DESC_D(accept_ncb); pos = STR$FIND_FIRST_IN_SET(ncb, &slash); if (pos == 0) rs = MCC_S_INV_NCB; else { pos = pos + 2; rs = STR$COPY_R(&accept_ncb, &pos, ncb->dsc_a_pointer); if _ODD(rs) { if (opt != 0) { chr_cnt = opt->dsc_w_length; count.dsc_w_length = 1; count.dsc_a_pointer = &chr_cnt; rs = STR$CONCAT(&accept_ncb, &accept_ncb, &count, opt, &dbl_quote); } else rs = STR$CONCAT(&accept_ncb, &accept_ncb, &dbl_quote); if _ODD(rs) { iob->iob_l_stat = SYS$QIOW( 0, iob->iob_w_lnk, IO$_ACCESS, &(iob->iob_r_sb), 0,0,0, &accept_ncb, 0,0,0,0); rs = mcc_evc_dna_check_alert ( iob ); } } } if _ODD(rs) rs = MCC_S_NORMAL; return(rs); } /************************************************************************* * * Routine: mcc_evc_dna_connect_complete * * Functional Description: * * This routine accepts as input the address of a null I/O block * and the address of a null descriptor into which the received * NCB will be written. This null descriptor must be initialized * to length zero and be of type DSC_K_DTYPE_T and of class * DSC_K_CLASS_D or an error is returned. It then translates * the SYS$NET logical name obtaining the incoming NCB, establishes * a communications channel to DECnet, associates a mailbox with the * the communications channel, and updates the I/O block. * * Pseudo-code: * * translate SYS$NET * establish communications path * update ncb descriptor * update I/O block * return ncb & I/O block on the stack * completion status in R0 * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * iob write MCC_R_DA_IOB reference I/O block * ncb write dsc_descriptor descriptor NCB * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * MCC_S_NORMAL - Successful normal completion * MCC_S_INV_DESC - Invalid descriptor * Any status returned by: * LIB$ASN_WTH_MBX * SYS$TRNLNM * STR$COPY_R * * Side Effects: * none * ******************************************************************/ MCC_T_CVR mcc_evc_dna_connect_complete (struct MCC_R_DA_IOB *iob,struct dsc_descriptor *ncb) { struct ITEM_LIST_3 item_list; MCC_T_CHAR buf[MAX_TRNS_CHARS]; MCC_T_Unsigned16 buf_len = 0; MCC_T_CVR rs = MCC_S_NORMAL; _DESCRIPTOR(search_table,"LNM$FILE_DEV"); _DESCRIPTOR(SYS$net,"SYS$NET"); _DESCRIPTOR(dev_dscr,"_NET:"); if ((ncb->dsc_w_length == 0) && (ncb->dsc_b_dtype == DSC_K_DTYPE_T) && (ncb->dsc_b_class == DSC_K_CLASS_D)) { item_list.len = MAX_TRNS_CHARS; item_list.code = LNM$_STRING; item_list.addr = &buf; item_list.ret_len = &buf_len; item_list.eol = 0; rs = SYS$TRNLNM( &LNM$M_CASE_BLIND, &search_table, &SYS$net, 0, &item_list); if _ODD(rs) { rs = LIB$ASN_WTH_MBX( &dev_dscr, &MCC_K_DA_DEF_MBX_SIZ, &DEFAULT_MBX_BUF_QUOTA, &(iob->iob_w_lnk), &(iob->iob_w_mbx)); if _ODD(rs) { rs = STR$COPY_R( ncb, &buf_len, &buf); if _ODD(rs) { iob->iob_l_stat = MCC_S_NORMAL; iob->iob_r_sb.sb_w_return_code = MCC_S_NORMAL; iob->iob_r_sb.sb_w_bytes_xferd = 0; iob->iob_r_sb.sb_l_dev_info = 0; } } } } else rs = MCC_S_INV_DESC; if _ODD(rs) rs = MCC_S_NORMAL; return(rs); } /************************************************************************* * * Routine: mcc_evc_dna_declare_name * * Functional Description: * * This routine accepts as input the address of an I/O block * and the address of a descriptor pointing to the desired * network name (maximum of 12 characters). It creates the * I/O channel and associated mailbox, and then declares the * network name as provided. It is the responsibility of the * of the user to invoke the required mcc_evc_dna_read_mbx procedure * necessary for processing inbound connects. * * Pseudo-code: * * assign I/O channel * create mailbox * associate the channel with the mailbox * issue declare name request via mcc_qiow * update I/O block * return I/O block on the stack * completion status in R0 * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * nam read dsc_descriptor descriptor Network name * iob write MCC_R_DA_IOB reference I/O block * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * MCC_S_NORMAL - Successful normal completion * Any status returned by: * LIB$ASN_WTH_MBX * mcc_qiow * * Side Effects: * none * **************************************************************/ MCC_T_CVR mcc_evc_dna_declare_name (struct dsc_descriptor *nam,struct MCC_R_DA_IOB * iob) { MCC_T_CVR rs = MCC_S_NORMAL ; union NFB_BLOCK block; _DECL_DESC_S(nfb_dscr); _DESCRIPTOR(dev_dscr, "_NET:"); if ((nam->dsc_w_length < 1) | (nam->dsc_w_length > 12)) rs = MCC_S_INV_NETNAM; else { block.nfb.decl_opt = NFB$C_DECLNAME; block.nfb.obj = 0; nfb_dscr.dsc_w_length = DECLARE_BUF_SIZ; nfb_dscr.dsc_a_pointer = █ /* Assign channel to network */ /* and associate with a mbx. */ rs = LIB$ASN_WTH_MBX ( &dev_dscr, &MCC_K_DA_DEF_MBX_SIZ, &DEFAULT_MBX_BUF_QUOTA, &(iob->iob_w_lnk), &(iob->iob_w_mbx)); if _ODD(rs) { iob->iob_l_stat = SYS$QIOW( 0, iob->iob_w_lnk, IO$_ACPCONTROL, &(iob->iob_r_sb), 0,0,&nfb_dscr,nam, 0,0,0,0); rs = mcc_evc_dna_check_alert ( iob ); } } if _ODD(rs) rs = MCC_S_NORMAL; return(rs); } /************************************************************************* * * Routine: mcc_da_disconnect * * Functional Description: * * This routine uses DECnet task-to-task communication to disconnect the * logical link synchronously. It accepts as input the address of an * I/O block; and, optionally, the address of a descriptor pointing to * from 1 to 16 bytes of optional data. It then disconnects the logical link * as described in the I/O block and deassigns both the link and mailbox * channels. * * Pseudo-code: * * disconnect logical link * deassign link and mailbox channels * update I/O block * return I/O block on the stack * completion status in R0 * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * iob modify MCC_R_DA_IOB reference I/O block * opt read dsc_descriptor descriptor Optional data * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * MCC_S_NORMAL - Successful normal completion * MCC_S_OPTDATA_NOTSENT - Link disconnect completed successfully, * but optional data not sent * Any status returned by: * sys$qiow, SYS$DASSGN * * Side Effects: * none */ MCC_T_CVR mcc_da_disconnect (struct MCC_R_DA_IOB *iob) { /* local variable */ MCC_T_CVR rs = MCC_S_NORMAL; MCC_T_BYTE chr_cnt; _DECL_DESC_D(opt_data); _DECL_DESC_S(count); iob->iob_l_stat = SYS$QIOW (0, iob->iob_w_lnk, IO$_DEACCESS+IO$M_SYNCH, &(iob->iob_r_sb), 0,0,0,0,0,0,0,0); rs = mcc_evc_dna_check_alert ( iob ); SYS$DASSGN(iob->iob_w_lnk); SYS$DASSGN(iob->iob_w_mbx); iob->iob_w_lnk = 0; iob->iob_w_mbx = 0; return ( rs ); } /* END mcc_da_disconnect */ /************************************************************************* * * Routine: mcc_evc_dna_named_read * * * Functional Description: * * This routine accepts as input the address of a named I/O block, * and as output the address of an I/O block, the address of a * descriptor that points to the ncb, and, optionally, the address * of the mailbox message. It then issues an mcc_evc_dna_read_mbx * obtaining the incoming connect request, sets up for and calls * mcc_evc_dna_connect_complete, and returns the I/O block and NCB * specific to the requested connect. The user may then call * mcc_evc_dna_connect_accept or mcc_evc_dna_connect_reject. * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * named_iob read MCC_R_DA_IOB reference I/O block * iob write MCC_R_DA_IOB reference I/O block * ncb write dsc_descriptor descriptor NCB * mbxmsg write MCC_R_DA_MBMSG_BLK reference Mailbox msg * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * Any status returned by: * mcc_qiow * MCC_S_NORMAL for successful completion * Side Effects: * none * *************************************************************/ MCC_T_CVR mcc_evc_dna_named_read (struct MCC_R_DA_IOB *named_iob, struct MCC_R_DA_IOB *iob, struct dsc_descriptor *ncb, union MCC_R_DA_MBMSG_BLK *mbxmsg) { MCC_T_Integer32 rs = MCC_S_NORMAL; MCC_T_Unsigned16 buf_len = 0; union MCC_R_DA_MBMSG_BLK msg; struct ITEM_LIST_3 item_list; _DESCRIPTOR(tab_name,"LNM$PROCESS_TABLE"); _DESCRIPTOR(log_name,"SYS$NET"); rs = mcc_evc_dna_read_mbx(named_iob,&msg); /* this routine does check the iosb for alert term req */ if _ODD(rs) { if (mbxmsg != 0) LIB$MOVC3(&(sizeof(msg)),&msg,mbxmsg); switch(msg.blk_r_msg.msg_w_type) { case MSG$_CONNECT : /* incoming connect request */ { item_list.len = msg.blk_r_msg.msg_b_info_cnt; item_list.code = LNM$_STRING; item_list.addr = &(msg.blk_r_msg.msg_b_buf); item_list.ret_len = &buf_len; item_list.eol = 0; rs = SYS$CRELNM(0,&tab_name,&log_name,0,&item_list); if _ODD(rs) rs = mcc_evc_dna_connect_complete(iob,ncb); break; } case MSG$_ABORT : /* i/o request canceled by */ { named_iob->iob_l_stat = SS$_ABORT; rs = SS$_ABORT; break; } case MSG$_EXIT : /* link exited */ { named_iob->iob_l_stat = SS$_LINKEXIT; rs = SS$_LINKEXIT; break; } case MSG$_PATHLOST : /* connection path lost */ { named_iob->iob_l_stat = SS$_PATHLOST; rs = SS$_PATHLOST; break; } case MSG$_PROTOCOL : /* protocol error */ { named_iob->iob_l_stat = SS$_PROTOCOL; rs = SS$_PROTOCOL; break; } case MSG$_TIMEOUT : /* connection timed out */ { named_iob->iob_l_stat = SS$_CONNECFAIL; rs = SS$_CONNECFAIL; break; } case MSG$_THIRDPARTY : /* connection terminated by 3rd */ { named_iob->iob_l_stat = SS$_THIRDPARTY; rs = SS$_THIRDPARTY; break; } case MSG$_NETSHUT : /* local or remote node is no */ { named_iob->iob_l_stat = SS$_SHUT; rs = SS$_SHUT; break; } default : /* unknown message received */ { named_iob->iob_l_stat = MCC_S_UNKNOWN_MBXMSG; rs = MCC_S_UNKNOWN_MBXMSG; break; } } } if _ODD(rs) rs = MCC_S_NORMAL; return(rs); } /* END mcc_evc_dna_named_read */ /************************************************************************* * * Routine: mcc_evc_dna_read_mbx * * Functional Description: * * This routine accepts as input the address of an I/O block and * the address of a mailbox message block. It then issues an * mcc_qiow IO$_READVBLK to the mailbox described within the I/O * block. * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * iob modify MCC_R_DA_IOB reference I/O block * msg write MCC_R_DA_MBMSG_BLK reference Mbx msg * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * Any status returned by: * mcc_qiow * MCC_S_NORMAL for successful completion * Side Effects: * none * ****************************************************************/ MCC_T_CVR mcc_evc_dna_read_mbx (struct MCC_R_DA_IOB *iob, union MCC_R_DA_MBMSG_BLK * msg) { MCC_T_CVR rs; iob->iob_l_stat = SYS$QIOW( 0, iob->iob_w_mbx, IO$_READVBLK, &(iob->iob_r_sb), 0,0,msg, MCC_K_DA_DEF_MBX_SIZ, 0,0,0,0); rs = mcc_evc_dna_check_alert ( iob ); if _ODD(rs) rs = MCC_S_NORMAL; return(rs); } /* END mcc_evc_dna_read_mbx */ /************************************************************************* * * Routine: mcc_evc_dna_receive_msg * * * Functional Description: * * This routine accepts as input the address of an I/O block and * the address of a null descriptor into which the received * message will be written. It queues a synchronous read on the * link described in the I/O block; returns the received response * via the supplied "msg" descriptor; and updates the I/O block. * * Pseudo-code: * * allocate response buffer * issue read request mcc_qiow * update I/O block * return the I/O block on the stack * response descriptor on the stack * completion status in R0 * * Function Parameters: * * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * iob modify MCC_R_DA_IOB reference I/O block * msg write dsc_descriptor descriptor Response buffer * * Implicit Inputs: * none * * Implicit Outputs: * none * * Return Status: * MCC_S_NORMAL - Successful normal completion * Any status returned by: * mcc_qiow * MCC_S_NORMAL for successful completion * Side Effects: * none * */ MCC_T_CVR mcc_evc_dna_receive_msg (struct MCC_R_DA_IOB *iob,struct dsc_descriptor *msg) { MCC_T_CVR rs = MCC_S_NORMAL; /* jesuraj oct. 10, 89 */ iob->iob_l_stat = SYS$QIOW( 0, iob->iob_w_lnk, IO$_READVBLK, &(iob->iob_r_sb), 0,0,msg->dsc_a_pointer, msg->dsc_w_length, 0,0,0,0); rs = mcc_evc_dna_check_alert ( iob ); if _ODD(rs) rs = MCC_S_NORMAL; return(rs); } /* END mcc_da_receive_msg */ /************************************************************************ * * Routine: mcc_evc_dna_connect * * Description: * This routine requests a logical link to a remote task (Connect * Initiate) in a synchronized manner using DECnet task-to-task * communication. It allocates and initializes an I/O block and a * descriptor pointing to a Network Connect Block (ncb). It * establishes a non-transparent DECnet logical link with the * remote task specified within the NCB. It returns the address of * the I/O block, the logical link ID, the associated mailbox * ID, the QIO completion status, and the final I/O completion * status. * * Input: * * destination - address of a simple name structure containing * the destination where the event report is * delivered to * * Input/Output: * * p_mcc_assc_handle - a pointer to a handle that represents the * association or the connectivity information * based on the various protocols. * * Pseudo-code: * * build "_NET:" descriptor * assign I/O channel * create mailbox * associate the channel with the mailbox * issue Connect Initiate mcc_qiow * if mbxmsg argument present, read mailbox * update I/O block * return IO block * * Return Status: * * Successful normal completion * Any status returned by: * LIB$ASN_WTH_MBX * sys$qiow * * Side Effects: * none *******************************************************************************/ MCC_T_CVR mcc_evc_dna_connect (evc_t_cs *pI_destination, evc_t_handle *pO_mcc_assc_handle) { /* Local variables */ MCC_T_Integer32 mbx_size=0, buf_quota=0; MCC_T_CVR rs = MCC_S_NORMAL; MCC_T_Integer32 step=0; MCC_T_CHAR ncbbuf[NCB_MAXLEN]; /* NCB buffer */ MCC_T_CHAR mbxbuf[MBX_DEF_SIZE]; /* MBX buffer */ struct dsc_descriptor_s dsc_ncb, /* NCB descriptor */ dsc_mbx; /* mbx descriptor */ struct evc_dna_iob *p_dna_iob = MCC_K_NULL_PTR; /* DECnet access iob */ _DESCRIPTOR(dsc_devchn, "_NET:"); /* Build NET descriptor */ do switch(step ++) { case 0: /* initialize ncb, mbx descriptors */ memset(ncbbuf,NULL,NCB_MAXLEN); memset(mbxbuf,NULL,MBX_DEF_SIZE); dsc_ncb.dsc_b_dtype = DSC_K_DTYPE_T; dsc_ncb.dsc_b_class = DSC_K_CLASS_S; dsc_ncb.dsc_a_pointer = &ncbbuf[0]; dsc_ncb.dsc_w_length = NCB_MAXLEN; rs = mcc_evc_dna_build_ncb(pI_destination,&dsc_ncb); break; case 1: /* Allocate memory and initialize the iob and iosb */ p_dna_iob = mcc_calloc(1, sizeof(struct evc_dna_iob)); if (p_dna_iob != MCC_K_NULL_PTR) { p_dna_iob->p_iosb = mcc_calloc(1,sizeof(struct evc_dna_iosb)); if (p_dna_iob->p_iosb != MCC_K_NULL_PTR) { p_dna_iob->iob_w_devchn = 0; p_dna_iob->iob_w_mbxchn = 0; p_dna_iob->p_iosb->iosb_w_iostat = 1; p_dna_iob->p_iosb->iosb_w_bytcnt = 0; p_dna_iob->p_iosb->iosb_l_info = 0; } else rs = MCC_S_MEM_ALLOC_FAILED; /* temporary */ } else rs = MCC_S_MEM_ALLOC_FAILED; break; case 2: /* Assign channel to network device and associate it * with a mbx. */ mbx_size = buf_quota = MBX_DEF_SIZE; rs = LIB$ASN_WTH_MBX ( &dsc_devchn, &mbx_size, &buf_quota, &(p_dna_iob->iob_w_devchn), &(p_dna_iob->iob_w_mbxchn)); break; case 3: /* Request a link to a remote task */ rs = SYS$QIOW( 0, p_dna_iob->iob_w_devchn, IO$_ACCESS, p_dna_iob->p_iosb, 0,0,0, &dsc_ncb,0,0,0,0); if (_ODD(rs) && _EVEN(p_dna_iob->p_iosb->iosb_w_iostat)) rs = p_dna_iob->p_iosb->iosb_w_iostat; break; case 4: /* receive and read mailbox message */ dsc_mbx.dsc_b_dtype = DSC_K_DTYPE_T; dsc_mbx.dsc_b_class = DSC_K_CLASS_S; dsc_mbx.dsc_a_pointer = &mbxbuf; dsc_mbx.dsc_w_length = MBX_DEF_SIZE; rs = SYS$QIOW( 0, p_dna_iob->iob_w_mbxchn, IO$_READVBLK+IO$M_NOW, p_dna_iob->p_iosb, 0,0,&dsc_mbx, MBX_DEF_SIZE,0,0,0,0); if (_ODD(rs) && _EVEN(p_dna_iob->p_iosb->iosb_w_iostat)) rs = p_dna_iob->p_iosb->iosb_w_iostat; break; } while (_ODD(rs) && (step <= 4)); if (_EVEN(rs)) { /* If any channels were assigned, make sure to deassign! */ if ( p_dna_iob->iob_w_devchn != 0 ) SYS$DASSGN(p_dna_iob->iob_w_devchn); if ( p_dna_iob->iob_w_mbxchn != 0 ) SYS$DASSGN(p_dna_iob->iob_w_mbxchn); /* dealloc the iob and iosb */ if (p_dna_iob->p_iosb != MCC_K_NULL_PTR) mcc_free(p_dna_iob->p_iosb); if (p_dna_iob != MCC_K_NULL_PTR) mcc_free(p_dna_iob); pO_mcc_assc_handle->net_io.p_iob = MCC_K_NULL_PTR; /* null pointer */ } else { rs = MCC_S_NORMAL; pO_mcc_assc_handle->net_io.p_iob = (struct evc_dna_iob *)p_dna_iob; } return(rs); } /* end of mcc_evc_dna_connect */ /************************************************************************ * * Routine: mcc_evc_dna_build_ncb * * Description: * * This routine accepts as input the address of a descriptor pointing * to a node identifier string, the address of a decscriptor into * which the Network Connect Block (NCB)is to be written. * * It builds the Network Control Block in order to set up a logical * connection with a MCC event sink via DECnet. * * The following information is supplied in a connection request: * * "user password account":: * | --------------------- | | * target entity | task with which for the target * | to communicate task (up to 16 * | bytes) * access control info (optional) * (not required in V1.2) * * The string destination contains the DECmcc destination it tries to * connect to. * * Specific to this example are the task specification and optional * data. * * Formal Arugments * * * p_dsc_ncbbuf Network Control Block buffer * Type: dsc_descriptor_s * * p_destination string * Type: Latin1String * * Condition values returned: * MCC_S_NORMAL * MCC_K_CANNOT_COMPLETE * ***********************************************************************/ MCC_T_CVR mcc_evc_dna_build_ncb (evc_t_cs *pI_destination, struct dsc_descriptor_s *pO_dsc_ncb) { MCC_T_CHAR task_spec[] = "::\"TASK=MCC_EVC_SINK\"", *ptr = MCC_K_NULL_PTR; MCC_T_Unsigned32 rs = MCC_S_NORMAL; /* return status code */ /* Create a NCB in this form : * ::"TASK=MCC_EVC_SINK/opt_msg" */ ptr = pO_dsc_ncb->dsc_a_pointer; strncpy(ptr,pI_destination->cs_string,pI_destination->cs_count); ptr += pI_destination->cs_count; strcpy(ptr,task_spec); ptr += strlen(task_spec); pO_dsc_ncb -> dsc_w_length = pI_destination->cs_count + strlen(task_spec); return(rs); } /* END mcc_evc_dna_build_ncb */ /****************************************************************** * * Routine: mcc_evc_dna_send_msg * * Description: * * This routine use the network and mailbox channel that's saved in the * I/O block to send the already formatted event report to the destination. * It returns updated qio status, the link status, and the final I/O status. * * Input: * * p_event_rpt - a fixed formatted event report * * In/Output: * * p_mcc_assc_handle - a pointer to a handle that represents the * association or the connectivity information * based on the various protocols. * * Pseudo-code: * * send the message via qiow * update I/O block * return the I/O block on the stack * completion status in R0 * * Return Status: * * Successful normal completion * Any status returned by: * sys$qiow * * Side Effects: * none * *****************************************************************************/ MCC_T_CVR mcc_evc_dna_send_msg (struct dsc_descriptor *pI_dsc_msg, evc_t_handle *pI_mcc_assc_handle) { MCC_T_Unsigned32 rs= MCC_S_NORMAL; struct evc_dna_iob *p_dna_iob = MCC_K_NULL_PTR ; p_dna_iob = (struct evc_dna_iob *)pI_mcc_assc_handle->net_io.p_iob; rs = SYS$QIOW( 0, p_dna_iob->iob_w_devchn, IO$_WRITEVBLK, p_dna_iob->p_iosb, 0,0, pI_dsc_msg->dsc_a_pointer, pI_dsc_msg->dsc_w_length, 0,0,0,0); if (_ODD(rs)) { if (_EVEN(p_dna_iob->p_iosb->iosb_w_iostat)) rs = p_dna_iob->p_iosb->iosb_w_iostat; else rs = MCC_S_NORMAL; } return(rs); } /* end of mcc_evc_dna_send_msg */ /************************************************************************* * * Routine: mcc_evc_dna_check_alert * * Functional Description: * * This routine accepts as input the address of an I/O block. * It check for an i/o status of ss$_abort if this is found then * an mcc_thread_test_alert call is made if the return status * from this call is true then set the return status to mcc_s_alert_termreq... * If the i/o status is not ss$_abort it then checks for an i/o * return code of ss$_abort or ss$_cancel if either is found then * an mcc_thread_test_alert call is made if the return status from * this call is true then set the return status to mcc_s_alert_termreq... * *************************************************************************** * * -- algorithm in pseudo code -- * * if the i/o status is equal to ss$_abort * then * test for alert * if true * then * set the return status to mcc_s_alert_termreq * * else if the i/o status is odd and the i/o return code is even * then * if the i/o return code is ss$_abort or ss$_cancel or ss$_linkabort * then * test for alert * if true * then * set the return status to mcc_s_alert_termreq * else * set the return status to the i/o status * *************************************************************************** * Formal Parameters: * Parameter Access Type Mechanism Description * --------- ------ ---- --------- ----------- * pI_iob read MCC_R_DA_IOB reference I/O block * * Implicit Inputs: * * None. * * Implicit Outputs: * * None. * * Routine Value: * * rs ( return status ) - network status * rs ( return status ) - network errors * * Side Effects: * * none ******************************************************************/ MCC_T_CVR mcc_evc_dna_check_alert (struct MCC_R_DA_IOB *pI_iob ) { MCC_T_CVR rs = MCC_S_NORMAL; #ifndef NOT_MCC /* --------------------------------------------------------------- */ /* check the i/o status for ss$_abort */ /* --------------------------------------------------------------- */ if (( pI_iob->iob_l_stat == SS$_ABORT ) || ( pI_iob->iob_l_stat == SS$_CANCEL ) || ( pI_iob->iob_l_stat == SS$_LINKABORT ) ) { if ( mcc_thread_test_alert() ) { rs = MCC_S_ALERT_TERMREQ; } } /* --------------------------------------------------------------- */ /* check odd i/o status and even i/o return code */ /* --------------------------------------------------------------- */ else if ( _ODD ( pI_iob->iob_l_stat ) && _EVEN ( pI_iob->iob_r_sb.sb_w_return_code ) ) { if ( ( pI_iob->iob_r_sb.sb_w_return_code == SS$_ABORT ) || ( pI_iob->iob_r_sb.sb_w_return_code == SS$_CANCEL ) || ( pI_iob->iob_r_sb.sb_w_return_code == SS$_LINKABORT ) ) { if ( mcc_thread_test_alert() ) { rs = MCC_S_ALERT_TERMREQ; } } rs = pI_iob->iob_r_sb.sb_w_return_code; } else { rs = pI_iob->iob_l_stat; } /* --------------------------------------------------------------- */ /* done */ /* --------------------------------------------------------------- */ if ( _ODD( rs ) ) rs = MCC_S_NORMAL; return ( rs ); #endif } /* Routine: mcc_evc_dna_disconnect (mcc_evc_dna_disconnect_unix) Functional Description: This routine uses DECnet task-to-task communication to disconnect the logical link synchronously. It accepts as input the address of an I/O block; and, optionally, the address of a descriptor pointing to from 1 to 16 bytes of optional data. It then disconnects the logical link as described in the I/O block and deassigns both the link and mailbox channels. Pseudo-code: disconnect logical link deassign link and mailbox channels update I/O block return I/O block on the stack completion status in R0 Function Parameters: Parameter Access Type Mechanism Description --------- ------ ---- --------- ----------- iob modify MCC_R_DA_IOB reference I/O block opt read dsc_descriptor descriptor Optional data Implicit Inputs: none Implicit Outputs: none Return Status: MCC_S_NORMAL - Successful normal completion MCC_S_OPTDATA_NOTSENT - Link disconnect completed successfully, but optional data not sent Any status returned by: sys$qiow, SYS$DASSGN Side Effects: none */ MCC_T_CVR mcc_evc_dna_disconnect (evc_t_handle *pIO_mcc_assc_handle) { /* local variable */ struct evc_dna_iob *p_dna_iob; MCC_T_CVR rs = MCC_S_NORMAL; p_dna_iob = pIO_mcc_assc_handle->net_io.p_iob; rs = SYS$QIOW ( 0, p_dna_iob->iob_w_devchn, IO$_DEACCESS+IO$M_SYNCH, p_dna_iob->p_iosb, 0,0,0,0,0,0,0,0); if (_ODD(rs)) { if (_EVEN(p_dna_iob->p_iosb->iosb_w_iostat)) rs = p_dna_iob->p_iosb->iosb_w_iostat; else rs = MCC_S_NORMAL; } /* deassign the channel */ SYS$DASSGN(p_dna_iob->iob_w_devchn); SYS$DASSGN(p_dna_iob->iob_w_mbxchn); p_dna_iob->iob_w_devchn = 0; p_dna_iob->iob_w_mbxchn = 0; /* dealloc the iob and iosb */ if (p_dna_iob->p_iosb != NULL) free(p_dna_iob->p_iosb); if (p_dna_iob != NULL) free(p_dna_iob); pIO_mcc_assc_handle->net_io.p_iob = NULL; /* null pointer */ return (rs); } /* END mcc_evc_dna_disconnect */