|
|
1.1 ! root 1: % run this through LaTeX with the appropriate wrapper ! 2: ! 3: \chapter {Reliable Transfer}\label{librtsap} ! 4: The \man librtsap(3n) library implements the reliable transfer service (RTS). ! 5: The abstraction provided to applications is that of an {\em association\/} ! 6: for reliably transfering data. ! 7: Most applications use the remote operations facilities, ! 8: described in the previous chapter, ! 9: and do not directly use the reliable transfer service.% ! 10: \footnote{Actually, applications such as message-handling systems explicitly ! 11: use the reliable transfer service to perform association management, ! 12: and then optionally utilize the remote operations service for actual ! 13: communication (otherwise they use reliable transfer directly). ! 14: Both usages are permitted and encouraged in this implementation.} ! 15: However, ! 16: for those applications which do not base themselves in remote operations, ! 17: the reliable transfer interface is used. ! 18: ! 19: As with most models of OSI services, ! 20: the underlying assumption is one of a symmetric, asynchronous environment. ! 21: That is, ! 22: although peers exist at a given layer, ! 23: one does not necessary view a peer as either a client or a server. ! 24: Further, ! 25: the service provider may generate events for the service user without the ! 26: latter entity triggering the actions which led to the event. ! 27: For example, ! 28: in a synchronous environment, ! 29: an indication that data has arrived usually occurs only when the service user ! 30: asks the service provider to read data; ! 31: in an asynchronous environment, ! 32: the service provider may interrupt the service user at any time to announce ! 33: the arrival of data. ! 34: ! 35: The \verb"rtsap" module in this release initially uses a client/server ! 36: paradigm to start communications. ! 37: Once the connection is established, ! 38: a symmetric view is taken. ! 39: In addition, ! 40: initially the interface is synchronous; ! 41: however once the connection is established, ! 42: an asynchronous interface may be selected. ! 43: ! 44: All of the routines in the \man librtsap(3n) library are integer-valued. ! 45: They return the manifest constant \verb"OK" on success, ! 46: or \verb"NOTOK" otherwise. ! 47: ! 48: \section {Associations}\label{rts:associations} ! 49: As briefly mentioned earlier, ! 50: an association is the binding between two applications. ! 51: An association is formed when one application, ! 52: termed the {\em initiator}, ! 53: specifies the address of a {\em responder\/} and asks the reliable transfer ! 54: service to establish a connection. ! 55: ! 56: There are three aspects of association management: ! 57: {\em association establishment}, ! 58: {\em association release}, ! 59: and, ! 60: {\em association abort}. ! 61: Each of these are now described in turn. ! 62: All of these facilities rely on the mechanisms described in ! 63: Section~\ref{acs:associations} on page~\pageref{acs:associations}. ! 64: ! 65: \subsection {Association Establishment} ! 66: The \man librtsap(3n) library distinguishes between the user which started an ! 67: assocoation, ! 68: the {\em initiator}, ! 69: and the user which was subsequently bound to the association, ! 70: the {\em responder}. ! 71: We sometimes term these two entities the {\em client\/} and the {\em server}, ! 72: respectively. ! 73: ! 74: \subsubsection {Addresses} ! 75: Addresses for the reliable transfer service entity consist of two parts: ! 76: a presentation address (as discussed in Section~\ref{psap:addresses} on ! 77: page~\pageref{psap:addresses} of \voltwo/), ! 78: and application-entity information ! 79: (as discussed in Section~\ref{acs:aei} on page~\pageref{acs:aei}). ! 80: ! 81: In Figure~\ref{getFTAMentity} on page~\pageref{getFTAMentity}, ! 82: an example of how these components are determined is given. ! 83: ! 84: \subsubsection {Server Initialization} ! 85: The \man tsapd(8c) daemon, ! 86: upon accepting a connection from an initiating host, ! 87: consults the ISO services database to determine which program ! 88: on the local system implements the desired application context. ! 89: Once the program has been ascertained, ! 90: the daemon runs the program with any argument listed in the database. ! 91: In addition, ! 92: it appends some {\em magic arguments\/} to the argument vector. ! 93: Hence, ! 94: the very first action performed by the responder is to re-capcture the RTSE ! 95: state contained in the magic arguments. ! 96: This is done by calling the routine \verb"RtInit", ! 97: which on a successful return, ! 98: is equivalent to a {\sf RT-OPEN.INDICATION\/} from the reliable transfer ! 99: service provider. ! 100: \begin{quote}\index{RtInit}\small\begin{verbatim} ! 101: int RtInit (vecp, vec, rts, rti) ! 102: int vecp; ! 103: char **vec; ! 104: struct RtSAPstart *rts; ! 105: struct RtSAPindication *rti; ! 106: \end{verbatim}\end{quote} ! 107: The parameters to this procedure are: ! 108: \begin{describe} ! 109: \item[\verb"vecp":] the length of the argument vector; ! 110: ! 111: \item[\verb"vec":] the argument vector; ! 112: ! 113: \item[\verb"rts":] a pointer to a \verb"RtSAPstart" structure, ! 114: which is updated only if the call succeeds; ! 115: and, ! 116: ! 117: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, ! 118: which is updated only if the call fails. ! 119: \end{describe} ! 120: If \verb"RtInit" is successful, ! 121: it returns information in the \verb"rts" parameter, ! 122: which is a pointer to a \verb"RtSAPstart" structure. ! 123: \begin{quote}\index{RtSAPstart}\small\begin{verbatim} ! 124: struct RtSAPstart { ! 125: int rts_sd; ! 126: ! 127: int rts_mode; ! 128: #define RTS_MONOLOGUE 0 ! 129: #define RTS_TWA 1 ! 130: ! 131: int rts_turn; ! 132: #define RTS_INITIATOR 0 ! 133: #define RTS_RESPONDER 1 ! 134: ! 135: PE rts_data; ! 136: ! 137: struct AcSAPstart rts_start; ! 138: }; ! 139: \end{verbatim}\end{quote} ! 140: The elements of this structure are: ! 141: \begin{describe} ! 142: \item[\verb"rts\_sd":] the association-descriptor to be used to ! 143: reference this association; ! 144: ! 145: \item[\verb"rts\_mode":] the dialogue mode (either monologue or two-way ! 146: alternate), ! 147: ! 148: \item[\verb"rts\_turn":] the owner of the turn initially; ! 149: ! 150: \item[\verb"rts\_data":] any initial data (this is a pointer to a ! 151: \verb"PElement" structure, which is fully explained in Chapter~\ref{libpsap}); ! 152: and, ! 153: ! 154: \item[\verb"rts\_start":] a \verb"AcSAPstart" structure ! 155: (consult page~\pageref{AcSAPstart}). ! 156: \end{describe} ! 157: Note that the \verb"rts_data" element is allocated via \man malloc(3) and ! 158: should be released by using the \verb"RTSFREE" macro when no longer referenced. ! 159: The \verb"RTSFREE" macro behaves as if it was defined as: ! 160: \begin{quote}\index{RTSFREE}\small\begin{verbatim} ! 161: void RTSFREE (rts) ! 162: struct RtSAPstart *rts; ! 163: \end{verbatim}\end{quote} ! 164: The macro frees only the data allocated by \verb"RtInit", ! 165: and not the \verb"RtSAPstart" structure itself. ! 166: Further, ! 167: \verb"RTSFREE" should be called only if the call to the \verb"RtInit" ! 168: routine returned \verb"OK". ! 169: ! 170: If the call to \verb"RtInit" is not successful, ! 171: then a {\sf RT-P-ABORT.INDICATION\/} event is simulated, ! 172: and the relevant information is returned in an encoded ! 173: \verb"RtSAPindication" structure ! 174: (discussed in Section~\ref{rts:transfer} on page~\pageref{rts:transfer}). ! 175: ! 176: After examining the information returned by \verb"RtInit" on a successful call ! 177: (and possibly after examining the argument vector), ! 178: the responder should either accept or reject the association. ! 179: For either response, ! 180: the responder should use ! 181: the \verb"RtOpenResponse" routine ! 182: (which corresponds to the {\sf RT-OPEN.RESPONSE\/} action). ! 183: \begin{quote}\index{RtOpenResponse}\small\begin{verbatim} ! 184: int RtOpenResponse (sd, status, context, respondtitle, ! 185: respondaddr, ctxlist, defctxresult, data, rti) ! 186: int sd, ! 187: status; ! 188: OID context; ! 189: AEI respondtitle; ! 190: struct PSAPaddr *respondaddr; ! 191: struct PSAPctxlist *ctxlist; ! 192: int defctxresult; ! 193: PE data; ! 194: struct RtSAPindication *rti; ! 195: \end{verbatim}\end{quote} ! 196: The parameters to this procedure are: ! 197: \begin{describe} ! 198: \item[\verb"sd":] the association-descriptor; ! 199: ! 200: \item[\verb"status":] the acceptance indicator ! 201: (either \verb"ACS_ACCEPT" if the association is to be accepted, ! 202: or one of the user-initiated rejection codes listed in ! 203: Table~\ref{AcSAPreasons} on page~\pageref{AcSAPreasons}); ! 204: ! 205: \item[\verb"data":] any initial data ! 206: (regardless of whether the association is to be accepted); ! 207: and, ! 208: ! 209: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, ! 210: which is updated only if the call fails. ! 211: \end{describe} ! 212: The remaining parameters are for the association control service, ! 213: consult the description of the \verb"AcAssocResponse" routine on ! 214: page~\pageref{AcAssocResponse}. ! 215: ! 216: If the call to \verb"RtOpenResponse" is successful, ! 217: and the \verb"status" parameter was set to \verb"ACS_ACCEPT", ! 218: then association establishment has now been completed. ! 219: If the call was successful, ! 220: but the \verb"status" parameter was not \verb"ACS_ACCEPT", ! 221: then the association has been rejected and the responder may exit. ! 222: Otherwise, ! 223: if the call failed and the reason is ``fatal'', ! 224: then the association is lost. ! 225: ! 226: \subsubsection {Client Initialization} ! 227: A program wishing to associate itself with another user of reliable transfer ! 228: services calls the \verb"RtOpenRequest" routine, ! 229: which corresponds to the {\sf RT-OPEN.REQUEST\/} action. ! 230: \begin{quote}\index{RtOpenRequest}\small\begin{verbatim} ! 231: int RtOpenRequest (mode, turn, context, callingtitle, ! 232: calledtitle, callingaddr, calledaddr, ctxlist, ! 233: defctxname, data, qos, rtc, rti) ! 234: int mode, ! 235: turn; ! 236: AEI callingtitle, ! 237: calledtitle; ! 238: OID context; ! 239: struct PSAPaddr *callingaddr, ! 240: *calledaddr; ! 241: int single; ! 242: struct PSAPctxlist *ctxlist; ! 243: OID defctxname; ! 244: PE data; ! 245: struct QOStype *qos; ! 246: struct RtSAPconnect *rtc; ! 247: struct RtSAPindication *rti; ! 248: \end{verbatim}\end{quote} ! 249: The parameters to this procedure are: ! 250: \begin{describe} ! 251: \item[\verb"mode":] the dialogue mode; ! 252: ! 253: \item[\verb"turn":] who gets the initial turn; ! 254: ! 255: \item[\verb"data":] any initial data; ! 256: ! 257: \item[\verb"qos":] the quality of service on the connection ! 258: (see Section~\ref{tsap:qos} in \voltwo/); ! 259: ! 260: \item[\verb"rtc":] a pointer to a \verb"RtSAPconnect" structure, which is ! 261: updated only if the call succeeds; ! 262: and, ! 263: ! 264: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 265: updated only if the call fails. ! 266: \end{describe} ! 267: The remaining parameters are for the association control service, ! 268: consult the description of the \verb"AcAssocRequest" routine on ! 269: page~\pageref{AcAssocRequest}. ! 270: If the call to \verb"RtOpenRequest" is successful ! 271: (this corresponds to a {\sf RT-OPEN.CON\-FIR\-MA\-TION\/} event), ! 272: it returns information in the \verb"rtc" parameter, ! 273: which is a pointer to a \verb"RtSAPconnect" structure. ! 274: \begin{quote}\index{RtSAPconnect}\small\begin{verbatim} ! 275: struct RtSAPconnect { ! 276: int rtc_sd; ! 277: ! 278: int rtc_result; ! 279: ! 280: PE rtc_data; ! 281: ! 282: struct AcSAPconnect rtc_connect; ! 283: }; ! 284: \end{verbatim}\end{quote} ! 285: The elements of this structure are: ! 286: \begin{describe} ! 287: \item[\verb"rtc\_sd":] the association-descriptor to be used to ! 288: reference this association; ! 289: ! 290: \item[\verb"rtc\_result":] the association response; ! 291: ! 292: \item[\verb"rtc\_data":] any initial data ! 293: (regardless of whether the association was accepted); ! 294: and, ! 295: ! 296: \item[\verb"rtc\_connect":] a \verb"AcSAPconnect" structure ! 297: (consult page~\pageref{AcSAPconnect}). ! 298: \end{describe} ! 299: If the call to \verb"RtOpenRequest" is successful, ! 300: and the \verb"rtc_result" element is set to \verb"RTS_ACCEPT", ! 301: then association establishment has completed. ! 302: If the call is successful, ! 303: but the \verb"rtc_result" element is not \verb"RTS_ACCEPT", ! 304: then the association attempt has been rejected; ! 305: consult Table~\ref{RtSAPreasons} to determine the reason for the reject. ! 306: Otherwise, if the call fails then the association is not established and ! 307: the \verb"RtSAPabort" structure of the \verb"RtSAPindication" discriminated ! 308: union has been updated. ! 309: ! 310: Note that the \verb"rtc_data" element is allocated via \man malloc(3) and ! 311: should be released using the \verb"RTCFREE" macro when no longer referenced. ! 312: The \verb"RTCFREE" macro behaves as if it was defined as: ! 313: \begin{quote}\index{RTCFREE}\small\begin{verbatim} ! 314: void RTCFREE (rtc) ! 315: struct RtSAPconnect *rtc; ! 316: \end{verbatim}\end{quote} ! 317: The macro frees only the data allocated by \verb"RtOpenRequest", ! 318: and not the \verb"RtSAPconnect" structure itself. ! 319: Further, ! 320: \verb"RTCFREE" should be called only if the call to the \verb"RtOpenRequest" ! 321: routine returned \verb"OK". ! 322: ! 323: \subsection {Association Release} ! 324: The \verb"RtCloseRequest" routine is used to request the release of an ! 325: association, ! 326: and corresponds to a {\sf RT-CLOSE.REQUEST\/} action. ! 327: \begin{quote}\index{RtCloseRequest}\small\begin{verbatim} ! 328: int RtCloseRequest (sd, reason, data, acr, rti) ! 329: int sd, ! 330: reason; ! 331: PE data; ! 332: struct AcSAPrelease *acr; ! 333: struct RtSAPindication *rti; ! 334: \end{verbatim}\end{quote} ! 335: The parameters to this procedure: ! 336: \begin{describe} ! 337: \item[\verb"sd":] the association-descriptor; ! 338: ! 339: \item[\verb"reason":] the reason why the association should be released, ! 340: one of: ! 341: \[\begin{tabular}{|l|l|} ! 342: \hline ! 343: \multicolumn{1}{|c|}{\bf Value}& ! 344: \multicolumn{1}{c|}{\bf Reason}\\ ! 345: \hline ! 346: \tt ACF\_NORMAL& normal\\ ! 347: \tt ACF\_URGENT& urgent\\ ! 348: \tt ACF\_UNDEFINED& undefined\\ ! 349: \hline ! 350: \end{tabular}\] ! 351: ! 352: \item[\verb"data":] any final data; ! 353: ! 354: \item[\verb"acr":] a pointer to a \verb"AcSAPrelease" structure, ! 355: which is updated only if the call succeeds; ! 356: and, ! 357: ! 358: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, ! 359: which is updated only if the call fails. ! 360: \end{describe} ! 361: If the call to \verb"RtCloseRequest" is successful, ! 362: then this corresponds to a {\sf RT-CLOSE.CONFIRMATION\/} event, ! 363: and it returns information in the \verb"acr" parameter, ! 364: which is a pointer to a \verb"AcSAPrelease" structure ! 365: (consult page~\pageref{AcSAPrelease}). ! 366: ! 367: If the call to \verb"RtCloseRequest" is successful, ! 368: then the association has been released. ! 369: Otherwise the \verb"RtSAPabort" element of the \verb"RtSAPindication" ! 370: parameter \verb"rti" contains the reason for failure. ! 371: ! 372: Upon receiving a {\sf RT-CLOSE.INDICATION\/} event, ! 373: the user is required to generate a {\sf RT-CLOSE.RESPONSE\/} action ! 374: using the \verb"RtCloseResponse" routine. ! 375: \begin{quote}\index{RtCloseResponse}\small\begin{verbatim} ! 376: int RtCloseResponse (sd, reason, data, rti) ! 377: int sd, ! 378: reason; ! 379: PE data; ! 380: struct RtSAPindication *rti; ! 381: \end{verbatim}\end{quote} ! 382: The parameters to this procedure: ! 383: \begin{describe} ! 384: \item[\verb"sd":] the association-descriptor; ! 385: ! 386: \item[\verb"reason":] the reason for the indicator, ! 387: one of: ! 388: \[\begin{tabular}{|l|l|} ! 389: \hline ! 390: \multicolumn{1}{|c|}{\bf Value}& ! 391: \multicolumn{1}{c|}{\bf Reason}\\ ! 392: \hline ! 393: \tt ACR\_NORMAL& normal\\ ! 394: \tt ACR\_NOTFINISHED& not finished\\ ! 395: \tt ACR\_UNDEFINED& undefined\\ ! 396: \hline ! 397: \end{tabular}\] ! 398: ! 399: \item[\verb"data":] any final data; ! 400: and, ! 401: ! 402: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, ! 403: which is updated only if the call fails. ! 404: \end{describe} ! 405: If the call to \verb"RtCloseResponse" is successful, ! 406: then the association has been released. ! 407: If the call was successful, ! 408: but the \verb"reason" parameter was not \verb"ACR_NORMAL", ! 409: then the association remains established. ! 410: ! 411: \subsection {Association Abort} ! 412: To unilaterally abort an association, ! 413: the routine \verb"RtUAbortRequest" routine is used ! 414: which corresponds to the {\sf RT-U-ABORT.REQUEST\/} action. ! 415: \begin{quote}\index{RtUAbortRequest}\small\begin{verbatim} ! 416: int RtUAbortRequest (sd, data, rti) ! 417: int sd; ! 418: PE data; ! 419: struct RtSAPindication *rti; ! 420: \end{verbatim}\end{quote} ! 421: The parameters to this procedure: ! 422: \begin{describe} ! 423: \item[\verb"sd":] the association-descriptor; ! 424: ! 425: \item[\verb"data":] any abort data; ! 426: and, ! 427: ! 428: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, ! 429: which is updated only if the call fails. ! 430: \end{describe} ! 431: If the call to \verb"RtUAbortRequest" is successful, ! 432: then the association is immediately relesaed, ! 433: and any data queued for the association may be lost. ! 434: ! 435: \section {Reliable Transfer}\label{rts:transfer} ! 436: ! 437: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 438: \bf NOTE:& Users should also consult Sectin~\ref{rts:revisited} on ! 439: page~\pageref{rts:revisited} for optional routines to ! 440: make RTS behave more sanely. ! 441: \end{tabular}}\] ! 442: ! 443: Once the association has been established, ! 444: an association-descriptor is used to reference the association. ! 445: This is usually the first parameter given to any of the remaining routines in ! 446: the \man librtsap(3n) library. ! 447: Further, ! 448: the last parameter is usually a pointer to a \verb"RtSAPindication" ! 449: structure. ! 450: If a call to one of these routines fails, ! 451: then the structure is updated. ! 452: \begin{quote}\index{RtSAPindication}\small\begin{verbatim} ! 453: struct RtSAPindication { ! 454: int rti_type; ! 455: #define RTI_TURN 0x00 ! 456: #define RTI_TRANSFER 0x01 ! 457: #define RTI_ABORT 0x02 ! 458: #define RTI_CLOSE 0x03 (X.410 CLOSE) ! 459: #define RTI_FINISH 0x04 (RT-CLOSE) ! 460: ! 461: union { ! 462: struct RrSAPturn rti_un_turn; ! 463: struct RtSAPtransfer rti_un_transfer; ! 464: struct RtSAPabort rti_un_abort; ! 465: struct RtSAPclose rti_un_close; ! 466: struct AcSAPfinish rti_un_finish ! 467: } rti_un; ! 468: #define rti_turn rti_un.rti_un_turn ! 469: #define rti_transfer rti_un.rti_un_transfer ! 470: #define rti_abort rti_un.rti_un_abort ! 471: #define rti_close rti_un.rti_un_close ! 472: #define rti_finish rti_un.rti_un_finish ! 473: }; ! 474: \end{verbatim}\end{quote} ! 475: As shown, this structure is really a discriminated union ! 476: (a structure with a tag element followed by a union). ! 477: Hence, on a failure return, ! 478: one first coerces a pointer to the \verb"RtSAPabort" structure contained ! 479: therein, ! 480: and then consults the elements of that structure. ! 481: \begin{quote}\index{RtSAPabort}\small\begin{verbatim} ! 482: struct RtSAPabort { ! 483: int rta_peer; ! 484: ! 485: int rta_reason; ! 486: ! 487: PE rta_udata; ! 488: ! 489: #define RTA_SIZE 512 ! 490: int rta_cc; ! 491: char rta_data[RTA_SIZE]; ! 492: }; ! 493: \end{verbatim}\end{quote} ! 494: The elements of a \verb"RtSAPabort" structure are: ! 495: \begin{describe} ! 496: \item[\verb"rta\_peer":] if set, indicates a user-initiated abort ! 497: (a {\sf RT-U-A\-BORT.IN\-DI\-CA\-TION\/} event); ! 498: if not set, indicates a provider-initiated abort ! 499: (a {\sf RT-P-ABORT.INDICATION\/} event); ! 500: ! 501: \item[\verb"rta\_reason":] the reason for the abort ! 502: (codes are listed in Table~\ref{RtSAPreasons}); ! 503: ! 504: \item[\verb"rta\_udata":] optionally, data associated with the user-initiated ! 505: abort; ! 506: and, ! 507: ! 508: \item[\verb"rta\_data"/\verb"rta\_cc":] a diagnostic string from the provider. ! 509: \end{describe} ! 510: \tagtable[tp]{2c-1}{RtSAP Failure Codes}{RtSAPreasons} ! 511: Note that the \verb"rta_udata" element is allocated via \man malloc(3) and ! 512: should be released using the \verb"RTAFREE" macro when no longer referenced. ! 513: The \verb"RTAFREE" macro behaves as if it was defined as: ! 514: \begin{quote}\index{RTAFREE}\small\begin{verbatim} ! 515: void RTAFREE (rta) ! 516: struct RtSAPabort *rta; ! 517: \end{verbatim}\end{quote} ! 518: The macro frees only the data allocated in the \verb"RtSAPabort" structure ! 519: and not the structure itself. ! 520: ! 521: On a failure return, ! 522: if the \verb"rta_reason" element of the \verb"RtSAPabort" structure is ! 523: associated with a fatal error, ! 524: the the association is released. ! 525: The \verb"RTS_FATAL" macro can be used to determine this. ! 526: \begin{quote}\index{RTS\_FATAL}\small\begin{verbatim} ! 527: int RTS_FATAL (r) ! 528: int r; ! 529: \end{verbatim}\end{quote} ! 530: For protocol purists, ! 531: the \verb"RTS_OFFICIAL" macro can be used to determine if the error is an ! 532: ``official'' error as defined by the specification, ! 533: or an ``unofficial'' error used by the implementation. ! 534: \begin{quote}\index{RTS\_OFFICIAL}\small\begin{verbatim} ! 535: int RTS_OFFICIAL (r) ! 536: int r; ! 537: \end{verbatim}\end{quote} ! 538: ! 539: \subsection {Sending Data} ! 540: When the user has the turn, ! 541: it can use the \verb"RtTransferRequest" routine ! 542: (this corresponds to the {\sf RT-TRANSFER.REQUEST\/} action) ! 543: to request the reliable transfer of a data structure. ! 544: \begin{quote}\index{RtTransferRequest}\small\begin{verbatim} ! 545: int RtTransferRequest (sd, data, secs, rti) ! 546: int sd; ! 547: PE data; ! 548: int secs; ! 549: struct RtSAPindication *rti; ! 550: \end{verbatim}\end{quote} ! 551: The parameters to this procedure are: ! 552: \begin{describe} ! 553: \item[\verb"sd":] the association-descriptor; ! 554: ! 555: \item[\verb"data":] the data to be transferred; ! 556: ! 557: \item[\verb"secs":] the amount of time, in seconds, permitted to transfer the ! 558: data (use the manifest constant \verb"NOTOK" if time is unimportant); ! 559: and, ! 560: ! 561: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 562: updated only if the call fails. ! 563: \end{describe} ! 564: If \verb"RtTransferRequest" succeeds, ! 565: then the data has been reliably transferred to the other user. ! 566: Otherwise the \verb"RtSAPabort" structure contained in ! 567: the \verb"RtSAPindication" parameter \verb"rti" ! 568: contains the reason for failure. ! 569: ! 570: \subsection {Receiving Data} ! 571: The \verb"RtWaitRequest" routine is used to wait for an event ! 572: (usually incoming data) to occur. ! 573: \begin{quote}\index{RtWaitRequest}\small\begin{verbatim} ! 574: int RtWaitRequest (sd, secs, rti) ! 575: int sd; ! 576: int secs; ! 577: struct RtSAPindication *rti; ! 578: \end{verbatim}\end{quote} ! 579: The parameters to this procedure are: ! 580: \begin{describe} ! 581: \item[\verb"sd":] the association-descriptor; ! 582: ! 583: \item[\verb"secs":] the maximum number of seconds to wait for the event ! 584: (a value of \verb"NOTOK" indicates that the call should block indefinitely, ! 585: whereas a value of \verb"OK" indicates that the call should not block at all, ! 586: e.g., a polling action); ! 587: and, ! 588: ! 589: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, ! 590: which is always updated. ! 591: \end{describe} ! 592: Unlike the other routines in the \man librtsap(3n) library, ! 593: the \verb"RtWaitRequest" routine returns one of three values: ! 594: \verb"NOTOK" (on failure), ! 595: \verb"OK" (on reading data) ! 596: or ! 597: \verb"DONE" (when something else happens). ! 598: ! 599: If the call to \verb"RtWaitRequest" returns the manifest constant ! 600: \verb"NOTOK", ! 601: then the \verb"RtSAPabort" structure contained in ! 602: the \verb"RtSAPindication" parameter ! 603: \verb"rti" contains the reason for the failure. ! 604: ! 605: Otherwise if the call to \verb"RoWaitRequest" returns the manifest constant ! 606: \verb"OK", ! 607: then data has arrived. ! 608: This event is encoded in the \verb"rti" parameter, ! 609: depending on the value of the \verb"rti_type" element. ! 610: Currently, ! 611: when \verb"RoWaitRequest" returns \verb"OK", ! 612: the \verb"rti_type" element is set to \verb"RTI_TRANSFER", ! 613: which indicates that a {\sf RT-TRANSFER.REQUEST\/} event has occurred. ! 614: ! 615: Otherwise if the call to \verb"RtWaitRequest" returns the manifest constant ! 616: \verb"DONE", ! 617: then some event other than data arriving has occurred. ! 618: This event is also encoded in the \verb"rti" parameter, ! 619: depending on the value of the \verb"rti_type" element. ! 620: Currently, ! 621: when \verb"RoWaitRequest" returns \verb"DONE", ! 622: the \verb"rti_type" element is set to one of two values: ! 623: \[\begin{tabular}{|l|l|} ! 624: \hline ! 625: \multicolumn{1}{|c|}{\bf Value}& ! 626: \multicolumn{1}{c|}{\bf Event}\\ ! 627: \hline ! 628: \tt RTI\_TURN& \sf RT-TURN-PLEASE.INDICATION\\ ! 629: \hline ! 630: \tt RTI\_TURN& \sf RT-TURN-GIVE.INDICATION\\ ! 631: \hline ! 632: \tt RTI\_CLOSE& \sf X.410 CLOSE.INDICATION\\ ! 633: & \ \ (for old-style associations)\\ ! 634: \hline ! 635: \tt RTI\_FINISH& \sf RT-CLOSE.INDICATION\\ ! 636: \hline ! 637: \end{tabular}\] ! 638: ! 639: \subsubsection {Transfer Indication} ! 640: When an {\sf RT-TRANSFER.INDICATION\/} event occurs, ! 641: the \verb"rti_type" field of the \verb"rti" parameter contains the value ! 642: \verb"RTI_TRANSFER", ! 643: and a \verb"RtSAPtransfer" structure is contained inside the \verb"rti" ! 644: parameter. ! 645: \begin{quote}\index{RtSAPtransfer}\small\begin{verbatim} ! 646: struct RtSAPtransfer { ! 647: PE rtt_data; ! 648: }; ! 649: \end{verbatim}\end{quote} ! 650: The elements of this structure are: ! 651: \begin{describe} ! 652: \item[\verb"rtt\_data":] the data received. ! 653: \end{describe} ! 654: Note that the \verb"rtt_data" element is allocated via \man malloc(3) and ! 655: should be released using the \verb"RTTFREE" macro when no longer referenced. ! 656: The \verb"RTTFREE" macro behaves as if it was defined as: ! 657: \begin{quote}\index{RTTFREE}\small\begin{verbatim} ! 658: void RTTFREE (rtt) ! 659: struct RtSAPtransfer *rtt; ! 660: \end{verbatim}\end{quote} ! 661: The macro frees only the data allocated in the \verb"RtSAPtransfer" structure ! 662: and not the structure itself. ! 663: ! 664: \subsubsection {Turn Indication} ! 665: When an {\sf RT-TURN-GIVE.INDICATION\/} or {\sf RT-TURN-PLEASE.INDICATION\/} ! 666: events occur, ! 667: the \verb"rti_type" field of the \verb"rti" parameter contains the value ! 668: \verb"RTI_TURN", ! 669: and a \verb"RtSAPturn" structure is contained inside the \verb"rti" ! 670: parameter. ! 671: \begin{quote}\index{RtSAPturn}\small\begin{verbatim} ! 672: struct RtSAPturn { ! 673: int rtu_please; ! 674: ! 675: int rtu_priority; ! 676: }; ! 677: \end{verbatim}\end{quote} ! 678: The elements of this structure are: ! 679: \begin{describe} ! 680: \item[\verb"rtu\_please":] if set, indicates that a ! 681: {\sf RT-PLEASE-TURN.INDICATION\/} event has occurred; ! 682: if not set, ! 683: indicates that a {\sf RT-GIVE-TURN.IN\-DI\-CA\-TION\/} event has occurred; ! 684: and, ! 685: ! 686: \item[\verb"rtu\_priority":] the priority at which the turn is requested ! 687: (meaningful only if \verb"rtu_please" is set). ! 688: \end{describe} ! 689: ! 690: \subsubsection {Close Indication} ! 691: When an {\sf X.410 CLOSE.INDICATION\/} event occurs, ! 692: the \verb"rti_type" field of the \verb"rti" parameter contains the value ! 693: \verb"RTI_CLOSE", ! 694: and a \verb"RtSAPclose" structure is contained inside the \verb"rti" ! 695: parameter. ! 696: \begin{quote}\index{RtSAPclose}\small\begin{verbatim} ! 697: struct RtSAPclose { ! 698: int rtc_dummy; ! 699: }; ! 700: \end{verbatim}\end{quote} ! 701: ! 702: \subsubsection {Finish Indication} ! 703: When an {\sf RT-CLOSE.INDICATION\/} event occurs, ! 704: the \verb"rti_type" field of the \verb"rti" parameter contains the value ! 705: \verb"RTI_FINISH", ! 706: and a \verb"AcSAPfinish" structure is contained inside the \verb"rti" ! 707: parameter. ! 708: ! 709: \subsection {Managing the Turn} ! 710: The user with the turn is permitted to send data to the other user. ! 711: To request the turn, ! 712: one invokes the \verb"RtPTurnRequest" routine, ! 713: which corresponds to the {\sf RT-PLEASE-TURN.REQUEST}. ! 714: \begin{quote}\index{RtPTurnRequest}\small\begin{verbatim} ! 715: int RtPTurnRequest (sd, priority, rti) ! 716: int sd; ! 717: int priority; ! 718: struct RtSAPindication *rti; ! 719: \end{verbatim}\end{quote} ! 720: The parameters to this procedure are: ! 721: \begin{describe} ! 722: \item[\verb"sd":] the association-descriptor; ! 723: ! 724: \item[\verb"priority":] the priority at which the turn is requested ! 725: (this is defined by each application); ! 726: and, ! 727: ! 728: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 729: updated only if the call fails. ! 730: \end{describe} ! 731: If the call to the \verb"RtPTurnRequest" routine succeeds, ! 732: then the turn has been requested of the remote user. ! 733: Otherwise the \verb"RtSAPabort" structure contained in ! 734: the \verb"RtSAPindication" parameter ! 735: \verb"rti" contains the reason for failure. ! 736: ! 737: To relinquish the turn, ! 738: one invokes the \verb"RtGTurnRequest" routine, ! 739: which corresponds to the {\sf RT-GIVE-TURN.REQUEST}. ! 740: \begin{quote}\index{RGPTurnRequest}\small\begin{verbatim} ! 741: int RtGTurnRequest (sd, rti) ! 742: int sd; ! 743: struct RtSAPindication *rti; ! 744: \end{verbatim}\end{quote} ! 745: The parameters to this procedure are: ! 746: \begin{describe} ! 747: \item[\verb"sd":] the association-descriptor; ! 748: and, ! 749: ! 750: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 751: updated only if the call fails. ! 752: \end{describe} ! 753: If the call to the \verb"RtGTurnRequest" routine succeeds, ! 754: then the turn has been relinquished to the remote user. ! 755: Otherwise the \verb"RtSAPabort" structure contained in ! 756: the \verb"RtSAPindication" parameter ! 757: \verb"rti" contains the reason for failure. ! 758: ! 759: \subsection {Asynchronous Event Handling} ! 760: The events discussed thus far have been synchronous in nature. ! 761: Some users of the reliable transfer service may wish an asynchronous interface. ! 762: The \verb"RtSetIndications" routine is used to change the service associated ! 763: with an association-descriptor to an asynchronous interface. ! 764: \begin{quote}\index{RtSetIndications}\small\begin{verbatim} ! 765: int RtSetIndications (sd, indication, rti) ! 766: int sd; ! 767: IFP indication; ! 768: struct RtSAPindication *rti; ! 769: \end{verbatim}\end{quote} ! 770: The parameters to this procedure are: ! 771: \begin{describe} ! 772: \item[\verb"sd":] the association-descriptor; ! 773: ! 774: \item[\verb"indication":] the address of an event-handler routine to be ! 775: invoked when an event occurs; ! 776: and, ! 777: ! 778: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 779: updated only if the call fails. ! 780: \end{describe} ! 781: If the service is to be made asynchronous, ! 782: then \verb"indication" is specified; ! 783: otherwise, ! 784: if the service is to be made synchronous, ! 785: it is not specified (use the manifest constant \verb"NULLIFP"). ! 786: The most likely reason for the call failing is \verb"RTS_WAITING", ! 787: which indicates that an event is waiting for the user. ! 788: ! 789: When an event occurs, ! 790: the event-handler routine is invoked with two parameters: ! 791: \begin{quote}\small\begin{verbatim} ! 792: (*handler) (sd, rti); ! 793: int sd; ! 794: struct RtSAPindication *rti; ! 795: \end{verbatim}\end{quote} ! 796: The parameters are: ! 797: \begin{describe} ! 798: \item[\verb"sd":] the association-descriptor; ! 799: and, ! 800: ! 801: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure encoding ! 802: the event. ! 803: \end{describe} ! 804: Note that the data contained in the structure was allocated via \man malloc(3), ! 805: and should be released with the appropriate macro ! 806: (either \verb"RTTFREE" or \verb"RTPFREE") ! 807: when no longer needed. ! 808: ! 809: When an event-handler is invoked, ! 810: future invocations of the event-hander are blocked until it returns. ! 811: The return value of the event-handler is ignored. ! 812: Further, ! 813: during the execution of a synchronous call to the library, ! 814: the event-handler will be blocked from being invoked. ! 815: ! 816: \[\fbox{\begin{tabular}{lp{0.8\textwidth}} ! 817: \bf NOTE:& The \man librtsap(3n) library uses the SIGEMT signal to ! 818: provide these services. ! 819: Programs using asynchronous association-descriptors should NOT ! 820: use SIGEMT for other purposes. ! 821: \end{tabular}}\] ! 822: ! 823: \subsection {Synchronous Event Multiplexing} ! 824: A user of the reliable transfer service may wish to manage multiple ! 825: asso\-ci\-ation-descriptors simultaneously; ! 826: the routine \verb"RtSelectMask" is provided for this purpose. ! 827: This routine updates a file-descriptor mask and associated counter for use ! 828: with \verb"xselect" (consult Section~\ref{acs:select}), ! 829: as assocation-descriptors are file-descriptors. ! 830: \begin{quote}\index{RtSelectMask}\small\begin{verbatim} ! 831: int RtSelectMask (sd, mask, nfds, rti) ! 832: int sd; ! 833: fd_set *mask, ! 834: int *nfds; ! 835: struct RtSAPindication *rti; ! 836: \end{verbatim}\end{quote} ! 837: The parameters to this procedure are: ! 838: \begin{describe} ! 839: \item[\verb"sd":] the association-descriptor; ! 840: ! 841: \item[\verb"mask":] a pointer to a file-descriptor mask meaningful to ! 842: \verb"xselect"; ! 843: ! 844: \item[\verb"nfds":] a pointer to an integer-valued location meaningful to ! 845: \verb"xselect"; ! 846: and, ! 847: ! 848: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 849: updated only if the call fails. ! 850: \end{describe} ! 851: If the call is successful, then the \verb"mask" and \verb"nfds" parameters can ! 852: be used as arguments to \verb"xselect". ! 853: The most likely reason for the call failing is \verb"RTS_WAITING", ! 854: which indicates that an event is waiting for the user. ! 855: ! 856: If \verb"xselect" indicates that the association-descriptor is ready for ! 857: reading, ! 858: \verb"RtWaitRequest" should be called with the \verb"secs" parameter equal to ! 859: \verb"OK". ! 860: If the network activity does not constitute an entire event for the user, ! 861: then \verb"RtWaitRequest" will return \verb"NOTOK" with error code ! 862: \verb"RTS_TIMER". ! 863: ! 864: \subsection {Reliable Transfer (revisited)}\label{rts:revisited} ! 865: The mechanism provided by \verb"RtTransferRequest" may not be useful for ! 866: applications which have large amounts of data to transfer. ! 867: In most cases, ! 868: it is preferable to transfer data incrementally. ! 869: To provide for this functionality, ! 870: the routine \verb"RtSetDownTrans" is provided: ! 871: \begin{quote}\index{RtSetDownTrans}\small\begin{verbatim} ! 872: int RtSetDownTrans (sd, fnx, rti) ! 873: int sd; ! 874: IFP fnx; ! 875: struct RtSAPindication *rti; ! 876: \end{verbatim}\end{quote} ! 877: The parameters to this procedure are: ! 878: \begin{describe} ! 879: \item[\verb"sd":] the association descriptor; ! 880: ! 881: \item[\verb"fnx":] the address of an event-handler routine to be invoked when ! 882: data is needed; and, ! 883: ! 884: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 885: updated only if the call fails. ! 886: \end{describe} ! 887: If the \verb"fnx" parameter is some value other than the manifest constant ! 888: \verb"NULLIFP", ! 889: then upon successful return from \verb"RtSetDownTrans", ! 890: the behavior of the routine \verb"RtTransferRequest" is altered. ! 891: \begin{enumerate} ! 892: \item The \verb"data" parameter to \verb"RtTransferRequest" may be ! 893: \verb"NULLPE". ! 894: ! 895: \item In this case, the event-handler routine \verb"fnx" will be invoked ! 896: in order to retrieve a portion of the data to be transferred: ! 897: \begin{quote}\small\begin{verbatim} ! 898: result = (*fnx) (sd, base, len, size, ack, ssn, rti); ! 899: int sd; ! 900: char **base; ! 901: int *len, ! 902: size; ! 903: long ack, ! 904: ssn; ! 905: struct RtSAPindication *rti; ! 906: \end{verbatim} ! 907: \end{quote} ! 908: where \verb"sd" is the association-descriptor which was given to the routine ! 909: \verb"RtTransferRequest". ! 910: ! 911: \item If the \verb"base" parameter has the value \verb"NULLVP", ! 912: then a {\sf RT-PLEASE.IN\-DI\-CA\-TION\/} event is being signaled, ! 913: and the \verb"size" parameter has the value of the priority associated ! 914: with the event. ! 915: ! 916: \item Otherwise, the \verb"base" and \verb"len" parameters point to a ! 917: pointer/length pair which should be set by the event handler to upto ! 918: \verb"size" octets. The event handler is responsible for any ! 919: memory allocation (e.g., allocating a buffer of \verb"size" octets and ! 920: then assigning the address of the buffer to \verb"*base"). ! 921: Once a buffer is chosen, the event handler should read upto ! 922: \verb"size" octets into the buffer and set \verb"*len" to the number ! 923: of octets actually read. The \verb"ssn" and \verb"ack" parameters ! 924: given the values of the last synchronization point requested and ! 925: acknolwedged (how this information should be used is unknown at this ! 926: time). If the value assigned to \verb"*len" is zero, then this ! 927: indicates that all data has been read and the transfer should be ! 928: completed. ! 929: ! 930: \item If the value of the \verb"size" is zero, then this indicates that the ! 931: provider could not negotiate a incremental transfer and the event ! 932: handler should allocate a buffer of arbitrary size, read all of the ! 933: data to be transferred into that one buffer, and then update ! 934: \verb"*base" and \verb"*len" accordingly. ! 935: ! 936: \item If the event handler encounters an error, it should return the ! 937: manifest constant \verb"NOTOK" (otherwise, it should return ! 938: \verb"OK"). ! 939: If an error is signaled, the event handler should update the ! 940: \verb"rti" structure accordingly. The easiest way to do this is: ! 941: \begin{quote}\small\begin{verbatim} ! 942: return rtsaplose (rti, RTS_TRANSFER, NULLCP, "text"); ! 943: \end{verbatim}\end{quote} ! 944: If the event is {\sf RT-PLEASE.REQUEST}, ! 945: then signaling an error results in the provider generating an ! 946: {\sf S-ACTIVITY-INTERRUPT.REQUEST}; ! 947: otherwise when an error is signaled, the provider will generate an ! 948: {\sf S-ACTIVITY-DISCARD.REQUEST\/} to abort the transfer. ! 949: \end{enumerate} ! 950: ! 951: For similar reasons, ! 952: the mechanism employed by \verb"RtWaitRequest" may not be useful for ! 953: applications which have large amounts of data to transfer. ! 954: Again, ! 955: in most cases it is preferable to transfer data incrementally. ! 956: To provide for this functionality, ! 957: the routine \verb"RtSetUpTrans" is provided: ! 958: \begin{quote}\index{RtSetUpTrans}\small\begin{verbatim} ! 959: int RtSetUpTrans (sd, fnx, rti) ! 960: int sd; ! 961: IFP fnx; ! 962: struct RtSAPindication *rti; ! 963: \end{verbatim}\end{quote} ! 964: The parameters to this procedure are: ! 965: \begin{describe} ! 966: \item[\verb"sd":] the association descriptor; ! 967: ! 968: \item[\verb"fnx":] the address of an event-handler routine to be invoked when ! 969: data has been received; and, ! 970: ! 971: \item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is ! 972: updated only if the call fails. ! 973: \end{describe} ! 974: If the \verb"fnx" parameter is some value other than the manifest constant ! 975: \verb"NULLIFP", ! 976: then upon successful return from \verb"RtSetUpTrans", ! 977: the behavior of the routine \verb"RtWaitRequest" is altered when it returns an ! 978: {\sf RT-TRANSFER.INDICATION\/} ! 979: (the \verb"rti_type" field of the \verb"rti" parameter contains the value ! 980: \verb"RTI_TRANSFER", ! 981: and a \verb"RtSAPtransfer" structure is contained inside the \verb"rti" ! 982: parameter). ! 983: No data is returned by \verb"RtWaitRequest", ! 984: rather as data is received, the event routine is invoked: ! 985: \begin{enumerate} ! 986: \item When data is received, the event-handler routine \verb"fnx" will ! 987: be invoked ! 988: in order to store a portion of the data being transferred: ! 989: \begin{quote}\small\begin{verbatim} ! 990: result = (*fnx) (sd, event, addr, rti); ! 991: int sd; ! 992: int event; ! 993: caddr_t addr; ! 994: struct RtSAPindication *rti; ! 995: \end{verbatim} ! 996: \end{quote} ! 997: where \verb"sd" is the association-descriptor which was given to the routine ! 998: \verb"RtWaitRequest". ! 999: ! 1000: \item If the \verb"event" parameter has the value \verb"SI_DATA", ! 1001: then the \verb"addr" parameter is really a pointer to a ! 1002: \verb"struct qbuf" structure, and the event handler should ! 1003: traverse the qbuf writing out the data found therein. ! 1004: ! 1005: \item If the \verb"event" parameter has the value \verb"SI_SYNC", ! 1006: then the \verb"addr" parameter is really a pointer to a ! 1007: \verb"struct SSAPsync" structure, and the event handler should note ! 1008: the information contained therein.Currently, this will only ! 1009: occur when a {\sf S-MINOR-SYNC.INDICATION\/} event is signaled. ! 1010: ! 1011: \item If the \verb"event" parameter has the value \verb"SI_ACTIVITY", ! 1012: then the \verb"addr" parameter is really a pointer to a ! 1013: \verb"struct SSAPactivity" structure, and the event handler should note ! 1014: the information contained therein. Currently, there are four events ! 1015: that are signaled: ! 1016: \begin{itemize} ! 1017: \item {\sf S-ACTIVITY-START.INDICATION\/} which indicates that a ! 1018: transfer is about to begin; ! 1019: ! 1020: \item {\sf S-ACTIVITY-END.INDICATION\/} which indicates that a ! 1021: transfer is about to complete; and, ! 1022: ! 1023: \item {\sf S-ACTIVITY-INTERRUPT.IN\-DI\-CA\-TION\/} and\\ %%% ! 1024: {\sf S-ACTIVITY-DIS\-CARD.IN\-DI\-CA\-TION\/} which indicate ! 1025: that an activity is either suspended or aborted. ! 1026: \end{itemize} ! 1027: ! 1028: \item If the \verb"event" parameter has the value \verb"SI_REPORT", ! 1029: then the \verb"addr" parameter is really a pointer to a ! 1030: \verb"struct SSAPreport" structure, and the event handler should note ! 1031: the information contained therein. Currently, this will only ! 1032: occur when a {\sf S-U-EXCEPTION-REPORT.IN\-DI\-CA\-TION\/} event is ! 1033: signaled. ! 1034: ! 1035: \item If the event handler encounters an error, it should return the ! 1036: manifest constant \verb"NOTOK" (otherwise, it should return ! 1037: \verb"OK"). ! 1038: If an error is signaled, the event handler should update the ! 1039: \verb"rti" structure accordingly. The easiest way to do this is: ! 1040: \begin{quote}\small\begin{verbatim} ! 1041: return rtsaplose (rti, RTS_TRANSFER, NULLCP, "text"); ! 1042: \end{verbatim}\end{quote} ! 1043: If the event is {\sf S-ACTIVITY-INTERRUPT.INDICATION}, ! 1044: {\sf S-ACTIVITY-INTERRUPT.INDICATION}, ! 1045: or {\sf S-ACTIVITY-INTERRUPT.IN\-DI\-CA\-TION}, ! 1046: then signaling an error is ignorred by the provider; ! 1047: otherwise, when an error is signaled, the provider will generate an ! 1048: {\sf S-U-EXCEPTION-REPORT.REQUEST\/} to abort the transfer. ! 1049: \end{enumerate} ! 1050: ! 1051: \section {Error Conventions} ! 1052: All of the routines in this library return the manifest constant \verb"NOTOK" ! 1053: on error, ! 1054: and also update the \verb"rti" parameter given to the routine. ! 1055: The \verb"rti_abort" element of the \verb"RtSAPindication" structure ! 1056: encodes the reason for the failure. ! 1057: One coerces a pointer to a \verb"RtSAPabort" structure, ! 1058: and consults the \verb"rta_reason" element of this latter structure. ! 1059: This element can be given as a ! 1060: parameter to the routine \verb"RtErrString" which returns a null-terminated ! 1061: diagnostic string. ! 1062: \begin{quote}\index{RtErrString}\small\begin{verbatim} ! 1063: char *RtErrString (c) ! 1064: int c; ! 1065: \end{verbatim}\end{quote} ! 1066: ! 1067: \section {Compiling and Loading} ! 1068: Programs using the \man librtsap(3n) library should include ! 1069: \verb"<isode/rtsap.h>", ! 1070: which automatically includes the header file \verb"<isode/psap.h>" described in ! 1071: Chapter~\ref{libpsap}. ! 1072: The programs should also be loaded with \verb"-lisode". ! 1073: ! 1074: \section {An Example} ! 1075: Let's consider how one might construct a generic server that uses ! 1076: reliable transfer services to establish an association, ! 1077: but then uses remote operation services to communicate with its peer. ! 1078: This entity will use a synchronous interface. ! 1079: ! 1080: There are two parts to the program: ! 1081: initialization and the request/reply loop. ! 1082: In our example, ! 1083: we assume that the routine \verb"error" results in the process being ! 1084: terminated after printing a diagnostic. ! 1085: ! 1086: In Figure~\ref{initRTSresponder}, ! 1087: the initialization steps for the generic responder, ! 1088: including the outer {\em C\/} wrapper, ! 1089: is shown. ! 1090: First, the RtSAP state is re-captured by calling \verb"RtInit". ! 1091: If this succeeds, ! 1092: then the association is authenticated and any command line arguments ! 1093: (as defined in the \man isoservices(5) file described in ! 1094: Chapter~\ref{isoservices} of \voltwo/) ! 1095: are parsed. ! 1096: Assuming that the responder is satisfied with the proposed association, ! 1097: it calls \verb"RtOpenResponse" to accept the association. ! 1098: The \verb"RoSetService" routine is called to set the underlying service to be ! 1099: used for remote operations. ! 1100: Finally, ! 1101: the main request/reply loop is realized. ! 1102: The responder calls \verb"RoWaitRequest" to get the next event, ! 1103: and then calls \verb"ros_indication" to decode that event. ! 1104: ! 1105: Figure~\ref{doROSresponder} on page~\pageref{doROSresponder} ! 1106: contains the definition of the ! 1107: \verb"ros_indication" routine and associated routines. ! 1108: Since the reliable transfer service was used to establish the association, ! 1109: a different closing handler must be used. ! 1110: This is shown in Figure~\ref{finRTSresponder}. ! 1111: {\let\small=\scriptsize %%% yikes! ! 1112: \clearpage ! 1113: \tagrind[tp]{grind2c-2}{Initializing the generic RTS responder}% ! 1114: {initRTSresponder} ! 1115: \clearpage ! 1116: \tagrind[tp]{grind2c-3}{Finalizing the generic RTS responder}% ! 1117: {finRTSresponder}} ! 1118: ! 1119: \section {For Further Reading} ! 1120: \cite{MHS.RTS} is the CCITT recommendation describing the reliable transfer ! 1121: service. ! 1122: The draft CCITT work which assumes the use of new-style associations is ! 1123: defined in \cite{CCITT.RTS.Service} and \cite{CCITT.RTS.Protocol}. ! 1124: Similarly, ! 1125: the corresponding ISO work is ! 1126: \cite{ISO.RTS.Service} and \cite{ISO.RTS.Protocol}. ! 1127: ! 1128: %%% \section {Changes Since the Last Release}\label{rtsap:changes} ! 1129: %%% A brief summary of the major changes between v~\rtsaprevrsn/ and ! 1130: %%% v~\rtsapvrsn/ are now presented. ! 1131: %%% These are the user-visible changes only; ! 1132: %%% changes of a strictly internal nature are not discussed. ! 1133:
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.