[comp.protocols.appletalk] Unix manual for ADSP connection

BILLY@VENERA.ISI.EDU ("Billy Brackenridge") (12/23/88)

IPT Inc. has implemented Apple Data Stream Protocol (ADSP) for Unix.
The following is a user manual for the Unix programmer's interface to
ADSP. This interface is similar to the Berkeley Unix sockets
interface. Apple has defined a similar programmer's interface for the
Macintosh.

ADSP is fairly new addition to the AppleTalk family of protocols. It
is similar to TCP. It provides flow control and guarantees reliable
delivery of data in the order in which it was sent.

Today there are few applications using ADSP, but Apple promises
future applications will utilize ADSP. If anyone else is doing ADSP
for Unix it would be nice to coordinate so there is only one
programmer's interface even if there are several implementations. Comments
and contacts with people interested in ADSP are welcome.




	       uShare UNIX ADSP Programmer's Interface
				   
			    Beta Draft 1.0




NAME
      adspAccept   --  accepts a connection request.


SYNOPSIS
    #include "adsp.h"

    int adspAccept(ccbRefNum)
    char *ccbRefNum;


DESCRIPTION
    adspAccept will accept a connection request on the connection obtained
    from adspListen by sending an open connection request and acknowledgement
    to the remote address. The it waits for an acknowledgement from the remote
    address before it returns. On success (i.e. ack is received) the 
    connection will become established and ADSP operations may be done on the
    connection.


RETURN VALUE
    A value of 0 is returned if there is no error and the connection is 
    established, otherwise a negative value is returned.

ERRORS
    Possible error value returned:
       [ERRREFNUM]      --      bad/invalid CCB reference number.





NAME
      adspConnect   -  initiate an ADSP connection.


SYNOPSIS
    #include "adsp.h"

    int adspConnect(ccbRefNum,destAddr)
    char    *ccbRefNum;
    DDPAddr *destAddr;


DESCRIPTION
    adspConnect tries to initiate a connection with destaddr by sending an
    open connection request packet. The routine will return either an
    acceptance (connection was established) or a denial. adspConnect uses
    adspOpnConn to establish the connection so that some of the peculiar
    aspects of opening an ADSP connection are hidden from the programmer.


RETURN VALUE
    A value of 0 is returned if there is no error and the connection request
    was accepted by the other end, otherwise a negative value is returned.


ERRORS
    possible error value returned:
       [ERRREFNUM]      --    bad or invalid CCB reference number.
       [ERRSTATE]       --    connection request was denied. 


SEE ALSO
    adspOpnConn(), and adspOpnDeny().





NAME
	adspCreateConn -- Create ADSP Connection Control Block (CCB).

SYNOPSIS
    #include "adsp.h"

    char *adspCreateConn(ddpSkt,recvQsize,attnSize,recvSeq,sendSeq,recvBuff,
                         sendBuff)
    int     ddpSkt;
    Ulong   recvQsize;
    Ulong   attnSize;
    Ulong   recvSeq;
    Ulong   sendSeq;
    char    *sendBuff;
    char    *recvBuff;

DESCRIPTION

    adspCreateConn creates and initializes a CCB with the information
    supplied, and also opens a socket for the connection on ddpSkt, the DDP
    socket number of the connection end.

    recvQsize and attnSize are the size of the receive and attention buffers
    that the connection end can receive. If attnSize is zero, the attention 
    buffer is set to the default value of ADSPMAXATTN. Similarly for
    recvQsize, the receive buffer will be set to the default value of
    ADSPMAXWDW. 

    recvSeq and  sendSeq are the initial receive and send sequence number of
    the connection end, usually they are set to zero. 

    sendBuff and recvBuff are pointers to the send and receive buffers/queues.
    If sendBuff and recvBuff are NULL pointers, the routine will allocate 
    default buffers of size sendBuffSz and recvBuffSz (sendBuffSz and 
    recvBuffSz are set by calling adspInitialize),respectively.

    Based on the information passed, all the fields on the CCB will be filled 
    and connection can be initiated on ddpSkt.


RETURN VALUE
    A NULL is returned if an error occurs, otherwise the return value is the
    CCB reference number, used to identify the CCB on subsequent operations.


ERROR
    The routine will fail if it can not open a socket for the connection and
    it will be aborted if it can not allocate enough memory for the buffers.


See Also
    adspInitialize.
    



NAME
       adspGetStatus  -- gets current status of a Connection Control Block.


SYNOPSIS
    #include "adsp.h"

    int adspGetStatus(ccbRefNum,sendQPending,sendQFree,recvQPending,recvQFree)
    char  *ccbRefNum;
    Ulong *sendQPending;
    Ulong *sendQFree;
    Ulong *recvQPending;
    Ulong *recvQFree;


DESCRIPTION
    adspGetStatus gets the current status of a Connection Control Block 
    referenced by ccbRefNum.
    
    The number of bytes of pending data on the send queue not yet acknowledged
    by the other end and the receive queue not yet delivered to the client
    is returned in <sendQPending> and <recvQPending>, respectively. 
    
    <sendQFree> and <recvQFree> will contain the number of free space still 
    available on the send and receive queue.  
    
    The caller can use the information returned as some kind of flow control,
    i.e. whether to send more data or to read pending data on the receive
    queue.


RETURN VALUE
    A value of 0 will be returned on success, otherwise a negative number will
    be returned.


ERRORS
    The only possible error is :
       [ERRREFNUM]      an invalid CCB reference number






NAME
     adspInitialize  -- initializes ADSP parameters.


SYNOPSIS
    #include "adsp.h"

    int  adspInitialize(bucketnum, sendBuffSize, recvBuffSize)
    int   bucketnum;
    Ulong sendBuffSize;
    Ulong recvBuffSize;


DESCRIPTION
    adspInitialize initializes certain ADSP parameters.
    * bucketnum sets the hash table size for hashing AT address/CID's
      to CCB's ( 0 means default value of ADSPBUCKETNUM).
    * sendBuffSize sets the send buffer size (0 means default value of 
      ADSPBUFFSIZE).
    * recvBuffSize sets the recv buffer size (0 means default value of 
      ADSPBUFFSIZE).

    Use this routine only to modify these ADSP parameters before any ADSP
    connections are made. If adspInitialize is never called, the default
    values will be used.


RETURN VALUE
    A value of 0 will be returned on success.


ERRORS
    The operation will be aborted if it can not allocate enough memory for the
    hash table.






NAME
     adspListen    --  listens for open connection.


SYNOPSIS
    #include "adsp.h"

    int adspListen(ccbRefNum,addrMask)
    char    *ccbRefNum;
    DDPAddr *addrMask;


DESCRIPTION
    adspListen will listen for an open connection request addressed to it from
    any address specified in addrMask. 
    AddrMask may be NULL to match all addresses, or the fields of addrMask
    may be set to -1 to match all values possible for the field.


RETURN VALUE
    A value of 0 is returned if there is no error and the connection request
    was accepted, otherwise a negative value is returned.


ERRORS
    Possible error value returned:
    [ERRREFNUM]       --    bad or invalid CCB reference number






NAME
      adspOpnConn   --  send an open and/or ack connection packet.


SYNOPSIS
    #include <bsd/sys/types.h>
    #include <bsd/sys/time.h>
    #include "adsp.h"

    int adspOpnConn(ccbRefNum, remoteAddr, type, timeout)
    char    *ccbRefNum;
    DDPAddr *remoteAddr;
    byte    type;
    struct  timeval *timeout;


DESCRIPTION
    adspOpnConn is used to initiate a new connection or to acknowledge an
    open connection request sent by the other end.

    ccbRefNum indicates which connection the caller refers to.

    remoteAddr indicates the Appletalk address of the intended recipient of
    the packet of type <type>. Possible values for <type> are OPNCONNREQ,
    OPNCONNACK and OPNREQACK. 
    * Use OPNCONNREQ to initiate a new connection and the caller did not 
      receive an open connection request from the other end.
    * Use OPNCONNACK to acknowledge a connection request and the caller end
      has been established, i.e. caller's previous request has been
      acknowledged by the other end.
    * Use OPNREQACK to piggyback an acknowledgement with open connection
      request.
      
    The timeout parameter is used to indicate how long the routine will 
    wait/block to receive an acknowledgement (meaningful only for OPENCONNREQ 
    or OPNREQACK) and a NULL value will make it block indefinitely until an 
    acknowledgement to the request is received.  


RETURN VALUE
    A value of 0 is returned on success, otherwise a negative value is
    returned.
    A value of -1 indicates that the open connection request is denied.


ERRORS
    Possible value of errors :
       [ERRREFNUM]          Invalid CCB reference number
       [ERROPENING]         Invalid open connection packet type.
       [ERRRETRY]           open connection request retries exhausted.
       [ERRSELECT]          Error in calling select.

SEE ALSO
    adspListen,adspPeek,adspOpenDeny,adspSelect.
    Inside Appletalk.






NAME
      adspOpnDeny    --  deny an open connection request.


SYNOPSIS
    #include "adsp.h"

    int adspOpenDeny(ccbRefNum)
    char    *ccbRefNum;


DESCRIPTION
    adspOpenDeny is used to deny an open connection request received on a 
    connection. 


RETURN VALUE
    A value of 0 is returned on success, otherwise a negative number will be
    returned.


ERRORS
    Possible error value returned:
	[ERRREFNUM]          bad/invalid CCB reference number.


SEE ALSO
    adspListen.



NAME
     adspPeek  -- peeks to a certain connection for the data/control packet.


SYNOPSIS
    #include "adsp.h"

    int adspPeek(ccbRefNum, addrMask, timeout, result)
    char    *ccbRefNum;
    DDPAddr *addrMask;
    struct  timeval *timeout;
    int     *result;


DESCRIPTION
    adspPeek will peek to a certain connection end to see whether there is a
    packet ready to receive on that connection end referenced by ccbRefNum.

    It specifies the address mask (addrMask) from whom it will  accept any 
    data.
    A NULL value for addrMask or (net=-1,node=-1,socket=-1) in addrMask 
    matches all address. 

    The timeout determines how long the routine will wait/block until data 
    arrives on the intended connection end (a NULL value will cause the
    routine to block indefinitely until data arrives).

    This routine is primarily used to listen for the open connection request 
    to establish a connection, although it can be used to receive other
    packets, such as attention, control or data packets. Based on the result
    (passed in result parameter and the return value, the caller can determine
    what to do next.


RETURN VALUE
    A non-negative value will be returned if successful, otherwise a negative
    integer will be returned.

    If the return value is 0, then it indicates that a control/attention
    packet was received, and the value of result determines what kind of
    control packet it was. 

    A result value of :
	PROBEORACK    indicates   probe or acknowledged packet.
	OPNCONNREQ    indicates   open connection request.
	OPNCONNACK    indicates   open connection acknowledgement.
	OPNREQACK     indicates   open connection request and acknowledgement.
	OPNCONNDENY   indicates   open connection deny.
	OPNCONNADV    indicates   close connection advice.
	FRWDRESET     indicates   forward reset.
	FRWDRSTACK    indicates   forward reset acknowledgement.
	RXMITADV      indicates   retransmit advice.
	ATTNPKT       indicates   attention packet.

     If the return value is 1, then it indicates that a data packet was
     received and is queued in the receive buffer. The result value will
     indicate whether there is an error in the data packet.  The result value
     will contain a negative number if there is an error, otherwise it returns
     the number of pending/unread data in receive queue.

ERRORS
     Possible error value returned:
	[ERRSELECT]         error in select operation.
	[ERRSTATE]          error in ddpRecv.
	[ERROPENING]        not accepting request from the sender.





NAME
    adspRead   --  read data from ADSP


SYNOPSIS
    #include "adsp.h"

    int adspRead(ccbRefNum, reqCount, dataPtr, eom, status)
    char  *ccbRefNum;
    Ulong *reqCount;
    char  *dataPtr;
    byte  *eom;
    int   *status;


DESCRIPTION
    ccbRefNum is the reference number of the connection where the caller 
    intends to read data from. 

    AdspRead will try to read reqCount bytes from the ADSP receive buffer
    into the buffer pointed to by dataPtr.

    If on return status contains a  non-negative number, it indicates that no
    errors occurred during adspRead, and depending on the value of reqCount
    returned, the caller can tell whether adspRead received a control or data
    packet. 
    
    When adspRead reads a control packet, it will set both reqCount and status
    to zero and the return value  to 1. When adspRead reads data packet, the 
    status is set to zero, reqCount is set to a positive number and the return
    value will be the sequence number of the last byte of data that gets 
    passed to the client (the lowest sequence number of unread data).


RETURN VALUE
    A return value of 0 indicates an error and the error code is stored in 
    status.

    A return value of 1 and status=0 and reqCount=0 indicates adspRead read
    a control packet.

    Otherwise a data packet is received and the sequence number of the first
      unread byte is returned.


ERRORS
    Possible error values returned:
       [ERRREFNUM]         bad/invalid reference number.
       [ERRRECEIVED]       adspListen fails.


SEE ALSO
    adspPeek, adspSelect.





NAME
    adspRemoveConn    -- removes/deletes an ADSP connection.

SYNOPSIS
    #include "adsp.h"

    int adspRemoveConn(ccbRefNum)
    char *ccbRefNum;

DESCRIPTION
    adspRemoveConn will remove/delete a connection referenced by ccbRefNum
    from a connection socket and its CCB is deallocated. If there are no other
    connections on that socket, the socket is closed.

RETURN VALUE
    A value of 0 is returned on success, otherwise a negative number is 
    returned.

ERRORS
    Possible error value returned:
       [ERRSTATE]       can not close socket.






NAME
    adspSelect     --  asynchronous ADSP I/O.


SYNOPSIS
    #include <bsd/sys/types.h>
    #include <bsd/sys/time.h>
    #include "adsp.h"

    int adspSelect(listOfCCB, readyCCB, timeout)
    char   *listOfCCB[];
    char   *readCCB[];
    struct timeval *timeout;


DESCRIPTION
    adspSelect functions similarly to the UNIX "select". Instead of checking on
    the sockets, adspSelect checks the connections whose connection reference
    numbers are  specified in listOfCCB. 
    
   
    The routine will wait/block for the duration specified by timeout, use a  
    NULL value to block indefinitely.

    The list of ready connections (i.e. has data pending) is returned in
    readyCCB. If no connection is immediately ready when adspSelect is called,
    it will return the first connection that is ready within the timeout
    period. If there are connections that are immediately ready when
    adspSelect gets called, it immediately returns all of the ready
    connections specified in listOfCCB.


RETURN VALUE
    On success, it returns a non-zero,positive  number to indicate the number 
    of ready CCB's. A value of 0 indicates that the timeout expired with no 
    connection ready. A negative number indicates an error.


ERRORS
    Possible error values returned:
       [ERRSELECT]         select operation fails.
       [ERRSTATE]          connection end address is inactive.
       [ERRNOCONN]         connection end does not have any connection.







NAME
      adspSendAttn    --  sends an ADSP attention packet.


SYNOPSIS
    #include "adsp.h" 

    int adspSendAttn(ccbRefNum, attnCode, message, mssglen)
    char    *ccbRefNum;
    char    *message;
    word    attnCode;
    int     mssglen;


DESCRIPTION
    adspSendAttn sends an attention packet for the connection referenced by
    ccbRefNum. attnCode is the intended attention code. Values in the range
    0x0000 to 0xEFFF are for the client's use, whereas values int the range 
    0xF000 through 0xFFFF are reserved for future use.

    message and mssglen are the attention message and its length.
   
    There can be only one attention message pending at one time. 


RETURN VALUE
     A value of 0 is returned on success, otherwise a negative number is
     returned.

ERRORS
     Possible error value returned:
	[ERRSTATE]          message is too long (> ADSPMAXDATA bytes).





NAME
       adspSendFwdRst     --   send a Forward Reset Packet.


SYNOPSIS
    #include "adsp.h"

    int adspSendFwdRst(ccb,ack,timeout)
    adspCCB *ccb;
    byte    ack;
    long    timeout;


DESCRIPTION
    adspSendFwdRst sends a forward Reset packet for the connection specified 
    by ccbRefNum. This mechanism allows an ADSP client to abort the delivery
    of any outstanding data to the remote end's client. 
    
    If a forward reset acknowledgement is expected, <ack> should be set to a 
    non-zero value and the timeout value will determine the interval in which 
    the forward reset packet is sent before an acknowledgement is received. 
    When the timer expires, the forward reset packet is retransmitted and the 
    timer is restarted. This action continues until either a valid forward 
    reset acknowledgement is received or until the connection is torn down.

RETURN VALUE
    adspSendFwdRst always returns 0.

ERRORS
    None.






NAME
       adspSendProbe    --  sends a probe packet.


SYNOPSIS
    #include <bsd/sys/types.h>
    #include <bsd/sys/time.h>
    #include "adsp.h"

    int adspSendProbe(ccbRefNum,timeout,retry)
    char *ccbRefNum;
    long timeout;
    int  retry;


DESCRIPTION
    adspSendProbe sends a probe packet to the other end of the connection 
    specified by ccbRefNum and expects an acknowledgement from the other end.
    The timeout period determines how long it will wait for any packet before
    it resends the probe packet. The routine continues resending the probe
    packet until the retries are exhausted.


RETURN VALUE
    A value of 1 is returned if the other end of the connection is alive,
    otherwise a value of 0 is returned and the connection is removed.


ERRORS
    See return value.





NAME
       adspWrite    --  write/send data to the other end of connection.


SYNOPSIS
    #include "adsp.h"

    unsigned int adspWrite(ccbRefNum,reqCount,dataPtr,eom,flush,ack,status)
    char  *ccbRefNum;
    Ulong *reqCount;
    char  *dataPtr;
    byte  eom;
    byte  flush;
    byte  ack;
    int   *status;


DESCRIPTION
    adspWrite writes data to the send buffer (if flush is 0 ) or sends data
    to the other end of connection specified by ccbRefNum (if flush is
    non-zero).

    reqCount indicates the number of bytes of data in dataPtr to be
    sent/written.

    Set eom if the last byte of the data is the end of message.

    Set ack to indicate that the recipient must send an ack upon receiving
    the packet.

    If flush and ack are non-zero, adspWrite will block until an ack is 
    received. It only makes sense to set ack if flush is set as well.

    It is up to the caller to determine whether to flush/send the data or 
    accumulate the data in the send buffer before finally sending the data.

    status is set to 0 if there is no error and it will be negative if there
    is an error.


RETURN VALUE
    On error, adspWrite will return 0 and status is set to a negative number,
    otherwise adspWrite will return the amount of free space in send buffer
    (send window) and status is set to 0.


ERRORS
    Possible error value returned (in status):
       [ERRREFNUM]         bad/invalid CCB reference number.




/* here follows "C" examples of how to set up an ADSP connection */

#include "adsp.h"

#define BUFFSZ 10000 

main (argc,argv)
int argc;
char **argv;
{
      .
      .
      .
   char    buffer[BUFFSZ];
   int     len=BUFFSZ;
   char    *refNum;
   int     socketnum;

   adspInitialize(0,0,0);  /* use default values */
   
   if (!(refNum= (char *) adspCreateConn(socketnum,wdwSize,100,0,0,
      (char *)NULL, (char *) NULL)) )
   {
      printf("server: can not create conn\n");
      exit(2);
   }

   /* Listen for an open connection from any source. */
   if ( adspListen(refNum,(DDPAddr *)NULL) < 0 )
   {
      printf("server: adspListen failed\n");
      exit(3);
   }

   /* server accepts an open connection */
   if ( adspAccept(refNum) < 0) 
   {
      printf("server: adspAccept failed\n");
      exit(4);
   }

   do
   {
       /* read data from the other end */
       if ( adspRead(refNum, &len, buffer, &eom, &status) < 0)
       {
	  printf("Server: adspRead error\n");
	  exit(3);
       }

       if ( (len==0) && (status==0) )
       {
	  /*  adspRead got control packet, ignore */
	  continue;
       }
          .
	  .   /* process data */
	  .
       len=BUFFSZ;
   } while ( !eom );

   /* got eom, tear down the connection */
   adspRemoveConn(refNum);
      
      .
      .
      .
}







#include "adsp.h"

int  BUFFSZ=1024;

main (argc,argv)
int argc;
char **argv;
{
      .
      .
      .
   char    *refNum;
   int     socketnum;
   int     eom=0;
      .
      .

   adspInitialize(0,0,0);  /* use default values */

   /* create connection with recv & attn buffer size=100 , use default for the
      other and let ADSP allocate the buffer */
   if (!(refNum= (char *) adspCreateConn(socketnum, 100,100,0,0,
      (char *)NULL, (char *) NULL)) )
   {
      printf("server: can not create conn\n");
      exit(2);
   }

   /* Establish an ADSP connection with server at servAddr. */
   if ( adspConnect(refNum, &servAddr) < 0)
   {
      printf("Client: can not open connection\n");
      exit(2);
   }

   numFree=256;

   for (;;)
   {
	 .
	 .  /* acquire data into buffer */
	 .  /* if eof on data, set eom to 1 */
	 .

       if ((numFree=adspWrite(refNum, &len, buffer, eom, 1, 1, &status)) < 0)
       {
	  printf("Client: adspWrite error\n");
	  exit(0);
       }
   }

    .
    .
    .

   adspRemoveConn(refNum);  /* remove the connection */

    .
    .
}
-------