/*
 	File:		ADSP.h
 
 	Contains:	AppleTalk Data Stream Protocol (ADSP) Interfaces.
 
 	Version:	Technology:	System 7.5
 				Release:	QuickTime 4.0
 
 	Copyright:	(c) 1986-1998, 1995-1997 by Apple Computer, Inc., all rights reserved
 
 	Bugs?:		For bug reports, consult the following page on
 				the World Wide Web:
 
 					http://developer.apple.com/bugreporter/
 
*/
#ifndef __ADSP__
#define __ADSP__

#ifndef __ERRORS__
#include <Errors.h>
#endif
#ifndef __APPLETALK__
#include <AppleTalk.h>
#endif



#if PRAGMA_ONCE
#pragma once
#endif

#ifdef __cplusplus
extern "C" {
#endif

#if PRAGMA_IMPORT
#pragma import on
#endif

#if PRAGMA_STRUCT_ALIGN
	#pragma options align=mac68k
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(push, 2)
#elif PRAGMA_STRUCT_PACK
	#pragma pack(2)
#endif

/*driver control csCodes*/

enum {
	dspInit						= 255,							/* create a new connection end */
	dspRemove					= 254,							/* remove a connection end */
	dspOpen						= 253,							/* open a connection */
	dspClose					= 252,							/* close a connection */
	dspCLInit					= 251,							/* create a connection listener */
	dspCLRemove					= 250,							/* remove a connection listener */
	dspCLListen					= 249,							/* post a listener request */
	dspCLDeny					= 248,							/* deny an open connection request */
	dspStatus					= 247,							/* get status of connection end */
	dspRead						= 246,							/* read data from the connection */
	dspWrite					= 245,							/* write data on the connection */
	dspAttention				= 244,							/* send an attention message */
	dspOptions					= 243,							/* set connection end options */
	dspReset					= 242,							/* forward reset the connection */
	dspNewCID					= 241							/* generate a cid for a connection end */
};


enum {
																/* connection opening modes */
	ocRequest					= 1,							/* request a connection with remote */
	ocPassive					= 2,							/* wait for a connection request from remote */
	ocAccept					= 3,							/* accept request as delivered by listener */
	ocEstablish					= 4								/* consider connection to be open */
};


enum {
																/* connection end states */
	sListening					= 1,							/* for connection listeners */
	sPassive					= 2,							/* waiting for a connection request from remote */
	sOpening					= 3,							/* requesting a connection with remote */
	sOpen						= 4,							/* connection is open */
	sClosing					= 5,							/* connection is being torn down */
	sClosed						= 6								/* connection end state is closed */
};


enum {
																/* client event flags */
	eClosed						= 0x80,							/* received connection closed advice */
	eTearDown					= 0x40,							/* connection closed due to broken connection */
	eAttention					= 0x20,							/* received attention message */
	eFwdReset					= 0x10							/* received forward reset advice */
};


enum {
																/* miscellaneous constants */
	attnBufSize					= 570,							/* size of client attention buffer */
	minDSPQueueSize				= 100							/* Minimum size of receive or send Queue */
};

/* connection control block */
typedef struct TRCCB 					TRCCB;
typedef TRCCB *							TPCCB;

struct TRCCB {
	TPCCB 							ccbLink;					/* link to next ccb */
	UInt16 							refNum;						/* user reference number */
	UInt16 							state;						/* state of the connection end */
	UInt8 							userFlags;					/* flags for unsolicited connection events */
	UInt8 							localSocket;				/* socket number of this connection end */
	AddrBlock 						remoteAddress;				/* internet address of remote end */
	UInt16 							attnCode;					/* attention code received */
	UInt16 							attnSize;					/* size of received attention data */
	void *							attnPtr;					/* ptr to received attention data */
	UInt8 							reserved[220];				/* for adsp internal use */
};

typedef CALLBACK_API( void , ADSPConnectionEventProcPtr )(TPCCB sourceCCB);
/*
	WARNING: ADSPConnectionEventProcPtr uses register based parameters under classic 68k
			 and cannot be written in a high-level language without 
			 the help of mixed mode or assembly glue.
*/
typedef struct DSPParamBlock 			DSPParamBlock;
typedef DSPParamBlock *					DSPPBPtr;
typedef CALLBACK_API( void , ADSPCompletionProcPtr )(DSPPBPtr thePBPtr);
/*
	WARNING: ADSPCompletionProcPtr uses register based parameters under classic 68k
			 and cannot be written in a high-level language without 
			 the help of mixed mode or assembly glue.
*/
typedef REGISTER_UPP_TYPE(ADSPConnectionEventProcPtr) 			ADSPConnectionEventUPP;
typedef REGISTER_UPP_TYPE(ADSPCompletionProcPtr) 				ADSPCompletionUPP;

struct TRinitParams {
	TPCCB 							ccbPtr;						/* pointer to connection control block */
	ADSPConnectionEventUPP 			userRoutine;				/* client routine to call on event */
	UInt16 							sendQSize;					/* size of send queue (0..64K bytes) */
	void *							sendQueue;					/* client passed send queue buffer */
	UInt16 							recvQSize;					/* size of receive queue (0..64K bytes) */
	void *							recvQueue;					/* client passed receive queue buffer */
	void *							attnPtr;					/* client passed receive attention buffer */
	UInt8 							localSocket;				/* local socket number */
	UInt8 							filler1;					/* filler for proper byte alignment */
};
typedef struct TRinitParams				TRinitParams;

struct TRopenParams {
	UInt16 							localCID;					/* local connection id */
	UInt16 							remoteCID;					/* remote connection id */
	AddrBlock 						remoteAddress;				/* address of remote end */
	AddrBlock 						filterAddress;				/* address filter */
	UInt32 							sendSeq;					/* local send sequence number */
	UInt16 							sendWindow;					/* send window size */
	UInt32 							recvSeq;					/* receive sequence number */
	UInt32 							attnSendSeq;				/* attention send sequence number */
	UInt32 							attnRecvSeq;				/* attention receive sequence number */
	UInt8 							ocMode;						/* open connection mode */
	UInt8 							ocInterval;					/* open connection request retry interval */
	UInt8 							ocMaximum;					/* open connection request retry maximum */
	UInt8 							filler2;					/* filler for proper byte alignment */
};
typedef struct TRopenParams				TRopenParams;

struct TRcloseParams {
	UInt8 							abort;						/* abort connection immediately if non-zero */
	UInt8 							filler3;					/* filler for proper byte alignment */
};
typedef struct TRcloseParams			TRcloseParams;

struct TRioParams {
	UInt16 							reqCount;					/* requested number of bytes */
	UInt16 							actCount;					/* actual number of bytes */
	void *							dataPtr;					/* pointer to data buffer */
	UInt8 							eom;						/* indicates logical end of message */
	UInt8 							flush;						/* send data now */
};
typedef struct TRioParams				TRioParams;

struct TRattnParams {
	UInt16 							attnCode;					/* client attention code */
	UInt16 							attnSize;					/* size of attention data */
	void *							attnData;					/* pointer to attention data */
	UInt8 							attnInterval;				/* retransmit timer in 10-tick intervals */
	UInt8 							filler4;					/* filler for proper byte alignment */
};
typedef struct TRattnParams				TRattnParams;

struct TRstatusParams {
	TPCCB 							statusCCB;					/* pointer to ccb */
	UInt16 							sendQPending;				/* pending bytes in send queue */
	UInt16 							sendQFree;					/* available buffer space in send queue */
	UInt16 							recvQPending;				/* pending bytes in receive queue */
	UInt16 							recvQFree;					/* available buffer space in receive queue */
};
typedef struct TRstatusParams			TRstatusParams;

struct TRoptionParams {
	UInt16 							sendBlocking;				/* quantum for data packets */
	UInt8 							sendTimer;					/* send timer in 10-tick intervals */
	UInt8 							rtmtTimer;					/* retransmit timer in 10-tick intervals */
	UInt8 							badSeqMax;					/* threshold for sending retransmit advice */
	UInt8 							useCheckSum;				/* use ddp packet checksum */
};
typedef struct TRoptionParams			TRoptionParams;

struct TRnewcidParams {
	UInt16 							newcid;						/* new connection id returned */
};
typedef struct TRnewcidParams			TRnewcidParams;

struct DSPParamBlock {
	QElem *							qLink;
	short 							qType;
	short 							ioTrap;
	Ptr 							ioCmdAddr;
	ADSPCompletionUPP 				ioCompletion;
	OSErr 							ioResult;
	StringPtr 						ioNamePtr;
	short 							ioVRefNum;
	short 							ioCRefNum;					/* adsp driver refNum */
	short 							csCode;						/* adsp driver control code */
	long 							qStatus;					/* adsp internal use */
	short 							ccbRefNum;
	union {
		TRinitParams 					initParams;
		TRopenParams 					openParams;
		TRcloseParams 					closeParams;			/*dspClose, dspRemove*/
		TRioParams 						ioParams;				/*dspRead, dspWrite*/
		TRattnParams 					attnParams;				/*dspAttention*/
		TRstatusParams 					statusParams;			/*dspStatus*/
		TRoptionParams 					optionParams;			/*dspOptions*/
		TRnewcidParams 					newCIDParams;			/*dspNewCID*/
	} 								u;
};

enum { uppADSPConnectionEventProcInfo = 0x0000B802 }; 			/* register no_return_value Func(4_bytes:A1) */
enum { uppADSPCompletionProcInfo = 0x00009802 }; 				/* register no_return_value Func(4_bytes:A0) */
#if MIXEDMODE_CALLS_ARE_FUNCTIONS
EXTERN_API(ADSPConnectionEventUPP)
NewADSPConnectionEventProc	   (ADSPConnectionEventProcPtr userRoutine);
EXTERN_API(ADSPCompletionUPP)
NewADSPCompletionProc		   (ADSPCompletionProcPtr	userRoutine);
EXTERN_API(void)
CallADSPConnectionEventProc	   (ADSPConnectionEventUPP	userRoutine,
								TPCCB					sourceCCB);
EXTERN_API(void)
CallADSPCompletionProc		   (ADSPCompletionUPP		userRoutine,
								DSPPBPtr				thePBPtr);
#else
#define NewADSPConnectionEventProc(userRoutine) 				(ADSPConnectionEventUPP)NewRoutineDescriptor((ProcPtr)(userRoutine), uppADSPConnectionEventProcInfo, GetCurrentArchitecture())
#define NewADSPCompletionProc(userRoutine) 						(ADSPCompletionUPP)NewRoutineDescriptor((ProcPtr)(userRoutine), uppADSPCompletionProcInfo, GetCurrentArchitecture())
#if TARGET_OS_MAC && TARGET_CPU_68K && !TARGET_RT_MAC_CFM
	#pragma parameter CallADSPConnectionEventProc(__A0, __A1)
	void CallADSPConnectionEventProc(ADSPConnectionEventUPP routine, TPCCB sourceCCB) = 0x4E90;
#else
	#define CallADSPConnectionEventProc(userRoutine, sourceCCB)  CALL_ONE_PARAMETER_UPP((userRoutine), uppADSPConnectionEventProcInfo, (sourceCCB))
#endif
#if TARGET_OS_MAC && TARGET_CPU_68K && !TARGET_RT_MAC_CFM
	#pragma parameter CallADSPCompletionProc(__A1, __A0)
	void CallADSPCompletionProc(ADSPCompletionUPP routine, DSPPBPtr thePBPtr) = 0x4E91;
#else
	#define CallADSPCompletionProc(userRoutine, thePBPtr) 		CALL_ONE_PARAMETER_UPP((userRoutine), uppADSPCompletionProcInfo, (thePBPtr))
#endif
#endif


#if PRAGMA_STRUCT_ALIGN
	#pragma options align=reset
#elif PRAGMA_STRUCT_PACKPUSH
	#pragma pack(pop)
#elif PRAGMA_STRUCT_PACK
	#pragma pack()
#endif

#ifdef PRAGMA_IMPORT_OFF
#pragma import off
#elif PRAGMA_IMPORT
#pragma import reset
#endif

#ifdef __cplusplus
}
#endif

#endif /* __ADSP__ */

