📄 psaputils.c
字号:
/* **************************************************************** * * * ISODECL - HULA project for connectionless ISODE * * * * module: psaputils.c * * author: Bill Haggerty * * date: 4/89 * * * * This code implements utility routines to support the * * P-UNIT-DATA service. * * * * entry points: * * * * ppdu2data (pb, pi, ps, info) * * qb2_info (qb, pe) * * info2_qb (pe, qp, pi) * * info2_ppdu (pb, pi, data, ndata, ppdu) * * ss2pulose (pb, pi, event, sa) * * pusaplose (va_alist) * * PuErrString (code) * * PS_print (pe, text, rw, fnx) * * newpublk () * * findpublk (sd) * * freepublk (sd) * * * * internal routines: * * * * _pusaplose (pi, reason, ap) * * * **************************************************************** * * * NOTICE * * * * Use of this module is subject to the restrictions of the * * ISODE license agreement. * * * **************************************************************** *//* HULA P-UNIT-DATA Service *//* psaputils.c - PPM: provider utility routines */#ifndef lintstatic char *rcsid = "$Header: /f/iso/psap2/RCS/psapinitiate.c,v 5.0 88/07/21 14:42:56 mrose Rel $";#endif/* * $Header: /f/iso/psap2/RCS/psapinitiate.c,v 5.0 88/07/21 14:42:56 mrose Rel $ * * * $Log$ *//* LINTLIBRARY */#include <stdio.h>#include <varargs.h>#include <signal.h>#include "PS-types.h"#include "pupkt.h"#include "isoservent.h"#include "tailor.h"/* HULA UD - the entire module */static int once_only = 0;static struct psapblk psapque;static struct psapblk *PuHead = &psapque;/* *//*----------------------------------------------------------------------------*/int ppdu2data (pb, pi, ps, info)/*----------------------------------------------------------------------------*/register struct psapblk *pb;struct PSAPindication *pi;struct PuSAPstart *ps;struct type_PS_User__data *info;{ register int i, j; int nctx, ctx, result; PE pe; register struct type_PS_Fully__encoded__data *full; PE *data; int *ndata; data = ps->ps_info; ndata = &ps->ps_ninfo; *ndata = 0; *data = NULLPE; if (info == NULL) return OK; i = 0; switch (info -> offset) { default: return pusaplose ( pi, PC_INVALID, NULLCP, "neither Simply- nor Fully-encoded-data"); case type_PS_User__data_simple: if (pb -> pb_ncontext < 1 ) ctx = PE_DFLT_CTX; else { if (pb -> pb_ncontext > 1) return pusaplose ( pi, PC_INVALID, NULLCP, "unexpected Simply-encoded-data"); else ctx = pb -> pb_contexts[0].pc_id; } while ((result = qb2_info (info -> un.simple, &pe)) == PS_ERR_NONE){ if (i++ >= NPDATA) { pe_free (pe); return pusaplose ( pi, PC_CONGEST, NULLCP, "too much user information"); } (*data++ = pe) -> pe_context = ctx; } if (result != PS_ERR_EOF) return pusaplose ( pi, result != PS_ERR_NMEM ? PC_INVALID : PC_CONGEST, NULLCP, "%s", ps_error (result)); break; case type_PS_User__data_complex: for (full = info -> un.complex; full; full = full -> next) { struct qbuf *qb; register struct PSAPcontext *qp; register struct type_PS_PDV__list *pdv = full -> PDV__list; ctx = pdv -> identifier; nctx = ps -> ps_ctxlist.pc_nctx; for (j = 0, qp = ps -> ps_ctxlist.pc_ctx; j < nctx; j++, qp++) if (qp -> pc_id == ctx && qp -> pc_result == PC_ACCEPT) break; if (j >= nctx) return pusaplose ( pi, PC_INVALID, NULLCP, "unexpected use of context %d", ctx); switch (pdv -> presentation__data__values -> offset) { case choice_PS_0_single__ASN1__type: if (i++ >= NPDATA) return pusaplose ( pi, PC_CONGEST, NULLCP, "too much user information"); pe = pdv -> presentation__data__values -> un.single__ASN1__type; pdv -> presentation__data__values -> un.single__ASN1__type = NULLPE; (*data++ = pe) -> pe_context = ctx; break; case choice_PS_0_octet__aligned: qb = pdv -> presentation__data__values -> un.octet__aligned; while ((result = qb2_info (qb, &pe)) == PS_ERR_NONE) { pe -> pe_context = ctx; if (i++ >= NPDATA) { pe_free (pe); return pusaplose ( pi, PC_CONGEST, NULLCP, "too much user information"); } (*data++ = pe) -> pe_context = ctx; } if (result != PS_ERR_EOF) return pusaplose ( pi, result != PS_ERR_NMEM ? PC_INVALID : PC_CONGEST, NULLCP, "%s", ps_error (result)); break; default: return pusaplose ( pi, PC_INVALID, NULLCP, "not expecting non-ASN.1 encoding"); } } break; } *ndata = i; return OK;}/* *//*----------------------------------------------------------------------------*/int qb2_info (qb, pe)/*----------------------------------------------------------------------------*/register struct qbuf *qb;PE *pe;{ int result;#ifdef DEBUG int len;#endif PE p; register PS ps; *pe = NULLPE; if ((ps = ps_alloc (qbuf_open)) == NULLPS) return PS_ERR_NMEM;#ifdef DEBUG len = ps -> ps_byteno;#endif if (qbuf_setup (ps, qb) == NOTOK || (p = ps2pe (ps)) == NULLPE) { if ((result = ps -> ps_errno) == PS_ERR_NONE) result = PS_ERR_EOF; } else { result = PS_ERR_NONE; *pe = p; } ps -> ps_addr = NULL; /* so ps_free doesn't free remainder of qbuf */#ifdef DEBUG len = ps -> ps_byteno - len;#endif ps_free (ps);#ifdef DEBUG if (p && (psaplevel & ISODELOG_PDUS)) { int isopen; FILE *fp; if (strcmp (psapfile, "-")) { char file[BUFSIZ]; (void) sprintf (file, psapfile, getpid ()); fp = fopen (file, "a"), isopen = 1; } else fp = stderr, isopen = 0, (void) fflush (stdout); if (fp) { pe2text (fp, p, 1, len); if (isopen) (void) fclose (fp); else (void) fflush (fp); } }#endif return result;}/* *//*----------------------------------------------------------------------------*/struct qbuf *info2_qb (pe, qp, pi)/*----------------------------------------------------------------------------*/register PE pe;register struct qbuf *qp;struct PSAPindication *pi;{ int len; register struct qbuf *qb; register PS ps; if ((qb = qp) == NULL) { if ((qb = (struct qbuf *) malloc ((unsigned) sizeof *qb + (len = ps_get_abs (pe)))) == NULL) {no_mem: ; (void) pusaplose (pi, PC_CONGEST, NULLCP, NULLCP); goto out; } qb -> qb_data = qb -> qb_base, qb -> qb_len = len; } if ((ps = ps_alloc (str_open)) == NULLPS) goto no_mem; if (str_setup (ps, qb -> qb_data, qb -> qb_len, 1) == NOTOK || pe2ps_aux (ps, pe, 0) == NOTOK) { (void) pusaplose (pi, PC_CONGEST, NULLCP, "error encoding user-info"); ps_free (ps); goto out; } len = ps -> ps_ptr - ps -> ps_base; if (qp) qp -> qb_data += len, qp -> qb_len -= len; else qb -> qb_len = len;#ifdef DEBUG if (psaplevel & ISODELOG_PDUS) { int isopen; FILE *fp; if (strcmp (psapfile, "-")) { char file[BUFSIZ]; (void) sprintf (file, psapfile, getpid ()); fp = fopen (file, "a"), isopen = 1; } else fp = stderr, isopen = 0, (void) fflush (stdout); if (fp) { pe2text (fp, pe, 0, len); if (isopen) (void) fclose (fp); else (void) fflush (fp); } }#endif ps_free (ps); return qb;out: ; if (qb && qb != qp) free ((char *) qb); return NULL;}/* *//*----------------------------------------------------------------------------*/struct type_PS_User__data *info2_ppdu (pb, pi, data, ndata, ppdu)/*----------------------------------------------------------------------------*/register struct psapblk *pb;struct PSAPindication *pi;PE *data;int ndata, ppdu;{ register int i, j; register PE *d, pe; register struct qbuf *qb; register struct PSAPcontext *qp; OID atn; struct type_PS_User__data *pdu; register struct type_PS_Simply__encoded__data *simple; register struct type_PS_Fully__encoded__data **complex, *full; if ((pdu = (struct type_PS_User__data *) calloc (1, sizeof *pdu)) == NULL) {no_mem: ; (void) pusaplose (pi, PC_CONGEST, NULLCP, "out of memory"); goto out; } pdu -> offset = type_PS_User__data_simple; for (d = data, i = 0; i < ndata; i++) { if ((pe = *d++) == NULLPE) { (void) pusaplose (pi, PC_PARAMETER, NULLCP, "missing %d%s PSDU", i + 1, i == 0 ? "st" : i == 1 ? "nd" : i == 2 ? "rd" : "th"); goto out; }/* for now and perhaps forever the choice of simply vs fully encoded *//* is the presence of more than one context since it is presumed that *//* AUDT is present and we don't want to force fully encoded just because *//* there is a context for the AUDT pdu */ if (pb -> pb_ncontext > 1) { if ( pe -> pe_context == PE_DFLT_CTX) { (void) pusaplose (pi, PC_PARAMETER, NULLCP, "default context not permitted"); goto out; } pdu -> offset = type_PS_User__data_complex; } } if (pdu -> offset == type_PS_User__data_simple) { if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL) goto no_mem; simple = pdu -> un.simple = qb; qb -> qb_forw = qb -> qb_back = qb; qb -> qb_data = NULL, qb -> qb_len = 0; j = 0; for (d = data, i = 0; i < ndata; i++) j += ps_get_abs (*d++); qb -> qb_len = j; if ((qb = (struct qbuf *) malloc (sizeof *qb + ((unsigned)j))) == NULL) goto no_mem; qb -> qb_data = qb -> qb_base, qb -> qb_len = j; insque (qb, simple -> qb_back); } else complex = &pdu -> un.complex;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -