/*
 * RPC debug module
 *
 *	Bakul Shah
 *
 * bvs 841102 -- original version
 * jht 850124 -- augment information about EFS/DFS.
 * jht 850403 -- cleanup interface to connection-layer.
 * jht 850410 -- ifdef the EFS and DFS-specific code.
 * smj 850813 -- remove refs (enable) to NEWRPC.
 */

#include "../h/param.h"
#include "../h/socket.h"
#include "../net/if.h"
#include "../h/dir.h"
#include "../h/user.h"
#include "../h/kernel.h"
#include "../h/proc.h"
#include "../h/mbuf.h"
#include "../vnet/vnet.h"
#include "../conn/conn.h"
#include "../rpc/rpc.h"


#ifdef	DEBUG

#ifdef	VALID_DFS
#include "../dfs/dfs.h"			/* DFS_DEBUG: xtra dfs info */
#endif	VALID_DFS

char * rpc_typename[] = {
	"Undefined",
	"Call",
	"Return",
	"Return ack",
	"Error",
	"Call ack",
};

#if	VALID_EFS || VALID_DFS
char * rpc_classname[] = {
	"und",		/* 0: RPC_CLASS_		*/
	"Efs",		/* 1: RPC_CLASS_EFS		*/
	"Dfs",		/* 2: RPC_CLASS_DFS		*/
	"und",		/* 3: RPC_CLASS_		*/
	"TimSvr",	/* 4: RPC_CLASS_TIME (server)	*/
	"TimCli",	/* 5: RPC_CLASS_TIME (client)	*/
	"Signal",	/* 6: RPC_CLASS_SIGNAL		*/
};

int	rpc_sizeofClassName  = sizeof(rpc_classname)/ sizeof(rpc_classname[0]);

#ifdef	VALID_DFS
/*
 * DFS tables
 */
extern	rpc_entry_t		dfs_optable[];
extern	rpc_serverClass_t	dfsServerClass;
extern	int			sizeof_dfs_optable;
#endif	VALID_DFS

#ifdef	VALID_EFS
/*
 * EFS tables
 */
extern	rpc_entry_t		efs_optable[];
extern	rpc_serverClass_t	efsServerClass;
extern	int			sizeof_efs_optable;
#endif	VALID_EFS

#if	0 && CLIENT
/*
 * CLIENT time-service tables
 */
int	timeClient_get(),
	timeClient_set(),
	timeClient_exception();

	rpc_entry_t	timeClient_optable[] = { /* RPC_CLASS_TIME == 4 */
   {"get",  (int) 0,	timeClient_get	}	/* 0 */
   {"set",  (int) 0,	timeClient_set	}	/* 1 */
};
#define TC_NOPS (sizeof(timeClient_optable) / sizeof(*timeClient_optable))
int	sizeof_timeClient_optable = TC_NOPS;

extern	rpc_clientClass_t	timeClientClass;
extern	rpc_serverClass_t	timeServerClass;
extern	int			sizeof_timeClient_optable;
#endif	0 && CLIENT

#if	0 && SERVER
/*
 * SERVER time-service tables
 */
int	timeServer_get(),
	timeServer_set(),
	timeServer_exception();

	rpc_entry_t	timeServer_optable[] = { /* RPC_CLASS_TIME == 4 */
   {"get",  (int) 0,	timeServer_get	}	/* 0 */
   {"set",  (int) 0,	timeServer_set	}	/* 1 */
};
#define TC_NOPS (sizeof(timeServer_optable) / sizeof(*timeServer_optable))
int	sizeof_timeServer_optable = TC_NOPS;

extern	rpc_clientClass_t	timeServerClass;
extern	rpc_serverClass_t	timeServerClass;
extern	int			sizeof_timeServer_optable;
#endif	0 && SERVER

#if	0 && SIGNAL
/*
 * RPC-Signal tables
 */
extern	rpc_entry_t		signal_optable[];
extern	rpc_clientClass_t	signalClientClass;
extern	rpc_serverClass_t	signalServerClass;
extern	int			sizeof_signal_optable;
#endif	0 && SIGNAL

#endif	VALID_EFS || VALID_DFS

u_long rpc_debugclass = 0xffffffff;
u_long rpc_debug = 0;

rpc_printdebug(rpc, incoming)
	register rpc_header_t * rpc;
{
	extern connection_t * conn_findConnection();
	register int error;
	register connection_t * conn;
	register int s = spl6();

	if (rpc->type == RPCPKT_RETURN && *(int *)&rpc[1]) {
#if	VALID_DFS && DFS_PACKETHDR
		error = *(int *)&rpc[1];
#else	VALID_DFS && DFS_PACKETHDR
#ifdef VALID_DFS
		if (rpc->class == RPC_CLASS_DFS) {
			register i = (int)&rpc[1];	/* Fix compiler-loop */

			i += sizeof(dfsPktHdr_t);
			error = *(int *) i;
		} else
#endif VALID_DFS
			error = *(int *)&rpc[1];
#endif	VALID_DFS && DFS_PACKETHDR
	} else
		error = 0;
	conn = conn_findConnection(&rpc->source); /* conn->count is unchanged */
#if	defined(VALID_DFS) && defined(DFS_DEBUG)
	if (error)
	   printf("0x%6x: %-10s (%-6s,%2d/%-7s,0x%04x) 0x%04x 0x%06x %s%s\n",
		rpc, rpc_typename[rpc->type > 5 ? 0 : rpc->type],
		rpc_classname[rpc->class>=rpc_sizeofClassName ? 0 : rpc->class],
		rpc->operation,
		((rpc->class == RPC_CLASS_DFS)
		   ? (char *) ((rpc->operation >= sizeof_dfs_optable)
			? "Unkwn"
			: dfsServerClass.optable[rpc->operation].name
			      )
#ifdef	VALID_EFS
		   : ((rpc->class == RPC_CLASS_EFS)
			? (char *) ((rpc->operation >= sizeof_efs_optable)
			     ? "Unkwn"
			     : efsServerClass.optable[rpc->operation].name
				   )
			: "..."
		     )
#else	VALID_EFS
		   : "..."
#endif	VALID_EFS
		),
		rpc->seqno,
		error&0xffff,
		rpc->client,
		incoming ? "<" : ">",
		conn ? conn->name : "unknown node");
	else
	   printf("0x%6x: %-10s (%-6s,%2d/%-7s,0x%04x) %-6s 0x%06x %s%s\n",
		rpc, rpc_typename[rpc->type > 5 ? 0 : rpc->type],
		rpc_classname[rpc->class>=rpc_sizeofClassName ? 0 : rpc->class],
		rpc->operation,
		((rpc->class == RPC_CLASS_DFS)
		   ? (char *) ((rpc->operation >= sizeof_dfs_optable)
			? "Unkwn"
			: dfsServerClass.optable[rpc->operation].name
			      )
#ifdef	VALID_EFS
		   : ((rpc->class == RPC_CLASS_EFS)
			? (char *) ((rpc->operation >= sizeof_efs_optable)
			     ? "Unkwn"
			     : efsServerClass.optable[rpc->operation].name
				   )
			: "..."
		     )
#else	VALID_EFS
		   : "..."
#endif	VALID_EFS
		),
		rpc->seqno,
		"",			/* error == 0 */
		rpc->client,
		incoming ? "<" : ">",
		conn ? conn->name : "unknown node");
#else	defined(VALID_DFS) && defined(DFS_DEBUG)
	printf("0x%6x: %-10s (%2d, %2d, 0x%04x) 0x%04x 0x%06x %s%s\n",
		rpc, rpc_typename[rpc->type > 5 ? 0 : rpc->type],
		rpc->class, rpc->operation, rpc->seqno,
		error&0xffff,
		rpc->client,
		incoming ? "<" : ">",
		conn ? conn->name : "unknown node");
#endif	defined(VALID_DFS) && defined(DFS_DEBUG)
	splx(s);
}
#endif	DEBUG
