📄 psapunitdata.c
字号:
/* **************************************************************** * * * ISODECL - HULA project for connectionless ISODE * * * * module: psapunitdata.c * * author: Bill Haggerty * * date: 4/89 * * * * This code implements the P-UNIT-DATA service. * * * * entry points: * * * * PUnitDataRequest (calling, called, ctxlist, * * data, ndata, qos, pi) * * PUnitDataBind ( sd, calling, called, ctxlist, qos, pi) * * PUnitDataRebind ( sd, called, pi ) * * PUnitDataWrite ( sd, data, ndata, pi ) * * PUnitDataRead ( sd, ps, secs, pi ) * * PUnitDataUnbind ( sd, pi ) * * PuSave ( sd, vecp, vec, pi ) * * * * internal routines: * * * * addrs2block ( callingaddr, calledaddr, pb, pi ) * * contexts2block ( contexts, nctx, pb, pi ) * * contexts2pdu ( pb, pdu ) * * pdu2contexts ( pb, ctxdeflist, ctxlist ) * * * **************************************************************** * * * NOTICE * * * * Use of this module is subject to the restrictions of the * * ISODE license agreement. * * * **************************************************************** *//* HULA P-UNIT-DATA Service *//* psapunitdata.c - PPM: initiator and responder *//* stolen from psapinitiate.c in ISODE's /psap2 library *//* LINTLIBRARY */#include <stdio.h>#include <varargs.h>#include <signal.h>#include "PS-types.h"#include "pupkt.h"#include "isoservent.h"#include "tailor.h"/*---------------------------------------------------------------------------*//* ^L P-UNIT-DATA.REQUEST *//* opens and closes a socket for each request *//*---------------------------------------------------------------------------*/int PUnitDataRequest (calling, called, ctxlist, data, ndata, qos, pi)/*---------------------------------------------------------------------------*/struct PSAPaddr *calling, *called;struct PSAPctxlist *ctxlist;int ndata;PE *data;struct QOStype *qos;struct PSAPindication *pi;{ SBV smask; int result; int i, len; PE pe; register struct psapblk *pb; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; register struct type_PS_UD__type *pdu; register struct type_PS_User__data *info; isodetailor ("pusap2");#ifdef notdef missingP (calling);#endif missingP (called); if (ctxlist && ctxlist -> pc_nctx > NPCTX) return pusaplose (pi, PC_PARAMETER, NULLCP, "only %d presentation contexts supported", NPCTX);/* let session provider catch errors in session parameters: qos */ toomuchP (data, ndata, NPDATA, "initial"); missingP (pi); smask = sigioblock (); if ((pb = newpublk ()) == NULLPB) { (void) sigiomask (smask); return pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); } if (called -> pa_selectlen > 0) { if (calling == NULLPA) { static struct PSAPaddr pas; calling = &pas; bzero ((char *) calling, sizeof *calling); } if (calling -> pa_selectlen == 0) { calling -> pa_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff))); calling -> pa_selectlen = sizeof calling -> pa_port; } }/* Start building ppdu */ pe = NULLPE; if ((pdu = (struct type_PS_UD__type *) calloc (1, sizeof *pdu)) == NULL) goto no_mem; if (calling && calling -> pa_selectlen > 0 && (pdu -> calling = str2qb (calling -> pa_selector, calling -> pa_selectlen, 1)) == NULL) goto no_mem; if (called -> pa_selectlen > 0 && (pdu -> called = str2qb (called -> pa_selector, called -> pa_selectlen, 1)) == NULL) goto no_mem;/* Ignore this comment for initial testing !!!! *//* We do need to specify a "default" context for code that exists *//* ? Since there is no default context carried in the ppdu we skip the *//* following validation of ASN.1/BER for the default context */ if ((pb -> pb_asn = ode2oid (DFLT_ASN)) == NULLOID) { (void) pusaplose (pi, PC_ABSTRACT, NULLCP, "%s: unknown", DFLT_ASN); goto no_good; } if ((pb -> pb_asn = oid_cpy (pb -> pb_asn)) == NULLOID) { pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); goto no_good; } if ((pb -> pb_atn = ode2oid (DFLT_ATN)) == NULLOID) { (void) pusaplose (pi, PC_TRANSFER, NULLCP, "%s: unknown", DFLT_ATN); goto no_good; } if ((pb -> pb_atn = oid_cpy (pb -> pb_atn)) == NULLOID) { pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); goto no_good; } if (ctxlist && ctxlist -> pc_nctx > 0) { if ( contexts2block ( ctxlist -> pc_ctx, ctxlist -> pc_nctx, pb, pi ) == NOTOK ) goto no_good; if ( contexts2pdu ( pb, pdu ) == NOTOK ) goto no_mem; } if (data && ndata > 0 && (pdu -> user__data = info2_ppdu (pb, pi, data, ndata, PPDU_UD)) == NULL) goto no_good; pe = NULLPE; if (encode_PS_UD__type (&pe, 1, 0, NULLCP, pdu) == NOTOK) { (void) pusaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s", PY_pepy); goto no_good; } #ifdef DEBUG if (psap2level & ISODELOG_PDUS) PS_print (pe, "UD-type", 0, print_PS_UD__type);#endif if (pe2ssdu (pe, &pb -> pb_retry, &len) == NOTOK) goto no_mem; free_PS_UD__type (pdu); pdu = NULL; pe_free (pe); pe = NULLPE; if ( (result = SUnitDataRequest ( calling ? &calling -> pa_addr : NULLSA, &called -> pa_addr, pb -> pb_retry, len, qos, si)) == NOTOK) { (void) ss2pulose (NULLPB, pi, "SUnitDataRequest", sa); } goto out;no_mem: ; (void) pusaplose (pi, PC_CONGEST, NULLCP, "out of memory");no_good: ; result = NOTOK; if (pe) pe_free (pe); if (pdu) free_PS_UD__type (pdu);out: ; if ( pb -> pb_retry ) free ( pb -> pb_retry ); /* ??? */ freepublk (pb); (void) sigiomask (smask); return result;}/*---------------------------------------------------------------------------*//* ^L BIND ... for P-UNIT-DATA.REQUEST and P-UNIT-DATA.INDICATION *//* opens a socket for later, multiple reads and writes *//*---------------------------------------------------------------------------*/int PUnitDataBind ( sd, calling, called, ctxlist, qos, pi)/*---------------------------------------------------------------------------*/int sd;struct PSAPaddr *calling, *called;struct PSAPctxlist *ctxlist;struct QOStype *qos;struct PSAPindication *pi;{ SBV smask; int result; int i, len; PE pe; register struct psapblk *pb; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; register struct type_PS_UD__type *pdu; register struct type_PS_User__data *info; isodetailor ("pusap2"); if ( calling == NULLPA && called == NULLPA ) return pusaplose (pi, PC_PARAMETER, NULLCP, "either calling or called address must be present"); if (ctxlist && ctxlist -> pc_nctx > NPCTX) return pusaplose (pi, PC_PARAMETER, NULLCP, "only %d presentation contexts supported", NPCTX);/* let session provider catch errors in session parameters: qos */ smask = sigioblock (); if (called && called -> pa_selectlen > 0) { if (calling == NULLPA) { static struct PSAPaddr pas; calling = &pas; bzero ((char *) calling, sizeof *calling); } if (calling -> pa_selectlen == 0) { calling -> pa_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff))); calling -> pa_selectlen = sizeof calling -> pa_port; } } if ( sd == NOTOK ) { if ((pb = newpublk ()) == NULLPB) { (void) sigiomask (smask); return pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); } } else if ((pb = findpublk (sd)) == NULLPB || !(pb -> pb_flags & PB_PUDT)) { (void) sigiomask (smask); return pusaplose (pi, PC_PARAMETER, NULLCP, "invalid presentation descriptor"); } if ( addrs2block ( calling, called, pb, pi ) == NOTOK ) goto no_good;/* Ignore this comment for initial testing !!!! *//* We do need to specify a "default" context for code that exists *//* ? Since there is no default context carried in the ppdu we skip the *//* following validation of ASN.1/BER for the default context */ if ((pb -> pb_asn = ode2oid (DFLT_ASN)) == NULLOID) { (void) pusaplose (pi, PC_ABSTRACT, NULLCP, "%s: unknown", DFLT_ASN); goto no_good; } if ((pb -> pb_asn = oid_cpy (pb -> pb_asn)) == NULLOID) { pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); goto no_good; } if ((pb -> pb_atn = ode2oid (DFLT_ATN)) == NULLOID) { (void) pusaplose (pi, PC_TRANSFER, NULLCP, "%s: unknown", DFLT_ATN); goto no_good; } if ((pb -> pb_atn = oid_cpy (pb -> pb_atn)) == NULLOID) { pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); goto no_good; } if (ctxlist && ctxlist -> pc_nctx > 0) if ( contexts2block ( ctxlist -> pc_ctx, ctxlist -> pc_nctx, pb, pi ) == NOTOK ) goto no_good; if ( (result = SUnitDataBind ( pb -> pb_fd, &calling -> pa_addr, called ? &called -> pa_addr : NULLSA, qos, si )) == NOTOK) { (void) ss2pulose (NULLPB, pi, "SUnitDataBind", sa); goto no_good; } pb -> pb_fd = result; pb -> pb_flags |= PB_PUDT; (void) sigiomask (smask); return result;no_good: ; freepublk (pb); (void) sigiomask (smask); return NOTOK;}/*---------------------------------------------------------------------------*//* ^L ReBIND ... resets called address on binding *//*---------------------------------------------------------------------------*/int PUnitDataRebind ( sd, called, pi)/*---------------------------------------------------------------------------*/int sd;struct PSAPaddr *called;struct PSAPindication *pi;{ SBV smask; int result; register struct psapblk *pb; register struct PSAPaddr *calling; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; missingP (called); missingP (pi); smask = sigioblock (); if ((pb = findpublk (sd)) == NULLPB || !(pb -> pb_flags & PB_PUDT)) { (void) sigiomask (smask); return pusaplose (pi, PC_PARAMETER, NULLCP, "invalid presentation descriptor"); } calling = pb->pb_calling; if (called -> pa_selectlen > 0) { if (calling == NULLPA) { static struct PSAPaddr pas; calling = &pas; bzero ((char *) calling, sizeof *calling); } if (calling -> pa_selectlen == 0) { calling -> pa_port = htons ((u_short) (0x8000 | (getpid () & 0x7fff))); calling -> pa_selectlen = sizeof calling -> pa_port; } } if ( addrs2block ( calling, called, pb, pi ) == NOTOK ) { (void) sigiomask (smask); return NOTOK; } if ( SUnitDataBind ( pb -> pb_fd, &calling -> pa_addr, &called -> pa_addr, NULL, si ) == NOTOK) { (void) ss2pulose (NULLPB, pi, "SUnitDataBind", sa); freepublk (pb); (void) sigiomask (smask); return NOTOK; } (void) sigiomask (smask); return OK;}/*---------------------------------------------------------------------------*//* send P-UNIT-DATA.REQUEST over locally bound association *//* socket must have been previously bound by PUnitDataBind() *//*---------------------------------------------------------------------------*/int PUnitDataWrite ( sd, data, ndata, pi )/*---------------------------------------------------------------------------*/int sd;int ndata;PE *data;struct PSAPindication *pi;{ SBV smask; int result; int i, len; PE pe; register struct psapblk *pb; struct SSAPindication sis; register struct SSAPindication *si = &sis; register struct SSAPabort *sa = &si -> si_abort; register struct type_PS_UD__type *pdu; register struct type_PS_User__data *info; register struct PSAPaddr *calling; register struct PSAPaddr *called; missingP (data); toomuchP (data, ndata, NPDATA, "user"); if (ndata <= 0) return pusaplose (pi, PC_PARAMETER, NULLCP, "illegal number of PSDUs (%d)", ndata); missingP (pi); smask = sigioblock (); if ((pb = findpublk (sd)) == NULLPB || !(pb -> pb_flags & PB_PUDT)) { (void) sigiomask (smask); return pusaplose (pi, PC_PARAMETER, NULLCP, "invalid presentation descriptor"); }/* Start building ppdu */ pe = NULLPE; if ((pdu = (struct type_PS_UD__type *) calloc (1, sizeof *pdu)) == NULL) goto no_mem; if ( (calling = pb -> pb_calling) && calling -> pa_selectlen > 0 && (pdu -> calling = str2qb (calling -> pa_selector, calling -> pa_selectlen, 1)) == NULL) goto no_mem; if ( (called = pb -> pb_called) && called -> pa_selectlen > 0 && (pdu -> called = str2qb (called -> pa_selector, called -> pa_selectlen, 1)) == NULL) goto no_mem;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -