Legacy Documentclose button

Important: The information in this document is obsolete and should not be used for new development.

Previous Book Contents Book Index Next

Inside Macintosh: Networking With Open Transport / Part 1 - Open Transport Essentials
Chapter 18 - Printer Access Protocol (PAP)


Using PAP

To use Open Transport PAP, you first open an endpoint as a PAP endpoint, which causes Open Transport to allocate the memory PAP needs for data buffers and for storing the variables PAP uses to maintain the connection between endpoints. After a connection is established, PAP manages and controls the data flow between the two endpoints throughout a session to ensure that data is delivered and received in the order in which it was sent and that duplicate data is not sent.

When you bind a PAP endpoint, the binding process associates a local protocol address with the endpoint. In PAP, this identifies the socket address, and PAP uses this as part of the address for sending and receiving packets of data. Each socket can maintain concurrent PAP connections with several other sockets, but only one PAP endpoint can bind with a qlen greater than 0.

As with other connection-oriented protocols, Open Transport PAP allows you to create a passive endpoint that listens for incoming connection requests rather than initiating such requests. In addition, the implementation of PAP under Open Transport includes some PAP-specific features:

PAP is also able to arbitrate connections requests and to accept requests from the workstations that have been waiting the longest to print.

Binding PAP Endpoints

You have two choices when binding a PAP endpoint: You can create an endpoint that can initiate connections and receive connection requests, or you can create a passive endpoint that can only receive connection requests. Typically, a passive PAP endpoint is a printer server.

If your endpoint can initiate connections, you can bind it as a normal Open Transport endpoint and use any of the three AppleTalk address formats for the socket address: DDP, NBP, or the combined DDP-NBP format. If the bind is successful, the endpoint is ready for use in establishing and using a connection.

The other choice when binding a PAP endpoint is to establish it as a passive peer that listens for incoming connection requests. The passive peer can accept or deny a connection request. The use of a passive peer is typical of a server environment in which a server, such as a printer server, is registered with a single name. Endpoints throughout the network can contact the printer server with connection requests. The server can accept or deny a request. It might deny a request, for example, when its resources are exhausted, based on criteria that you define.

To create a passive peer that listens, you specify a qlen field value greater than 0 during the binding process. The number you use determines how many connection requests the endpoint can support. Once the endpoint is bound, it starts listening for incoming connection requests. When a request arrives, the endpoint retrieves certain information about the request and continues to process the connection request by accepting or rejecting it.

You can bind multiple PAP endpoints to the same socket, but you can have only one passive peer that listens for a given socket. When a server accepts a connection from a client workstation for processing its print request, it cannot accept another connection request from the same workstation endpoint. As with other connection-oriented protocols, you can only have one concurrent connection between the same pair of endpoints.

Specifying PAP Options

You can use one of two options with PAP endpoints:

The following two sections explain the use of these options.

The End-of-Message Option

You can send a PAP data stream that contains no logical boundaries which need to be preserved across the connection, or you can use transport service data units (TSDUs) to separate the data stream into discrete logical units when sending and receiving it across a connection. By default, PAP does not support TSDUs. Instead, PAP sends and receives a continuous stream of data with no message delimiters.

If transport independence is not crucial for your application, you can use a PAP-specific option that allows TSDUs. The OPT_ENABLEEOM option enables the PAP end-of-message feature, which permits dividing data streams into smaller logical units. Open Transport uses a flag in the send and receive functions to indicate multiple sends and receives. The use of this flag, the T_MORE flag, allows you to break up a large data stream without losing its logical boundaries at the other end of the connection. The flag, however, indicates nothing about how the data is packaged for transport on the lower-level protocols below the PAP endpoint provider.

To send a data stream that is broken up into TSDUs, set the T_MORE flag on each send after setting the OPT_ENABLEEOM option. This indicates to the provider that there are more packets coming that are part of this same message. When you send data without the T_MORE flag set, the provider knows this is the last packet for this message and sends an EOM packet to the remote peer. It is possible for this last (EOM) packet to contain no data because PAP supports the sending of zero-length packets. This is useful when you send a packet with the T_MORE flag set only to discover that you have no more data to send. In this case, PAP still expects another packet, but you have no data to put into it. You can send a zero-length packet to set the T_MORE flag correctly.

Because printers expect an EOM indicator on the last packet of a connection, if you do not choose to use the OPT_ENABLEEOM option, PAP takes care of that for you, guaranteeing that the EOM indicator is set on the last packet. If, however, you do choose to use the OPT_ENABLEEOM option, you are responsible for setting the EOM indicator, by using the T_MORE flag on every packet but the last.

You can enable the EOM option for an endpoint in several ways. One way is to define the option as part of the configuration string you use to open the endpoint. The following line of code enables the EOM option for a PAP endpoint:

OTOpenEndpoint(OTCreateConfiguration("pap(EnableEOM=1)"),0, NULL, &err);
Or you could call a function like that shown in Listing 7-5 as follows:

err=SetFourByteOption(ep, ATK_PAP, OPT_ENABLEEOM, 1);
to enable the EOM option for a PAP endpoint.

The Open Retry Option

By default, when a PAP endpoint provider calls the OTConnect function, which creates a connection request, it only tries to establish the connection once. This behavior is controlled by an option, PAP_OPT_OPENRETRY, whose default value is 1. (The default value of 1 for this option differs from the default retry count of 5 specified in Inside AppleTalk, second edition. In other aspects of Open Transport AppleTalk, AppleTalk protocols adhere to the specifications detailed in that book. )

To force PAP to try again to open the connection, you can set a value greater than 1 for the PAP_OPT_OPENRETRY option. Workstation client applications that want to print data, for example, will probably keep trying to get access to a printer server, retrying printer connections until it succeeds or until the user presses the cancel button.

The Server Status Option

In a client-server interaction, a client may sometimes need to know the status of the server. In these cases, the client can request the server's status. This request can occur outside a connection. If the OPT_SERVERSTATUS option has been set, with a C string up to 255 bytes long, the server can return that string as the server status.

The Reply Count Option

One-call specific option which you might find useful when trying to connect to some printers is the ATP_OPTREPLYCNT option.

A PAP-compliant printer will respond to a PAP connection request with a single connection reply packet in which the EOM flag is set. Some printers do not set this flag in the response packet, so ATP (upon which PAP is layered) expects additional packets to be sent. After the timeout, the endpoint resends the connection request, and again the printer responds without setting the EOM bit. The ATP_OPTREPLYCNT option tells PAP to expect only one reply packet.

Listing 18-1 demonstrates how to implement the ATP_OPTREPLYCNT option. By default when you make a connection request, the response bitmap is set to request 8 packets. By using the ATP_OPTREPLYCNT option set to 1 (with the OTConnect call), the connection request can be satisfied when the response packet is received even when the EOM bit is not set. In the sample, the endpoint is assumed to be in synchronous mode.

Listing 18-1 Using the ATP_OPTREPLYCNT option

OSStatus DoPAPSpecialConnect(TEndpoint* ep, UInt8 *addr, UInt32 addrLen,
               UInt32 openRetryVal,
               UInt32 retryIntervalVal, 
               UInt32 replyCntVal)
{
   TCall             theCall;
   static unsigned char optbuf[3 * kOTFourByteOptionSize];
   OSStatus          err;
   short             i = 0;

   if (!OTIsSynchronous(ep))
   {
         /* this routines assumes that the endpoint is synchronous. */
      return (-1);
   }
   
      /* set the address field */
   theCall.addr.buf= addr;
   theCall.addr.len= addrLen;
   
   if (openRetryVal != 0)
   {
      ((TOption*)optbuf)->len= kOTFourByteOptionSize;
      ((TOption*)optbuf)->level= ATK_PAP;
      ((TOption*)optbuf)->name= PAP_OPT_OPENRETRY;
      ((TOption*)optbuf)->value[0]= openRetryVal;
      (((TOption*)optbuf) + 1)->len= kOTFourByteOptionSize;
      (((TOption*)optbuf) + 1)->level= ATK_PAP;
      (((TOption*)optbuf) + 1)->name= OPT_INTERVAL;
      (((TOption*)optbuf) + 1)->value[0]= retryIntervalVal;
      
      i += 2;// increment the options counter index
   }

   if (replyCntVal != 0)
   {
         /* If the replyCntVal is non zero then make sure that it */
         /* falls between 1 and 8 */
      if (replyCntVal < 1)
         replyCntVal = 1;
      if (replyCntVal > 8)
         replyCntVal = 8;
   
      (((TOption*)optbuf) + i)->len= kOTFourByteOptionSize;
      (((TOption*)optbuf) + i)->level= ATK_ATP;
      (((TOption*)optbuf) + i)->name= ATP_OPT_REPLYCNT;
      (((TOption*)optbuf) + i)->value[0]= replyCntVal;
      
      i++;/* increment the options counter index */
   }
   
      /* go ahead and set the option buffer field */
   theCall.opt.buf= (UInt8*)optbuf;
      /* set the length field depending on number of options set. */
   theCall.opt.len= i * kOTFourByteOptionSize;

   theCall.udata.len= 0;
   
   err = ep->Connect(&theCall, NULL);

   return err;
}

Disconnecting

As with all connection-oriented Open Transport protocols, PAP supports abortive disconnects. In addition, PAP supports orderly disconnects, although it can only implement them locally.

An abortive disconnect directs the remote endpoint to abruptly tear down its connection without making any accomodation for the data that may be in the transmission pipeline at the time. You can define your own handshake to prevent losing data during the disconnect process.

PAP implements orderly disconnects locally, not over the wire. This means that immediately after you request the disconnect, PAP sends all data buffered at the local end and then tears down the connection, breaking communication with the remote end. As a result, no data can be sent from either the local or remote endpoint. The endpoints can continue to process data already in their receive queues, but no new data can go out.

Using General Open Transport Functions With PAP

This section describes any special considerations you must take into account for Open Transport functions when you use them with the Open Transport PAP implementation. You must be familiar with the function descriptions in the chapter "Endpoints" before reading this section.

OTBind

The OTBind function associates a local protocol address with the endpoint specified by the ref parameter.

You can bind multiple PAP endpoints to a single protocol address, but you can bind only one passive endpoint that listens at that address.

With PAP, as with other connection-oriented protocols, the req->qlen parameter specifies the number of outstanding connection requests that an endpoint can support. The endpoint can negotiate a lower final value of qlen if it cannot handle the requested number of outstanding connection requests.

OTConnect

The OTConnect function requests a connection to a specified remote endpoint.

PAP does not allow application-specific data to be included when you establish a connection, so you need to set the sndcall->udata.len field to 0. PAP ignores the sndcall->udata.buf field.

OTRcvConnect

The OTRcvConnect function reads the status of a previously issued connection request.

Because PAP does not allow application-specific data to be associated with a connection request, you need to set the call->udata.maxlen field to 0. PAP ignores the call->udata.buf field.

OTListen

The OTListen function listens for an incoming connection request.

PAP does not allow application-specific data to be included when you request a connection, so you need to set the call->udata.maxlen field to 0. PAP ignores any data in the call->udata.buf field.

OTAccept

The OTAccept function accept a connection request either on the same endpoint that received the connection request or on a different endpoint.

PAP does not allow application-specific data to be included when you accept a connection, so you need to set the call->udata.len field to 0. PAP ignores the call->udata.buf field.

OTSnd

The OTSnd function sends normal and expedited data through a connection-oriented transactionless endpoint.

PAP supports TSDUs through the OPT_ENABLEEOM option. In PAP, TSDUs sent from the client endpoint can be of infinite length, but TSDUs sent from a server endpoint can only be up to 512 bytes long. Zero-length packets are supported by PAP.

OTRcv

The OTRcv function receives normal and expedited data through a connection-oriented transactionless endpoint.

PAP supports TSDUs through the OPT_ENABLEEOM option.

OTSndDisconnect

The OTSndDisconnect function initiates an abortive disconnect or rejects a connection request.

In an abortive disconnect, the call parameter is ignored because PAP does not allow application-specific data to be associated with a disconnect. You need to set the call->udata.len field to 0. PAP ignores the call->udata.buf field.

OTRcvDisconnect

The OTRcvDisconnect function returns information about why a connection attempt failed or an established connection was terminated.

Because PAP does not allow application-specific data to be associated with a disconnect, you need to set the discon->udata.maxlen field to 0. PAP ignores the discon->udata.buf field.


Subtopics
Binding PAP Endpoints
Specifying PAP Options
The End-of-Message Option
The Open Retry Option
The Server Status Option
The Reply Count Option
Disconnecting
Using General Open Transport Functions With PAP
OTBind
OTConnect
OTRcvConnect
OTListen
OTAccept
OTSnd
OTRcv
OTSndDisconnect
OTRcvDisconnect

Previous Book Contents Book Index Next

© Apple Computer, Inc.
15 JAN 1998