📄 acsapunitdat.c
字号:
/* **************************************************************** * * * HULA project - connectionless ISODE * * * * module: acsapunitdat.c * * author: Bill Haggerty * * date: 4/89 * * * * This code implements ACSE for the A-UNIT-DATA service. * * * * entry points: * * * * AcUnitDataRequest ( context, callingtitle, calledtitle, * * callingaddr, calledaddr, ctxlist, * * data, ndata, qos, aci ) * * AcUnitDataBind ( sd, binding, context, callingtitle, * * calledtitle, callingaddr, calledaddr, * * ctxlist, qos, aci ) * * AcUnitDataRebind ( sd, calledtitle, calledaddr, aci ) * * AcUnitDataWrite ( sd, data, ndata, aci ) * * AcUnitDataRead ( sd, acs, secs, aci ) * * AcUnitDataUnbind (sd, aci) * * AcuSave (sd, vecp, vec, aci) * * * * internal routines: * * * * titles2block ( callingtitle, calledtitle, acb, aci ) * * titles2pdu ( callingtitle, calledtitle, pdu ) * * ctx2block ( ctxlist, acb, ppcx, aci ) * * validaudtctx ( ctx, acb, ps, aci ) * * pdu2start ( pdu, acs ) * * * **************************************************************** * * * NOTICE * * * * Use of this module is subject to the restrictions of the * * ISODE license agreement. * * * **************************************************************** *//* modified from ISODE's acsapinitiat.c and acsaprespond.c *//* acsapinitiat.c - ACPM: initiator */#ifndef lintstatic char *rcsid = "$Header: /f/iso/acsap/RCS/acsapinitiat.c,v 5.0 88/07/21 14:21:35 mrose Rel $";#endif/* LINTLIBRARY */#include <stdio.h>#include <signal.h>#include "ACS-types.h"#define ACSE#include "acupkt.h"#include "acusap.h"#include "isoservent.h"#include "tailor.h"#define BER "asn.1 basic encoding"#define NULLACC ((struct AcSAPconnect *)0)/*---------------------------------------------------------------------------*//* A-UNIT-DATA.REQUEST *//* opens and closes a socket for each request *//*---------------------------------------------------------------------------*/int AcUnitDataRequest ( context, callingtitle, calledtitle, callingaddr, calledaddr, ctxlist, data, ndata, qos, aci )/*---------------------------------------------------------------------------*/OID context;AEI callingtitle, calledtitle;struct PSAPaddr *callingaddr, *calledaddr;struct PSAPctxlist *ctxlist;PE *data;int ndata;struct QOStype *qos;struct AcSAPindication *aci;{ SBV smask; int result; PE pe; register struct assocblk *acb; struct PSAPcontext *pp; struct PSAPindication pis; register struct PSAPindication *pi = &pis; register struct PSAPabort *pa = &pi -> pi_abort; register struct type_ACS_AUDT__apdu *pdu; isodetailor ("acsap"); missingP (context);#ifdef notdef missingP (callingtitle); missingP (calledtitle);#endif missingP (data); toomuchP (data, ndata, NACDATA, "user"); if ( ndata <= 0 ) (void) acusaplose (aci, ACS_PARAMETER, NULLCP, "illegal number of ASDUs (%d)", ndata ); missingP (aci); smask = sigioblock (); if ((acb = newacublk ()) == NULL) { (void) sigiomask (smask); return acusaplose (aci, ACS_CONGEST, NULLCP, "out of memory"); } pe = NULLPE; if ((pdu = (struct type_ACS_AUDT__apdu *) calloc (1, sizeof *pdu)) == NULL) { acusaplose (aci, ACS_CONGEST, NULLCP, "out of memory"); goto no_good; } pdu -> application__context__name = context; (void) titles2pdu ( callingtitle, calledtitle, pdu );/* Unfortunately info2_apdu() below only does fully encoded data *//* Will change to allow simple encoding later */ if (data && ndata > 0 && (pdu -> user__information = info2_apdu (acb, aci, data, ndata)) == NULL) goto no_good; if ( encode_ACS_AUDT__apdu (&pe, 1, 0, NULLCP, pdu) == NOTOK ) { (void) acusaplose (aci, ACS_CONGEST, NULLCP, "error encoding PDU: %s", PY_pepy); goto no_good; } pp = NULLPC; if ( ctx2block (ctxlist, acb, &pp, aci) == NOTOK ) /* set AUDT p-context */ goto no_good; pe -> pe_context = acb -> acb_id; #ifdef DEBUG if (acsaplevel & ISODELOG_PDUS) ACU_print (pe, "AUDT-apdu", 0);#endif result = PUnitDataRequest (callingaddr, calledaddr, ctxlist, &pe, 1, qos, pi); if (pp) { /* created an AUDT context for PUnitDataRequest, so free it */ ctxlist -> pc_nctx--; pp -> pc_id = 0; oid_free (pp -> pc_asn); if (pp -> pc_atn) oid_free (pp -> pc_atn); pp -> pc_asn = pp -> pc_atn = NULLOID; } if ( result == NOTOK) { (void) ps2aculose (NULLACB, aci, "PUnitDataRequest", pa); goto no_good; } goto out;no_good: ; result = NOTOK;out: ; if (pdu) { if (pdu -> user__information) free_ACS_Association__information (pdu -> user__information); free ((char *) pdu); } if (pe) pe_free (pe); freeacublk (acb); (void) sigiomask (smask); return result;}/*---------------------------------------------------------------------------*//* set a local binding for AcUnitDataWrite() and AcUnitDataRead() */ /* a socket is created and bound if sd is NOTOK on input *//*---------------------------------------------------------------------------*/int AcUnitDataBind ( sd, binding, context, callingtitle, calledtitle, callingaddr, calledaddr, ctxlist, qos, aci )/*---------------------------------------------------------------------------*/int sd;int binding;OID context;AEI callingtitle, calledtitle;struct PSAPaddr *callingaddr, *calledaddr;struct PSAPctxlist *ctxlist;struct QOStype *qos;struct AcSAPindication *aci;{ SBV smask; int result; register int i; register struct assocblk *acb; struct PSAPcontext *pp; struct PSAPindication pis; register struct PSAPindication *pi = &pis; register struct PSAPabort *pa = &pi -> pi_abort; isodetailor ("acsap"); missingP (context); missingP (aci);/* binding is static by default *//* but if dynamic calledaddr and calledtitle may be reset, AcUnitDataRebind */ if ( binding == BIND_DYNAMIC ) { missingP (callingaddr); } else { missingP (calledaddr); } smask = sigioblock ();/* Bind remembers the input parameters, not the processed AUDT PE *//* necessary to unhook the AUDT PE from user space. */ if ( sd == NOTOK ) { if ((acb = newacublk ()) == NULL) { (void) sigiomask (smask); return acusaplose (aci, ACS_CONGEST, NULLCP, "out of memory"); } acb -> acb_fd = sd; } else { if ((acb = findacublk (sd)) == NULL || !(acb -> acb_flags & ACB_AUDT)) { (void) sigiomask (smask); return acusaplose (aci, ACS_PARAMETER, NULLCP, "invalid association descriptor"); } } acb -> acb_binding = ((binding == BIND_DYNAMIC) ? binding : BIND_STATIC); if ((acb -> acb_context = oid_cpy (context)) == NULLOID) { (void) acusaplose (aci, ACS_CONGEST, NULLCP, NULLCP); goto no_good; } if ( titles2block ( callingtitle, calledtitle, acb, aci ) == NOTOK ) goto no_good; { pp = NULLPC; if ( ctx2block ( ctxlist, acb, &pp, aci ) == NOTOK ) goto no_good; result = PUnitDataBind ( acb -> acb_fd, callingaddr, calledaddr, ctxlist, qos, pi ); if (pp) { /* free part of created AUDT context */ ctxlist -> pc_nctx--; pp -> pc_id = 0; if (pp -> pc_atn) oid_free (pp -> pc_atn); pp -> pc_asn = pp -> pc_atn = NULLOID; } } if ( result == NOTOK ) { (void) ps2aculose (NULLACB, aci, "PUnitDataBind", pa); goto no_good; } acb -> acb_fd = result;/* acb -> acb_uabort = PUnitDataUnbind; ? *//* set flags - for connectionless both sides of binding "association" *//* should be able to initiate operations */ acb -> acb_flags |= ACB_AUDT; acb -> acb_flags |= ACB_ACS; /* may be necessary to fake out rosap */ acb -> acb_flags |= ACB_INIT; /* may be necessary to fake out rosap */ (void) sigiomask (smask); return result;no_good: ; freeacublk (acb); (void) sigiomask (smask); return NOTOK;}/*---------------------------------------------------------------------------*//* reset a local binding for new called addr and called title */ /*---------------------------------------------------------------------------*/int AcUnitDataRebind ( sd, calledtitle, calledaddr, aci )/*---------------------------------------------------------------------------*/int sd;AEI calledtitle;struct PSAPaddr *calledaddr;struct AcSAPindication *aci;{ SBV smask; int result; register struct assocblk *acb; struct PSAPindication pis; register struct PSAPindication *pi = &pis; register struct PSAPabort *pa = &pi -> pi_abort; missingP (calledaddr); missingP (aci); smask = sigioblock (); if ((acb = findacublk (sd)) == NULL || !(acb -> acb_flags & ACB_AUDT)) { acusaplose (aci, ACS_PARAMETER, NULLCP, "invalid association descriptor"); goto no_good; } if ( acb -> acb_binding != BIND_DYNAMIC ) { acusaplose (aci, ACS_PARAMETER, NULLCP,"association cannot be rebound"); goto no_good; }/* free any old called title */ if ( acb -> acb_calledtitle ) { AEIFREE ( acb -> acb_calledtitle ); free ( acb -> acb_callingtitle ); } if ( titles2block ( acb -> acb_callingtitle, calledtitle, acb, aci ) == NOTOK ) goto no_good; if ( PUnitDataRebind ( acb -> acb_fd, calledaddr, pi) == NOTOK ) { (void) ps2aculose (NULLACB, aci, "PUnitDataRebind", pa); goto no_good; } (void) sigiomask (smask); return OK;no_good: ; (void) sigiomask (smask); return NOTOK;}/*---------------------------------------------------------------------------*//* set off A-UNIT-DATA.REQUEST over locally bound association *//* socket must have been previously bound by AcUnitDataBind() *//*---------------------------------------------------------------------------*/int AcUnitDataWrite ( sd, data, ndata, aci )/*---------------------------------------------------------------------------*/int sd;int ndata;PE *data;struct AcSAPindication *aci;{ SBV smask; int result; register int i; PE pe; register struct assocblk *acb; register struct PSAPcontext *pp; struct PSAPindication pis; register struct PSAPindication *pi = &pis; register struct PSAPabort *pa = &pi -> pi_abort; register struct type_ACS_AUDT__apdu *pdu; missingP (data); toomuchP (data, ndata, NACDATA, "user"); if ( ndata <= 0 ) (void) acusaplose (aci, ACS_PARAMETER, NULLCP, "illegal number of ASDUs (%d)", ndata ); missingP (aci); smask = sigioblock (); if ((acb = findacublk (sd)) == NULL || !(acb -> acb_flags & ACB_AUDT)) { (void) sigiomask (smask); return acusaplose (aci, ACS_PARAMETER, NULLCP, "invalid association descriptor"); } if ((pdu = (struct type_ACS_AUDT__apdu *) calloc (1, sizeof *pdu)) == NULL) { acusaplose (aci, ACS_CONGEST, NULLCP, "out of memory"); goto no_good; } pdu -> application__context__name = acb -> acb_context; (void) titles2pdu ( acb -> acb_callingtitle, acb -> acb_calledtitle, pdu );/* Unfortunately info2_apdu() below only does fully encoded data *//* Will change to allow simple encoding later */ if ((pdu -> user__information = info2_apdu (acb, aci, data, ndata)) == NULL) goto no_good; pe = NULLPE; if ( encode_ACS_AUDT__apdu (&pe, 1, 0, NULLCP, pdu) == NOTOK ) { (void) acusaplose (aci, ACS_CONGEST, NULLCP, "error encoding PDU: %s", PY_pepy); goto no_good; } pe -> pe_context = acb -> acb_id; if ( (result = PUnitDataWrite ( sd, &pe, 1, pi )) == NOTOK ) (void) ps2aculose (NULLACB, aci, "PUnitDataWrite", pa); goto out;no_good: ; result = NOTOK;/* ? should we distinguish fatal vs nonfatal reasons ? PUnitDataUnbind ( sd, pi ); freeacublk (acb);*/out: ; if (pdu) { if (pdu -> user__information) free_ACS_Association__information (pdu -> user__information); free ((char *) pdu); } if (pe) pe_free (pe); (void) sigiomask (smask); return result;}/*---------------------------------------------------------------------------*//* implements A-UNIT-DATA.INDICATION on locally bound association *//* socket must have been previously bound by AcUnitDataBind() which *//* bound both the application context and all valid p-contexts *//*---------------------------------------------------------------------------*/int AcUnitDataRead ( sd, acs, secs, aci )/*---------------------------------------------------------------------------*/int sd;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -