|
|
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.