|
|
1.1 root 1: /* psaprovider.c - implement the presentation protocol */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/psap2/RCS/psaprovider.c,v 7.3 90/07/01 21:05:11 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/psap2/RCS/psaprovider.c,v 7.3 90/07/01 21:05:11 mrose Exp $
9: *
10: *
11: * $Log: psaprovider.c,v $
12: * Revision 7.3 90/07/01 21:05:11 mrose
13: * pepsy
14: *
15: * Revision 7.2 90/03/23 17:27:48 mrose
16: * update
17: *
18: * Revision 7.1 89/11/24 16:22:20 mrose
19: * sync
20: *
21: * Revision 7.0 89/11/23 22:14:33 mrose
22: * Release 6.0
23: *
24: */
25:
26: /*
27: * NOTICE
28: *
29: * Acquisition, use, and distribution of this module and related
30: * materials are subject to the restrictions of a license agreement.
31: * Consult the Preface in the User's Manual for the full terms of
32: * this agreement.
33: *
34: */
35:
36:
37: /* LINTLIBRARY */
38:
39: #include <stdio.h>
40: #include <signal.h>
41: #include "PS-types.h"
42: #include "ppkt.h"
43: #include "tailor.h"
44:
45: /* DATA */
46:
47: static int once_only = 0;
48: static struct psapblk psapque;
49: static struct psapblk *PHead = &psapque;
50:
51:
52: struct pair preq_pairs[] = {
53: PR_MANAGEMENT, bit_PS_Presentation__requirements_context__management,
54: PR_RESTORATION, bit_PS_Presentation__requirements_restoration,
55: 0, 0
56: };
57:
58:
59: struct pair sreq_pairs[] = {
60: SR_HALFDUPLEX, bit_PS_User__session__requirements_half__duplex,
61: SR_DUPLEX, bit_PS_User__session__requirements_duplex,
62: SR_EXPEDITED, bit_PS_User__session__requirements_expedited__data,
63: SR_MINORSYNC, bit_PS_User__session__requirements_minor__synchronize,
64: SR_MAJORSYNC, bit_PS_User__session__requirements_major__synchronize,
65: SR_RESYNC, bit_PS_User__session__requirements_resynchronize,
66: SR_ACTIVITY, bit_PS_User__session__requirements_activity__management,
67: SR_NEGOTIATED, bit_PS_User__session__requirements_negotiated__release,
68: SR_CAPABILITY, bit_PS_User__session__requirements_capability__data,
69: SR_EXCEPTIONS, bit_PS_User__session__requirements_exceptions,
70: SR_TYPEDATA, bit_PS_User__session__requirements_typed__data,
71: 0, 0
72: };
73:
74: /* */
75:
76: #define doABORT ss2psabort
77:
78:
79: int DATAser (), TOKENser (), SYNCser (), ACTIVITYser (), REPORTser (),
80: FINISHser (), ABORTser ();
81:
82:
83: /* P-[*-]DATA.REQUEST */
84:
85: int PDataRequest (sd, data, ndata, pi)
86: int sd;
87: PE *data;
88: int ndata;
89: struct PSAPindication *pi;
90: {
91: return PDataRequestAux (sd, data, ndata, pi, "user", SDataRequest,
92: "SDataRequest", "P-DATA user-data", PPDU_TD);
93: }
94:
95: /* */
96:
97: int PDataRequestAux (sd, data, ndata, pi, dtype, sfunc, stype, text, ppdu)
98: int sd;
99: PE *data;
100: int ndata;
101: struct PSAPindication *pi;
102: char *dtype,
103: *stype,
104: *text;
105: IFP sfunc;
106: int ppdu;
107: {
108: SBV smask;
109: int i,
110: len,
111: result;
112: char *base,
113: *realbase;
114: register struct psapblk *pb;
115: struct SSAPindication sis;
116: register struct SSAPabort *sa = &sis.si_abort;
117: register PE *d,
118: p;
119:
120: missingP (data);
121: toomuchP (data, ndata, NPDATA, dtype);
122: if (ndata <= 0)
123: return psaplose (pi, PC_PARAMETER, NULLCP,
124: "illegal number of PDVs (%d)", ndata);
125: missingP (pi);
126: missingP (sfunc);
127: missingP (stype);
128: missingP (text);
129:
130: smask = sigioblock ();
131:
132: psapPsig (pb, sd);
133:
134: if (ppdu == PPDU_TE) {
135: for (d = data, i = 0; i < ndata; i++)
136: if ((p = *d++) && p -> pe_context != PE_DFLT_CTX) {
137: (void) sigiomask (smask);
138: return psaplose (pi, PC_OPERATION, NULLCP,
139: "defined context not permited with expedited service");
140: }
141: }
142:
143: if (ppdu == PPDU_TTD && !(pb -> pb_urequirements & SR_TYPEDATA)) {
144: (void) sigiomask (smask);
145: return psaplose (pi, PC_OPERATION, NULLCP,
146: "typed data service unavailable");
147: }
148:
149: if ((result = info2ssdu (pb, pi, data, ndata, &realbase, &base, &len, text,
150: ppdu)) != OK)
151: goto out2;
152:
153: if ((result = (*sfunc) (sd, base, len, &sis)) == NOTOK)
154: if (SC_FATAL (sa -> sa_reason))
155: (void) ss2pslose (pb, pi, stype, sa);
156: else {
157: (void) ss2pslose (NULLPB, pi, stype, sa);
158: goto out1;
159: }
160:
161: out2: ;
162: if (result == NOTOK)
163: freepblk (pb);
164: else
165: if (result == DONE)
166: result = NOTOK;
167: out1: ;
168: if (realbase)
169: free (realbase);
170: else
171: if (base)
172: free (base);
173:
174: (void) sigiomask (smask);
175:
176: return result;
177: }
178:
179: /* P-READ.REQUEST (pseudo) */
180:
181: int PReadRequest (sd, px, secs, pi)
182: int sd;
183: struct PSAPdata *px;
184: int secs;
185: struct PSAPindication *pi;
186: {
187: SBV smask;
188: int result;
189: register struct psapblk *pb;
190:
191: missingP (px);
192: missingP (pi);
193:
194: smask = sigioblock ();
195:
196: psapPsig (pb, sd);
197:
198: result = PReadRequestAux (pb, px, secs, pi);
199:
200: (void) sigiomask (smask);
201:
202: return result;
203: }
204:
205: /* */
206:
207: static int PReadRequestAux (pb, px, secs, pi)
208: register struct psapblk *pb;
209: struct PSAPdata *px;
210: int secs;
211: register struct PSAPindication *pi;
212: {
213: int result;
214: struct SSAPdata sxs;
215: register struct SSAPdata *sx = &sxs;
216: struct SSAPindication sis;
217: register struct SSAPindication *si = &sis;
218:
219: bzero ((char *) px, sizeof *px);
220: bzero ((char *) pi, sizeof *pi);
221:
222: for (;;) {
223: switch (result = SReadRequest (pb -> pb_fd, sx, secs, si)) {
224: case NOTOK:
225: return doABORT (pb, &si -> si_abort, pi);
226:
227: case OK:
228: return doDATA (pb, sx, px, pi);
229:
230: case DONE:
231: switch (si -> si_type) {
232: case SI_TOKEN:
233: return doTOKEN (pb, &si -> si_token, pi);
234:
235: case SI_SYNC:
236: return doSYNC (pb, &si -> si_sync, pi);
237:
238: case SI_ACTIVITY:
239: return doACTIVITY (pb, &si -> si_activity, pi);
240:
241: case SI_REPORT:
242: return doREPORT (pb, &si -> si_report, pi);
243:
244: case SI_FINISH:
245: return doFINISH (pb, &si -> si_finish, pi);
246:
247: default:
248: (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE,
249: NULLCP,
250: "unknown indication (0x%x) from session",
251: si -> si_type);
252: break;
253: }
254: break;
255:
256: default:
257: (void) ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP,
258: "unexpected return from SReadRequest=%d", result);
259: break;
260: }
261: break;
262: }
263:
264: freepblk (pb);
265: return NOTOK;
266: }
267:
268: /* */
269:
270: static int doDATA (pb, sx, px, pi)
271: register struct psapblk *pb;
272: register struct SSAPdata *sx;
273: register struct PSAPdata *px;
274: struct PSAPindication *pi;
275: {
276: int ppdu,
277: result;
278: char *text;
279:
280: switch (px -> px_type = sx -> sx_type) {
281: case SX_NORMAL:
282: ppdu = PPDU_TD;
283: text = "P-DATA user-data";
284: break;
285:
286: case SX_EXPEDITED:
287: ppdu = PPDU_TE;
288: text = "P-EXPEDITED-DATA user-data";
289: break;
290:
291: case SX_CAPDIND:
292: ppdu = PPDU_TC;
293: goto capd;
294: case SX_CAPDCNF:
295: ppdu = PPDU_TCC;
296: capd: ;
297: text = "P-CAPABILITY-DATA user-data";
298: break;
299:
300: case SX_TYPED:
301: ppdu = PPDU_TTD;
302: text = "P-TYPED-DATA user-data";
303: break;
304:
305: default:
306: result = ppktlose (pb, pi, PC_PROTOCOL, PPDU_NONE, NULLCP,
307: "unknown data indication type=0x%x, %d bytes",
308: sx -> sx_type, sx -> sx_cc);
309: freepblk (pb);
310: goto out;
311: }
312:
313: result = qbuf2info (pb, pi, &sx -> sx_qbuf, sx -> sx_cc,
314: px -> px_info, &px -> px_ninfo, text, ppdu);
315:
316: out: ;
317: if (result == NOTOK)
318: SXFREE (sx);
319:
320: return result;
321: }
322:
323: /* */
324:
325: static int doTOKEN (pb, st, pi)
326: register struct psapblk *pb;
327: register struct SSAPtoken *st;
328: struct PSAPindication *pi;
329: {
330: int result;
331: register struct PSAPtoken *pt = &pi -> pi_token;
332:
333: pi -> pi_type = PI_TOKEN;
334:
335: pt -> pt_type = st -> st_type;
336: pt -> pt_tokens = st -> st_tokens;
337: pt -> pt_owned = pb -> pb_owned = st -> st_owned;
338:
339: result = ssdu2info (pb, pi, st -> st_data, st -> st_cc, pt -> pt_info,
340: &pt -> pt_ninfo, "P-PLEASE-TOKEN user-data", PPDU_NONE);
341:
342: STFREE (st);
343:
344: return (result != NOTOK ? DONE : NOTOK);
345: }
346:
347: /* */
348:
349: static int doSYNC (pb, sn, pi)
350: register struct psapblk *pb;
351: register struct SSAPsync *sn;
352: struct PSAPindication *pi;
353: {
354: int result;
355: register struct PSAPsync *pn = &pi -> pi_sync;
356:
357: pi -> pi_type = PI_SYNC;
358:
359: pn -> pn_type = sn -> sn_type;
360: pn -> pn_options = sn -> sn_options;
361: pn -> pn_ssn = sn -> sn_ssn;
362: pn -> pn_settings = sn -> sn_settings;
363:
364: result = ssdu2info (pb, pi, sn -> sn_data, sn -> sn_cc, pn -> pn_info,
365: &pn -> pn_ninfo, sn -> sn_type <= SN_MAJORCNF
366: ? "P-MAJOR-SYNC user-data"
367: : sn -> sn_type <= SN_MINORCNF
368: ? "P-MINOR-SYNC user-data"
369: : "P-RESYNCHRONIZE user-data",
370: sn -> sn_type == SN_RESETIND
371: ? PPDU_RS
372: : sn -> sn_type == SN_RESETCNF
373: ? PPDU_RSA
374: : PPDU_NONE);
375:
376: SNFREE (sn);
377:
378: return (result != NOTOK ? DONE : NOTOK);
379: }
380:
381: /* */
382:
383: static int doACTIVITY (pb, sv, pi)
384: register struct psapblk *pb;
385: register struct SSAPactivity *sv;
386: struct PSAPindication *pi;
387: {
388: int result;
389: register struct PSAPactivity *pv = &pi -> pi_activity;
390:
391: pi -> pi_type = PI_ACTIVITY;
392:
393: pv -> pv_type = sv -> sv_type;
394: pv -> pv_id = sv -> sv_id; /* struct copy */
395: pv -> pv_oid = sv -> sv_oid; /* struct copy */
396: pv -> pv_connect = sv -> sv_connect; /* struct copy */
397: pv -> pv_ssn = sv -> sv_ssn;
398: pv -> pv_reason = sv -> sv_reason;
399:
400: result = ssdu2info (pb, pi, sv -> sv_data, sv -> sv_cc, pv -> pv_info,
401: &pv -> pv_ninfo, sv -> sv_type <= SV_START
402: ? "P-ACTIVITY-START user-data"
403: : sv -> sv_type <= SV_RESUME
404: ? "P-ACTIVITY-RESUME user-data"
405: : "P-ACTIVITY-END user-data", PPDU_NONE);
406:
407: SVFREE (sv);
408:
409: return (result != NOTOK ? DONE : NOTOK);
410: }
411:
412: /* */
413:
414: static int doREPORT (pb, sp, pi)
415: register struct psapblk *pb;
416: register struct SSAPreport *sp;
417: struct PSAPindication *pi;
418: {
419: int result;
420: register struct PSAPreport *pp = &pi -> pi_report;
421:
422: pi -> pi_type = PI_REPORT;
423:
424: pp -> pp_peer = sp -> sp_peer;
425: pp -> pp_reason = sp -> sp_reason;
426:
427: result = ssdu2info (pb, pi, sp -> sp_data, sp -> sp_cc, pp -> pp_info,
428: &pp -> pp_ninfo, "P-U-EXCEPTION-REPORT user-data", PPDU_NONE);
429:
430: SPFREE (sp);
431:
432: return (result != NOTOK ? DONE : NOTOK);
433: }
434:
435: /* */
436:
437: static int doFINISH (pb, sf, pi)
438: register struct psapblk *pb;
439: register struct SSAPfinish *sf;
440: struct PSAPindication *pi;
441: {
442: int result;
443: register struct PSAPfinish *pf = &pi -> pi_finish;
444:
445: pi -> pi_type = PI_FINISH;
446:
447: result = ssdu2info (pb, pi, sf -> sf_data, sf -> sf_cc, pf -> pf_info,
448: &pf -> pf_ninfo, "P-RELEASE user-data", PPDU_NONE);
449:
450: SFFREE (sf);
451:
452: if (result == NOTOK)
453: return NOTOK;
454:
455: pb -> pb_flags |= PB_FINN;
456:
457: return DONE;
458: }
459:
460: /* */
461:
462: int ss2psabort (pb, sa, pi)
463: register struct psapblk *pb;
464: register struct SSAPabort *sa;
465: struct PSAPindication *pi;
466: {
467: int result,
468: ppdu;
469: register PE pe;
470: register struct PSAPabort *pa = &pi -> pi_abort;
471: struct type_PS_Abort__type *pdu;
472: register struct element_PS_3 *aru;
473: register struct type_PS_ARP__PPDU *arp;
474: register struct type_PS_User__data *info;
475:
476: pdu = NULL, pe = NULLPE;
477: if (!sa -> sa_peer) {
478: if (sa -> sa_reason == SC_TIMER)
479: return psaplose (pi, PC_TIMER, NULLCP, NULLCP);
480:
481: (void) ss2pslose (pb, pi, NULLCP, sa);
482: goto out;
483: }
484:
485: if (sa -> sa_cc == 0) {
486: (void) psaplose (pi, PC_ABORTED, NULLCP, NULLCP);
487: goto out;
488: }
489:
490: bzero ((char *) pi, sizeof *pi);
491: pi -> pi_type = PI_ABORT;
492:
493: if ((pe = ssdu2pe (sa -> sa_info, sa -> sa_cc, NULLCP, &result))
494: == NULLPE) {
495: (void) psaplose (pi, result == PS_ERR_NMEM ? PC_CONGEST : PC_PROTOCOL,
496: NULLCP, "%s", ps_error (result));
497: goto out;
498: }
499:
500: if (decode_PS_Abort__type (pe, 1, NULLIP, NULLVP, &pdu) == NOTOK) {
501: (void) psaplose (pi, PC_UNRECOGNIZED, NULLCP, "%s", PY_pepy);
502: goto out;
503: }
504:
505: PLOGP (psap2_log,PS_Abort__type, pe, "Abort-type", 1);
506:
507: switch (pdu -> offset) {
508: default:
509: pa -> pa_peer = 1;
510: pa -> pa_reason = PC_ABORTED;
511: info = NULL, ppdu = PPDU_NONE;
512: break;
513:
514: case type_PS_Abort__type_normal__mode:
515: aru = pdu -> un.normal__mode;
516: pa -> pa_peer = 1;
517: pa -> pa_reason = PC_ABORTED;
518: info = aru -> user__data, ppdu = PPDU_ARU;
519: break;
520:
521: case type_PS_Abort__type_provider__abort:
522: if ((arp = pdu -> un.provider__abort) -> provider__reason) {
523: if ((result = arp -> provider__reason -> parm) == 0)
524: result = PC_NOTSPECIFIED;
525: else
526: result += PC_ABORT_BASE;
527: }
528: else
529: result = PC_NOTSPECIFIED;
530:
531: (void) psaplose (pi, result, NULLCP, NULLCP);
532: info = NULL, ppdu = PPDU_ARP;
533: break;
534: }
535:
536: (void) ppdu2info (pb, pi, info, pa -> pa_info, &pa -> pa_ninfo, ppdu);
537:
538: out: ;
539: SAFREE (sa);
540: if (pe)
541: pe_free (pe);
542: if (pdu)
543: free_PS_Abort__type (pdu);
544: pb -> pb_fd = NOTOK;
545: freepblk (pb);
546:
547: return NOTOK;
548: }
549:
550: /* define vectors for INDICATION events */
551:
552: #define e(i) (data ? (i) : NULLIFP)
553:
554:
555: int PSetIndications (sd, data, tokens, sync, activity, report, finish,
556: abort, pi)
557: int sd;
558: IFP data,
559: tokens,
560: sync,
561: activity,
562: report,
563: finish,
564: abort;
565: struct PSAPindication *pi;
566: {
567: SBV smask;
568: register struct psapblk *pb;
569: struct SSAPindication sis;
570: register struct SSAPabort *sa = &sis.si_abort;
571:
572: if (data || tokens || sync || activity || report || finish || abort) {
573: missingP (data);
574: missingP (tokens);
575: missingP (sync);
576: missingP (activity);
577: missingP (report);
578: missingP (finish);
579: missingP (abort);
580: }
581:
582: smask = sigioblock ();
583:
584: psapPsig (pb, sd);
585:
586: if (SSetIndications (pb -> pb_fd, e (DATAser), e (TOKENser),
587: e (SYNCser), e (ACTIVITYser), e (REPORTser), e (FINISHser),
588: e (ABORTser), &sis) == NOTOK)
589: switch (sa -> sa_reason) {
590: case SC_WAITING:
591: (void) sigiomask (smask);
592: return psaplose (pi, PC_WAITING, NULLCP, NULLCP);
593:
594: default:
595: (void) ss2pslose (pb, pi, "SSetIndications", sa);
596: freepblk (pb);
597: (void) sigiomask (smask);
598: return NOTOK;
599: }
600:
601: if (pb -> pb_DataIndication = data)
602: pb -> pb_flags |= PB_ASYN;
603: else
604: pb -> pb_flags &= ~PB_ASYN;
605: pb -> pb_TokenIndication = tokens;
606: pb -> pb_SyncIndication = sync;
607: pb -> pb_ActivityIndication = activity;
608: pb -> pb_ReportIndication = report;
609: pb -> pb_ReleaseIndication = finish;
610: pb -> pb_AbortIndication = abort;
611:
612: (void) sigiomask (smask);
613:
614: return OK;
615: }
616:
617: #undef e
618:
619: /* SSAP interface */
620:
621: int ss2pslose (pb, pi, event, sa)
622: register struct psapblk *pb;
623: register struct PSAPindication *pi;
624: char *event;
625: register struct SSAPabort *sa;
626: {
627: int reason;
628: char *cp,
629: buffer[BUFSIZ];
630:
631: if (event && SC_FATAL (sa -> sa_reason))
632: SLOG (psap2_log, LLOG_EXCEPTIONS, NULLCP,
633: (sa -> sa_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event,
634: SErrString (sa -> sa_reason), sa -> sa_cc, sa -> sa_cc,
635: sa -> sa_data));
636:
637: cp = "";
638: switch (sa -> sa_reason) {
639: case SC_SSAPID:
640: case SC_SSUSER:
641: case SC_ADDRESS:
642: reason = PC_ADDRESS;
643: break;
644:
645: case SC_REFUSED:
646: reason = PC_REFUSED;
647: break;
648:
649: case SC_CONGEST:
650: reason = PC_CONGEST;
651: break;
652:
653: case SC_TRANSPORT:
654: case SC_ABORT:
655: reason = PC_SESSION;
656: break;
657:
658: default:
659: reason = PC_SESSION;
660: if (pb == NULLPB)
661: switch (sa -> sa_reason) {
662: case SC_PARAMETER:
663: reason = PC_PARAMETER;
664: break;
665:
666: case SC_OPERATION:
667: reason = PC_OPERATION;
668: break;
669:
670: case SC_TIMER:
671: reason = PC_TIMER;
672: break;
673:
674: case SC_WAITING:
675: reason = PC_WAITING;
676: break;
677: }
678: (void) sprintf (cp = buffer, " (%s at session)",
679: SErrString (sa -> sa_reason));
680: break;
681: }
682:
683: if (pb) {
684: if (sa -> sa_cc > 0)
685: return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%*.*s%s",
686: sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp);
687: else
688: return ppktlose (pb, pi, reason, PPDU_NONE, NULLCP, "%s",
689: *cp ? cp + 1 : cp);
690: }
691: else {
692: if (sa -> sa_cc > 0)
693: return psaplose (pi, reason, NULLCP, "%*.*s%s",
694: sa -> sa_cc, sa -> sa_cc, sa -> sa_data, cp);
695: else
696: return psaplose (pi, reason, NULLCP, "%s",
697: *cp ? cp + 1 : cp);
698: }
699: }
700:
701: /* */
702:
703: static int DATAser (sd, sx)
704: int sd;
705: register struct SSAPdata *sx;
706: {
707: IFP abort;
708: register struct psapblk *pb;
709: struct PSAPindication pis;
710: register struct PSAPindication *pi = &pis;
711: register struct PSAPdata *px = &pi -> pi_data;
712:
713: if ((pb = findpblk (sd)) == NULL)
714: return;
715:
716: bzero ((char *) px, sizeof *px);
717: bzero ((char *) pi, sizeof *pi);
718: abort = pb -> pb_AbortIndication;
719:
720: if (doDATA (pb, sx, px, pi) == NOTOK)
721: (*abort) (sd, &pi -> pi_abort);
722: else
723: (*pb -> pb_DataIndication) (sd, px);
724: }
725:
726: /* */
727:
728: static int TOKENser (sd, st)
729: int sd;
730: register struct SSAPtoken *st;
731: {
732: IFP abort;
733: register struct psapblk *pb;
734: struct PSAPindication pis;
735: register struct PSAPindication *pi = &pis;
736:
737: if ((pb = findpblk (sd)) == NULL)
738: return;
739:
740: bzero ((char *) pi, sizeof *pi);
741: abort = pb -> pb_AbortIndication;
742:
743: if (doTOKEN (pb, st, pi) == NOTOK)
744: (*abort) (sd, &pi -> pi_abort);
745: else
746: (*pb -> pb_TokenIndication) (sd, &pi -> pi_token);
747: }
748:
749: /* */
750:
751: static int SYNCser (sd, sn)
752: int sd;
753: register struct SSAPsync *sn;
754: {
755: IFP abort;
756: register struct psapblk *pb;
757: struct PSAPindication pis;
758: register struct PSAPindication *pi = &pis;
759:
760: if ((pb = findpblk (sd)) == NULL)
761: return;
762:
763: bzero ((char *) pi, sizeof *pi);
764: abort = pb -> pb_AbortIndication;
765:
766: if (doSYNC (pb, sn, pi) == NOTOK)
767: (*abort) (sd, &pi -> pi_abort);
768: else
769: (*pb -> pb_SyncIndication) (sd, &pi -> pi_sync);
770: }
771:
772: /* */
773:
774: static int ACTIVITYser (sd, sv)
775: int sd;
776: register struct SSAPactivity *sv;
777: {
778: IFP abort;
779: register struct psapblk *pb;
780: struct PSAPindication pis;
781: register struct PSAPindication *pi = &pis;
782:
783: if ((pb = findpblk (sd)) == NULL)
784: return;
785:
786: bzero ((char *) pi, sizeof *pi);
787: abort = pb -> pb_AbortIndication;
788:
789: if (doACTIVITY (pb, sv, pi) == NOTOK)
790: (*abort) (sd, &pi -> pi_abort);
791: else
792: (*pb -> pb_ActivityIndication) (sd, &pi -> pi_activity);
793: }
794:
795: /* */
796:
797: static int REPORTser (sd, sp)
798: int sd;
799: register struct SSAPreport *sp;
800: {
801: IFP abort;
802: register struct psapblk *pb;
803: struct PSAPindication pis;
804: register struct PSAPindication *pi = &pis;
805:
806: if ((pb = findpblk (sd)) == NULL)
807: return;
808:
809: bzero ((char *) pi, sizeof *pi);
810: abort = pb -> pb_AbortIndication;
811:
812: if (doREPORT (pb, sp, pi) == NOTOK)
813: (*abort) (sd, &pi -> pi_abort);
814: else
815: (*pb -> pb_ReportIndication) (sd, &pi -> pi_report);
816: }
817:
818: /* */
819:
820: static int FINISHser (sd, sf)
821: int sd;
822: register struct SSAPfinish *sf;
823: {
824: IFP abort;
825: register struct psapblk *pb;
826: struct PSAPindication pis;
827: register struct PSAPindication *pi = &pis;
828:
829: if ((pb = findpblk (sd)) == NULL)
830: return;
831:
832: bzero ((char *) pi, sizeof *pi);
833: abort = pb -> pb_AbortIndication;
834:
835: if (doFINISH (pb, sf, pi) == NOTOK)
836: (*abort) (sd, &pi -> pi_abort);
837: else
838: (*pb -> pb_ReleaseIndication) (sd, &pi -> pi_finish);
839: }
840:
841: /* */
842:
843: static int ABORTser (sd, sa)
844: int sd;
845: register struct SSAPabort *sa;
846: {
847: IFP abort;
848: register struct psapblk *pb;
849: struct PSAPindication pis;
850: register struct PSAPindication *pi = &pis;
851:
852: if ((pb = findpblk (sd)) == NULL)
853: return;
854:
855: bzero ((char *) pi, sizeof *pi);
856: abort = pb -> pb_AbortIndication;
857:
858: (void) doABORT (pb, sa, pi);
859: (*abort) (sd, &pi -> pi_abort);
860: }
861:
862: /* INTERNAL */
863:
864: struct psapblk *newpblk () {
865: register struct psapblk *pb;
866:
867: pb = (struct psapblk *) calloc (1, sizeof *pb);
868: if (pb == NULL)
869: return NULL;
870:
871: pb -> pb_fd = NOTOK;
872:
873: if (once_only == 0) {
874: PHead -> pb_forw = PHead -> pb_back = PHead;
875: once_only++;
876: }
877:
878: insque (pb, PHead -> pb_back);
879:
880: return pb;
881: }
882:
883:
884: int freepblk (pb)
885: register struct psapblk *pb;
886: {
887: register int i;
888: register struct PSAPcontext *qp;
889:
890: if (pb == NULL)
891: return;
892:
893: if (pb -> pb_fd != NOTOK) {
894: struct SSAPindication sis;
895:
896: (void) SUAbortRequest (pb -> pb_fd, NULLCP, 0, &sis);
897: }
898:
899: if (pb -> pb_realbase)
900: free (pb -> pb_realbase);
901: else
902: if (pb -> pb_retry)
903: free (pb -> pb_retry);
904:
905: for (qp = pb -> pb_contexts, i = pb -> pb_ncontext - 1;
906: i >= 0;
907: qp++, i--) {
908: if (qp -> pc_asn)
909: oid_free (qp -> pc_asn);
910: if (qp -> pc_atn)
911: oid_free (qp -> pc_atn);
912: }
913: if (pb -> pb_asn)
914: oid_free (pb -> pb_asn);
915: if (pb -> pb_atn)
916: oid_free (pb -> pb_atn);
917:
918: if (pb -> pb_ber)
919: oid_free (pb -> pb_ber);
920:
921: remque (pb);
922:
923: free ((char *) pb);
924: }
925:
926: /* */
927:
928: struct psapblk *findpblk (sd)
929: register int sd;
930: {
931: register struct psapblk *pb;
932:
933: if (once_only == 0)
934: return NULL;
935:
936: for (pb = PHead -> pb_forw; pb != PHead; pb = pb -> pb_forw)
937: if (pb -> pb_fd == sd)
938: return pb;
939:
940: return NULL;
941: }
942:
943: /* */
944:
945: struct type_PS_User__data *info2ppdu (pb, pi, data, ndata, ppdu)
946: register struct psapblk *pb;
947: struct PSAPindication *pi;
948: PE *data;
949: int ndata,
950: ppdu;
951: {
952: register int i,
953: j;
954: register PE *d,
955: pe;
956: register struct qbuf *qb;
957: register struct PSAPcontext *qp;
958: OID atn;
959: struct type_PS_User__data *pdu;
960: register struct type_PS_Simply__encoded__data *simple;
961: register struct type_PS_Fully__encoded__data **complex,
962: *full;
963:
964: if ((pdu = (struct type_PS_User__data *) calloc (1, sizeof *pdu))
965: == NULL) {
966: no_mem: ;
967: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
968: goto out;
969: }
970:
971: pdu -> offset = type_PS_User__data_simple;
972: for (d = data, i = 0; i < ndata; i++) {
973: if ((pe = *d++) == NULLPE) {
974: (void) psaplose (pi, PC_PARAMETER, NULLCP,
975: "missing %d%s PDV in PSDU", i + 1,
976: i == 0 ? "st" : i == 1 ? "nd" : i == 2 ? "rd" : "th");
977: goto out;
978: }
979: if (pb -> pb_ncontext > 0
980: && pe -> pe_context == PE_DFLT_CTX) {
981: if (ppdu != PPDU_TE) {
982: (void) psaplose (pi, PC_PARAMETER, NULLCP,
983: "default context not permitted");
984: goto out;
985: }
986: }
987: else
988: if (ppdu == PPDU_CP
989: || (pb -> pb_ncontext > 1
990: && pe -> pe_context != PE_DFLT_CTX))
991: pdu -> offset = type_PS_User__data_complex;
992: }
993:
994: if (pdu -> offset == type_PS_User__data_simple) {
995: if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
996: goto no_mem;
997: simple = pdu -> un.simple = qb;
998: qb -> qb_forw = qb -> qb_back = qb;
999: qb -> qb_data = NULL, qb -> qb_len = 0;
1000:
1001: j = 0;
1002: for (d = data, i = 0; i < ndata; i++)
1003: j += ps_get_abs (*d++);
1004: qb -> qb_len = j;
1005: if ((qb = (struct qbuf *) malloc (sizeof *qb + ((unsigned)j))) == NULL)
1006: goto no_mem;
1007: qb -> qb_data = qb -> qb_base, qb -> qb_len = j;
1008: insque (qb, simple -> qb_back);
1009: }
1010: else
1011: complex = &pdu -> un.complex;
1012:
1013: for (d = data, i = 0; i < ndata; i++) {
1014: pe = *d++;
1015: switch (pe -> pe_context) {
1016: case PE_DFLT_CTX:
1017: atn = pb -> pb_atn;
1018: break;
1019:
1020: default:
1021: for (j = 0, qp = pb -> pb_contexts;
1022: j < pb -> pb_ncontext;
1023: j++, qp++)
1024: if (qp -> pc_id == pe -> pe_context)
1025: break;
1026: if (j >= pb -> pb_ncontext) {
1027: (void) psaplose (pi, PC_PARAMETER, NULLCP,
1028: "context %d is undefined", pe -> pe_context);
1029: goto out;
1030: }
1031: if (qp -> pc_result != PC_ACCEPT) {
1032: (void) psaplose (pi, PC_PARAMETER, NULLCP,
1033: "context %d is unsupported", pe -> pe_context);
1034: goto out;
1035: }
1036: atn = qp -> pc_atn;
1037: break;
1038: }
1039:
1040: if (!atn_is_ber (pb, atn)) {
1041: (void) psaplose (pi, PC_PARAMETER, NULLCP,
1042: "ATN not BER for context %d", pe -> pe_context);
1043: goto out;
1044: }
1045:
1046: if (pdu -> offset == type_PS_User__data_simple) {
1047: if (info2qb (pe, qb, pi) == NULL)
1048: goto out;
1049: }
1050: else {
1051: register PE *q;
1052:
1053: if ((full = (struct type_PS_Fully__encoded__data *)
1054: calloc (1, sizeof *full)) == NULL)
1055: goto no_mem;
1056: *complex = full;
1057: complex = &full -> next;
1058: if ((full -> PDV__list = (struct type_PS_PDV__list *)
1059: calloc (1, sizeof *full -> PDV__list))
1060: == NULL)
1061: goto no_mem;
1062: full -> PDV__list -> identifier = pe -> pe_context;
1063: if ((full -> PDV__list -> presentation__data__values =
1064: (struct choice_PS_0 *)
1065: calloc (1, sizeof (struct choice_PS_0))) == NULL)
1066: goto no_mem;
1067:
1068: for (q = d, j = i + 1; j < ndata; q++, j++)
1069: if ((*q) -> pe_context != pe -> pe_context)
1070: break;
1071: q--, j--;
1072:
1073: if (i == j) {
1074: full -> PDV__list -> presentation__data__values ->
1075: offset = choice_PS_0_single__ASN1__type;
1076: (full -> PDV__list -> presentation__data__values ->
1077: un.single__ASN1__type = pe) -> pe_refcnt++;
1078: }
1079: else {
1080: register struct qbuf *qb2;
1081:
1082: full -> PDV__list -> presentation__data__values ->
1083: offset = choice_PS_0_octet__aligned;
1084: if ((qb2 = (struct qbuf *) malloc (sizeof *qb2)) == NULL)
1085: goto no_mem;
1086: full -> PDV__list -> presentation__data__values ->
1087: un.octet__aligned = qb2;
1088: qb2 -> qb_forw = qb2 -> qb_back = qb2;
1089: qb2 -> qb_data = NULL, qb2 -> qb_len = 0;
1090: for (d--, j++; i < j; i++) {
1091: if ((qb = info2qb (*d++, (struct qbuf *) NULL, pi))
1092: == NULL)
1093: goto out;
1094: qb2 -> qb_len += qb -> qb_len;
1095: insque (qb, qb2 -> qb_back);
1096: }
1097: }
1098: }
1099: }
1100:
1101: return pdu;
1102:
1103: out: ;
1104: if (pdu)
1105: free_PS_User__data (pdu);
1106:
1107: return NULL;
1108: }
1109:
1110: /* */
1111:
1112: int ppdu2info (pb, pi, info, data, ndata, ppdu)
1113: register struct psapblk *pb;
1114: struct PSAPindication *pi;
1115: struct type_PS_User__data *info;
1116: PE *data;
1117: int *ndata,
1118: ppdu;
1119: {
1120: register int i,
1121: j;
1122: int ctx,
1123: result;
1124: PE pe;
1125: register struct type_PS_Fully__encoded__data *full;
1126:
1127: *ndata = 0;
1128: if (info == NULL)
1129: return OK;
1130:
1131: i = 0;
1132: switch (info -> offset) {
1133: case type_PS_User__data_simple:
1134: if (pb -> pb_ncontext < 1 || ppdu == PPDU_TE)
1135: ctx = PE_DFLT_CTX;
1136: else
1137: if (pb -> pb_ncontext > 1)
1138: return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP,
1139: "unexpected Simply-encoded-data");
1140: else
1141: ctx = pb -> pb_contexts[0].pc_id;
1142: while ((result = qb2info (info -> un.simple, &pe)) == PS_ERR_NONE){
1143: if (i++ >= NPDATA) {
1144: pe_free (pe);
1145: return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP,
1146: "too much user information");
1147: }
1148: (*data++ = pe) -> pe_context = ctx;
1149: }
1150: if (result != PS_ERR_EOF)
1151: return ppktlose (pb, pi, result != PS_ERR_NMEM ? PC_INVALID
1152: : PC_CONGEST, ppdu, NULLCP, "%s",
1153: ps_error (result));
1154: break;
1155:
1156: case type_PS_User__data_complex:
1157: for (full = info -> un.complex; full; full = full -> next) {
1158: struct qbuf *qb;
1159: register struct PSAPcontext *qp;
1160: register struct type_PS_PDV__list *pdv = full -> PDV__list;
1161:
1162: ctx = pdv -> identifier;
1163: for (j = 0, qp = pb -> pb_contexts;
1164: j < pb -> pb_ncontext;
1165: j++, qp++)
1166: if (qp -> pc_id == ctx)
1167: break;
1168: if (j >= pb -> pb_ncontext)
1169: return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP,
1170: "unexpected use of context %d", ctx);
1171: switch (pdv -> presentation__data__values -> offset) {
1172: case choice_PS_0_single__ASN1__type:
1173: if (i++ >= NPDATA)
1174: return ppktlose (pb, pi, PC_CONGEST, ppdu, NULLCP,
1175: "too much user information");
1176: pe = pdv -> presentation__data__values ->
1177: un.single__ASN1__type;
1178: pdv -> presentation__data__values ->
1179: un.single__ASN1__type = NULLPE;
1180: (*data++ = pe) -> pe_context = ctx;
1181: break;
1182:
1183: case choice_PS_0_octet__aligned:
1184: qb = pdv -> presentation__data__values ->
1185: un.octet__aligned;
1186: while ((result = qb2info (qb, &pe)) == PS_ERR_NONE) {
1187: pe -> pe_context = ctx;
1188: if (i++ >= NPDATA) {
1189: pe_free (pe);
1190: return ppktlose (pb, pi, PC_CONGEST, ppdu,
1191: NULLCP,
1192: "too much user information");
1193: }
1194: (*data++ = pe) -> pe_context = ctx;
1195: }
1196: if (result != PS_ERR_EOF)
1197: return ppktlose (pb, pi, result != PS_ERR_NMEM
1198: ? PC_INVALID : PC_CONGEST, ppdu,
1199: NULLCP, "%s", ps_error (result));
1200: break;
1201:
1202: default:
1203: return ppktlose (pb, pi, PC_INVALID, ppdu, NULLCP,
1204: "not expecting non-BER encoding");
1205: }
1206: }
1207: break;
1208: }
1209: *ndata = i;
1210:
1211: return OK;
1212: }
1213:
1214: /* */
1215:
1216: #ifndef DEBUG
1217: /* ARGSUSED */
1218: #endif
1219:
1220: int info2ssdu (pb, pi, data, ndata, realbase, base, len, text, ppdu)
1221: register struct psapblk *pb;
1222: struct PSAPindication *pi;
1223: PE *data;
1224: int ndata;
1225: char **realbase,
1226: **base;
1227: int *len;
1228: char *text;
1229: int ppdu;
1230: {
1231: int result;
1232: PE pe;
1233: struct type_PS_User__data *info;
1234:
1235: *realbase = *base = NULLCP, *len = 0;
1236: if (data == NULLPEP || ndata <= 0)
1237: return OK;
1238:
1239: if ((info = info2ppdu (pb, pi, data, ndata, ppdu)) == NULL)
1240: return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE);
1241:
1242: if (ppdu == PPDU_TTD) {
1243: pe = NULLPE;
1244: if ((result = encode_PS_User__data (&pe, 1, 0, NULLCP, info))
1245: == NOTOK) {
1246: losing: ;
1247: free_PS_User__data (info);
1248: return psaplose (pi, PC_CONGEST, NULLCP, "error encoding PDU: %s",
1249: PY_pepy);
1250: }
1251:
1252: PLOGP (psap2_log,PS_User__data, pe, text, 0);
1253:
1254: goto serialize;
1255: }
1256: else
1257: if (ppdu == PPDU_RS || ppdu == PPDU_RSA) {
1258: /* this works 'cause RS-PPDU == RSA-PPDU */
1259: struct type_PS_RS__PPDU rss;
1260: register struct type_PS_RS__PPDU *rs = &rss;
1261:
1262: if ((rs -> context__list = silly_list (pb, pi)) == NULL)
1263: return (PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE);
1264: rs -> user__data = info;
1265:
1266: pe = NULLPE;
1267: if ((result = encode_PS_RS__PPDU (&pe, 1, 0, NULLCP, rs))
1268: == NOTOK) {
1269: free_PS_Identifier__list (rs -> context__list);
1270: goto losing;
1271: }
1272:
1273: PLOGP (psap2_log,PS_RS__PPDU, pe, text, 0);
1274:
1275: free_PS_Identifier__list (rs -> context__list);
1276:
1277: goto serialize;
1278: }
1279:
1280: if (info -> offset == type_PS_User__data_simple) {
1281: register struct qbuf *qb;
1282:
1283: qb = info -> un.simple;
1284: *len = qb -> qb_len;
1285:
1286: qb = qb -> qb_forw;
1287: remque (qb);
1288:
1289: *realbase = (char *) qb, *base = qb -> qb_base;
1290:
1291: #ifdef DEBUG
1292: if (psap2_log -> ll_events & LLOG_PDUS)
1293: while (ndata-- > 0)
1294: pvpdu (psap2_log, vunknown_P, *data++, text, 0);
1295: #endif
1296: }
1297: else {
1298: pe = NULLPE;
1299: if (encode_PS_Fully__encoded__data (&pe, 0, 0, NULLCP,
1300: info -> un.complex) == NOTOK)
1301: goto losing;
1302: pe -> pe_class = PE_CLASS_APPL, pe -> pe_id = 1;
1303:
1304: PLOGP (psap2_log,PS_User__data, pe, text, 0);
1305:
1306: serialize: ;
1307: result = pe2ssdu (pe, base, len);
1308:
1309: pe_free (pe);
1310:
1311: if (result == NOTOK) {
1312: free_PS_User__data (info);
1313: return psaplose (pi, PC_CONGEST, NULLCP, NULLCP);
1314: }
1315: }
1316: free_PS_User__data (info);
1317:
1318: return OK;
1319: }
1320:
1321: /* */
1322:
1323: #ifndef DEBUG
1324: /* ARGSUSED */
1325: #endif
1326:
1327: int ssdu2info (pb, pi, base, len, data, ndata, text, ppdu)
1328: register struct psapblk *pb;
1329: struct PSAPindication *pi;
1330: char *base;
1331: int len;
1332: PE *data;
1333: int *ndata;
1334: char *text;
1335: int ppdu;
1336: {
1337: int result;
1338: register PE pe;
1339: register struct type_PS_User__data *info;
1340:
1341: *ndata = 0;
1342: if (base == NULLCP || len <= 0)
1343: return OK;
1344:
1345: if (ppdu == PPDU_RS || ppdu == PPDU_RSA) {
1346: struct type_PS_RS__PPDU *rs;/* this works 'cause RS-PPDU == RSA-PPDU */
1347:
1348: if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE)
1349: return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
1350: : PC_PROTOCOL, ppdu, NULLCP, "%s",
1351: ps_error (result));
1352:
1353: rs = NULL, info = NULL;
1354: result = decode_PS_RS__PPDU (pe, 1, NULLIP, NULLVP, &rs);
1355:
1356: #ifdef DEBUG
1357: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
1358: pvpdu (psap2_log, print_PS_RS__PPDU_P, pe, text, 1);
1359: #endif
1360:
1361: info = rs -> user__data, rs -> user__data = NULL;
1362: free_PS_RS__PPDU (rs);
1363:
1364: goto punch_it;
1365: }
1366:
1367: if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info))
1368: == NULL) {
1369: no_mem: ;
1370: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
1371: out: ;
1372: if (info)
1373: free_PS_User__data (info);
1374: return NOTOK;
1375: }
1376:
1377: if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) {
1378: register struct qbuf *qb;
1379:
1380: info -> offset = type_PS_User__data_simple;
1381:
1382: if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
1383: goto no_mem;
1384: info -> un.simple = qb;
1385: qb -> qb_forw = qb -> qb_back = qb;
1386: qb -> qb_data = NULL, qb -> qb_len = len;
1387: if ((qb = (struct qbuf *) malloc (sizeof *qb)) == NULL)
1388: goto no_mem;
1389: insque (qb, info -> un.simple);
1390: qb -> qb_data = base, qb -> qb_len = len;
1391: }
1392: else {
1393: info -> offset = type_PS_User__data_complex;
1394:
1395: if ((pe = ssdu2pe (base, len, NULLCP, &result)) == NULLPE) {
1396: (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
1397: : PC_PROTOCOL, ppdu, NULLCP, "%s",
1398: ps_error (result));
1399: goto out;
1400: }
1401:
1402: if (pe -> pe_class != PE_CLASS_APPL
1403: || pe -> pe_form != PE_FORM_CONS
1404: || pe -> pe_id != 1) {
1405: PY_advise (NULLCP,
1406: "Fully-encoded-data bad class/form/id: %s/%d/0x%x",
1407: pe_classlist[pe -> pe_class], pe -> pe_form,
1408: pe -> pe_id);
1409: result = NOTOK;
1410: }
1411: else
1412: result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP,
1413: &info -> un.complex);
1414:
1415: #ifdef DEBUG
1416: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
1417: pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1);
1418: #endif
1419:
1420: punch_it: ;
1421: pe_free (pe);
1422:
1423: if (result == NOTOK) {
1424: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s",
1425: PY_pepy);
1426: goto out;
1427: }
1428: }
1429:
1430: if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK)
1431: result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE;
1432:
1433: #ifdef DEBUG
1434: if (result == OK
1435: && ppdu != PPDU_RS
1436: && ppdu != PPDU_RSA
1437: && info -> offset == type_PS_User__data_simple
1438: && (psap2_log -> ll_events & LLOG_PDUS)) {
1439: register int i;
1440:
1441: for (i = *ndata; i > 0; i--)
1442: pvpdu (psap2_log, vunknown_P, *data++, text, 1);
1443: }
1444: #endif
1445:
1446: free_PS_User__data (info);
1447:
1448: return result;
1449: }
1450:
1451: /* */
1452:
1453: #ifndef DEBUG
1454: /* ARGSUSED */
1455: #endif
1456:
1457: int qbuf2info (pb, pi, qb, len, data, ndata, text, ppdu)
1458: register struct psapblk *pb;
1459: struct PSAPindication *pi;
1460: struct qbuf *qb;
1461: int len;
1462: PE *data;
1463: int *ndata;
1464: char *text;
1465: int ppdu;
1466: {
1467: int result;
1468: register PE pe;
1469: register struct qbuf *qp;
1470: struct type_PS_User__data *info;
1471:
1472: *ndata = 0;
1473: if (qb == NULL || len <= 0)
1474: return OK;
1475:
1476: if (ppdu == PPDU_TTD) {
1477: if ((pe = qbuf2pe (qb, len, &result)) == NULLPE)
1478: return ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
1479: : PC_PROTOCOL, ppdu, NULLCP, "%s",
1480: ps_error (result));
1481:
1482: info = NULL;
1483: result = decode_PS_User__data (pe, 1, NULLIP, NULLVP, &info);
1484:
1485: #ifdef DEBUG
1486: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
1487: pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1);
1488: #endif
1489:
1490: goto punch_it;
1491: }
1492:
1493: if ((info = (struct type_PS_User__data *) calloc (1, sizeof *info))
1494: == NULL) {
1495: no_mem: ;
1496: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
1497: goto out;
1498: }
1499:
1500: if (pb -> pb_ncontext <= 1 || ppdu == PPDU_TE) {
1501: register struct qbuf *qbp,
1502: *qpp;
1503:
1504: info -> offset = type_PS_User__data_simple;
1505: if ((qp = (struct qbuf *) malloc (sizeof *qp)) == NULL)
1506: goto no_mem;
1507: info -> un.simple = qpp = qp;
1508: qp -> qb_forw = qp -> qb_back = qp;
1509: qp -> qb_data = NULL, qp -> qb_len = len;
1510: for (qp = qb -> qb_forw; qp != qb; qp = qbp) {
1511: qbp = qp -> qb_forw;
1512:
1513: remque (qp);
1514: insque (qp, qpp -> qb_back);
1515: }
1516: }
1517: else {
1518: info -> offset = type_PS_User__data_complex;
1519:
1520: if ((pe = qbuf2pe (qb, len, &result)) == NULLPE) {
1521: (void) ppktlose (pb, pi, result == PS_ERR_NMEM ? PC_CONGEST
1522: : PC_PROTOCOL, ppdu, NULLCP, "%s",
1523: ps_error (result));
1524: goto out;
1525: }
1526: if (pe -> pe_class != PE_CLASS_APPL
1527: || pe -> pe_form != PE_FORM_CONS
1528: || pe -> pe_id != 1) {
1529: PY_advise (NULLCP,
1530: "Fully-encoded-data bad class/form/id: %s/%d/0x%x",
1531: pe_classlist[pe -> pe_class], pe -> pe_form,
1532: pe -> pe_id);
1533: result = NOTOK;
1534: }
1535: else
1536: result = decode_PS_Fully__encoded__data (pe, 0, NULLIP, NULLVP,
1537: &info -> un.complex);
1538:
1539: #ifdef DEBUG
1540: if (result == OK && (psap2_log -> ll_events & LLOG_PDUS))
1541: pvpdu (psap2_log, print_PS_User__data_P, pe, text, 1);
1542: #endif
1543:
1544: punch_it: ;
1545: pe_free (pe);
1546:
1547: if (result == NOTOK) {
1548: (void) ppktlose (pb, pi, PC_UNRECOGNIZED, ppdu, NULLCP, "%s",
1549: PY_pepy);
1550: goto out;
1551: }
1552: }
1553:
1554: if ((result = ppdu2info (pb, pi, info, data, ndata, ppdu)) == NOTOK)
1555: result = PC_FATAL (pi -> pi_abort.pa_reason) ? NOTOK : DONE;
1556:
1557: #ifdef DEBUG
1558: if (result == OK
1559: && ppdu != PPDU_TTD
1560: && info -> offset == type_PS_User__data_simple
1561: && (psap2_log -> ll_events & LLOG_PDUS)) {
1562: register int i;
1563:
1564: for (i = *ndata; i > 0; i--)
1565: pvpdu (psap2_log, vunknown_P, *data++, text, 1);
1566: }
1567: #endif
1568:
1569: free_PS_User__data (info);
1570:
1571: return result;
1572:
1573: out: ;
1574: if (info)
1575: free_PS_User__data (info);
1576:
1577: return NOTOK;
1578: }
1579:
1580: /* */
1581:
1582: struct qbuf *info2qb (pe, qp, pi)
1583: register PE pe;
1584: register struct qbuf *qp;
1585: struct PSAPindication *pi;
1586: {
1587: int len;
1588: register struct qbuf *qb;
1589: register PS ps;
1590:
1591: if ((qb = qp) == NULL) {
1592: if ((qb = (struct qbuf *) malloc ((unsigned) sizeof *qb
1593: + (len = ps_get_abs (pe))))
1594: == NULL) {
1595: no_mem: ;
1596: (void) psaplose (pi, PC_CONGEST, NULLCP, NULLCP);
1597: goto out;
1598: }
1599:
1600: qb -> qb_data = qb -> qb_base, qb -> qb_len = len;
1601: }
1602:
1603: if ((ps = ps_alloc (str_open)) == NULLPS)
1604: goto no_mem;
1605: if (str_setup (ps, qb -> qb_data, qb -> qb_len, 1) == NOTOK
1606: || pe2ps_aux (ps, pe, 0) == NOTOK) {
1607: (void) psaplose (pi, PC_CONGEST, NULLCP, "error encoding user-info");
1608: ps_free (ps);
1609: goto out;
1610: }
1611:
1612: len = ps -> ps_ptr - ps -> ps_base;
1613: if (qp)
1614: qp -> qb_data += len, qp -> qb_len -= len;
1615: else
1616: qb -> qb_len = len;
1617:
1618: #ifdef DEBUG
1619: if (psap_log -> ll_events & LLOG_PDUS)
1620: pe2text (psap_log, pe, 0, len);
1621: #endif
1622:
1623: ps_free (ps);
1624:
1625: return qb;
1626:
1627: out: ;
1628: if (qb && qb != qp)
1629: free ((char *) qb);
1630:
1631: return NULL;
1632: }
1633:
1634: /* */
1635:
1636: int qb2info (qb, pe)
1637: register struct qbuf *qb;
1638: PE *pe;
1639: {
1640: int result;
1641: #ifdef DEBUG
1642: int len;
1643: #endif
1644: PE p;
1645: register PS ps;
1646:
1647: *pe = NULLPE;
1648:
1649: if ((ps = ps_alloc (qbuf_open)) == NULLPS)
1650: return PS_ERR_NMEM;
1651: #ifdef DEBUG
1652: len = ps -> ps_byteno;
1653: #endif
1654: if (qbuf_setup (ps, qb) == NOTOK || (p = ps2pe (ps)) == NULLPE) {
1655: if ((result = ps -> ps_errno) == PS_ERR_NONE)
1656: result = PS_ERR_EOF;
1657: }
1658: else {
1659: result = PS_ERR_NONE;
1660: *pe = p;
1661: }
1662:
1663: ps -> ps_addr = NULL; /* so ps_free doesn't free remainder of qbuf */
1664: #ifdef DEBUG
1665: len = ps -> ps_byteno - len;
1666: #endif
1667: ps_free (ps);
1668:
1669: #ifdef DEBUG
1670: if (p && (psap_log -> ll_events & LLOG_PDUS))
1671: pe2text (psap_log, p, 1, len);
1672: #endif
1673:
1674: return result;
1675: }
1676:
1677: /* */
1678:
1679: struct type_PS_Identifier__list *silly_list (pb, pi)
1680: register struct psapblk *pb;
1681: struct PSAPindication *pi;
1682: {
1683: register int j;
1684: register struct PSAPcontext *qp;
1685: struct type_PS_Identifier__list *list;
1686: register struct type_PS_Identifier__list *lp,
1687: **mp;
1688:
1689: list = NULL;
1690: mp = &list;
1691:
1692: for (j = 0, qp = pb -> pb_contexts;
1693: j < pb -> pb_ncontext;
1694: j++, qp++) {
1695: if ((lp = (struct type_PS_Identifier__list *)
1696: calloc (1, sizeof *lp)) == NULL) {
1697: no_mem: ;
1698: (void) psaplose (pi, PC_CONGEST, NULLCP, "out of memory");
1699: free_PS_Identifier__list (list);
1700: return NULL;
1701: }
1702: *mp = lp;
1703: mp = &lp -> next;
1704: if ((lp -> element_PS_10 = (struct element_PS_11 *)
1705: calloc (1, sizeof (struct element_PS_11))) == NULL
1706: || (lp -> element_PS_10 -> transfer__syntax =
1707: oid_cpy (qp -> pc_atn)) == NULLOID)
1708: goto no_mem;
1709: lp -> element_PS_10 -> identifier = qp -> pc_id;
1710: }
1711:
1712: return list;
1713: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.