DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T r

⟦0c296e770⟧ TextFile

    Length: 41486 (0xa20e)
    Types: TextFile
    Names: »rtsap.tex«

Derivation

└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape
    └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« 
        └─⟦d3ac74d73⟧ 
            └─⟦this⟧ »isode-5.0/doc/manual/rtsap.tex« 
└─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0
    └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« 
        └─⟦de7628f85⟧ 
            └─⟦this⟧ »isode-6.0/doc/manual/rtsap.tex« 

TextFile

% run this through LaTeX with the appropriate wrapper

\f

\chapter	{Reliable Transfer}\label{librtsap}
The \man librtsap(3n) library implements the reliable transfer service (RTS).
The abstraction provided to applications is that of an {\em association\/}
for reliably transfering data.
Most applications use the remote operations facilities,
described in the previous chapter,
and do not directly use the reliable transfer service.%
\footnote{Actually, applications such as message-handling systems explicitly
use the reliable transfer service to perform association management,
and then optionally utilize the remote operations service for actual
communication (otherwise they use reliable transfer directly). 
Both usages are permitted and encouraged in this implementation.}
However,
for those applications which do not base themselves in remote operations,
the reliable transfer interface is used.

As with most models of OSI services,
the underlying assumption is one of a symmetric, asynchronous environment.
That is,
although peers exist at a given layer,
one does not necessary view a peer as either a client or a server.
Further,
the service provider may generate events for the service user without the
latter entity triggering the actions which led to the event.
For example,
in a synchronous environment,
an indication that data has arrived usually occurs only when the service user
asks the service provider to read data;
in an asynchronous environment,
the service provider may interrupt the service user at any time to announce
the arrival of data.

The \verb"rtsap" module in this release initially uses a client/server
paradigm to start communications.
Once the connection is established,
a symmetric view is taken.
In addition,
initially the interface is synchronous;
however once the connection is established,
an asynchronous interface may be selected.

All of the routines in the \man librtsap(3n) library are integer-valued.
They return the manifest constant \verb"OK" on success,
or \verb"NOTOK" otherwise.

\f

\section	{Associations}\label{rts:associations}
As briefly mentioned earlier,
an association is the binding between two applications.
An association is formed when one application,
termed the {\em initiator},
specifies the address of a {\em responder\/} and asks the reliable transfer
service to establish a connection.

There are three aspects of association management:
{\em association establishment},
{\em association release},
and,
{\em association abort}.
Each of these are now described in turn.
All of these facilities rely on the mechanisms described in
Section~\ref{acs:associations} on page~\pageref{acs:associations}.

\subsection	{Association Establishment}
The \man librtsap(3n) library distinguishes between the user which started an
assocoation,
the {\em initiator},
and the user which was subsequently bound to the association,
the {\em responder}.
We sometimes term these two entities the {\em client\/} and the {\em server},
respectively.

\subsubsection	{Addresses}
Addresses for the reliable transfer service entity consist of two parts:
a presentation address (as discussed in Section~\ref{psap:addresses} on
page~\pageref{psap:addresses} of \voltwo/),
and application-entity information
(as discussed in Section~\ref{acs:aei} on page~\pageref{acs:aei}).

In Figure~\ref{getFTAMentity} on page~\pageref{getFTAMentity},
an example of how these components are determined is given.

\subsubsection	{Server Initialization}
The \man tsapd(8c) daemon,
upon accepting a connection from an initiating host,
consults the ISO services database to determine which program
on the local system implements the desired application context.
Once the program has been ascertained,
the daemon runs the program with any argument listed in the database.
In addition,
it appends some {\em magic arguments\/} to the argument vector.
Hence,
the very first action performed by the responder is to re-capcture the RTSE
state contained in the magic arguments.
This is done by calling the routine \verb"RtInit",
which on a successful return,
is equivalent to a {\sf RT-OPEN.INDICATION\/} from the reliable transfer
service provider.
\begin{quote}\index{RtInit}\small\begin{verbatim}
int     RtInit (vecp, vec, rts, rti)
int     vecp;
char  **vec;
struct RtSAPstart *rts;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"vecp":] the length of the argument vector;

\item[\verb"vec":] the argument vector;

\item[\verb"rts":] a pointer to a \verb"RtSAPstart" structure,
which is updated only if the call succeeds;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure,
which is updated only if the call fails.
\end{describe}
If \verb"RtInit" is successful,
it returns information in the \verb"rts" parameter,
which is a pointer to a \verb"RtSAPstart" structure.
\begin{quote}\index{RtSAPstart}\small\begin{verbatim}
struct RtSAPstart {
    int     rts_sd;

    int     rts_mode;
#define RTS_MONOLOGUE   0
#define RTS_TWA         1

    int     rts_turn;
#define RTS_INITIATOR   0
#define RTS_RESPONDER   1

    PE      rts_data;

    struct AcSAPstart rts_start;
};
\end{verbatim}\end{quote}
The elements of this structure are:
\begin{describe}
\item[\verb"rts\_sd":] the association-descriptor to be used to
reference this association;

\item[\verb"rts\_mode":] the dialogue mode (either monologue or two-way
alternate),

\item[\verb"rts\_turn":] the owner of the turn initially;

\item[\verb"rts\_data":] any initial data (this is a pointer to a
\verb"PElement" structure, which is fully explained in Chapter~\ref{libpsap});
and,

\item[\verb"rts\_start":] a \verb"AcSAPstart" structure
(consult page~\pageref{AcSAPstart}).
\end{describe}
Note that the \verb"rts_data" element is allocated via \man malloc(3) and
should be released by using the \verb"RTSFREE" macro when no longer referenced.
The \verb"RTSFREE" macro behaves as if it was defined as:
\begin{quote}\index{RTSFREE}\small\begin{verbatim}
void    RTSFREE (rts)
struct RtSAPstart *rts;
\end{verbatim}\end{quote}
The macro frees only the data allocated by \verb"RtInit",
and not the \verb"RtSAPstart" structure itself.
Further,
\verb"RTSFREE" should be called only if the call to the \verb"RtInit"
routine returned \verb"OK".

If the call to \verb"RtInit" is not successful,
then a {\sf RT-P-ABORT.INDICATION\/} event is simulated,
and the relevant information is returned in an encoded
\verb"RtSAPindication" structure
(discussed in Section~\ref{rts:transfer} on page~\pageref{rts:transfer}).

After examining the information returned by \verb"RtInit" on a successful call
(and possibly after examining the argument vector),
the responder should either accept or reject the association.
For either response,
the responder should use
the \verb"RtOpenResponse" routine
(which corresponds to the {\sf RT-OPEN.RESPONSE\/} action).
\begin{quote}\index{RtOpenResponse}\small\begin{verbatim}
int     RtOpenResponse (sd, status, context, respondtitle, 
        respondaddr, ctxlist, defctxresult, data, rti)
int     sd,
        status;
OID     context;
AEI     respondtitle;
struct PSAPaddr *respondaddr;
struct PSAPctxlist *ctxlist;
int     defctxresult;
PE      data;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"status":] the acceptance indicator
(either \verb"ACS_ACCEPT" if the association is to be accepted,
or one of the user-initiated rejection codes listed in
Table~\ref{AcSAPreasons} on page~\pageref{AcSAPreasons});

\item[\verb"data":] any initial data
(regardless of whether the association is to be accepted);
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure,
which is updated only if the call fails.
\end{describe}
The remaining parameters are for the association control service,
consult the description of the \verb"AcAssocResponse" routine on
page~\pageref{AcAssocResponse}.

If the call to \verb"RtOpenResponse" is successful,
and the \verb"status" parameter was set to \verb"ACS_ACCEPT",
then association establishment has now been completed.
If the call was successful,
but the \verb"status" parameter was not \verb"ACS_ACCEPT",
then the association has been rejected and the responder may exit.
Otherwise,
if the call failed and the reason is ``fatal'',
then the association is lost.

\subsubsection	{Client Initialization}
A program wishing to associate itself with another user of reliable transfer
services calls the \verb"RtOpenRequest" routine,
which corresponds to the {\sf RT-OPEN.REQUEST\/} action.
\begin{quote}\index{RtOpenRequest}\small\begin{verbatim}
int     RtOpenRequest (mode, turn, context, callingtitle,
        calledtitle, callingaddr, calledaddr, ctxlist,
        defctxname, data, qos, rtc, rti)
int     mode,
        turn;
AEI     callingtitle,
        calledtitle;
OID     context;
struct PSAPaddr *callingaddr,
                *calledaddr;
int     single;
struct PSAPctxlist *ctxlist;
OID     defctxname;
PE      data;
struct QOStype *qos;
struct RtSAPconnect *rtc;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"mode":] the dialogue mode;

\item[\verb"turn":] who gets the initial turn;

\item[\verb"data":] any initial data;

\item[\verb"qos":] the quality of service on the connection
(see Section~\ref{tsap:qos} in \voltwo/);

\item[\verb"rtc":] a pointer to a \verb"RtSAPconnect" structure, which is
updated only if the call succeeds;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
The remaining parameters are for the association control service,
consult the description of the \verb"AcAssocRequest" routine on
page~\pageref{AcAssocRequest}.
If the call to \verb"RtOpenRequest" is successful
(this corresponds to a {\sf RT-OPEN.CON\-FIR\-MA\-TION\/} event),
it returns information in the \verb"rtc" parameter,
which is a pointer to a \verb"RtSAPconnect" structure.
\begin{quote}\index{RtSAPconnect}\small\begin{verbatim}
struct RtSAPconnect {
    int     rtc_sd;

    int     rtc_result;

    PE      rtc_data;

    struct AcSAPconnect rtc_connect;
};
\end{verbatim}\end{quote}
The elements of this structure are:
\begin{describe}
\item[\verb"rtc\_sd":] the association-descriptor to be used to
reference this association;

\item[\verb"rtc\_result":] the association response;

\item[\verb"rtc\_data":] any initial data
(regardless of whether the association was accepted);
and,

\item[\verb"rtc\_connect":] a \verb"AcSAPconnect" structure
(consult page~\pageref{AcSAPconnect}).
\end{describe}
If the call to \verb"RtOpenRequest" is successful,
and the \verb"rtc_result" element is set to \verb"RTS_ACCEPT",
then association establishment has completed.
If the call is successful,
but the \verb"rtc_result" element is not \verb"RTS_ACCEPT",
then the association attempt has been rejected;
consult Table~\ref{RtSAPreasons} to determine the reason for the reject.
Otherwise, if the call fails then the association is not established and
the \verb"RtSAPabort" structure of the \verb"RtSAPindication" discriminated
union has been updated.

Note that the \verb"rtc_data" element is allocated via \man malloc(3) and
should be released using the \verb"RTCFREE" macro  when no longer referenced.
The \verb"RTCFREE" macro behaves as if it was defined as:
\begin{quote}\index{RTCFREE}\small\begin{verbatim}
void    RTCFREE (rtc)
struct RtSAPconnect *rtc;
\end{verbatim}\end{quote}
The macro frees only the data allocated by \verb"RtOpenRequest",
and not the \verb"RtSAPconnect" structure itself.
Further,
\verb"RTCFREE" should be called only if the call to the \verb"RtOpenRequest"
routine returned \verb"OK".

\subsection	{Association Release}
The \verb"RtCloseRequest" routine is used to request the release of an
association,
and corresponds to a {\sf RT-CLOSE.REQUEST\/} action.
\begin{quote}\index{RtCloseRequest}\small\begin{verbatim}
int     RtCloseRequest (sd, reason, data, acr, rti)
int     sd,
        reason;
PE      data;
struct AcSAPrelease *acr;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"reason":] the reason why the association should be released,
one of:
\[\begin{tabular}{|l|l|}
\hline
    \multicolumn{1}{|c|}{\bf Value}&
		\multicolumn{1}{c|}{\bf Reason}\\
\hline
    \tt ACF\_NORMAL&	normal\\
    \tt ACF\_URGENT&	urgent\\
    \tt ACF\_UNDEFINED&	undefined\\
\hline
\end{tabular}\]

\item[\verb"data":] any final data;

\item[\verb"acr":] a pointer to a \verb"AcSAPrelease" structure,
which is updated only if the call succeeds;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure,
which is updated only if the call fails.
\end{describe}
If the call to \verb"RtCloseRequest" is successful,
then this corresponds to a {\sf RT-CLOSE.CONFIRMATION\/} event,
and it returns information in the \verb"acr" parameter,
which is a pointer to a \verb"AcSAPrelease" structure
(consult page~\pageref{AcSAPrelease}).

If the call to \verb"RtCloseRequest" is successful,
then the association has been released
(the \verb"acr_affirmative" element of the \verb"acr" parameter is always set).
Otherwise the \verb"AcSAPabort" element of the \verb"AcSAPindication"
parameter \verb"aci" contains the reason for failure.

Upon receiving a {\sf RT-CLOSE.INDICATION\/} event,
the user is required to generate a {\sf RT-CLOSE.RESPONSE\/} action
using the \verb"RtCloseResponse" routine.
\begin{quote}\index{RtCloseResponse}\small\begin{verbatim}
int     RtCloseResponse (sd, reason, data, rti)
int     sd,
        reason;
PE      data;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"reason":] the reason for the indicator,
one of:
\[\begin{tabular}{|l|l|}
\hline
    \multicolumn{1}{|c|}{\bf Value}&
		\multicolumn{1}{c|}{\bf Reason}\\
\hline
    \tt ACR\_NORMAL&		normal\\
    \tt ACR\_NOTFINISHED&	not finished\\
    \tt ACR\_UNDEFINED&		undefined\\
\hline
\end{tabular}\]

\item[\verb"data":] any final data;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure,
which is updated only if the call fails.
\end{describe}
If the call to \verb"RtCloseResponse" is successful,
then the association has been released.
If the call was successful,
but the \verb"result" parameter was not \verb"ACS_ACCEPT",
then the association remains established.

\subsection	{Association Abort}
To unilaterally abort an association,
the routine \verb"RtUAbortRequest" routine is used
which corresponds to the {\sf RT-U-ABORT.REQUEST\/} action.
\begin{quote}\index{RtUAbortRequest}\small\begin{verbatim}
int     RtUAbortRequest (sd, data, rti)
int     sd;
PE      data;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"data":] any abort data;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure,
which is updated only if the call fails.
\end{describe}
If the call to \verb"RtUAbortRequest" is successful,
then the association is immediately relesaed,
and any data queued for the association may be lost.

\f

\section	{Reliable Transfer}\label{rts:transfer}

\[\fbox{\begin{tabular}{lp{0.8\textwidth}}
\bf NOTE:&	Users should also consult Sectin~\ref{rts:revisited} on
		page~\pageref{rts:revisited} for optional routines to
		make RTS behave more sanely.
\end{tabular}}\]

Once the association has been established,
an association-descriptor is used to reference the association.
This is usually the first parameter given to any of the remaining routines in
the \man librtsap(3n) library.
Further,
the last parameter is usually a pointer to a \verb"RtSAPindication"
structure.
If a call to one of these routines fails,
then the structure is updated.
\begin{quote}\index{RtSAPindication}\small\begin{verbatim}
struct RtSAPindication {
    int     rti_type;
#define RTI_TURN        0x00
#define RTI_TRANSFER    0x01
#define RTI_ABORT       0x02
#define RTI_CLOSE       0x03
#define RTI_FINISH      0x04

    union {
        struct RrSAPturn rti_un_turn;
        struct RtSAPresult rti_un_transfer;
        struct RtSAPabort rti_un_abort;
        struct RtSAPclose rti_un_close;
        struct AcSAPfinish rti_un_finish
    }   rti_un;
#define rti_turn        rti_un.rti_un_turn
#define rti_transfer    rti_un.rti_un_transfer
#define rti_abort       rti_un.rti_un_abort
#define rti_close       rti_un.rti_un_close
#define rti_finish      rti_un.rti_un_finish
};
\end{verbatim}\end{quote}
As shown, this structure is really a discriminated union
(a structure with a tag element followed by a union).
Hence, on a failure return,
one first coerces a pointer to the \verb"RtSAPabort" structure contained
therein,
and then consults the elements of that structure.
\begin{quote}\index{RtSAPabort}\small\begin{verbatim}
struct RtSAPabort {
    int     rta_peer;

    int     rta_reason;

    PE      rta_udata;

#define RTA_SIZE        512
    int     rta_cc;
    char    rta_data[RTA_SIZE];
};
\end{verbatim}\end{quote}
The elements of a \verb"RtSAPabort" structure are:
\begin{describe}
\item[\verb"rta\_peer":] if set, indicates a user-initiated abort
(a {\sf RT-U-A\-BORT.IN\-DI\-CA\-TION\/} event);
if not set, indicates a provider-initiated abort
(a {\sf RT-P-ABORT.INDICATION\/} event);

\item[\verb"rta\_reason":] the reason for the abort
(codes are listed in Table~\ref{RtSAPreasons});

\item[\verb"rta\_udata":] optionally, data associated with the user-initiated
abort;
and,

\item[\verb"rta\_data"/\verb"rta\_cc":] a diagnostic string from the provider.
\end{describe}
\tagtable[tp]{2c-1}{RtSAP Failure Codes}{RtSAPreasons}
Note that the \verb"rta_udata" element is allocated via \man malloc(3) and
should be released using the \verb"RTAFREE" macro  when no longer referenced.
The \verb"RTAFREE" macro behaves as if it was defined as:
\begin{quote}\index{RTAFREE}\small\begin{verbatim}
void    RTAFREE (rta)
struct RtSAPabort *rta;
\end{verbatim}\end{quote}
The macro frees only the data allocated in the \verb"RtSAPabort" structure
and not the structure itself.

On a failure return,
if the \verb"rta_reason" element of the \verb"RtSAPabort" structure is
associated with a fatal error,
the the association is released.
The \verb"RTS_FATAL" macro can be used to determine this.
\begin{quote}\index{RTS\_FATAL}\small\begin{verbatim}
int     RTS_FATAL (r)
int     r;
\end{verbatim}\end{quote}
For protocol purists,
the \verb"RTS_OFFICIAL" macro can be used to determine if the error is an
``official'' error as defined by the specification,
or an ``unofficial'' error used by the implementation.
\begin{quote}\index{RTS\_OFFICIAL}\small\begin{verbatim}
int     RTS_OFFICIAL (r)
int     r;
\end{verbatim}\end{quote}

\subsection	{Sending Data}
When the user has the turn,
it can use the \verb"RtTransferRequest" routine
(this corresponds to the {\sf RT-TRANSFER.REQUEST\/} action)
to request the reliable transfer of a data structure.
\begin{quote}\index{RtTransferRequest}\small\begin{verbatim}
int     RtTransferRequest (sd, data, secs, rti)
int     sd;
PE      data;
int     secs;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"data":] the data to be transferred;

\item[\verb"secs":] the amount of time, in seconds, permitted to transfer the
data (use the manifest constant \verb"NOTOK" if time is unimportant);
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If \verb"RtTransferRequest" succeeds,
then the data has been reliably transferred to the other user.
Otherwise the \verb"RtSAPabort" structure contained in
the \verb"RtSAPindication" parameter \verb"rti"
contains the reason for failure.

\subsection	{Receiving Data}
The \verb"RtWaitRequest" routine is used to wait for an event
(usually incoming data) to occur.
\begin{quote}\index{RtWaitRequest}\small\begin{verbatim}
int     RtWaitRequest (sd, secs, rti)
int     sd;
int     secs;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"secs":] the maximum number of seconds to wait for the event
(a value of \verb"NOTOK" indicates that the call should block indefinitely,
whereas a value of \verb"OK" indicates that the call should not block at all,
e.g., a polling action);
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure,
which is always updated.
\end{describe}
Unlike the other routines in the \man librtsap(3n) library,
the \verb"RtWaitRequest" routine returns one of three values:
\verb"NOTOK" (on failure),
\verb"OK" (on reading data)
or
\verb"DONE" (when something else happens).

If the call to \verb"RtWaitRequest" returns the manifest constant
\verb"NOTOK",
then the \verb"RtSAPabort" structure contained in
the \verb"RtSAPindication" parameter
\verb"rti" contains the reason for the failure.

Otherwise if the call to \verb"RoWaitRequest" returns the manifest constant
\verb"OK",
then data has arrived.
This event is encoded in the \verb"rti" parameter,
depending on the value of the \verb"rti_type" element.
Currently,
when \verb"RoWaitRequest" returns \verb"OK",
the \verb"rti_type" element is set to \verb"RTI_TRANSFER",
which indicates that a {\sf RT-TRANSFER.REQUEST\/} event has occurred.

Otherwise if the call to \verb"RtWaitRequest" returns the manifest constant
\verb"DONE",
then some event other than data arriving has occurred.
This event is also encoded in the \verb"rti" parameter,
depending on the value of the \verb"rti_type" element.
Currently,
when \verb"RoWaitRequest" returns \verb"DONE",
the \verb"rti_type" element is set to one of two values:
\[\begin{tabular}{|l|l|}
\hline
    \multicolumn{1}{|c|}{\bf Value}&
			\multicolumn{1}{c|}{\bf Event}\\
\hline
    \tt RTI\_TURN&	\sf RT-TURN-PLEASE.INDICATION\\
\hline
    \tt RTI\_TURN&	\sf RT-TURN-GIVE.INDICATION\\
\hline
    \tt RTI\_CLOSE&	\sf X.410 CLOSE.INDICATION\\
	&		\ \ (for old-style associations)\\
\hline
    \tt RTI\_FINISH&	\sf RT-CLOSE.INDICATION\\
\hline
\end{tabular}\]

\subsubsection	{Transfer Indication}
When an {\sf RT-TRANSFER.INDICATION\/} event occurs,
the \verb"rti_type" field of the \verb"rti" parameter contains the value
\verb"RTI_TRANSFER",
and a \verb"RtSAPtransfer" structure is contained inside the \verb"rti"
parameter.
\begin{quote}\index{RtSAPtransfer}\small\begin{verbatim}
struct RtSAPtransfer {
    PE      rtt_data;
};
\end{verbatim}\end{quote}
The elements of this structure are:
\begin{describe}
\item[\verb"rtt\_data":] the data received.
\end{describe}
Note that the \verb"rtt_data" element is allocated via \man malloc(3) and
should be released using the \verb"RTTFREE" macro  when no longer referenced.
The \verb"RTTFREE" macro behaves as if it was defined as:
\begin{quote}\index{RTTFREE}\small\begin{verbatim}
void    RTTFREE (rtt)
struct RtSAPtransfer *rtt;
\end{verbatim}\end{quote}
The macro frees only the data allocated in the \verb"RtSAPtransfer" structure
and not the structure itself.

\subsubsection	{Turn Indication}
When an {\sf RT-TURN-GIVE.INDICATION\/} or {\sf RT-TURN-PLEASE.INDICATION\/}
events occur,
the \verb"rti_type" field of the \verb"rti" parameter contains the value
\verb"RTI_TURN",
and a \verb"RtSAPturn" structure is contained inside the \verb"rti"
parameter.
\begin{quote}\index{RtSAPturn}\small\begin{verbatim}
struct RtSAPturn {
    int     rtu_please;

    int     rtu_priority;
};
\end{verbatim}\end{quote}
The elements of this structure are:
\begin{describe}
\item[\verb"rtu\_please":] if set, indicates that a
{\sf RT-PLEASE-TURN.INDICATION\/} event has occurred;
if not set,
indicates that a {\sf RT-GIVE-TURN.IN\-DI\-CA\-TION\/} event has occurred;
and,

\item[\verb"rtu\_priority":] the priority at which the turn is requested
(meaningful only if \verb"rtu_please" is set).
\end{describe}

\subsubsection	{Close Indication}
When an {\sf X.410 CLOSE.INDICATION\/} event occurs,
the \verb"rti_type" field of the \verb"rti" parameter contains the value
\verb"RTI_CLOSE",
and a \verb"RtSAPclose" structure is contained inside the \verb"rti"
parameter.
\begin{quote}\index{RtSAPclose}\small\begin{verbatim}
struct RtSAPclose {
    int     rtc_dummy;
};
\end{verbatim}\end{quote}

\subsubsection	{Finish Indication}
When an {\sf RT-CLOSE.INDICATION\/} event occurs,
the \verb"rti_type" field of the \verb"rti" parameter contains the value
\verb"RTI_FINISH",
and a \verb"AcSAPfinish" structure is contained inside the \verb"rti"
parameter.

\subsection	{Managing the Turn}
The user with the turn is permitted to send data to the other user.
To request the turn,
one invokes the \verb"RtPTurnRequest" routine,
which corresponds to the {\sf RT-PLEASE-TURN.REQUEST}.
\begin{quote}\index{RtPTurnRequest}\small\begin{verbatim}
int     RtPTurnRequest (sd, priority, rti)
int     sd;
int     priority;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"priority":] the priority at which the turn is requested
(this is defined by each application);
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If the call to the \verb"RtPTurnRequest" routine succeeds,
then the turn has been requested of the remote user.
Otherwise the \verb"RtSAPabort" structure contained in
the \verb"RtSAPindication" parameter
\verb"rti" contains the reason for failure.

To relinquish the turn,
one invokes the \verb"RtGTurnRequest" routine,
which corresponds to the {\sf RT-GIVE-TURN.REQUEST}.
\begin{quote}\index{RGPTurnRequest}\small\begin{verbatim}
int     RtGTurnRequest (sd, rti)
int     sd;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If the call to the \verb"RtGTurnRequest" routine succeeds,
then the turn has been relinquished to the remote user.
Otherwise the \verb"RtSAPabort" structure contained in
the \verb"RtSAPindication" parameter
\verb"rti" contains the reason for failure.

\subsection     {Asynchronous Event Handling}
The events discussed thus far have been synchronous in nature.
Some users of the reliable transfer service may wish an asynchronous interface.
The \verb"RtSetIndications" routine is used to change the service associated
with an association-descriptor to an asynchronous interface.
\begin{quote}\index{RtSetIndications}\small\begin{verbatim}
int   RtSetIndications (sd, indication, rti)
int   sd;
IFP   indication;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"indication":] the address of an event-handler routine to be
invoked when an event occurs;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If the service is to be made asynchronous,
then \verb"indication" is specified;
otherwise,
if the service is to be made synchronous,
it is not specified (use the manifest constant \verb"NULLIFP").
The most likely reason for the call failing is \verb"RTS_WAITING",
which indicates that an event is waiting for the user.

When an event occurs,
the event-handler routine is invoked with two parameters:
\begin{quote}\small\begin{verbatim}
(*handler) (sd, rti);
int     sd;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure encoding
the event.
\end{describe}
Note that the data contained in the structure was allocated via \man malloc(3),
and should be released with the appropriate macro
(either \verb"RTTFREE" or \verb"RTPFREE")
when no longer needed.

When an event-handler is invoked,
future invocations of the event-hander are blocked until it returns.
The return value of the event-handler is ignored.
Further,
during the execution of a synchronous call to the library,
the event-handler will be blocked from being invoked.

\[\fbox{\begin{tabular}{lp{0.8\textwidth}}
\bf NOTE:&	The \man librtsap(3n) library uses the SIGEMT signal to
		provide these services.
		Programs using asynchronous association-descriptors should NOT
		use SIGEMT for other purposes.
\end{tabular}}\]

\subsection     {Synchronous Event Multiplexing}
A user of the reliable transfer service may wish to manage multiple
asso\-ci\-ation-descriptors simultaneously;
the routine \verb"RtSelectMask" is provided for this purpose.
This routine updates a file-descriptor mask and associated counter for use
with \verb"xselect" (consult Section~\ref{acs:select}),
as assocation-descriptors are file-descriptors.
\begin{quote}\index{RtSelectMask}\small\begin{verbatim}
int     RtSelectMask (sd, mask, nfds, rti)
int     sd;
fd_set *mask,
int    *nfds;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association-descriptor;

\item[\verb"mask":] a pointer to a file-descriptor mask meaningful to
\verb"xselect";

\item[\verb"nfds":] a pointer to an integer-valued location meaningful to
\verb"xselect";
and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If the call is successful, then the \verb"mask" and \verb"nfds" parameters can
be used as arguments to \verb"xselect".
The most likely reason for the call failing is \verb"RTS_WAITING",
which indicates that an event is waiting for the user.

If \verb"xselect" indicates that the association-descriptor is ready for
reading,
\verb"RtWaitRequest" should be called with the \verb"secs" parameter equal to
\verb"OK".
If the network activity does not constitute an entire event for the user,
then \verb"RtWaitRequest" will return \verb"NOTOK" with error code
\verb"RTS_TIMER".

\subsection     {Reliable Transfer (revisited)}\label{rts:revisited}
The mechanism provided by \verb"RtTransferRequest" may not be useful for
applications which have large amounts of data to transfer.
In most cases,
it is preferable to transfer data incrementally.
To provide for this functionality,
the routine \verb"RtSetDownTrans" is provided:
\begin{quote}\index{RtSetDownTrans}\small\begin{verbatim}
int     RtSetDownTrans (sd, fnx, rti)
int     sd;
IFP     fnx;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association descriptor;

\item[\verb"fnx":] the address of an event-handler routine to be invoked when
data is needed; and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If the \verb"fnx" parameter is some value other than the manifest constant
\verb"NULLIFP",
then upon successful return from \verb"RtSetDownTrans",
the behavior of the routine \verb"RtTransferRequest" is altered.
\begin{enumerate}
\item	The \verb"data" parameter to \verb"RtTransferRequest" may be
	\verb"NULLPE".

\item	In this case, the event-handler routine \verb"fnx" will be invoked
	in order to retrieve a portion of the data to be transferred:
\begin{quote}\small\begin{verbatim}
result = (*fnx) (sd, base, len, size, ack, ssn, rti);
int     sd;
char  **base;
int    *len,
        size;
long    ack,
        ssn;
struct RtSAPindication *rti;
\end{verbatim}
\end{quote}
where \verb"sd" is the association-descriptor which was given to the routine
\verb"RtTransferRequest".

\item	If the \verb"base" parameter has the value \verb"NULLVP",
	then a {\sf RT-PLEASE.IN\-DI\-CA\-TION\/} event is being signaled,
	and the \verb"size" parameter has the value of the priority associated
	with the event.

\item	Otherwise, the \verb"base" and \verb"len" parameters point to a
	pointer/length pair which should be set by the event handler to upto
	\verb"size" octets.  The event handler is responsible for any
	memory allocation (e.g., allocating a buffer of \verb"size" octets and
	then assigning the address of the buffer to \verb"*base").
	Once a buffer is chosen, the event handler should read upto
	\verb"size" octets into the buffer and set \verb"*len" to the number
	of octets actually read.  The \verb"ssn" and \verb"ack" parameters
	given the values of the last synchronization point requested and
	acknolwedged (how this information should be used is unknown at this
	time).  If the value assigned to \verb"*len" is zero, then this
	indicates that all data has been read and the transfer should be
	completed.

\item	If the value of the \verb"size" is zero, then this indicates that the
	provider could not negotiate a incremental transfer and the event
	handler should allocate a buffer of arbitrary size, read all of the
	data to be transferred into that one buffer, and then update
	\verb"*base" and \verb"*len" accordingly.

\item	If the event handler encounters an error, it should return the
	manifest constant \verb"NOTOK" (otherwise, it should return
	\verb"OK").
	If an error is signaled, the event handler should update the
	\verb"rti" structure accordingly.  The easiest way to do this is:
\begin{quote}\small\begin{verbatim}
return rtsaplose (rti, RTS_TRANSFER, NULLCP, "text");
\end{verbatim}\end{quote}
If the event is {\sf RT-PLEASE.REQUEST},
then signaling an error results in the provider generating an
{\sf S-ACTIVITY-INTERRUPT.REQUEST};
otherwise when an error is signaled, the provider will generate an
{\sf S-ACTIVITY-DISCARD.REQUEST\/} to abort the transfer.
\end{enumerate}

For similar reasons,
the mechanism employed by \verb"RtWaitRequest" may not be useful for
applications which have large amounts of data to transfer.
Again,
in most cases it is preferable to transfer data incrementally.
To provide for this functionality,
the routine \verb"RtSetUpTrans" is provided:
\begin{quote}\index{RtSetUpTrans}\small\begin{verbatim}
int     RtSetDownTrans (sd, fnx, rti)
int     sd;
IFP     fnx;
struct RtSAPindication *rti;
\end{verbatim}\end{quote}
The parameters to this procedure are:
\begin{describe}
\item[\verb"sd":] the association descriptor;

\item[\verb"fnx":] the address of an event-handler routine to be invoked when
data has been received; and,

\item[\verb"rti":] a pointer to a \verb"RtSAPindication" structure, which is
updated only if the call fails.
\end{describe}
If the \verb"fnx" parameter is some value other than the manifest constant
\verb"NULLIFP",
then upon successful return from \verb"RtSetUpTrans",
the behavior of the routine \verb"RtWaitRequest" is altered when it returns an
{\sf RT-TRANSFER.INDICATION\/}
(the \verb"rti_type" field of the \verb"rti" parameter contains the value
\verb"RTI_TRANSFER",
and a \verb"RtSAPtransfer" structure is contained inside the \verb"rti"
parameter).
No data is returned by \verb"RtWaitRequest",
rather as data is received, the event routine is invoked:
\begin{enumerate}
\item	When data is received, the event-handler routine \verb"fnx" will 
	be invoked
	in order to store a portion of the data being transferred:
\begin{quote}\small\begin{verbatim}
result = (*fnx) (sd, event, addr, rti);
int     sd;
int     event;
caddr_t addr;
struct RtSAPindication *rti;
\end{verbatim}
\end{quote}
where \verb"sd" is the association-descriptor which was given to the routine
\verb"RtWaitRequest".

\item	If the \verb"event" parameter has the value \verb"SI_DATA",
	then the \verb"addr" parameter is really a pointer to a
	\verb"struct qbuf" structure, and the event handler should
	traverse the qbuf writing out the data found therein.

\item	If the \verb"event" parameter has the value \verb"SI_SYNC",
	then the \verb"addr" parameter is really a pointer to a 
	\verb"struct SSAPsync" structure, and the event handler should note
	the information contained therein.Currently, this will only
	occur when a {\sf S-MINOR-SYNC.INDICATION\/} event is signaled.

\item	If the \verb"event" parameter has the value \verb"SI_ACTIVITY",
	then the \verb"addr" parameter is really a pointer to a
	\verb"struct SSAPactivity" structure, and the event handler should note
	the information contained therein.  Currently, there are four events
	that are signaled:
    \begin{itemize}
    \item	{\sf S-ACTIVITY-START.INDICATION\/} which indicates that a
		transfer is about to begin;

    \item	{\sf S-ACTIVITY-END.INDICATION\/} which indicates that a
		transfer is about to complete; and,

    \item	{\sf S-ACTIVITY-INTERRUPT.IN\-DI\-CA\-TION\/} and\\ %%%
		{\sf S-ACTIVITY-DIS\-CARD.IN\-DI\-CA\-TION\/} which indicate
		that an activity is either suspended or aborted.
    \end{itemize}

\item	If the \verb"event" parameter has the value \verb"SI_REPORT",
	then the \verb"addr" parameter is really a pointer to a
	\verb"struct SSAPreport" structure, and the event handler should note
	the information contained therein.  Currently, this will only
	occur when a {\sf S-U-EXCEPTION-REPORT.IN\-DI\-CA\-TION\/} event is
	signaled.

\item	If the event handler encounters an error, it should return the
	manifest constant \verb"NOTOK" (otherwise, it should return
	\verb"OK").
	If an error is signaled, the event handler should update the
	\verb"rti" structure accordingly.  The easiest way to do this is:
\begin{quote}\small\begin{verbatim}
return rtsaplose (rti, RTS_TRANSFER, NULLCP, "text");
\end{verbatim}\end{quote}
If the event is {\sf S-ACTIVITY-INTERRUPT.INDICATION},
{\sf S-ACTIVITY-INTERRUPT.INDICATION},
or {\sf S-ACTIVITY-INTERRUPT.IN\-DI\-CA\-TION},
then signaling an error is ignorred by the provider;
otherwise, when an error is signaled, the provider will generate an
{\sf S-U-EXCEPTION-REPORT.REQUEST\/} to abort the transfer.
\end{enumerate}

\f

\section	{Error Conventions}
All of the routines in this library return the manifest constant \verb"NOTOK"
on error,
and also update the \verb"rti" parameter given to the routine.
The \verb"rti_abort" element of the \verb"RtSAPindication" structure
encodes the reason for the failure.
One coerces a pointer to a \verb"RtSAPabort" structure,
and consults the \verb"rta_reason" element of this latter structure.
This element can be given as a
parameter to the routine \verb"RtErrString" which returns a null-terminated
diagnostic string.
\begin{quote}\index{RtErrString}\small\begin{verbatim}
char   *RtErrString (c)
int     c;
\end{verbatim}\end{quote}

\f

\section	{Compiling and Loading}
Programs using the \man librtsap(3n) library should include
\verb"<isode/rtsap.h>",
which automatically includes the header file \verb"<isode/psap.h>" described in
Chapter~\ref{libpsap}.
The programs should also be loaded with \verb"-lisode".

\f

\section	{An Example}
Let's consider how one might construct a generic server that uses
reliable transfer services to establish an association,
but then uses remote operation services to communicate with its peer.
This entity will use a synchronous interface.

There are two parts to the program:
initialization and the request/reply loop.
In our example,
we assume that the routine \verb"error" results in the process being
terminated after printing a diagnostic.

In Figure~\ref{initRTSresponder},
the initialization steps for the generic responder,
including the outer {\em C\/} wrapper,
is shown.
First, the RtSAP state is re-captured by calling \verb"RtInit".
If this succeeds,
then the association is authenticated and any command line arguments
(as defined in the \man isoservices(5) file described in
Chapter~\ref{isoservices} of \voltwo/)
are parsed.
Assuming that the responder is satisfied with the proposed association,
it calls \verb"RtOpenResponse" to accept the association.
The \verb"RoSetService" routine is called to set the underlying service to be
used for remote operations.
Finally,
the main request/reply loop is realized.
The responder calls \verb"RoWaitRequest" to get the next event,
and then calls \verb"ros_indication" to decode that event.

Figure~\ref{doROSresponder} on page~\pageref{doROSresponder}
contains the definition of the
\verb"ros_indication" routine and associated routines.
Since the reliable transfer service was used to establish the association,
a different closing handler must be used.
This is shown in Figure~\ref{finRTSresponder}.
{\let\small=\scriptsize			%%% yikes!
\clearpage
\tagrind[tp]{grind2c-2}{Initializing the generic RTS responder}%
	{initRTSresponder}
\clearpage
\tagrind[tp]{grind2c-3}{Finalizing the generic RTS responder}%
	{finRTSresponder}}

\f

\section	{For Further Reading}
\cite{MHS.RTS} is the CCITT recommendation describing the reliable transfer
service.
The draft CCITT work which assumes the use of new-style associations is
defined in \cite{CCITT.RTS.Service} and \cite{CCITT.RTS.Protocol}.
Similarly,
the corresponding ISO work is
\cite{ISO.RTS.Service} and \cite{ISO.RTS.Protocol}.

%%% \f

\section	{Changes Since the Last Release}\label{rtsap:changes}