/*
 * megtest.c
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1991,1996  Arizona Board of Regents
 *
 * $Revision: 1.2 $
 * $Date: 1996/02/01 15:36:43 $
 */


#define PROT_STRING "meg"

#include "xkernel.h"
#include "tcp.h"
#include "ip.h"


#define TIMES 1
#define LENGTH 1000*1024
#define BUFFER_SIZE 50 * 1024
#define DROP_INTERVAL 0 
#define DIS_INTERVAL 0 

static  IPhost 	ServerAddr = {0,0,0,0};
static  IPhost  ClientAddr = {0,0,0,0};

static	void 	client( Event, void * );
static 	void 	server( Event, void * );
static  void    endTest( Event, void * );
static  void    saveStats( tcpVars * );
static 	void	subtime( XTime *, XTime *, XTime *);
static  void 	processOptions(tcpVars *);
static  int	isServer(tcpVars *);
static  int	isClient(tcpVars *);
static  void	clientSetPart(tcpVars *, Part *);
static  void	serverSetPart(tcpVars *, Part *);
static	XkReturn closeDone(Sessn);
static	XkReturn saveServerSessn(Protl, Protl, Sessn, Protl);
static  int 	runTest(tcpVars *);
static  XkReturn serverDemux(Protl,Sessn,Msg *);
static  XkReturn clientDemux(Protl,Sessn,Msg *);
int 	megtest_init(Protl);


static void
processOptions(v)
  tcpVars *v;

{
}

int
megtest_init( self )
    Protl self;
{
    Protl	llp;
    tcpVars	*v;

    v = (tcpVars *)xMalloc(sizeof(tcpVars));
    v->serverParam = 0;
    v->clientParam = 0;

    processOptions(v);

    llp = xGetProtlDown(self, 0);
    if (!xIsProtl(llp)) {
	Kabort("Test protocol has no lower protocol");
    }
    v->llpName = llp->name;
    if (xControlProtl(xGetProtlDown(self, 0), GETMYHOST, (char *)&v->myHost,
        sizeof(IPhost)) < 0)
      Kabort("GETMYHOST fails! in megtest\n");

    printf("[%s] %s timing test\n", v->hostStr, PROT_STRING);
    /* 
     * Call the per-test initialization function which gives the test
     * the opportunity to override the default functions
     */
    if (isServer(v)) {
      evDetach( evSchedule(server, (void *)v, 0) );
    } else if (isClient(v)) {
      evDetach( evSchedule(client, (void *)v, v->delay*1000) );
    } else {
      printf("[%s] %stest: I am neither server nor client\n", 
	     v->hostStr, PROT_STRING);
    }
    return 0;
}


static int
isServer(v)
  tcpVars *v;

{
    if ( v->serverParam ) {
	return TRUE;
    }
    return ! bcmp((char *)&v->myHost, (char *)&v->serverAddr, sizeof(IPhost));
}


static int
isClient(v)
  tcpVars *v;
{
    
    if ( v->clientParam ) {
	str2ipHost(&v->serverAddr, v->serverString);
	v->clientAddr = v->myHost;
	return TRUE;
    }
    return ! bcmp((char *)&v->myHost, (char *)&v->clientAddr, sizeof(IPhost));
}



static void
clientSetPart( v, p )
  tcpVars 	*v;
  Part 		*p;
{
  partInit(p, 1);
  partPush(p[0], &v->serverAddr, sizeof(IPhost));
  partPush(p[0], &v->serverPort, sizeof(long));
  printf("[%s] Client sending to: %s\n", v->hostStr,
	 ipHostStr(&v->serverAddr));

}

static void
serverSetPart( v, p )
  tcpVars 	*v;
  Part 		*p;
{
  partInit(p, 1);
  partPush(*p, ANY_HOST, 0);
  partPush(*p, &v->serverPort, sizeof(long));
  printf("[%s] Server responding to: %s\n", v->hostStr, "ANY_HOST");
}


static XkReturn
closeDone( lls )
  Sessn	lls;
{
    xTrace2(prottest, TR_MAJOR_EVENTS, "%s test -- closedone (%x) called",
	    "meg", lls);
    return XK_SUCCESS;
}

static XkReturn
saveServerSessn( self, llp, s, hlpType )
    Protl self, llp, hlpType;
    Sessn s;
{

  if (xControlSessn(s, TCP_SETRCVBUFSIZE, (char*)&v->space, sizeof(v->space)) < 0) {
    xError("saveServerSessn: TCP_SETRCVBUFSIZE failed");
  } /* if */

  if (xControlSessn(s, TCP_SETSNDBUFSIZE, (char*)&v->space, sizeof(v->space)) < 0) {
    xError("saveServerSessn: TCP_SETSNDBUFSIZE failed");
  } /* if */

  if (xControlSessn(s, TCP_SETRCVBUFSPACE, (char*)&v->space, sizeof(v->space)) < 0){
    xError("saveServerSessn: TCP_SETRCVBUFSPACE failed");
  } /* if */

  return XK_SUCCESS;
}


static void
server( ev, foo )
  Event	ev;
  VOID 	*foo;
{
  Part 	p;
  tcpVars 	*v=(tcpVars *)foo;
  
  printf("\n*** I am the server\n");/* Don't change (LSB) */
  printf("[%s] buffer size: %d\n", v->hostStr, v->space);
  v->myProtl->demux = serverDemux;
  v->myProtl->opendone = saveServerSessn;
  v->myProtl->closedone = closeDone;
  serverSetPart(v, &p);

  if (xControlProtl(xGetProtlDown(v->myProtl, 0), TCP_SETRCVBUFSIZE, (char*)&v->space, 
               sizeof(v->space)) < 0) {
    xError("server: TCP_SETRCVBUFSIZE failed");
  } /* if */

  if ( xOpenEnable(v->myProtl, v->myProtl, xGetProtlDown(v->myProtl, 0), &p)
      == XK_FAILURE ) {
    printf("[%s] %stest server can't openenable lower protocol\n",
	   v->hostStr, PROT_STRING);
  } else {
    printf("[%s] %stest server done with xopenenable\n", 
	   v->hostStr, PROT_STRING);
    }
  return;
}

static void
client( ev, foo )
    Event	ev;
    VOID 	*foo;
{
  char  str[100];
  Part	p[2];
  tcpVars *v=(tcpVars *)foo;
  
  printf("\n*** I am the client\n");
  printf("[%s] *** buffer size: %d\n", v->hostStr, v->space);
  
  v->myProtl->demux = clientDemux;
  
  clientSetPart(v, p);
  xGetTime(&v->starttime0);
  if ( v->clientDownSes == 0 ) {
/*    if (xControlProtl(v->myProtl, TCP_SETRCVBUFSIZE, (char*)&v->space,
                 sizeof(v->space)) < 0) {
      sprintf(str, "[%s] client: TCP_SETRCVBUFSIZE for prot failed",v->hostStr);
      xError(str);
    } 
*/
    v->clientDownSes = xOpen(v->myProtl, v->myProtl, 
			     xGetProtlDown(v->myProtl, 0), p);
    if ( v->clientDownSes == ERR_SESSN ) {
      printf("[%s] %stest: open failed!\n", v->hostStr, PROT_STRING);
      Kabort("End of test");
      return;
    }
  }
  
  if (xControlSessn(v->clientDownSes, TCP_SETTHRESH, (char*)&v->thresh,
               sizeof(v->thresh)) < 0) {
    sprintf(str, "[%s] client: TCP_SETTHRESH failed", v->hostStr);
    xError(str);
  } /* if */

  if (xControlSessn(v->clientDownSes, TCP_SETRCVBUFSIZE, (char*)&v->space, 
	       sizeof(v->space)) < 0) {
    sprintf(str, "[%s] client: TCP_SETRCVBUFSIZE failed", v->hostStr);
    xError(str);
  } /* if */

  if (xControlSessn(v->clientDownSes, TCP_SETSNDBUFSIZE, (char*)&v->space, 
	       sizeof(v->space)) < 0) {
    sprintf(str, "[%s] client: TCP_SETSNDBUFSIZE failed", v->hostStr);
    xError(str);
    } /* if */
  
  if (xControlSessn(v->clientDownSes, TCP_SETRCVBUFSPACE, (char*)&v->space, 
		 sizeof(v->space)) < 0){
    sprintf(str, "[%s] client: TCP_SETRCVBUFSIZE failed", v->hostStr);
    xError(str);
  } /* if */

  runTest(v);
  if (!v->doneFlag)
    saveStats(v);

}

static int
runTest( v )
    tcpVars *v;
{
}

static XkReturn
serverDemux( self, lls, dg )
    Protl self;
    Sessn lls;
    Msg *dg;
{

  return XK_SUCCESS;
}

static XkReturn
clientDemux( self, lls, dg )
    Protl self;
    Sessn lls;
    Msg *dg;
{

  return XK_SUCCESS;
}
