/*
 * evtrace.h
 *
 * x-kernel v3.3
 *
 * Copyright (c) 1996,1993,1991,1990  Arizona Board of Regents
 */

#ifndef evtrace_h
#define evtrace_h

#ifndef DONT_INCLUDE
#include "xkernel.h"
#endif

#include "datatrace.h"
#include <signal.h>
#define TRACE_CIRCULAR
#define TRACE_STRUCT_I	 	1367
#define TRACE_STRUCT_MINMAX	1489

#define TRACE_NOTIME_FLAG	0x80

#define TRACE_NOTIME(x)		((x) | TRACE_NOTIME_FLAG)
#define TRACE_GET_EVENT(x)	((x).event & 0x7f)
#define TRACE_WITH_TIME(x)	(!((x).event & TRACE_NOTIME_FLAG))

/* --- Trace Status */
#define TRACE_OK		0
#define TRACE_ERROR		1
#define TRACE_BUSY		1

/* --- Protcol ID's */
#define TRACE_PROTL_ETHD	1
#define TRACE_PROTL_TRAFFIC	2
#define TRACE_PROTL_TTCP	3
#define TRACE_PROTL_RTCP	4
#define TRACE_PROTL_VTCP	5
#define TRACE_PROTL_NTCP	6
#define TRACE_PROTL_LTP		7
#define TRACE_PROTL_IP		8
#define TRACE_PROTL_TEMP	9

/* --- Router/sim ID's */
#define TRACE_ROUTER_FCFS	60
#define TRACE_ROUTER_RED	61
#define TRACE_ROUTER_TEMP	62

#define TRACE_EVENT_OPENEN	1
#define TRACE_EVENT_OPEN	2
#define TRACE_EVENT_PUSH	3
#define TRACE_EVENT_CLOSE	4
/* #define TRACE_EVENT_PUSH_DROP	4 */
#define TRACE_EVENT_PUSH_BLOCK	5
#define TRACE_EVENT_PUSH_AWAKE	6
/* #define TRACE_EVENT_PUSH_ERROR	7 */
#define TRACE_EVENT_PUSH_SEND	8
#define TRACE_EVENT_DEMUX	9
#define TRACE_EVENT_CTL_PROTL	10
#define TRACE_EVENT_CTL_SESSN	11
#define TRACE_EVENT_IN		12
/* #define TRACE_EVENT_IN_DROP	13 */
/* #define TRACE_EVENT_IN_ERROR	14 */
#define TRACE_EVENT_BACKOFF	15
#define TRACE_EVENT_SEND	16
#define TRACE_EVENT_SEND_OKAY	17
#define TRACE_EVENT_SEND_BUSY	18
#define TRACE_EVENT_SENT_OKAY	27
#define TRACE_EVENT_QUEUE	19
#define TRACE_EVENT_OUT		20
#define TRACE_EVENT_OUTORDER	21
#define TRACE_EVENT_TO		22
#define TRACE_EVENT_CB		23
#define TRACE_EVENT_ERROR	24
#define TRACE_EVENT_ERROR_DROP	7
#define TRACE_EVENT_DATA	25
#define TRACE_EVENT_LEN		26
#define TRACE_EVENT_DROP	28
#define TRACE_EVENT_MAX		29

typedef struct {
    union {
        u_long time; /* VENKAT */
        u_long ldata; /* VENKAT */
        struct {
            u_short sdata1;
            u_short sdata2;
        }     s;
    }       u;
    u_short data;
    u_char  sid;
    u_char  event;
} TraceEntry;

typedef struct {
    int   stype;
    short protocol;
    short type;
    int   traceNumMax;
    dt    *traceObj;
} TraceStruct;

/*#define ARRAY_SIZE 20000*/
/* VENKAT: Made this array size huge for Traces */
#define ARRAY_SIZE 100000
typedef struct {
    int   stype;
    int   packetCnt;
    int   byteCnt;
    long   nextTime; /* VENKAT */
    long   timeInc; /* VENKAT */
    int   sum;
    int   m_factor, d_factor;
    char  id[100];
    int   arrayNum;
    short array[ARRAY_SIZE];
} ITrace;

typedef struct {
    int    stype;
    long   nextTime; /* VENKAT */
    long   timeInc; /* VENKAT */
    int    max;
    int    min;
    char   id[100];
    int    arrayNum;
    u_char maxArray[ARRAY_SIZE];
    u_char minArray[ARRAY_SIZE];
    u_char avgArray[ARRAY_SIZE];
    int    sum, cnt, otime, div;
} MaxMinTrace;

typedef struct {
  int protocol;
  long time; /* VENKAT */
  long runTime; /* VENKAT */
  int nbufs;
} ExTraceDesc;

void traceCloseFunc();

#ifdef TRACE_ON

#define TRACE_MALLOC(ts,size,protl, traceName, instName, fileSize) {   \
  (ts).traceObj = dtCreateTraceObj(traceName, instName,                \
				   sizeof(TraceEntry)*size, fileSize); \
  dtRegisterCloseFunc((ts).traceObj, traceCloseFunc, &(ts));           \
  xAssert((ts).traceObj);                                              \
  (ts).protocol = protl;                                               \
}

#define DO_TRACE_WT(ts,e,d,id)                                        \
  if ((ts).traceObj && (ts).traceObj->fileHdr.bufferSize) {           \
    ((TraceEntry *)(ts).traceObj->current)->event = (e);              \
    ((TraceEntry *)(ts).traceObj->current)->u.time  = traceGetTime(); \
    ((TraceEntry *)(ts).traceObj->current)->data  = (d);              \
    ((TraceEntry *)(ts).traceObj->current)->sid = (id);               \
    dtWrapBuffer((ts).traceObj, sizeof(TraceEntry));                  \
  }

#define DO_TRACE_L(ts,e,d,l,id)                                      \
  if ((ts).traceObj && (ts).traceObj->fileHdr.bufferSize) {          \
    ((TraceEntry *)(ts).traceObj->current)->event = TRACE_NOTIME(e); \
    ((TraceEntry *)(ts).traceObj->current)->u.ldata  = (l);          \
    ((TraceEntry *)(ts).traceObj->current)->data  = (d);             \
    ((TraceEntry *)(ts).traceObj->current)->sid = (id);              \
    dtWrapBuffer((ts).traceObj, sizeof(TraceEntry));                 \
  }

#define DO_TRACE_S(ts,e,d,s1,s2,id)                                  \
  if ((ts).traceObj && (ts).traceObj->fileHdr.bufferSize) {          \
    ((TraceEntry *)(ts).traceObj->current)->event = TRACE_NOTIME(e); \
    ((TraceEntry *)(ts).traceObj->current)->u.s.sdata1  = (s1);      \
    ((TraceEntry *)(ts).traceObj->current)->u.s.sdata2  = (s2);      \
    ((TraceEntry *)(ts).traceObj->current)->data  = (d);             \
    ((TraceEntry *)(ts).traceObj->current)->sid = (id);              \
    dtWrapBuffer((ts).traceObj, sizeof(TraceEntry));                 \
  }

#else /* ! TRACE_ON*/

#define TRACE_MALLOC(ts,size,protl, traceName, instName, fileSize) \
  {(ts).traceObj = NULL;}
#define DO_TRACE_WT(ps,e,d,id)
#define DO_TRACE_L(ps,e,d,l,id)
#define DO_TRACE_S(ps,e,d,s1,s2,id)

#endif /* TRACE_ON */

#ifndef DONT_INCLUDE
int           traceRegisterAddBuf(dt *, char *, int);
void          traceSaveAll(void);
long 	      traceGetTime(void); /* VENKAT */
void          traceInit(void);
#endif

#endif  /* EVTRACE_H */
