/*     
 * $RCSfile: sunrpctest.c,v $
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1993,1991,1990,1996  Arizona Board of Regents
 *
 * $Revision: 1.2 $
 * $Date: 1996/01/29 22:36:24 $
 */

/*
 * Ping-pong test of SUNRPC
 */

#include "xkernel.h"
#include <rpc/rpc.h>
#include "sunrpc.h"

/*
 * These definitions describe the lower protocol
 */
#define HOST_TYPE IPhost
#define INIT_FUNC sunrpctest_init
#define TRACE_VAR tracesunrpctestp
#define PROT_STRING "sunrpc"

/* 
 * If a host is booted without client/server parameters and matches
 * one of these addresses, it will come up in the appropriate role.
 */
static HOST_TYPE ServerAddr = { 0, 0, 0, 0 };
static HOST_TYPE ClientAddr = { 0, 0, 0, 0 };

static	long	prog = 100, proc = 5, vers = 2;
static	long	clientPort = 2000, serverPort = 1002;

#define TRIPS 100
#define TIMES 1
#define DELAY 3
/*
 * Define to do timing calculations
 */
#define TIME
#define SAVE_SERVER_SESSN
#define RPCTEST
#define CUSTOM_ASSIGN

static void
setServer( p )
    Part	*p;
{
    partPush(*p, &ServerAddr, sizeof(IPhost));	/* IP host 		*/
    partPush(*p, &serverPort, sizeof(long));
    partPush(*p, &prog, sizeof(long));
    partPush(*p, &vers, sizeof(long));
}

static void
serverSetPart( p )
    Part	*p;
{
    partInit(p, 1);
    setServer(p);
}


static void
clientSetPart( p )
    Part	*p;
{
    partInit(p, 2);
    setServer(p);
#if 1
    partPush(p[1], ANY_HOST, 0);
    partPush(p[1], &clientPort, sizeof(long));
#endif    
}


static int lens[] = { 
  1000, 2000, 4000, 8000, 16000
};


#include "common_test.c"


static XkReturn
sunrpctestCallDemux( self, lls, dg, rMsg )
    Protl self;
    Sessn lls;
    Msg *dg, *rMsg;
{
    msgAssign(rMsg, dg);
    xAssert(msgLength(rMsg) >= sizeof(long));
    msgDiscard(rMsg, sizeof(long));
    return XK_SUCCESS;
}


static int
sunrpcTryCall( sessn, times, length )
  Sessn sessn;
  int times;
  int length;
{
    XkReturn ret_val;
    int i;
    Msg	savedMsg, request, reply;
    char *buf;
    int c = 0;
    
    /* 
     * We need to push the procedure number on the message itself.  
     * :-/
     */
    buf = msgConstructAllocate(&savedMsg, length + sizeof(long));
    *(long *)buf = proc;

    msgConstructEmpty(&reply);
    msgConstructEmpty(&request);
    for (i=0; i<times; i++) {
	msgAssign(&request, &savedMsg);
	ret_val = xCall(sessn, &request, &reply);
	xIfTrace(prottest, TR_MAJOR_EVENTS) {
	    putchar('.');
	    if (! (++c % 50)) {
		putchar('\n');
	    }
	}
	if( ret_val == XK_FAILURE ) {
	    printf( "RPC call error %d\n" , ret_val );
	    goto abort;
	}
	if (msgLength(&reply) != length) {
	    printf("Bizarre reply length.  Expected %d, received %d\n",
		   length, msgLength(&reply));
	    goto abort;
	}
	msgTruncate(&reply, 0);
    }

abort:
    msgDestroy(&savedMsg);
    msgDestroy(&reply);
    msgDestroy(&request);
    return i;
}


static void
testInit()
{
    serverCallDemux = sunrpctestCallDemux;
    tryCall = sunrpcTryCall;
}
