|
|
1.1 root 1: /* acsapinitiat.c - ACPM: initiator */
2:
3: #ifndef lint
4: static char *rcsid = "$Header: /f/osi/acsap/RCS/acsapinitiat.c,v 7.2 90/07/09 14:30:32 mrose Exp $";
5: #endif
6:
7: /*
8: * $Header: /f/osi/acsap/RCS/acsapinitiat.c,v 7.2 90/07/09 14:30:32 mrose Exp $
9: *
10: *
11: * $Log: acsapinitiat.c,v $
12: * Revision 7.2 90/07/09 14:30:32 mrose
13: * sync
14: *
15: * Revision 7.1 90/07/01 21:01:55 mrose
16: * pepsy
17: *
18: * Revision 7.0 89/11/23 21:21:50 mrose
19: * Release 6.0
20: *
21: */
22:
23: /*
24: * NOTICE
25: *
26: * Acquisition, use, and distribution of this module and related
27: * materials are subject to the restrictions of a license agreement.
28: * Consult the Preface in the User's Manual for the full terms of
29: * this agreement.
30: *
31: */
32:
33:
34: /* LINTLIBRARY */
35:
36: #include <stdio.h>
37: #include <signal.h>
38: #include "ACS-types.h"
39: #define ACSE
40: #include "acpkt.h"
41: #include "isoservent.h"
42: #include "tailor.h"
43:
44: /* A-(ASYN-)ASSOCIATE.REQUEST */
45:
46: int AcAsynAssocRequest (context, callingtitle, calledtitle, callingaddr,
47: calledaddr, ctxlist, defctxname, prequirements, srequirements, isn,
48: settings, ref, data, ndata, qos, acc, aci, async)
49: OID context;
50: AEI callingtitle,
51: calledtitle;
52: struct PSAPaddr *callingaddr,
53: *calledaddr;
54: int prequirements,
55: srequirements,
56: settings,
57: ndata,
58: async;
59: long isn;
60: struct PSAPctxlist *ctxlist;
61: OID defctxname;
62: struct SSAPref *ref;
63: PE *data;
64: struct QOStype *qos;
65: struct AcSAPconnect *acc;
66: struct AcSAPindication *aci;
67: {
68: SBV smask;
69: int result;
70:
71: isodetailor (NULLCP, 0);
72:
73: missingP (context);
74: #ifdef notdef
75: missingP (callingtitle);
76: missingP (calledtitle);
77: #endif
78:
79: /* let presentation provider catch errors in presentation parameters */
80: /* except this one... */
81: missingP (ctxlist);
82:
83: toomuchP (data, ndata, NACDATA, "initial");
84: if (data) { /* XXX: probably should have a more intensive check... */
85: register int i;
86: register PE *pep;
87:
88: for (pep = data, i = ndata; i > 0; pep++, i--)
89: if ((*pep) -> pe_context == PE_DFLT_CTX)
90: return acsaplose (aci, ACS_PARAMETER, NULLCP,
91: "default context not allowed for user-data at slot %d",
92: pep - data);
93: }
94: missingP (acc);
95: missingP (aci);
96:
97: smask = sigioblock ();
98:
99: result = AcAssocRequestAux (context, callingtitle, calledtitle,
100: callingaddr, calledaddr, ctxlist, defctxname, prequirements,
101: srequirements, isn, settings, ref, data, ndata, qos, acc, aci,
102: async);
103:
104: (void) sigiomask (smask);
105:
106: return result;
107: }
108:
109: /* */
110:
111: static int AcAssocRequestAux (context, callingtitle, calledtitle, callingaddr,
112: calledaddr, ctxlist, defctxname, prequirements, srequirements, isn,
113: settings, ref, data, ndata, qos, acc, aci, async)
114: OID context;
115: AEI callingtitle,
116: calledtitle;
117: struct PSAPaddr *callingaddr,
118: *calledaddr;
119: int prequirements,
120: srequirements,
121: settings,
122: ndata,
123: async;
124: long isn;
125: struct PSAPctxlist *ctxlist;
126: OID defctxname;
127: struct SSAPref *ref;
128: PE *data;
129: struct QOStype *qos;
130: struct AcSAPconnect *acc;
131: struct AcSAPindication *aci;
132: {
133: register int i;
134: int result;
135: PE pe;
136: register struct assocblk *acb;
137: register struct PSAPcontext *pp;
138: register struct PSAPconnect *pc = &acc -> acc_connect;
139: struct PSAPindication pis;
140: register struct PSAPindication *pi = &pis;
141: register struct PSAPabort *pa = &pi -> pi_abort;
142: register struct type_ACS_AARQ__apdu *pdu;
143:
144: if ((acb = newacblk ()) == NULL)
145: return acsaplose (aci, ACS_CONGEST, NULLCP, "out of memory");
146:
147: pe = NULLPE;
148: if ((pdu = (struct type_ACS_AARQ__apdu *) calloc (1, sizeof *pdu))
149: == NULL) {
150: no_mem: ;
151: result = acsaplose (aci, ACS_CONGEST, NULLCP, "out of memory");
152: goto out;
153: }
154: pdu -> application__context__name = context;
155: if (calledtitle) {
156: pdu -> called__AP__title = calledtitle -> aei_ap_title;
157: pdu -> called__AE__qualifier = calledtitle -> aei_ae_qualifier;
158: if (calledtitle -> aei_flags & AEI_AP_ID)
159: pdu -> called__AP__invocation__id =
160: (struct type_ACS_AP__invocation__id *)
161: &calledtitle -> aei_ap_id;
162: if (calledtitle -> aei_flags & AEI_AE_ID)
163: pdu -> called__AE__invocation__id =
164: (struct type_ACS_AE__invocation__id *)
165: &calledtitle -> aei_ae_id;
166: }
167: if (callingtitle) {
168: pdu -> calling__AP__title = callingtitle -> aei_ap_title;
169: pdu -> calling__AE__qualifier = callingtitle -> aei_ae_qualifier;
170: if (callingtitle -> aei_flags & AEI_AP_ID)
171: pdu -> calling__AP__invocation__id =
172: (struct type_ACS_AP__invocation__id *)
173: &callingtitle -> aei_ap_id;
174: if (callingtitle -> aei_flags & AEI_AE_ID)
175: pdu -> calling__AE__invocation__id =
176: (struct type_ACS_AE__invocation__id *)
177: &callingtitle -> aei_ae_id;
178: }
179: if (data
180: && ndata > 0
181: && (pdu -> user__information = info2apdu (acb, aci, data, ndata))
182: == NULL)
183: goto out;
184:
185: result = encode_ACS_AARQ__apdu (&pe, 1, 0, NULLCP, pdu);
186:
187: if (pdu -> user__information)
188: free_ACS_Association__information (pdu -> user__information);
189: free ((char *) pdu);
190: pdu = NULL;
191:
192: if (result == NOTOK) {
193: (void) acsaplose (aci, ACS_CONGEST, NULLCP, "error encoding PDU: %s",
194: PY_pepy);
195: goto out;
196: }
197:
198: if (ctxlist -> pc_nctx >= NPCTX) {
199: result = acsaplose (aci, ACS_PARAMETER, NULLCP,
200: "too many contexts");
201: goto out;
202: }
203:
204: {
205: register int ctx;
206: register OID oid;
207:
208: if ((oid = ode2oid (AC_ASN)) == NULLOID) {
209: result = acsaplose (aci, ACS_PARAMETER, NULLCP,
210: "%s: unknown", AC_ASN);
211: goto out;
212: }
213:
214: for (pp = ctxlist -> pc_ctx, i = ctxlist -> pc_nctx - 1;
215: i >= 0;
216: pp++, i--)
217: if (oid_cmp (pp -> pc_asn, oid)) {
218: if (acb -> acb_rosid == PE_DFLT_CTX)
219: acb -> acb_rosid = pp -> pc_id;
220: break;
221: }
222:
223: ctx = 1;
224: for (pp = ctxlist -> pc_ctx, i = ctxlist -> pc_nctx - 1;
225: i >= 0;
226: i--, pp++) {
227: if (oid_cmp (pp -> pc_asn, oid) == 0) {
228: acb -> acb_id = pp -> pc_id;
229: acb -> acb_offset = pp - ctxlist -> pc_ctx;
230:
231: pp = NULL;
232: goto ready;
233: }
234:
235: if (ctx <= pp -> pc_id)
236: ctx = pp -> pc_id + 2;
237: }
238: pp -> pc_id = ctx;
239: if ((pp -> pc_asn = oid_cpy (oid)) == NULLOID)
240: goto no_mem;
241: if (pp -> pc_atn = ode2oid (BER))
242: pp -> pc_atn = oid_cpy (pp -> pc_atn);
243:
244: acb -> acb_id = pp -> pc_id;
245: acb -> acb_offset = -1;
246:
247: ctxlist -> pc_nctx++;
248: }
249: ready: ;
250: pe -> pe_context = acb -> acb_id;
251:
252: PLOGP (acsap_log,ACS_ACSE__apdu, pe, "AARQ-apdu", 0);
253:
254: bzero ((char *) acc, sizeof *acc);
255:
256: result = PAsynConnRequest (callingaddr, calledaddr,
257: ctxlist, defctxname, prequirements, srequirements, isn,
258: settings, ref, &pe, 1, qos, pc, pi, async);
259:
260: if (pp) {
261: oid_free (pp -> pc_asn);
262: if (pp -> pc_atn)
263: oid_free (pp -> pc_atn);
264: pp -> pc_asn = pp -> pc_atn = NULLOID;
265: }
266:
267: pe_free (pe);
268: pe = NULLPE;
269:
270: if (result == NOTOK) {
271: (void) ps2acslose (NULLACB, aci, "PAsynConnRequest", pa);
272: goto out;
273: }
274:
275: acb -> acb_fd = pc -> pc_sd;
276: acb -> acb_flags |= ACB_ACS;
277: acb -> acb_uabort = PUAbortRequest;
278:
279: if (async) {
280: switch (result) {
281: case CONNECTING_1:
282: case CONNECTING_2:
283: acc -> acc_sd = acb -> acb_fd;
284: return result;
285: }
286: }
287: if ((result = AcAsynRetryAux (acb, pc, pi, acc, aci)) == DONE && !async)
288: result = OK;
289: return result;
290:
291: out: ;
292: if (pdu) {
293: if (pdu -> user__information)
294: free_ACS_Association__information (pdu -> user__information);
295: free ((char *) pdu);
296: }
297: if (pe)
298: pe_free (pe);
299:
300: freeacblk (acb);
301:
302: return result;
303: }
304:
305: /* A-ASYN-RETRY.REQUEST (pseudo) */
306:
307: int AcAsynRetryRequest (sd, acc, aci)
308: int sd;
309: struct AcSAPconnect *acc;
310: struct AcSAPindication *aci;
311: {
312: SBV smask;
313: int result;
314: register struct assocblk *acb;
315: register struct PSAPconnect *pc;
316: struct PSAPindication pis;
317: register struct PSAPindication *pi = &pis;
318: register struct PSAPabort *pa = &pi -> pi_abort;
319:
320: missingP (acc);
321: missingP (aci);
322:
323: smask = sigioblock ();
324:
325: if ((acb = findacblk (sd)) == NULL) {
326: (void) sigiomask (smask);
327: return acsaplose (aci, ACS_PARAMETER, NULLCP,
328: "invalid association descriptor");
329: }
330: if (acb -> acb_flags & ACB_CONN) {
331: (void) sigiomask (smask);
332: return acsaplose (aci, ACS_OPERATION, NULLCP,
333: "association descriptor connected");
334: }
335:
336: pc = &acc -> acc_connect;
337: bzero ((char *) acc, sizeof *acc);
338:
339: switch (result = PAsynRetryRequest (acb -> acb_fd, pc, pi)) {
340: case NOTOK:
341: acb -> acb_fd = NOTOK;
342: (void) ps2acslose (acb, aci, "PAsynRetryRequest", pa);
343: freeacblk (acb);
344: break;
345:
346: case CONNECTING_1:
347: case CONNECTING_2:
348: break;
349:
350: case DONE:
351: result = AcAsynRetryAux (acb, pc, pi, acc, aci);
352: break;
353: }
354:
355: (void) sigiomask (smask);
356:
357: return result;
358: }
359:
360: /* */
361:
362: static int AcAsynRetryAux (acb, pc, pi, acc, aci)
363: register struct assocblk *acb;
364: struct PSAPconnect *pc;
365: struct PSAPindication *pi;
366: struct AcSAPconnect *acc;
367: struct AcSAPindication *aci;
368: {
369: register int i;
370: int result;
371: PE pe;
372: register struct PSAPcontext *pp;
373: register struct PSAPabort *pa = &pi -> pi_abort;
374: struct type_ACS_ACSE__apdu *pdu;
375: register struct type_ACS_AARE__apdu *aare;
376:
377: if (pc -> pc_result == PC_ABORTED) {
378: (void) ps2acsabort (acb, pa, aci);
379:
380: acc -> acc_sd = NOTOK;
381: acc -> acc_result = ACS_ABORTED;
382:
383: return DONE;
384: }
385:
386: pe = NULLPE;
387: pdu = NULL;
388:
389: if (pc -> pc_ninfo < 1) {
390: if (pc -> pc_result != PC_ACCEPT) {
391: bzero ((char *) pa, sizeof *pa);
392: pa -> pa_reason = pc -> pc_result;
393: acb -> acb_fd = NOTOK;
394: (void) ps2acslose (acb, aci, "PAsynConnRequest(pseudo)", pa);
395:
396: acc -> acc_sd = NOTOK;
397: acc -> acc_result = aci -> aci_abort.aca_reason;
398:
399: result = DONE;
400: }
401: else
402: result = acpktlose (acb, aci, ACS_PROTOCOL, NULLCP, NULLCP);
403: goto out;
404: }
405:
406: acb -> acb_fd = pc -> pc_sd;
407: acb -> acb_sversion = pc -> pc_qos.qos_sversion;
408:
409: result = decode_ACS_ACSE__apdu (pe = pc -> pc_info[0], 1, NULLIP, NULLVP,
410: &pdu);
411:
412: #ifdef DEBUG
413: if (result == OK && (acsap_log -> ll_events & LLOG_PDUS))
414: pvpdu (acsap_log, print_ACS_ACSE__apdu_P, pe, "ACSE-apdu", 1);
415: #endif
416:
417: pe_free (pe);
418: pe = pc -> pc_info[0] = NULLPE;
419:
420: if (result == NOTOK) {
421: (void) acpktlose (acb, aci, ACS_PROTOCOL, NULLCP, "%s", PY_pepy);
422: goto out;
423: }
424:
425: if (pdu -> offset != type_ACS_ACSE__apdu_aare) {
426: result = acpktlose (acb, aci, ACS_PROTOCOL, NULLCP,
427: "unexpected PDU %d on P-CONNECT", pdu -> offset);
428: goto out;
429: }
430:
431: aare = pdu -> un.aare;
432: switch (aare -> result) {
433: case int_ACS_result_accepted:
434: if (pc -> pc_result != PC_ACCEPT) {
435: result = acpktlose (acb, aci, ACS_PROTOCOL, NULLCP,
436: "not accepted [%s]",
437: PErrString (pc -> pc_result));
438: goto out;
439: }
440:
441: acb -> acb_flags |= ACB_CONN;
442:
443: acc -> acc_sd = acb -> acb_fd;
444: acc -> acc_result = ACS_ACCEPT;
445:
446: if ((i = acb -> acb_offset) < 0)
447: i = pc -> pc_ctxlist.pc_nctx - 1;
448: pp = pc -> pc_ctxlist.pc_ctx + i;
449: if (pp -> pc_id != acb -> acb_id) {
450: result = acpktlose (acb, aci, ACS_PROTOCOL, NULLCP,
451: "ACSE PCI not found");
452: goto out;
453: }
454: if (pp -> pc_result != PC_ACCEPT) {
455: result = acpktlose (acb, aci, ACS_PROTOCOL, NULLCP,
456: "ACSE PCI rejected");
457: goto out;
458: }
459:
460: if (acb -> acb_offset < 0)
461: pc -> pc_ctxlist.pc_nctx--;
462:
463: for (pp = pc -> pc_ctxlist.pc_ctx; i >= 0; i--, pp++)
464: if (pp -> pc_id != acb -> acb_id
465: && pp -> pc_result == PC_ACCEPT) {
466: acb -> acb_rosid = pp -> pc_id;
467: break;
468: }
469: break;
470:
471: case int_ACS_result_rejected__permanent:
472: acc -> acc_result = ACS_PERMANENT;
473: goto rejected;
474:
475: case int_ACS_result_rejected__transient:
476: acc -> acc_result = ACS_TRANSIENT;
477: rejected: ;
478: if (pc -> pc_result != PC_ACCEPT)
479: acb -> acb_fd = NOTOK;
480: acc -> acc_sd = NOTOK;
481: if (acb -> acb_offset < 0
482: && (i = pc -> pc_ctxlist.pc_nctx - 1) >= 0)
483: pc -> pc_ctxlist.pc_nctx = i;
484: break;
485: }
486:
487: switch (aare -> result__source__diagnostic -> offset) {
488: case type_ACS_Associate__source__diagnostic_acse__service__user:
489: acc -> acc_diagnostic =
490: aare -> result__source__diagnostic -> un.acse__service__user
491: + ACS_USER_BASE;
492: break;
493:
494: case type_ACS_Associate__source__diagnostic_acse__service__provider:
495: default:
496: acc -> acc_diagnostic =
497: aare -> result__source__diagnostic -> un.acse__service__provider
498: + ACS_PROV_BASE;
499: break;
500: }
501:
502: if ((result = apdu2info (acb, aci, aare -> user__information,
503: acc -> acc_info, &acc -> acc_ninfo)) == NOTOK)
504: goto out;
505:
506: acc -> acc_context = aare -> application__context__name;
507: aare -> application__context__name = NULLOID;
508: acc -> acc_respondtitle.aei_ap_title = aare -> responding__AP__title;
509: aare -> responding__AP__title = NULLPE;
510: acc -> acc_respondtitle.aei_ae_qualifier =
511: aare -> responding__AE__qualifier;
512: aare -> responding__AE__qualifier = NULLPE;
513: if (aare -> responding__AP__invocation__id) {
514: acc -> acc_respondtitle.aei_ap_id =
515: aare -> responding__AP__invocation__id -> parm;
516: acc -> acc_respondtitle.aei_flags |= AEI_AP_ID;
517: }
518: if (aare -> responding__AE__invocation__id) {
519: acc -> acc_respondtitle.aei_ae_id =
520: aare -> responding__AE__invocation__id -> parm;
521: acc -> acc_respondtitle.aei_flags |= AEI_AE_ID;
522: }
523:
524: for (i = pc -> pc_ninfo - 1; i >= 0; i--)
525: if (pc -> pc_info[i]) {
526: pe_free (pc -> pc_info[i]);
527: pc -> pc_info[i] = NULL;
528: }
529: pc -> pc_ninfo = 0;
530:
531: free_ACS_ACSE__apdu (pdu);
532:
533: if (pc -> pc_result != PC_ACCEPT)
534: freeacblk (acb);
535:
536: return DONE;
537:
538: out: ;
539: if (pc -> pc_ninfo > 0 && pe == pc -> pc_info[0])
540: pe = NULLPE;
541: PCFREE (pc);
542: if (pe)
543: pe_free (pe);
544: if (pdu)
545: free_ACS_ACSE__apdu (pdu);
546:
547: freeacblk (acb);
548:
549: return result;
550: }
551:
552: /* A-ASYN-NEXT.REQUEST (pseudo) */
553:
554: int AcAsynNextRequest (sd, acc, aci)
555: int sd;
556: struct AcSAPconnect *acc;
557: struct AcSAPindication *aci;
558: {
559: SBV smask;
560: int result;
561: register struct assocblk *acb;
562: register struct PSAPconnect *pc;
563: struct PSAPindication pis;
564: register struct PSAPindication *pi = &pis;
565: register struct PSAPabort *pa = &pi -> pi_abort;
566:
567: missingP (acc);
568: missingP (aci);
569:
570: smask = sigioblock ();
571:
572: if ((acb = findacblk (sd)) == NULL) {
573: (void) sigiomask (smask);
574: return acsaplose (aci, ACS_PARAMETER, NULLCP,
575: "invalid association descriptor");
576: }
577: if (acb -> acb_flags & ACB_CONN) {
578: (void) sigiomask (smask);
579: return acsaplose (aci, ACS_OPERATION, NULLCP,
580: "association descriptor connected");
581: }
582:
583: pc = &acc -> acc_connect;
584: bzero ((char *) acc, sizeof *acc);
585:
586: switch (result = PAsynNextRequest (acb -> acb_fd, pc, pi)) {
587: case NOTOK:
588: acb -> acb_fd = NOTOK;
589: (void) ps2acslose (acb, aci, "PAsynRetryRequest", pa);
590: freeacblk (acb);
591: break;
592:
593: case CONNECTING_1:
594: case CONNECTING_2:
595: break;
596:
597: case DONE:
598: result = AcAsynRetryAux (acb, pc, pi, acc, aci);
599: break;
600: }
601:
602: (void) sigiomask (smask);
603:
604: return result;
605: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.