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 */ . . } -------