|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T s
Length: 86209 (0x150c1) Types: TextFile Names: »ssap.tex«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/doc/manual/ssap.tex«
% run this through LaTeX with the appropriate wrapper \f \chapter {Session Services}\label{libssap} The \man libssap(3n) library implements the session service. 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"ssap" 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 libssap(3n) library are integer-valued. They return the manifest constant \verb"OK" on success, or \verb"NOTOK" otherwise. \f \section {Warning} Please read the following important message. \[\fbox{\begin{tabular}{lp{0.8\textwidth}} \bf NOTE:& Readers of this chapter should have an intimate understanding of the OSI session service. It is not the intent of this chapter to present a tutorial on these services, so novice users will suffer greatly if they choose to read further. \end{tabular}}\] \f \section {Addresses}\label{ssap:addresses} Addresses at the session service access point are represented by the \verb"SSAPaddr" structure. \begin{quote}\index{SSAPaddr}\small\begin{verbatim} struct SSAPaddr { struct TSAPaddr sa_addr; #define SSSIZE 64 int sa_selectlen; char sa_selector[SSSIZE]; }; #define NULLSA ((struct SSAPaddr *) 0) \end{verbatim}\end{quote} This structure contains two elements: \begin{describe} \item[\verb"sa\_addr":] the transport address, as described in Section~\ref{tsap:addresses} on page~\pageref{tsap:addresses}; and, \item[\verb"sa\_selector"/\verb"sa\_selectlen":] the session selector, as described in the \man isoservices(5) database in Chapter~\ref{isoservices}, for the service provider \verb"ssap". \end{describe} In Figure~\ref{getASprovider}, an example of how one constructs the SSAP address for the Presentation provider on host \verb"RemoteHost" is presented. The routine \verb"is2saddr" takes a host and service, and then consults the \man isoentities(5) file described in Chapter~\ref{isoentities} of \volone/ to construct a session address. \begin{quote}\index{is2saddr}\small\begin{verbatim} struct SSAPaddr *is2saddr (host, service, is) char *host, *service; struct isoservent *is; \end{verbatim}\end{quote} \tagrind[tp]{grind5b-1}% {Constructing the SSAP address for the Presentation provider}% {getASprovider} \subsection {Calling Address} Certain users of the session service (e.g., the reliable transfer service) need to know the name of the local host when they initiate a connection. The routine \verb"SLocalHostName" has been provided for this reason. \begin{quote}\index{SLocalHostName}\small\begin{verbatim} char *SLocalHostName () \end{verbatim}\end{quote} \subsection {Address Encodings} It may be useful to encode a session address for viewing. Although a consensus for a standard way of doing this has not yet been reached, the routines \verb"saddr2str" and \verb"str2saddr" may be used in the interim. \begin{quote}\index{saddr2str}\small\begin{verbatim} char *saddr2str (sa) struct SSAPaddr *sa; \end{verbatim}\end{quote} The parameter to this procedure is: \begin{describe} \item[\verb"sa":] the session address. \end{describe} If \verb"saddr2str" fails, it returns the manifest constant \verb"NULLCP". The routine \verb"str2saddr" takes an ascii string encoding and returns a session address. \begin{quote}\index{str2saddr}\small\begin{verbatim} struct SSAPaddr *str2saddr (str) char *str; \end{verbatim}\end{quote} The parameter to this procedure is: \begin{describe} \item[\verb"str":] the ascii string. \end{describe} If \verb"str2saddr" fails, it returns the manifest constant \verb"NULLSA". \f \section {Connection Establishment} Until the connection has been fully established, the implementation distinguishes between clients and servers, which are more properly referred to as {\em initiators\/} and {\em responders}, to use OSI terminology. \subsection {Connection Negotiation}\label{ssap:negotiation} From the user's perspective, there are several parameters which are negotiated by the session providers during connection establishment. Suggestions as to the values of some of these parameters are made by the user. \subsubsection {Maximum SSDU Size} The session provider will accept arbitrarily large session service data units (SSDUs) and transparently fragment and re-assemble them during transit. Hence, the actual SSDU is of unlimited size. However, for efficiency reasons, it may be desirable for the user to send SSDUs which are no larger than a certain threshold. When a connection has been established, the service providers inform the initiator and responder as to what this threshold is. \[\fbox{\begin{tabular}{lp{0.8\textwidth}}\label{SSDU:atomic} \bf NOTE:& In the current implementation, SSDUs which are no larger than the maximum atomic SSDU size are handled very efficiently. For optimal performance, users of the session service should strive to avoid sending SSDUs which are larger than this threshold. \end{tabular}}\] \subsubsection {Session Requirements} Users may specify the particular services that they will require from the session provider. The particular requirements supported in the current implementation are listed in Table~\ref{SSAPrequirements}. These requirements are always negotiated downward. That is, the initiator of the connection (i.e., the ``client'') indicates the desired session requirements. These are then given to the responder to the connection request (i.e., the ``server'') who may select any (or all) of the indicated session requirements.% \footnote{There is one exception, the responder may not select both the half- and full-duplex requirements. It must choose one. If the initiator selects both initially, it is indicating that the choice is made at the responder's discretion.} This selection is then indicated to the initiator. \tagtable[tp]{5b-1}{Session Requirements}{SSAPrequirements} \subsubsection {Session Tokens} Depending on the session requirements selected, several session tokens may be available in order to coordinate the use of session services. There are two terms commonly used when referring to a session token: \begin{itemize} \item Availability\\ If a token is available, then it exists for use during the session connection. The availability of a token depends on the session requirements selected for the connection. \item Ownership\\ Certain session services are may not be requested by a user unless that user owns the token associated with those services. \end{itemize} The particular tokens supported in the current implementation, along with their associated availability information are listed in Table~\ref{SSAPtokens}. \tagtable[tp]{5b-2}{Session Tokens}{SSAPtokens} The session requirements are encoded as a single integer (actually, only the low-order 2~octets of an integer). To determine if a token is available, one can use a simple test involving the session requirements: \begin{quote}\small\begin{verbatim} if (requirements & SR_xxx_EXISTS) { ... } \end{verbatim}\end{quote} For example, to determine if the negotiated release token is available: \begin{quote}\small\begin{verbatim} if (requirements & SR_RLS_EXISTS) { ... } \end{verbatim}\end{quote} Finally, the macro \verb"dotokens" may be used to execute {\em C\/} code for each session token (regardless of availability).\index{dotokens} This macro acts as if it executes: \begin{quote}\index{dotoken}\small\begin{verbatim} dotoken (SR_xxx_EXISTS, ST_xxx_SHIFT, ST_xxx_TOKEN, "xxx"); \end{verbatim}\end{quote} for each token. Usually, \verb"dotoken" is a macro which executes some code for each token. An example is provided momentarily. \subsubsection {Initial Token Settings} For each token which is made available during connection negotiation, the choice as to which user initially has the token is left to the discretion of the initiator. The three choices for the initial settings of a token are listed in Table~\ref{SSAPsettings}. \tagtable[tp]{5b-3}{Initial Token Settings}{SSAPsettings} The initial settings for all available tokens are encoded in a single integer (actually, only the low-order 2~octets of an integer). To encode a value: \begin{quote}\small\begin{verbatim} settings &= ~(ST_MASK << ST_yyy_SHIFT); settings |= ST_xxx_VALUE << ST_yyy_SHIFT; \end{verbatim}\end{quote} For example, to indicate that the responder of the connection is to initially have the data token: \begin{quote}\small\begin{verbatim} settings &= ~(ST_MASK << ST_DAT_SHIFT); settings |= ST_RESP_VALUE << ST_DAT_SHIFT; \end{verbatim}\end{quote} The first statement, which clears the field in \verb"settings" by using \verb"ST_MASK", is not required if \verb"settings" is initially \verb"0". If the initiator indicates that the initial setting of a token is left to the responder's choice, then the responder must decide. In Figure~\ref{setINITtokens}, an example of the \verb"dotokens" macro is presented. In this example, the responder examines the initial setting for each available token, and: \begin{itemize} \item Notes if the responder initially owns the token (the \verb"ST_RESP_VALUE" case); or, \item Gives ownership of the token to the initiator if the choice is at the responder's discretion (the \verb"ST_CALL_VALUE" case). \end{itemize} \tagrind[tp]{grind5b-2}{Determining the Initial Token Settings}{setINITtokens} \subsection {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 TSAP entity. In the case of the session service, the \pgm{tsapd} program contains the bootstrap for the session provider. The daemon will again consult the ISO services database to determine which program on the system implements the desired SSAP entity. Once the program has been ascertained, the daemon runs the program with any arguments 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-capture the SSAP state contained in the magic arguments. This is done by calling the routine \verb"SInit", which on a successful return, is equivalent to a {\sf S-CONNECT.INDICATION\/} from the session service provider. \begin{quote}\index{SInit}\small\begin{verbatim} int SInit (vecp, vec, ss, si) int vecp; char **vec; struct SSAPstart *ss; struct SSAPindication *si; \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"ss":] a pointer to a \verb"SSAPstart" structure, which is updated only if the call succeeds; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If \verb"SInit" is successful, it returns information in the \verb"ss" parameter, which is a pointer to a \verb"SSAPstart" structure. \begin{quote}\index{SSAPstart}\small\begin{verbatim} struct SSAPstart { int ss_sd; struct SSAPref ss_connect; struct SSAPaddr ss_calling; struct SSAPaddr ss_called; int ss_requirements; int ss_settings; long ss_isn; int ss_ssdusize; struct QOStype ss_qos; #define SS_SIZE 512 int ss_cc; char ss_data[SS_SIZE]; }; \end{verbatim}\end{quote} The elements of this structure are: \begin{describe} \item[\verb"ss\_sd":] the session-descriptor to be used to reference this connection; \item[\verb"ss\_connect":] the connection identifier (a.k.a. SSAP reference) used by the initiator; \item[\verb"ss\_calling":] the address of the peer initiating the connection; \item[\verb"ss\_called":] the address of the peer being asked to respond; \item[\verb"ss\_requirements":] the proposed session requirements; \item[\verb"ss\_settings":] the initial token settings; \item[\verb"ss\_isn":] the initial serial-number; \item[\verb"ss\_ssdusize":] the largest atomic SSDU size that can be used on the connection (see the note on page~\pageref{SSDU:atomic}); \item[\verb"ss\_qos":] the quality of service on the connection (see Section~\ref{tsap:qos}); and, \item[\verb"ss\_data"/\verb"ss\_cc":] any initial data (and the length of that data). \end{describe} The \verb"ss_connect" element is a \verb"SSAPref" structure, which is passed transparently by the session service. \begin{quote}\index{SSAPref}\small\begin{verbatim} struct SSAPref { #define SREF_USER_SIZE 64 u_char sr_ulen; char sr_udata[SREF_USER_SIZE]; #define SREF_COMM_SIZE 64 u_char sr_clen; char sr_cdata[SREF_COMM_SIZE]; #define SREF_ADDT_SIZE 4 u_char sr_alen; char sr_adata[SREF_ADDT_SIZE]; u_char sr_vlen; char sr_vdata[SREF_USER_SIZE]; }; \end{verbatim}\end{quote} The elements of this structure are:\label{SSAPref} \begin{describe} \item[\verb"sr\_udata"/\verb"sr\_ulen":] the user reference (and length of that reference, which may not exceed \verb"SREF_USER_SIZE" octets); \item[\verb"sr\_cdata"/\verb"sr\_clen":] the common reference (and length of that reference, which may not exceed \verb"SREF_COMM_SIZE" octets); \item[\verb"sr\_adata"/\verb"sr\_adata":] the additional reference (and length of that reference, which may not exceed \verb"SREF_ADDT_SIZE" octets); and, \item[\verb"sr\_vdata"/\verb"sr\_vlen":] a second user reference (and length of that reference, which may not exceed \verb"SREF_USER_SIZE" octets), which is used only when starting or resuming an activity. \end{describe} If the call to the \verb"SInit" routine is not successful, then a {\sf S-P-ABORT.IN\-DI\-CA\-TION\/} event is simulated, and the relevant information is returned in a \verb"SSAPindication" structure.\label{SSAPindication} \begin{quote}\index{SSAPindication}\small\begin{verbatim} struct SSAPindication { int si_type; #define SI_DATA 0x00 #define SI_TOKEN 0x01 #define SI_SYNC 0x02 #define SI_ACTIVITY 0x03 #define SI_REPORT 0x04 #define SI_FINISH 0x05 #define SI_ABORT 0x06 union { struct SSAPdata si_un_data; struct SSAPtoken si_un_token; struct SSAPsync si_un_sync; struct SSAPactivity si_un_activity; struct SSAPreport si_un_report; struct SSAPfinish si_un_finish; struct SSAPabort si_un_abort; } si_un; #define si_data si_un.si_un_data #define si_token si_un.si_un_token #define si_sync si_un.si_un_sync #define si_activity si_un.si_un_activity #define si_report si_un.si_un_report #define si_finish si_un.si_un_finish #define si_abort si_un.si_un_abort }; \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"SSAPabort" structure contained therein, and then consults the elements of that structure. \begin{quote}\index{SSAPabort}\small\begin{verbatim} struct SSAPabort { int sa_peer; int sa_reason; #define SA_SIZE 512 int sa_cc; char sa_data[SA_SIZE]; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPabort" structure are: \begin{describe} \item[\verb"sa\_peer":] if set, indicates that a user-initiated abort occurred (a {\sf S-U-ABORT.INDICATION\/} event); if not set, indicates that a provider-initiated abort occurred (a {\sf S-P-ABORT.INDICATION\/} event); \item[\verb"sa\_reason":] the reason for the provider-initiated abort (codes are listed in Table~\ref{SSAPreasons}), meaningless if the abort is user-initiated; and, \item[\verb"sa\_data"/\verb"sa\_cc":] any abort data (and the length of that data) from the peer (if \verb"sa_peer" is set) or a diagnostic string from the provider (if \verb"sa_peer" is not set). \end{describe} \tagtable[tp]{5b-4}{SSAP Failure Codes}{SSAPreasons} \[\fbox{\begin{tabular}{lp{0.8\textwidth}} \bf NOTE:& Although both \cite{ISO.SP.Protocol} and \cite{CCITT.SP.Protocol} both require a maximum length of \verb"9" octets for a user-initiated abort, the current implementation permits up to \verb"512" octets to be used. Without this freedom, higher-layer protocols which use presentation encoding mechanisms would be unable to successfully use the session abort facility. \end{tabular}}\] After examining the information returned by \verb"SInit" on a successful call (and possibly after examining the argument vector), the responder should either accept or reject the connection. For either response, the responder should use the \verb"SConnResponse" routine (which corresponds to the {\sf S-CONNECT.RESPONSE\/} action). \begin{quote}\index{SConnResponse}\small\begin{verbatim} int SConnResponse (sd, ref, called, result, requirements, settings, isn, data, cc, si) int sd; struct SSAPref *ref; struct SSAPaddr *called; int result, requirements, settings, cc; long isn; char *data; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"ref":] the connection identifier used by the responder (consult page~\pageref{SSAPref} for a description of the \verb"SSAPref" structure); \item[\verb"called":] the SSAP address of the responder (defaulting to the called address, if not present); \item[\verb"result":] the acceptance indicator (either \verb"SC_ACCEPT" if the connection is to be accepted, or one of the user-initiated abort error codes listed in Table~\ref{SSAPreasons} on page~\pageref{SSAPreasons}); \item[\verb"requirements":] the responder's session requirements (this may not include any requirements not listed in the initiator's session requirements); \item[\verb"settings":] the initial token settings (for each token, if the initiator specified \verb"ST_CALL_VALUE", then the responder should specify either \verb"ST_INIT_VALUE" or \verb"ST_RESP_VALUE"; instead, if the initiator specified \verb"ST_INIT_VALUE", and the responder wants the token, it can specify the value \verb"ST_RSVD_VALUE". This is interpreted by the service provider as a ``tokens please'' request; \item[\verb"isn":] the initial serial-number; \item[\verb"data"/\verb"cc":] any initial data (and the length of that data, which may not exceed \verb"SC_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SConnResponse" is successful, and if the \verb"result" parameter is set to \verb"SC_ACCEPT", then connection establishment has completed and the users of the session service now operate as symmetric peers. If the call is successful, but the \verb"result" parameter is not \verb"SC_ACCEPT", then the connection has been rejected and the responder may exit. Otherwise, if the call fails and the reason is not an interface error (see Table~\ref{SSAPreasons} on page~\pageref{SSAPreasons}), then the connection is closed. Note that when the responder rejects the connection, it need not supply meaningful values for the the \verb"requirements", \verb"settings", and \verb"isn" parameters. The \verb"data"/\verb"cc" parameters are also optional, but it is recommended that the responder return some diagnostic information. \subsection {Client Initialization} A program wishing to connect to another user of session services calls the \verb"SConnRequest" routine, which corresponds to the {\sf S-CONNECT.REQUEST\/} action. \begin{quote}\index{SConnRequest}\small\begin{verbatim} int SConnRequest (ref, calling, called, requirements, settings, isn, data, cc, qos, sc, si) struct SSAPref *ref; struct SSAPaddr *calling, *called; int requirements, settings, cc; long isn; char *data; struct QOStype *qos; struct SSAPconnect *sc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"ref":] the connection identifier used by the initiator (consult page~\pageref{SSAPref} for a description of the \verb"SSAPref" structure); \item[\verb"calling":] the SSAP address of the responder; \item[\verb"called":] the SSAP address of the initiator; \item[\verb"requirements":] the session requirements; \item[\verb"settings":] the initial token settings; \item[\verb"isn":] the initial serial-number; \item[\verb"data"/\verb"cc":] any initial data (and the length of that data, which may not exceed \verb"SS_SIZE" octets); \item[\verb"qos":] the quality of service on the connection (see Section~\ref{tsap:qos}); \item[\verb"sc":] a pointer to a \verb"SSAPconnect" structure, which is updated only if the call succeeds; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if either: \begin{itemize} \item the call fails; or, \item the call succeeds, but the value of the \verb"sc_result" element of the \verb"sc" parameter is not \verb"SC_ACCEPT" (see below). \end{itemize} \end{describe} If the call to \verb"SConnRequest" is successful (a successful return corresponds to a {\sf S-CONNECT.CONFIRMATION\/} event), then information is returned in the \verb"sc" parameter, which is a pointer to a \verb"SSAPconnect" structure. \begin{quote}\index{SSAPconnect}\small\begin{verbatim} struct SSAPconnect { int sc_sd; struct SSAPref sc_connect; struct SSAPaddr sc_responding; int sc_result; int sc_requirements; int sc_settings; int sc_please; lnog sc_isn; int sc_ssdusize; struct QOStype sc_qos; #define SC_SIZE 512 int sc_cc; char sc_data[SC_SIZE]; }; \end{verbatim}\end{quote} The elements of this structure are: \begin{describe} \item[\verb"sc\_sd":] the session-descriptor to be used to reference this connection; \item[\verb"sc\_connect":] the connection identifier used by the responder (consult page~\pageref{SSAPref} for a description of the \verb"SSAPref" structure); \item[\verb"sc\_responding":] the responding peer's address (which is the same as the \verb"called" parameter given to \verb"SConnRequest"); \item[\verb"sc\_result":] the connection response; \item[\verb"sc\_requirements":] the (negotiated) session requirements; \item[\verb"sc\_settings":] the (negotiated) initial token settings; \item[\verb"sc\_please":] the tokens which the responder wants to own (if any); \item[\verb"sc\_isn":] the (negotiated) initial serial-number; \item[\verb"sc\_ssdusize":] the largest atomic SSDU size that can be used on the connection (see the note on page~\pageref{SSDU:atomic}); \item[\verb"sc\_qos":] the quality of service on the connection (see Section~\ref{tsap:qos}); and, \item[\verb"sc\_data"/\verb"sc\_cc":] any initial data (and the length of that data). \end{describe} If the call to \verb"SConnRequest" is successful, and the \verb"sc_result" element is set to \verb"SC_ACCEPT", then connection establishment has completed and the users of the session service now operate as symmetric peers. If the call is successful, but the \verb"sc_result" element is not \verb"SC_ACCEPT", then the connection has been rejected; consult Table~\ref{SSAPreasons} to determine the reason (further information can be found in the \verb"si" parameter). Otherwise, if the call fails then the connection is not established and the \verb"SSAPabort" structure of the \verb"SSAPindication" discriminated union has been updated. Normally \verb"SConnRequest" returns only after a connection has succeeded or failed. This is termed a {\em synchronous\/} connection initiation. If the user desires, an {\em asynchronous\/} connection may be initiated. The routine \verb"SConnRequest" is really a macro which calls the routine \verb"SAsynConnRequest" with an argument indicating that a connection should be attempted synchronously. \begin{quote}\index{SAsynConnRequest}\small\begin{verbatim} int SAsynConnRequest (ref, calling, called, requirements, settings, isn, data, cc, qos, sc, si, async) struct SSAPref *ref; struct SSAPaddr *calling, *called; int requirements, settings, cc, async; long isn; char *data; struct QOStype *qos; struct SSAPconnect *sc; struct SSAPindication *si; \end{verbatim}\end{quote} The additional parameter to this procedure is: \begin{describe} \item[\verb"async":] whether the connection should be initiated asynchronously. \end{describe} If the \verb"async" parameter is non-zero, then \verb"SAsynConnRequest" returns one of three values: \verb"NOTOK", which indicates that the connection request failed; \verb"DONE", which indicates that the connection request succeeded; and, \verb"OK", which indicates that the connection request is still in progress. In the first two cases, the usual procedures for \verb"SConnRequest" are employed (i.e., a \verb"NOTOK" return from \verb"SAsynConnRequest" is equivalent to a \verb"NOTOK" return from \verb"SConnRequest", and, a \verb"DONE" return from \verb"SAsynConnRequest" is equivalent to a \verb"OK" return from \verb"SConnRequest"). In the final case, when \verb"OK" is returned, only the \verb"sc_sd" element of the \verb"sc" parameter has been updated; it reflects the session-descriptor to be used to reference this connection. Note that the \verb"data" parameter is still being referenced by \man libssap(3n) and should not be tampered with until the connection attempt has been completed. To determine when the connection attempt has been completed, the routine \verb"xselect" (consult Section~\ref{acs:select} of \volone/) should be used after calling \verb"SSelectMask". In order to determine if the connection attempt is successful, the \verb"SAsynRetryRequest" routine is called: \begin{quote}\index{SAsynRetryRequest}\small\begin{verbatim} int SAsynRetryRequest (sd, sc, si) int sd; struct SSAPconnect *sc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"sc":] a pointer to a \verb"SSAPconnect" structure, which is updated only if the call succeeds; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} Again, one of three values are returned: \verb"NOTOK", which indicates that the connection request failed; \verb"DONE", which indicates that the connection request succeeded; and, \verb"OK", which indicates that the connection request is still in progress. Refer to Section~\ref{tsap:async} on page~\pageref{tsap:async} for information on how to make efficient use of the asynchronous connection facility. \f \section {Data Transfer} Once the connection has been established, a session-descriptor is used to reference the connection. This is usually the first parameter given to any of the remaining routines in the \man libssap(3n) library. Further, the last parameter is usually a pointer to a \verb"SSAPindication" structure (as described on page~\pageref{SSAPindication}). If a call to one of these routines fails, then the structure is updated. Consult the \verb"SSAPabort" element of the \verb"SSAPindication" structure. If the \verb"sa_reason" element of the \verb"SSAPabort" structure is associated with a fatal error, then the connection is closed. That is, a {\sf S-P-ABORT.INDICATION\/} event has occurred. The \verb"SC_FATAL" macro can be used to determine this. \begin{quote}\index{SC\_FATAL}\small\begin{verbatim} int SC_FATAL (r) int r; \end{verbatim}\end{quote} The most common interface error to occur is \verb"SC_OPERATION" which usually indicates that either the user is lacking ownership of a session token to perform an operation, or that a session requirement required by the operation was not negotiated during connection establishment. For protocol purists, the \verb"SC_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{SC\_OFFICIAL}\small\begin{verbatim} int SC_OFFICIAL (r) int r; \end{verbatim}\end{quote} \subsection {Sending Data} There are six routines which may be used to send data. A call to the \verb"SDataRequest" routine is equivalent to a {\sf S-DATA.REQUEST\/} action on the part of the user. \begin{quote}\index{SDataRequest}\small\begin{verbatim} int SDataRequest (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] the data to be written (and the length of that data); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SDataRequest" is successful, then the data has been queued for sending to the peer. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. A call to the \verb"SExpdRequest" routine is equivalent to a {\sf S-EXPEDITED-DATA.REQUEST\/} action on the part of the user. \begin{quote}\index{SExpdRequest}\small\begin{verbatim} int SExpdRequest (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] the data to be written (and the length of that data, which may not exceed \verb"SX_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SExpdRequest" is successful, then the data has been queued for expedited sending. Otherwise the \verb"SSAPabort" element of the \verb"si" parameter contains the reason for failure. A call to the \verb"STypedRequest" routine is equivalent to a {\sf S-TYP\-ED-DA\-TA.RE\-QUEST\/} action on the part of the user. \begin{quote}\index{STypedRequest}\small\begin{verbatim} int STypedRequest (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] the data to be written (and the length of that data); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"STypedRequest" is successful, then the data has been queued for sending to the peer. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. A call to the \verb"SCapdRequest" routine is equivalent to a {\sf S-CAPABILITY-DATA.REQUEST\/} action on the part of the user. \begin{quote}\index{SCapdRequest}\small\begin{verbatim} int SCapdRequest (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] the data to be written (and the length of that data, which may not exceed \verb"SX_CDSIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SCapdRequest" is successful, then the data has been queued for sending. When the {\sf S-CAPABILITY-DATA.CONFIRMATION\/} event is received, the data has been successfully received. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-CAPABILITY-DATA.INDICATION\/} event, the user is required to generate a {\sf S-CAPABILITY-DATA.RESPONSE\/} action using the \verb"SCapdResponse" routine. \begin{quote}\index{SCapdResponse}\small\begin{verbatim} int SCapdResponse (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] the data to be written (and the length of that data, which may not exceed \verb"SX_CDASIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SCapdResponse" is successful, then the data has been queued for sending to the peer. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. The \verb"SWriteRequest" routine is similar in nature to the \verb"SDataRequest" and \verb"STypedRequest" routines, but uses a different set of parameters. The invocation is: \begin{quote}\index{SWriteRequest}\small\begin{verbatim} int SWriteRequest (sd, typed, uv, si) int sd; int typed; struct udvec *uv; int cc; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"typed":] whether this is typed-data or not; \item[\verb"uv":] the data to be written, described in a null-terimated array of scatter/gather elements; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SWriteRequest" is successful, then the data has been queued for sending to the peer. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. \subsection {Receiving Data} There is one routine used to read data, \verb"SReadRequest", a call to which is equivalent to waiting for an event (usually an incoming data event) to occur. \begin{quote}\index{SReadRequest}\small\begin{verbatim} int SReadRequest (sd, sx, secs, si) int sd; struct SSAPdata *sx; int secs; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"sx":] a pointer to the \verb"SSAPdata" structure to be given the data; \item[\verb"secs":] the maximum number of seconds to wait for the data (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"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if data is not read. \end{describe} Unlike the other routines in the \man libssap(3n) library, the \verb"SReadRequest" routine returns one of three values: \verb"NOTOK" (on failure), \verb"OK" (on reading data), or \verb"DONE" (otherwise). If the call to \verb"SReadRequest" returns the manifest constant \verb"OK", then the data has been read into the \verb"sx" parameter, which is a pointer to a \verb"SSAPdata" structure. \begin{quote}\index{SSAPdata}\small\begin{verbatim} struct SSAPdata { int sx_type; #define SX_NORMAL 0x00 #define SX_EXPEDITED 0x01 #define SX_TYPED 0x02 #define SX_CAPDIND 0x03 #define SX_CAPDCNF 0x04 int sx_cc; struct qbuf sx_qbuf; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPdata" structure are: \begin{describe} \item[\verb"sx\_type":] indicates how the data was received: \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Event}\\ \hline \tt SX\_NORMAL& \sf S-DATA.INDICATION\\ \tt SX\_EXPEDITED& \sf S-EXPEDITED-DATA.INDICATION\\ \tt SX\_TYPED& \sf S-TYPED-DATA.INDICATION\\ \tt SX\_CAPDIND& \sf S-CAPABILITY-DATA.INDICATION\\ \tt SX\_CAPDCNF& \sf S-CAPABILITY-DATA.CONFIRMATION\\ \hline \end{tabular}\] \item[\verb"sx\_cc":] the total number of octets that was read; and, \item[\verb"sx\_qbuf":] the data that was read in a buffer-queue form (see page~\pageref{tsap:qbuf} for a description of this structure). \end{describe} Note that the data contained in the structure was allocated via \man malloc(3), and should be released by using the \verb"SXFREE" macro when no longer referenced. The \verb"SXFREE" macro, behaves as if it was defined as:\label{SXFREE} \begin{quote}\index{SXFREE}\small\begin{verbatim} void SXFREE (sx) struct SSAPdata *sx; \end{verbatim}\end{quote} The macro frees only the data allocated by \verb"SReadRequest", and not the \verb"SSAPdata" structure itself. Further, \verb"SXFREE" should be called only if the call to the \verb"SReadRequest" routine returned \verb"OK". \[\fbox{\begin{tabular}{lp{0.8\textwidth}} \bf NOTE:& Because the \verb"SSAPdata" structure contains a \verb"qbuf" element, care must be taken in initializing and copying variables of this type. The routines in \man libssap(3n) library will correctly initialize these structures when given as parameters. But, users who otherwise manipulate these structures should take great care. \end{tabular}}\] Otherwise if the call to \verb"SReadRequest" returns the manifest constant \verb"NOTOK", then the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. If the call to \verb"SReadRequest" returns the manifest constant \verb"DONE", then some event other than data arrival has occurred. This event is encoded in the \verb"si" parameter, depending on the value of the \verb"si_type" element. When \verb"SReadRequest" returns \verb"DONE", the \verb"si_type" element may be set to one of five values: \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Event}\\ \hline \tt SI\_TOKEN& Token management\\ \tt SI\_SYNC& Synchronization management\\ \tt SI\_ACTIVITY& Activity management\\ \tt SI\_REPORT& Exception reporting\\ \tt SI\_FINISH& Connection release\\ \hline \end{tabular}\] \subsubsection {Token Indications} When an event associated with token management occurs, the \verb"si_type" field of the \verb"si" parameter contains the value \verb"SI_TOKEN", and a \verb"SSAPtoken" structure is contained inside the \verb"si" parameter. \begin{quote}\index{SSAPtoken}\small\begin{verbatim} struct SSAPtoken { int st_type; #define ST_GIVE 0x00 #define ST_PLEASE 0x01 #define ST_CONTROL 0x02 u_char st_tokens; u_char st_owned; #define ST_SIZE 512 int st_cc; char st_data[ST_SIZE]; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPtoken" structure are: \begin{describe} \item[\verb"st\_type":] defines the token management indication which occurred: \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Event}\\ \hline \tt ST\_GIVE& \sf S-TOKEN-GIVE.INDICATION\\ \tt ST\_PLEASE& \sf S-TOKEN-PLEASE.INDICATION\\ \tt ST\_CONTROL& \sf S-GIVE-CONTROL.INDICATION\\ \hline \end{tabular}\] \item[\verb"st\_tokens":] the session tokens requested or given; \item[\verb"st\_owned":] all of the session tokens currently owned by the user; and, \item[\verb"st\_base"/\verb"st\_cc":] associated data (and the length of that data) if tokens are requested. \end{describe} It is entirely at the discretion of the user what actions are to be taken when an indication event associated with token management occurs. \subsubsection {Synchronization Indications} When an event associated with synchronization occurs, the \verb"si_type" field of the \verb"si" parameter contains the value \verb"SI_SYNC", and a \verb"SSAPsync" structure is contained inside the \verb"si" parameter. \begin{quote}\index{SSAPsync}\small\begin{verbatim} struct SSAPsync { int sn_type; #define SN_MAJORIND 0x00 #define SN_MAJORCNF 0x01 #define SN_MINORIND 0x02 #define SN_MINORCNF 0x03 #define SN_RESETIND 0x04 #define SN_RESETCNF 0x05 int sn_options; #define SYNC_CONFIRM 1 #define SYNC_NOCONFIRM 0 #define SYNC_RESTART 0 #define SYNC_ABANDON 1 #define SYNC_SET 2 long sn_ssn; #define SERIAL_NONE (-1L) #define SERIAL_MIN 000000L #define SERIAL_MAX 999998L int sn_settings; #define SN_SIZE 512 int sn_cc; char sn_data[SN_SIZE]; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPsync" structure are: \begin{describe} \item[\verb"sn\_type":] defines the synchronization management indication which occurred: \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Event}\\ \hline \tt SN\_MAJORIND& \sf S-MAJOR-SYNC.INDICATION\\ \tt SN\_MAJORCNF& \sf S-MAJOR-SYNC.CONFIRMATION\\ \tt SN\_MINORIND& \sf S-MINOR-SYNC.INDICATION\\ \tt SN\_MINORCNF& \sf S-MINOR-SYNC.CONFIRMATION\\ \tt SN\_RESETIND& \sf S-RESYNCHRONIZE.INDICATION\\ \tt SN\_RESETCNF& \sf S-RESYNCHRONIZE.CONFIRMATION\\ \hline \end{tabular}\] \item[\verb"sn\_options":] various modifiers of the indication. For the minorsync indication (as described in Section~\ref{sync:mgmt} on page~\pageref{sync:mgmt}): \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Modifier}\\ \hline \tt SYNC\_CONFIRM& peer wants explicit confirmation\\ \tt SYNC\_NOCONFIRM& peer doesn't want explicit confirmation\\ \hline \end{tabular}\] For the resync indication (also described in Section~\ref{sync:mgmt}): \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Modifier}\\ \hline \tt SYNC\_RESTART& a ``restart'' resynchronization is requested\\ \tt SYNC\_ABANDON& a ``abandon'' resynchronization is requested\\ \tt SYNC\_SET& a ``set'' resynchronization is requested\\ \hline \end{tabular}\] \item[\verb"sn\_ssn":] the serial-number associated with this synchronization management event; \item[\verb"sn\_settings":] for resync events, the proposed (resync indication) or new (resync confirmation) token settings; and, \item[\verb"sn\_data"/\verb"sn\_cc":] associated data (and the length of that data). \end{describe} Note that for minorsync events, the user is not obligated to confirm the synchronization point even if the originator requested it. \subsubsection {Activity Indications} When an event associated with activity management occurs, the \verb"si_type" field of the \verb"si" parameter contains the value \verb"SI_ACTIVITY", and the \verb"si" parameter contains a \verb"SSAPactivity" structure. \begin{quote}\index{SSAPactivity}\small\begin{verbatim} struct SSAPactivity { int sv_type; #define SV_START 0x00 #define SV_RESUME 0x01 #define SV_INTRIND 0x02 #define SV_INTRCNF 0x03 #define SV_DISCIND 0x04 #define SV_DISCCNF 0x05 #define SV_ENDIND 0x06 #define SV_ENDCNF 0x07 struct SSAPactid sv_id; struct SSAPactid sv_oid; struct SSAPref sv_connect; long sv_ssn; int sv_reason; #define SV_SIZE 512 int sv_cc; char sv_data[SV_SIZE]; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPactivity" structure are: \begin{describe} \item[\verb"sv\_type":] defines the activity management indication which occurred: \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Event}\\ \hline \tt SV\_START& \sf S-ACTIVITY-START.INDICATION\\ \tt SV\_RESUME& \sf S-ACTIVITY-RESUME.INDICATION\\ \tt SV\_INTRIND& \sf S-ACTIVITY-INTERRUPT.INDICATION\\ \tt SV\_INTRCNF& \sf S-ACTIVITY-INTERRUPT.CONFIRMATION\\ \tt SV\_DISCIND& \sf S-ACTIVITY-DISCARD.INDICATION\\ \tt SV\_DISCCNF& \sf S-ACTIVITY-DISCARD.CONFIRMATION\\ \tt SV\_ENDIND& \sf S-ACTIVITY-END.INDICATION\\ \tt SV\_ENDCNF& \sf S-ACTIVITY-END.CONFIRMATION\\ \hline \end{tabular}\] \item[\verb"sv\_id":] the activity identifier for an activity start or resume indication; \item[\verb"sv\_oid":] the previous activity identifier for an activity resume indication (see page~\pageref{SSAPactref}); \item[\verb"sv\_connect":] the previous connection identifier for an activity resume indication; \item[\verb"sv\_ssn":] the serial-number for an activity resume or end indication; \item[\verb"sv\_reason":] the reason for an activity interrupt or discard indication (codes are listed in Table~\ref{SSAPexceptions}); and, \item[\verb"sv\_data"/\verb"sv\_cc":] associated data (and the length of that data). \end{describe} \tagtable[tp]{5b-5}{SSAP Exception Codes}{SSAPexceptions} \subsubsection {Report Indications} When an event associated with exception reporting occurs, the \verb"si_type" field of the \verb"si" parameter contains the value \verb"SI_REPORT", and a \verb"SSAPreport" structure is contained inside the \verb"si" parameter. \begin{quote}\index{SSAPreport}\small\begin{verbatim} struct SSAPreport { int sp_peer; int sp_reason; #define SP_SIZE 512 int sp_cc; char sp_data[SP_SIZE]; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPreport" structure are: \begin{describe} \item[\verb"sp\_peer":] if set, indicates that a user-initiated report occurred (a {\sf S-U-EXCEPTION-REPORT.INDICATION\/} event); if not set, indicates that a provider-initiated report occurred (a {\sf S-P-EXCEPTION-REPORT.INDICATION\/} event); \item[\verb"sp\_reason":] the reason for the report (codes are listed in Table~\ref{SSAPexceptions} on page~\pageref{SSAPexceptions}); and, \item[\verb"sp\_data"/\verb"sp\_cc":] any report data (and the length of that data) from the peer; meaningless if the report is provider-initiated. \end{describe} \subsubsection {Finish Indication} When a {\sf S-RELEASE.INDICATION\/} event occurs, the \verb"si_type" field of the \verb"si" parameter contains the value \verb"SI_FINISH", and a \verb"SSAPfinish" structure is contained inside the \verb"si" parameter. \begin{quote}\index{SSAPfinish}\small\begin{verbatim} struct SSAPfinish { #define SF_SIZE 512 int sf_cc; char sf_data[SF_SIZE]; }; \end{verbatim}\end{quote} The elements of a \verb"SSAPfinish" structure are: \begin{describe} \item[\verb"sf\_data"/\verb"sf\_cc":] any final data (and the length of that data). \end{describe} \subsection {Token Management} The fundamental aspect of token management deals with transferring ownership of the tokens. \subsubsection {Sending Tokens} To transfer ownership of one or more session tokens to the remote user, the \verb"SGTokenRequest" routine is called (which corresponds to the {\sf S-TOKEN-GIVE.REQUEST\/} action). \begin{quote}\index{SGTokenRequest}\small\begin{verbatim} int SGTokenRequest (sd, tokens, si) int sd; int tokens; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"tokens":] the tokens to be transferred; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SGTokenRequest" is successful, then ownership of the tokens has been transferred to the remote user. If activity management has been selected, then the ownership of all tokens can be transferred using the \verb"SGControlRequest" routine (which corresponds to the {\sf S-CONTROL-GIVE.REQUEST\/} action). \begin{quote}\index{SGControlRequest}\small\begin{verbatim} int SGControlRequest (sd, si) int sd; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SGControlRequest" is successful, then ownership of all available tokens has been transferred to the remote user. Until this transfer of ownership is acknowledged, other token management functions will (non-fatally) fail. \subsubsection {Requesting Tokens} To request ownership of one or more session tokens, the \verb"SPTokenRequest" routine is called (which corresponds to the {\sf S-TOKEN-PLEASE.REQUEST\/} action). \begin{quote}\index{SPTokenRequest}\small\begin{verbatim} int SPTokenRequest (sd, tokens, data, cc, si) int sd; int tokens, cc; char *data; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"tokens":] the tokens to requested; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"ST_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SPTokenRequest" is successful, then the remote user has been notified of the request; however, the ownership of the tokens is not actually transferred until the session provider notifies the user with a {\sf S-TOKEN-GIVE-INDICATION\/} event, which typically occurs on the next call to \verb"SReadRequest". \subsection {Synchronization Management}\label{sync:mgmt} There are three types of synchronization services: majorsyncs, minorsyncs, and resyncs. \subsubsection {Major Synchronization} To indicate a major synchronization point, the \verb"SMajSyncRequest" routine is used (which corresponds to the {\sf S-MAJOR-SYNC.REQUEST\/} action). \begin{quote}\index{SMajSyncRequest}\small\begin{verbatim} int SMajSyncRequest (sd, ssn, data, cc, si) int sd; long *ssn; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"ssn":] a pointer to a long integer which, on a successful return, will be updated to reflect the current serial-number ($V(M)-1$); \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SN_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SMajSyncRequest" is successful, then the major synchronization has been queued for the remote user. When the {\sf S-MAJOR-SYNC.CON\-FIR\-MA\-TION\/} event is received, the major synchronization is complete. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-MAJOR-SYNC.INDICATION\/} event, the user is required to generate a {\sf S-MAJOR-SYNC.RESPONSE\/} action by calling the \verb"SMajSyncResponse" routine. \begin{quote}\index{SMajSyncResponse}\small\begin{verbatim} int SMajSyncResponse (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SN_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SMajSyncResponse" is successful, then the major synchronization has been completed. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. \subsubsection {Minor Synchronization} To indicate a minor synchronization point, the \verb"SMinSyncRequest" routine is used (which corresponds to the {\sf S-MINOR-SYNC.REQUEST\/} action). \begin{quote}\index{SMinSyncRequest}\small\begin{verbatim} int SMinSyncRequest (sd, type, ssn, data, cc, si) int sd; int type; long *ssn; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"type":] the type of minor synchronization requested, one of: \[\begin{tabular}{|l|l|} \hline \multicolumn{1}{|c|}{\bf Value}& \multicolumn{1}{c|}{\bf Type}\\ \hline \tt SYNC\_CONFIRM& explicit confirmation requested\\ \tt SYNC\_NOCONFIRM& no confirmation requested\\ \hline \end{tabular}\] \item[\verb"ssn":] a pointer to a long integer which, on a successful return, will be updated to reflect the current serial-number ($V(M)-1$); \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SN_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SMinSyncRequest" is successful, then the minor synchronization has been queued for the remote user. If a {\sf S-MINOR-SYNC.CONFIRMATION\/} event is received, the minor synchronization is complete. However, the remote user is under no obligation to acknowledge the minorsync. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-MINOR-SYNC.INDICATION\/} event, the user may optionally use the \verb"SMinSyncResponse" routine to generate a {\sf S-MINOR-SYNC.RESPONSE\/} action. \begin{quote}\index{SMinSyncResponse}\small\begin{verbatim} int SMinSyncResponse (sd, ssn, data, cc, si) int sd; long ssn; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"ssn":] the highest serial-number being confirmed; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SN_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SMinSyncResponse" is successful, then the minor synchronization has been completed. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. \subsubsection {ReSynchronization} To resynchronize the connection to a known state, the \verb"SReSyncRequest" is used (which corresponds to the {\sf S-RESYNCHRONIZE.REQUEST\/} action). \begin{quote}\index{SReSyncRequest}\small\begin{verbatim} int SReSyncRequest (sd, type, ssn, settings, data, cc, si) int sd; int type, settings; long ssn; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"type":] the type of resynchronization requested (either \verb"SYNC_RESTART", \verb"SYNC_ABANDON", or \verb"SYNC_SET"); \item[\verb"ssn":] the serial-number to resynchronize to; \item[\verb"settings":] the new token settings; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SN_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SReSyncRequest" is successful, then the resynchronization has been queued for the remote user. When the {\sf S-RESYNCHRONIZE.CON\-FIR\-MA\-TION\/} event is received, the resynchronization is complete. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-RESYNCHRONIZE.INDICATION\/} event, the user is required to generate a {\sf S-RESYNCHRONIZE.RESPONSE\/} action using using the \verb"SReSyncResponse" routine.% \footnote{Actually, the user has other choices by using the rules of contention resolution. Consult the ISO session service specification for the gruesome details.} \begin{quote}\index{SReSyncResponse}\small\begin{verbatim} int SReSyncResponse (sd, ssn, settings, data, cc, si) int sd; int settings; long ssn; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"ssn":] the serial-number to resynchronize to; \item[\verb"settings":] the new token settings; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SN_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} \subsection {Activity Management} There are several types of activity management services: activity start and resume, activity interrupt and discard, and activity end. \subsubsection {Activity Start/Resume} To initiate a new activity, the \verb"SActStartRequest" routine is used (which corresponds to the {\sf S-ACTIVITY-START.REQUEST\/} action). \begin{quote}\index{SActStartRequest}\small\begin{verbatim} int SActStartRequest (sd, id, data, cc, si) int sd; struct SSAPactid *id; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"id":] the activity-identifier; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SV_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} The \verb"id" parameter is a pointer to a \verb"SSAPactid" structure, which is passed transparently by the session service. \begin{quote}\index{SSAPref}\small\begin{verbatim} struct SSAPactid { #define SID_DATA_SIZE 6 u_char sd_len; char sd_data[SID_DATA_SIZE]; }; \end{verbatim}\end{quote} The elements of this structure are:\label{SSAPactid} \begin{describe} \item[\verb"sd\_data"/\verb"sd\_len":] the data (and length of that data, which may not exceed \verb"SID_DATA_SIZE" octets); \end{describe} If the call to the \verb"SActStartRequest" routine is successful, then the activity is started. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. To resume a previously interrupted activity, the \verb"SActResumeRequest" routine is used (which corresponds to the {\sf S-ACTIVITY-RESUME.REQUEST\/} action). \begin{quote}\index{SActResumeRequest}\small\begin{verbatim} int SActResumeRequest (sd, id, oid, ssn, ref, data, cc, si) int sd; struct SSAPactid *id, *oid; long ssn; struct SSAPref *ref; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"id":] the activity-identifier (consult page~\pageref{SSAPactid} for a description of the \verb"SSAPactid" structure); \item[\verb"oid":] the previous activity-identifier (again, consult page~\pageref{SSAPactid}); \item[\verb"ssn":] the serial-number to resume the activity at; \item[\verb"ref":] the previous connection identifier; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SV_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} The \verb"ref" parameter is a pointer to a \verb"SSAPref" structure. Note that unlike the connection identifiers used during connection establishment (as described on page~\pageref{SSAPref}), there are four fields:\label{SSAPactref} \[\begin{tabular}{|l|l|l|} \hline \multicolumn{1}{|c|}{\bf Field}& \multicolumn{1}{c|}{\bf Contents}& \multicolumn{1}{c|}{\bf Length}\\ \hline calling SSAP user reference& \tt sr\_calling& \tt sr\_calling\_len\\ called SSAP user reference& \tt sr\_called& \tt sr\_called\_len\\ common reference& \tt sr\_cdata& \tt sr\_clen\\ additional reference& \tt sr\_adata& \tt sr\_alen\\ \hline \end{tabular}\] If the call to the \verb"SActResumeRequest" routine is successful, then the activity is resumed. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. \subsubsection {Activity Interrupt/Discard} To interrupt an activity in progress, the \verb"SActIntrRequest" routine is used (which corresponds to the {\sf S-ACTIVITY-INTERRUPT.REQUEST\/} action). \begin{quote}\index{SActIntrRequest}\small\begin{verbatim} int SActIntrRequest (sd, reason, si) int sd; int reason; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"reason":] the reason for the interrupt (codes are listed in Table~\ref{SSAPexceptions}); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SActIntrRequest" is successful, then the activity interrupt has been queued for the remote user. When the {\sf S-ACTIVITY-INTERRUPT.CON\-FIR\-MA\-TION\/} event is received, the activity interrupt is complete. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-ACTIVITY-INTERRUPT.INDICATION\/} event, the user is required to generate a {\sf S-ACTIVITY-INTERRUPT.RESPONSE\/} action using the \verb"SActIntrResponse" routine. \begin{quote}\index{SActIntrResponse}\small\begin{verbatim} int SActIntrResponse (sd, si) int sd; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SActIntrResponse" is successful, then the activity interrupt has been completed. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. To discard an activity in progress, the \verb"SActDiscRequest" routine is used (which corresponds to the {\sf S-ACTIVITY-DISCARD.REQUEST\/} action). \begin{quote}\index{SActDiscRequest}\small\begin{verbatim} int SActDiscRequest (sd, reason, si) int sd; int reason; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"reason":] the reason for the discard (codes are listed in Table~\ref{SSAPexceptions}); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SActDiscRequest" is successful, then the activity discard has been queued for the remote user. When the {\sf S-ACTIVITY-DISCARD.CON\-FIR\-MA\-TION\/} event is received, the activity discard is complete. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-ACTIVITY-DISCARD.INDICATION\/} event, the user is required to generate a {\sf S-ACTIVITY-DISCARD.RESPONSE\/} action using the \verb"SActDiscResponse" routine. \begin{quote}\index{SActDiscResponse}\small\begin{verbatim} int SActDiscResponse (sd, si) int sd; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SActDiscResponse" is successful, then the activity discard has been completed. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. \subsubsection {Activity End} To end an activity in progress, the \verb"SActEndRequest" routine is used (which corresponds to the {\sf S-ACTIVITY-END.REQUEST\/} action). \begin{quote}\index{SActEndRequest}\small\begin{verbatim} int SActEndRequest (sd, ssn, data, cc, si) int sd; long *ssn; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"ssn":] a pointer to a long integer which, on a successful return, will be updated to reflect the current serial-number ($V(M)-1$); \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SV_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SActEndRequest" is successful, then the activity end has been queued for the remote user. When the {\sf S-ACTIVITY-END.CONFIRMATION\/} event is received, the activity end is complete. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-ACTIVITY-END.INDICATION\/} event, the user is required to call the \verb"SActEndResponse" routine to generate a {\sf S-ACTIVITY-END.RESPONSE\/} action. \begin{quote}\index{SActEndResponse}\small\begin{verbatim} int SActEndResponse (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] any additional data (and the length of that data, which may not exceed \verb"SV_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SActEndResponse" is successful, then the activity end has been completed. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. \subsection {Exception Reporting} To report an exception and place the connection in a special error-recovery state, the \verb"SUReportRequest" routine is called (which corresponds to the {\sf S-U-EXCEPTION-REPORT.REQUEST\/} action). \begin{quote}\index{SUReportRequest}\small\begin{verbatim} int SUReportRequest (sd, reason, data, cc, si) int sd; int reason; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"reason":] the reason for the report (codes are listed in Table~\ref{SSAPexceptions}); \item[\verb"data"/\verb"cc":] any report data (and the length of that data, which may not exceed \verb"SP_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SUReportRequest" is successful, then the connection is placed in an error state, and any data queued for the connection may be lost until recovery is complete. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Typically, error recovery can be achieved by giving away the data token or by aborting the connection (discussed next). Error recovery is discussed in greater detail in the ISO session service specification. \subsection {User-initiated Aborts} To unilaterally initiate an abort of the connection, the \verb"SUAbortRequest" routine is called (which corresponds to the {\sf S-U-ABORT.REQUEST\/} action). \begin{quote}\index{SUAbortRequest}\small\begin{verbatim} int SUAbortRequest (sd, data, cc, si) int sd; char *data; int cc; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] any abort data (and the length of that data, which may not exceed \verb"SA_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SUAbortRequest" is successful, then the connection is immediately closed, and any data queued for the connection may be lost. \subsection {Asynchronous Event Handling} The data transfer events discussed thus far have been synchronous in nature. Some users of the session service may wish an asynchronous interface. The \verb"SSetIndications" routine is used to change the service associated with a session-descriptor to or from an asynchronous interface. \begin{quote}\index{SSetIndications}\small\begin{verbatim} int SSetIndications (sd, data, tokens, sync, activity, report, finish, abort, si) int sd; int (*data) (), (*tokens) (), (*sync) (), (*activity) (), (*report) (), (*finish) (), (*abort) (); struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data":] the address of an event-handler routine to be invoked when data has arrived; \item[\verb"tokens":] the address of an event-handler routine to be invoked when a token management event occurs; \item[\verb"sync":] the address of an event-handler routine to be invoked when a synchronization management event occurs; \item[\verb"activity":] the address of an event-handler routine to be invoked when an activity management event occurs; \item[\verb"report":] the address of an event-handler routine to be invoked when an exception report event occurs; \item[\verb"finish":] the address of an event-handler routine to be invoked when the connection is ready to be released; \item[\verb"abort":] the address of an event-handler routine to be invoked when a user-initiated abort (a {\sf S-U-ABORT.INDICATION\/} event occurs) or a provider-initiated abort (a {\sf S-P-ABORT.INDICATION\/} event occurs); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the service is to be made asynchronous, then all event handlers are specified, otherwise, if the service is to be made synchronous, then no event handlers should be specified (use the manifest constant \verb"NULLIFP"). The most likely reason for the call failing is \verb"SC_WAITING", which indicates that an event is waiting for the user. 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. When an event associated with data arrival occurs, the event-handler routine is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*data) (sd, sx); int sd; struct SSAPdata *sx; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"sx":] a pointer to the \verb"SSAPdata" structure containing the data. \end{describe} Note that the data contained in the structure was allocated via \man malloc(3), and should be released with the \verb"SXFREE" macro (described on page~\pageref{SXFREE}) when no longer needed. When an event associated with token management arrives the event-handler routine is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*tokens) (sd, st); int sd; struct SSAPtoken *st; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"st":] a pointer to the \verb"SSAPtoken" structure containing the token management information. \end{describe} When an event associated with synchronization management arrives the event-handler routine is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*sync) (sd, sn); int sd; struct SSAPsync *sn; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"sn":] a pointer to the \verb"SSAPsync" structure containing the synchronization management information. \end{describe} When an event associated with activity management arrives the event-handler routine is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*activity) (sd, sv); int sd; struct SSAPactivity *sv; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"sv":] a pointer to the \verb"SSAPactivity" structure containing the activity management information. \end{describe} When an event associated with exception reporting arrives the event-handler routine is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*report) (sd, sp); int sd; struct SSAPreport *sp; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"sp":] a pointer to the \verb"SSAPreport" structure containing the exception report information. \end{describe} When an event associated with connection termination arrives the event-handler routine is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*finish) (sd, sf); int sd; struct SSAPfinish *sf; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"sf":] a pointer to the \verb"SSAPfinish" structure containing information concerning the request to terminate the connection. \end{describe} When an event associated with a user- or provider-initiated abort occurs, the event-handler is invoked with two parameters: \begin{quote}\small\begin{verbatim} (*abort) (sd, sa); int sd; struct SSAPabort *sa; \end{verbatim}\end{quote} The parameters are: \begin{describe} \item[\verb"sd":] the session-descriptor; and, \item[\verb"sa":] a pointer to the \verb"SSAPabort" structure indicating why the connection was aborted. \end{describe} Note that the session-descriptor is no longer valid at the instant the call is made. \[\fbox{\begin{tabular}{lp{0.8\textwidth}} \bf NOTE:& The \man libssap(3n) library uses the SIGEMT signal to provide these services. Programs using asynchronous session-descriptors should NOT use SIGEMT for other purposes. \end{tabular}}\] \subsection {Synchronous Event Multiplexing} A user of the session service may wish to manage multiple session-de\-scrip\-tors simultaneously; the routine \verb"SSelectMask" is provided for this purpose. This routine updates a file-descriptor mask and associated counter for use with \verb"xselect". \begin{quote}\index{SSelectMask}\small\begin{verbatim} int SSelectMask (sd, mask, nfds, si) int sd; fd_set *mask, int *nfds; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-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"si":] a pointer to a \verb"SSAPindication" 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"SC_WAITING", which indicates that an event is waiting for the user. If \verb"xselect" indicates that the session-descriptor is ready for reading, \verb"SReadRequest" 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"SReadRequest" will return \verb"NOTOK" with error code \verb"SC_TIMER". \f \section {Connection Release} The \verb"SRelRequest" routine is used to request the release a connection, and corresponds to a {\sf S-RELEASE.REQUEST\/} action. The SSAP attempts to gracefully drain any queued data before closing the connection. \begin{quote}\index{SRelRequest}\small\begin{verbatim} int SRelRequest (sd, data, cc, sr, si) int sd; char *data; int cc; struct SSAPrelease *sr; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"data"/\verb"cc":] any final data (and the length of that data, which may not exceed \verb"SF_SIZE" octets); \item[\verb"sr":] a pointer to a \verb"SSAPrelease" structure, which is updated only if the call succeeds; and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SRelRequest" is successful, then this corresponds to a {\sf S-RELEASE.CONFIRMATION\/} event, and it returns information in the \verb"sr" parameter, which is a pointer to a \verb"SSAPrelease" structure. \begin{quote}\index{SSAPrelease}\small\begin{verbatim} struct SSAPrelease { int sr_affirmative; #define SR_SIZE 512 int sr_cc; char sr_data[SR_SIZE]; }; \end{verbatim}\end{quote} The elements of this structure are: \begin{describe} \item[\verb"sr\_affirmative":] the acceptance indicator; and, \item[\verb"sr\_data"/\verb"sr\_cc":] any final data (and the length of that data). \end{describe} If the call to \verb"SRelRequest" is successful, and the \verb"sr_affirmative" element is set, then the connection has been closed. If the call is successful, but the \verb"sr_affirmative" element is not set (i.e., zero), then the request to close the connection has been rejected by the remote user, and the connection is still open. Otherwise the \verb"SSAPabort" structure contained in the \verb"SSAPindication" parameter \verb"si" contains the reason for failure. Upon receiving a {\sf S-RELEASE.INDICATION\/} event, the user is required to generate a {\sf S-RELEASE.RESPONSE\/} action using the \verb"SRelResponse" routine. \begin{quote}\index{SRelResponse}\small\begin{verbatim} int SRelResponse (sd, status, data, cc, si) int sd; int status, cc; char *data; struct SSAPindication *si; \end{verbatim}\end{quote} The parameters to this procedure are: \begin{describe} \item[\verb"sd":] the session-descriptor; \item[\verb"status":] the acceptance indicator (either \verb"SC_ACCEPT" if the connection is to be closed, or \verb"SC_REJECTED" otherwise); \item[\verb"data"/\verb"cc":] any final data (and the length of that data, which may not exceed \verb"SR_SIZE" octets); and, \item[\verb"si":] a pointer to a \verb"SSAPindication" structure, which is updated only if the call fails. \end{describe} If the call to \verb"SRelResponse" is successful, and if the \verb"result" parameter is set to \verb"SC_ACCEPT", then the connection has been closed. If the call is successful, but the \verb"result" parameter is not \verb"SC_ACCEPT", then the connection still remains open. Note that in order to specify a value other tha \verb"SC_ACCEPT" for the \verb"result" parameter to \verb"SRelResponse", the release token must exist but must not be owned by the user making the call to \verb"SRelResponse".% \footnote{Gentle reader, we don't write the standards; we just try to implement them.} \f \section {Restrictions on User Data} The \man libssap(3n) contains partial support for the use of unlimited user data for session services. With the exception of the {\sf S-DATA\/} and the {\sf S-TYPED-DATA\/} services, the initial session service limited the amount of user data that could be present. With the introduction of the unlimited user data addendum\cite{ISO.SS.UserData,ISO.SP.UserData} to the session service and protocol, this restriction has been lifted. During connection establishment, the \man libssap(3n) library will attempt to negotate the use of unlimited user data. If this negotiation fails, then session services which permit user data, other than {\sf S-DATA\/} and {\sf S-TYPED-DATA}, are limited to 512~octets of user data.% \footnote{Strictly speaking, the {\sf S-U-ABORT} service permits only 9~octets of user data. This limitation is unreasonable~---~upto 512~octets will be permitted.} If the negotation succeeds, then session services which permit user data, other than {\sf S-DATA\/} and {\sf S-TYPED-DATA}, are limited to 65400~octets of user data, with the exception of the {\sf S-CONNECT.REQUEST\/} primitive, which is limited to 10240~octets of user data (the {\sf S-CONNECT.RESPONSE\/} primitive is limited to 65528~octets).% \footnote{Strictly speaking, the amount should be unlimited. However this full generality is not available at this time.} There is one further limitation however: although the initiator of a connection can send upto 10240~octets, due to limitations in the \unix/ kernel, if the \man tsapd(8c) is dispatching based on session selector, then a responder can accept upto approximately 1536~octets. To avoid this problem, have \man tsapd(8c) dispatch based on transport selector (see Section~\ref{service:standard} in \volone/). \f \section {Error Conventions} All of the routines in this library return the manifest constant \verb"NOTOK" on error, and also update the \verb"si" parameter given to the routine. The \verb"si_abort" element of the \verb"SSAPindication" structure contains a \verb"SSAPabort" structure detailing the reason for the failure. The \verb"sa_reason" element of this latter structure can be given as a parameter to the routine \verb"SErrString" which returns a null-terminated diagnostic string. \begin{quote}\index{SErrString}\small\begin{verbatim} char *SErrString (c) int c; \end{verbatim}\end{quote} \f \section {Compiling and Loading} Programs using the \man libssap(3n) library should include \verb"<isode/ssap.h>". The programs should also be loaded with \verb"-lssap" and \verb"-ltsap" (this latter library contains the routines which implement the transport services used by the session provider). \f \section {An Example} Let's consider how one might construct a source entity that resides on the SSAP. This entity will use a synchronous interface. There are two parts to the program: initialization and data transfer; release will occur when the standard input has been exhausted. In our example, we assume that the routine \verb"error" results in the process being terminated after printing a diagnostic. In Figure~\ref{initSSsource}, the initialization steps for the source entity, including the outer {\em C\/} wrapper, is shown. First, a lookup is done in the ISO services database, and the \verb"SSAPaddr" is initialized. The \verb"SSAPref" is zeroed. Next, for each token associated with the session requirements, initial ownership of that token is claimed. Finally, the call to \verb"SConnRequest" is made. If the call is successful, a check is made to see if the remote user accepted the connection. If so, the session-descriptor is captured, along with the negotiated requirements and initial token settings. In Figure~\ref{dataSSsource} on page~\pageref{dataSSsource}, the data transfer loop is realized. The source entity reads a line from the standard input, and then queues that line for sending to the remote side. When an end-of-file occurs on the standard input, the source entity requests release and then gracefully terminates. Although no checking is done in this example, for the calls to \verb"SDataRequest" and \verb"SRelRequest", on failure a check for the operational error \verb"SC_OPERATION" should be made. For \verb"SDataRequest", this would occur when the data token was not owned by the user; for \verb"SRelRequest", this would occur when the release token was not owned by the user. \clearpage \tagrind[tp]{grind5b-3a}{Initializing the SSAP source entity}{initSSsource} \clearpage \tagrind[tp]{grind5b-3b}{Initializing the SSAP source entity (continued)}\empty \clearpage \tagrind[tp]{grind5b-4}{Data Transfer for the SSAP source entity}% {dataSSsource}. \f \section {For Further Reading} The ISO specification for session services is defined in \cite{ISO.SP.Service}, while the complementary CCITT recommendation is defined in \cite{CCITT.SP.Service}. The corresponding protocol definitions are \cite{ISO.SP.Protocol} and \cite{CCITT.SP.Protocol}, respectively. \f \section {Changes Since the Last Release}\label{ssap:changes} A brief summary of the changes between \verb"ssap"~\ssaprevrsn/ and \verb"ssap"~\ssapvrsn/ are now presented. These are the user-visible changes only; changes of a strictly internal nature are not discussed. The \verb"ss_version" element of the \verb"SSAPstart" structure along with the \verb"sc_version" element of the \verb"SSAPconnect" structure were removed. The session version number in use is now encoded in the \verb"ss_qos" or \verb"sc_qos" elements of their respective structures. These elements are \verb"QOStype" structures as defined in Section~\ref{tsap:qos}.