|
|
1.1 ! root 1: /* ro2rts.c - ROPM: RtSAP interface */ ! 2: ! 3: #ifndef lint ! 4: static char *rcsid = "$Header: /f/osi/rosap/RCS/ro2rts.c,v 7.1 90/07/01 21:05:46 mrose Exp $"; ! 5: #endif ! 6: ! 7: /* ! 8: * $Header: /f/osi/rosap/RCS/ro2rts.c,v 7.1 90/07/01 21:05:46 mrose Exp $ ! 9: * ! 10: * Based on an TCP-based implementation by George Michaelson of University ! 11: * College London. ! 12: * ! 13: * ! 14: * $Log: ro2rts.c,v $ ! 15: * Revision 7.1 90/07/01 21:05:46 mrose ! 16: * pepsy ! 17: * ! 18: * Revision 6.0 89/03/18 23:42:10 mrose ! 19: * Release 5.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 "ROS-types.h" ! 38: #include "ropkt.h" ! 39: #include "tailor.h" ! 40: ! 41: /* DATA */ ! 42: ! 43: int rtslose (); ! 44: int rtsINDICATIONser (); ! 45: ! 46: /* bind underlying service */ ! 47: ! 48: int RoRtService (acb, roi) ! 49: register struct assocblk *acb; ! 50: struct RoSAPindication *roi; ! 51: { ! 52: if (!(acb -> acb_flags & ACB_RTS)) ! 53: return rosaplose (roi, ROS_OPERATION, NULLCP, ! 54: "not an association descriptor for ROS on reliable transfer"); ! 55: ! 56: acb -> acb_putosdu = ro2rtswrite; ! 57: acb -> acb_rowaitrequest = ro2rtswait; ! 58: acb -> acb_ready = ro2rtsready; ! 59: acb -> acb_rosetindications = ro2rtsasync; ! 60: acb -> acb_roselectmask = ro2rtsmask; ! 61: acb -> acb_ropktlose = NULLIFP; ! 62: ! 63: acb -> acb_flags |= ACB_STICKY; ! 64: ! 65: return OK; ! 66: } ! 67: ! 68: /* define vectors for INDICATION events */ ! 69: ! 70: #define e(i) (indication ? (i) : NULLIFP) ! 71: ! 72: ! 73: /* ARGSUSED */ ! 74: ! 75: int ro2rtsasync (acb, indication, roi) ! 76: register struct assocblk *acb; ! 77: IFP indication; ! 78: struct RoSAPindication *roi; ! 79: { ! 80: struct RtSAPindication rtis; ! 81: register struct RtSAPabort *rta = &rtis.rti_abort; ! 82: ! 83: if (RtSetIndications (acb -> acb_fd, e (rtsINDICATIONser), &rtis) ! 84: == NOTOK) ! 85: switch (rta -> rta_reason) { ! 86: case RTS_WAITING: ! 87: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); ! 88: ! 89: default: ! 90: (void) rtslose (acb, roi, "RtSetIndications", rta); ! 91: freeacblk (acb); ! 92: return NOTOK; ! 93: } ! 94: ! 95: if (acb -> acb_rosindication = indication) ! 96: acb -> acb_flags |= ACB_ASYN; ! 97: else ! 98: acb -> acb_flags &= ~ACB_ASYN; ! 99: ! 100: return OK; ! 101: } ! 102: ! 103: #undef e ! 104: ! 105: /* map association descriptors for select() */ ! 106: ! 107: /* ARGSUSED */ ! 108: ! 109: int ro2rtsmask (acb, mask, nfds, roi) ! 110: register struct assocblk *acb; ! 111: fd_set *mask; ! 112: int *nfds; ! 113: struct RoSAPindication *roi; ! 114: { ! 115: struct RtSAPindication rtis; ! 116: register struct RtSAPabort *rta = &rtis.rti_abort; ! 117: ! 118: if (RtSelectMask (acb -> acb_fd, mask, nfds, &rtis) == NOTOK) ! 119: switch (rta -> rta_reason) { ! 120: case RTS_WAITING: ! 121: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); ! 122: ! 123: default: ! 124: (void) rtslose (acb, roi, "RtSelectMask", rta); ! 125: freeacblk (acb); ! 126: return NOTOK; ! 127: } ! 128: ! 129: return OK; ! 130: } ! 131: ! 132: /* RtSAP interface */ ! 133: ! 134: #define doRTSdata(a,i,t,r) acb2osdu ((a), (i), (t) -> rtt_data, (r)) ! 135: ! 136: ! 137: int ro2rtswait (acb, invokeID, secs, roi) ! 138: register struct assocblk *acb; ! 139: int *invokeID, ! 140: secs; ! 141: register struct RoSAPindication *roi; ! 142: { ! 143: int result; ! 144: struct RtSAPindication rtis; ! 145: register struct RtSAPindication *rti = &rtis; ! 146: ! 147: if (acb -> acb_apdu) { ! 148: result = acb2osdu (acb, NULLIP, acb -> acb_apdu, roi); ! 149: acb -> acb_apdu = NULLPE; ! 150: ! 151: return result; ! 152: } ! 153: if (acb -> acb_flags & ACB_CLOSING) { ! 154: acb -> acb_flags |= ACB_FINN; ! 155: acb -> acb_flags &= ~ACB_CLOSING; ! 156: if (acb -> acb_flags & ACB_FINISH) { ! 157: acb -> acb_flags &= ~ACB_FINISH; ! 158: ! 159: roi -> roi_type = ROI_FINISH; ! 160: { ! 161: register struct AcSAPfinish *acf = &roi -> roi_finish; ! 162: ! 163: *acf = acb -> acb_finish; /* struct copy */ ! 164: } ! 165: } ! 166: else { ! 167: roi -> roi_type = ROI_END; ! 168: { ! 169: register struct RoSAPend *roe = &roi -> roi_end; ! 170: ! 171: bzero ((char *) roe, sizeof *roe); ! 172: } ! 173: } ! 174: ! 175: return DONE; ! 176: } ! 177: ! 178: for (;;) { ! 179: switch (result = RtWaitRequest (acb -> acb_fd, secs, rti)) { ! 180: case NOTOK: ! 181: return doRTSabort (acb, &rti -> rti_abort, roi); ! 182: ! 183: case OK: ! 184: if ((result = doRTSdata (acb, invokeID, &rti -> rti_transfer, ! 185: roi)) != OK) ! 186: return (result != DONE ? result : OK); ! 187: continue; ! 188: ! 189: case DONE: ! 190: switch (rti -> rti_type) { ! 191: case RTI_TURN: ! 192: if (doRTSturn (acb, &rti -> rti_turn, roi) != OK) ! 193: return result; ! 194: continue; ! 195: ! 196: case RTI_CLOSE: ! 197: if (doRTSclose (acb, &rti -> rti_close, roi) != OK) ! 198: return result; ! 199: continue; ! 200: ! 201: case RTI_FINISH: ! 202: if (doRTSfinish (acb, &rti -> rti_finish, roi) != OK) ! 203: return result; ! 204: continue; ! 205: ! 206: default: ! 207: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 208: "unknown indication (0x%x) from rts", ! 209: rti -> rti_type); ! 210: break; ! 211: } ! 212: break; ! 213: ! 214: default: ! 215: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 216: "unexpected return from RtWaitRequest=%d", result); ! 217: break; ! 218: } ! 219: break; ! 220: } ! 221: ! 222: freeacblk (acb); ! 223: return NOTOK; ! 224: } ! 225: ! 226: /* */ ! 227: ! 228: /* ARGSUSED */ ! 229: ! 230: int ro2rtswrite (acb, pe, fe, priority, roi) ! 231: register struct assocblk *acb; ! 232: register PE pe; ! 233: PE fe; ! 234: int priority; ! 235: struct RoSAPindication *roi; ! 236: { ! 237: int result; ! 238: struct RtSAPindication rtis; ! 239: register struct RtSAPabort *rta = &rtis.rti_abort; ! 240: ! 241: #ifdef DEBUG ! 242: if (rosap_log -> ll_events & LLOG_PDUS) ! 243: if (acb -> acb_flags & ACB_ACS) ! 244: pvpdu (rosap_log, print_ROS_ROSEapdus_P, pe, "ROSEapdus", 0); ! 245: else ! 246: pvpdu (rosap_log, print_ROS_OPDU_P, pe, "OPDU", 0); ! 247: #endif ! 248: ! 249: result = RtTransferRequest (acb -> acb_fd, pe, NOTOK, &rtis); ! 250: ! 251: if (fe) ! 252: (void) pe_extract (pe, fe); ! 253: pe_free (pe); ! 254: ! 255: if (result == OK) ! 256: return OK; ! 257: ! 258: if (rta -> rta_reason == RTS_TRANSFER) ! 259: return rosaplose (roi, ROS_APDU, NULLCP, NULLCP); ! 260: ! 261: (void) rtslose (acb, roi, "RtTransferRequest", rta); ! 262: ! 263: freeacblk (acb); ! 264: return NOTOK; ! 265: } ! 266: ! 267: /* */ ! 268: ! 269: static int doRTSturn (acb, rtu, roi) ! 270: register struct assocblk *acb; ! 271: register struct RtSAPturn *rtu; ! 272: register struct RoSAPindication *roi; ! 273: { ! 274: struct RtSAPindication rtis; ! 275: register struct RtSAPindication *rti = &rtis; ! 276: register struct RtSAPabort *rta = &rti -> rti_abort; ! 277: ! 278: if (rtu -> rtu_please) { ! 279: if (RtGTurnRequest (acb -> acb_fd, rti) == NOTOK) ! 280: return rtslose (acb, roi, "RtGTurnRequest", rta); ! 281: } ! 282: ! 283: return OK; ! 284: } ! 285: ! 286: /* */ ! 287: ! 288: /* ARGSUSED */ ! 289: ! 290: static int doRTSclose (acb, rtc, roi) ! 291: register struct assocblk *acb; ! 292: struct RtSAPclose *rtc; ! 293: register struct RoSAPindication *roi; ! 294: { ! 295: if (acb -> acb_flags & ACB_INIT) { ! 296: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 297: "association management botched"); ! 298: freeacblk (acb); ! 299: return NOTOK; ! 300: } ! 301: ! 302: roi -> roi_type = ROI_END; ! 303: { ! 304: register struct RoSAPend *roe = &roi -> roi_end; ! 305: ! 306: bzero ((char *) roe, sizeof *roe); ! 307: } ! 308: ! 309: return DONE; ! 310: } ! 311: ! 312: /* */ ! 313: ! 314: static int doRTSfinish (acb, acf, roi) ! 315: register struct assocblk *acb; ! 316: struct AcSAPfinish *acf; ! 317: register struct RoSAPindication *roi; ! 318: { ! 319: if (acb -> acb_flags & ACB_INIT) { ! 320: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 321: "association management botched"); ! 322: ACFFREE (acf); ! 323: freeacblk (acb); ! 324: return NOTOK; ! 325: } ! 326: ! 327: roi -> roi_type = ROI_FINISH; ! 328: roi -> roi_finish = *acf; /* struct copy */ ! 329: ! 330: return DONE; ! 331: } ! 332: ! 333: /* */ ! 334: ! 335: static int doRTSabort (acb, rta, roi) ! 336: register struct assocblk *acb; ! 337: register struct RtSAPabort *rta; ! 338: register struct RoSAPindication *roi; ! 339: { ! 340: if (!rta -> rta_peer) { ! 341: if (rta -> rta_reason == RTS_TIMER) ! 342: return rosaplose (roi, ROS_TIMER, NULLCP, NULLCP); ! 343: ! 344: (void) rtslose (acb, roi, NULLCP, rta); ! 345: } ! 346: else ! 347: (void) rosaplose (roi, ROS_ABORTED, NULLCP, NULLCP); ! 348: ! 349: RTAFREE (rta); ! 350: acb -> acb_fd = NOTOK; ! 351: freeacblk (acb); ! 352: ! 353: return NOTOK; ! 354: } ! 355: ! 356: /* */ ! 357: ! 358: static int rtsINDICATIONser (sd, rti) ! 359: int sd; ! 360: register struct RtSAPindication *rti; ! 361: { ! 362: int result; ! 363: IFP handler; ! 364: register struct assocblk *acb; ! 365: struct RoSAPindication rois; ! 366: register struct RoSAPindication *roi = &rois; ! 367: ! 368: if ((acb = findacblk (sd)) == NULL) ! 369: return; ! 370: ! 371: handler = acb -> acb_rosindication; ! 372: ! 373: switch (rti -> rti_type) { ! 374: case RTI_TURN: ! 375: result = doRTSturn (acb, &rti -> rti_turn, roi); ! 376: break; ! 377: ! 378: case RTI_TRANSFER: ! 379: result = doRTSdata (acb, NULLIP, &rti -> rti_transfer, roi); ! 380: break; ! 381: ! 382: case RTI_ABORT: ! 383: result = doRTSabort (acb, &rti -> rti_abort, roi); ! 384: break; ! 385: ! 386: case RTI_CLOSE: ! 387: result = doRTSclose (acb, &rti -> rti_close, roi); ! 388: break; ! 389: ! 390: case RTI_FINISH: ! 391: result = doRTSfinish (acb, &rti -> rti_finish, roi); ! 392: break; ! 393: ! 394: default: ! 395: result = ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 396: "unknown indication (0x%x) from rts", ! 397: rti -> rti_type); ! 398: freeacblk (acb); ! 399: break; ! 400: } ! 401: ! 402: if (result != OK) ! 403: (*handler) (sd, roi); ! 404: } ! 405: ! 406: /* */ ! 407: ! 408: int ro2rtsready (acb, priority, roi) ! 409: register struct assocblk *acb; ! 410: int priority; ! 411: struct RoSAPindication *roi; ! 412: { ! 413: int result; ! 414: struct RtSAPindication rtis; ! 415: register struct RtSAPindication *rti = &rtis; ! 416: register struct RtSAPabort *rta = &rti -> rti_abort; ! 417: ! 418: if (acb -> acb_apdu || (acb -> acb_flags & ACB_CLOSING)) ! 419: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); ! 420: ! 421: if (RtPTurnRequest (acb -> acb_fd, priority, rti) == NOTOK) { ! 422: (void) rtslose (acb, roi, "RtPTurnRequest", rta); ! 423: goto out; ! 424: } ! 425: ! 426: do { ! 427: switch (result = RtWaitRequest (acb -> acb_fd, NOTOK, rti)) { ! 428: case NOTOK: ! 429: return doRTSabort (acb, &rti -> rti_abort, roi); ! 430: ! 431: case OK: ! 432: acb -> acb_apdu = rti -> rti_transfer.rtt_data; ! 433: return rosaplose (roi, ROS_WAITING, NULLCP, NULLCP); ! 434: ! 435: case DONE: ! 436: switch (rti -> rti_type) { ! 437: case RTI_TURN: ! 438: if (doRTSturn (acb, &rti -> rti_turn, roi) != OK) ! 439: return result; ! 440: continue; ! 441: ! 442: case RTI_CLOSE: ! 443: switch (doRTSclose (acb, &rti -> rti_close, roi)) { ! 444: case NOTOK: ! 445: return NOTOK; ! 446: ! 447: case OK: ! 448: break; ! 449: ! 450: case DONE: ! 451: acb -> acb_flags |= ACB_CLOSING; ! 452: acb -> acb_flags &= ~ACB_FINN; ! 453: return rosaplose (roi, ROS_WAITING, NULLCP, ! 454: NULLCP); ! 455: } ! 456: continue; ! 457: ! 458: case RTI_FINISH: ! 459: switch (doRTSfinish (acb, &rti -> rti_finish, roi)) { ! 460: case NOTOK: ! 461: return NOTOK; ! 462: ! 463: case OK: ! 464: break; ! 465: ! 466: case DONE: ! 467: acb -> acb_flags |= ACB_FINISH | ACB_CLOSING; ! 468: acb -> acb_flags &= ~ACB_FINN; ! 469: /* struct copy */ ! 470: acb -> acb_finish = roi -> roi_finish; ! 471: return rosaplose (roi, ROS_WAITING, NULLCP, ! 472: NULLCP); ! 473: } ! 474: continue; ! 475: ! 476: default: ! 477: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 478: "unknown indication (0x%x) from rts", ! 479: rti -> rti_type); ! 480: break; ! 481: } ! 482: goto out; ! 483: ! 484: default: ! 485: (void) ropktlose (acb, roi, ROS_PROTOCOL, NULLCP, ! 486: "unexpected return from RtWaitRequest=%d", result); ! 487: goto out; ! 488: } ! 489: } ! 490: while (!(acb -> acb_flags & ACB_TURN)); ! 491: ! 492: return OK; ! 493: ! 494: out: ; ! 495: freeacblk (acb); ! 496: return NOTOK; ! 497: } ! 498: ! 499: /* */ ! 500: ! 501: static int rtslose (acb, roi, event, rta) ! 502: register struct assocblk *acb; ! 503: register struct RoSAPindication *roi; ! 504: char *event; ! 505: register struct RtSAPabort *rta; ! 506: { ! 507: int reason; ! 508: char *cp, ! 509: buffer[BUFSIZ]; ! 510: ! 511: if (event) ! 512: SLOG (rosap_log, LLOG_EXCEPTIONS, NULLCP, ! 513: (rta -> rta_cc > 0 ? "%s: %s [%*.*s]": "%s: %s", event, ! 514: RtErrString (rta -> rta_reason), rta -> rta_cc, rta -> rta_cc, ! 515: rta -> rta_data)); ! 516: ! 517: cp = ""; ! 518: switch (rta -> rta_reason) { ! 519: case RTS_ADDRESS: ! 520: reason = ROS_ADDRESS; ! 521: break; ! 522: ! 523: case RTS_REFUSED: ! 524: reason = ROS_REFUSED; ! 525: break; ! 526: ! 527: case RTS_CONGEST: ! 528: reason = ROS_CONGEST; ! 529: break; ! 530: ! 531: default: ! 532: (void) sprintf (cp = buffer, " (%s at rts)", ! 533: RtErrString (rta -> rta_reason)); ! 534: case RTS_SESSION: ! 535: reason = ROS_RTS; ! 536: break; ! 537: } ! 538: ! 539: if (rta -> rta_cc > 0) ! 540: return ropktlose (acb, roi, reason, NULLCP, "%*.*s%s", ! 541: rta -> rta_cc, rta -> rta_cc, rta -> rta_data, cp); ! 542: else ! 543: return ropktlose (acb, roi, reason, NULLCP, "%s", *cp ? cp + 1 : cp); ! 544: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.