/* 1610, Fri 12 Sep 97 CHART.C: Strip chart in screen window for AU monitor Time functions for PC (using class PentiumClock) Copyright (C) 1992-1999 by Nevil Brownlee, ITSS Technology Development, The University of Auckland */ /* * $Log: chart.cpp,v $ * Revision 1.1.1.2 1999/10/03 21:06:22 nevil * *** empty log message *** * * Revision 1.1.1.1.2.2 1999/05/26 02:41:37 nevil * Integrate V6 and ASN code into PC versions of the meter. * This required a rework of the makefiles, using @cflags.opt files * to provide a much longer command line to the Borland C compiler. * * Revision 1.1.1.1.2.1 1999/01/08 01:31:52 nevil * Implementation of TCP attributes, part 3 * * Revision 1.1.1.1 1998/11/16 03:57:28 nevil * Import of NeTraMet 4.3b3 * * Revision 1.1.1.1 1998/11/16 03:22:01 nevil * Import of release 4.3b3 * * Revision 1.1.1.1 1998/10/28 20:31:26 nevil * Import of NeTraMet 4.3b1 * * Revision 1.1.3.2.2.1 1998/10/19 22:32:43 nevil * Meter improvements, mostly arising from developments for the * OCxMON meter. These are documented in notes_oc.txt * * Revision 1.1.3.2 1998/10/14 04:53:21 nevil * Merge Nicolai's patches into 4.2.1 distribution * * Revision 1.1.1.1 1998/10/13 01:35:03 nevil * Import of NeTraMet 4.2.1 * * Revision 1.1.1.1 1998/08/24 12:09:29 nguba * NetraMet 4.2 Original Distribution */ #define UPTIME_DBG 1 #ifndef __DPMI32__ #include #endif #include #include #include #include #include /* biostime() */ #include /* gettextinfo() */ #include #include "ausnmp.h" #include "asn1.h" #include "snmp.h" #include "snmpimpl.h" #include "..\types\types.h" /* Bit8, Bit16, Bit32 .. */ #include "..\intel\timestmp.h" /* class PentiumClock */ #include "pktsnap.h" #include "flowhash.h" #include "met_vars.h" #ifndef CLK_86 /* CLK_86 timer handles offset itself */ PentiumClock uptime_offset; #endif #if UPTIME_DBG extern int bad_uptimes; /* Declared in met_vars.c */ static unsigned long last_s = 0L; static PentiumClock last_clock; static Bit32 last_rb = 0; #define SZUTLOG 20 struct utlog_ent { Bit32 pkt_interval; /* Nbr of packets since last bad time */ Bit64 time, last_time; }; static struct utlog_ent utlog[SZUTLOG]; static int utlogx = 0; static Bit32 ut_count = 0; extern "C" void print_uptime_log(void) { int j,k,n; char msg[80]; struct utlog_ent *ep; if (bad_uptimes > SZUTLOG) { n = SZUTLOG; k = utlogx; } else { n = bad_uptimes; k = utlogx+(SZUTLOG-bad_uptimes); if (k >= SZUTLOG) k -= SZUTLOG; } for (j = 0; j != n; ++j) { ep = &utlog[k]; sprintf(msg, "%8lu %08lx %c %08lx", ep->pkt_interval, ep->time.low, ep->time < ep->last_time ? '<' : '>', ep->last_time.low); printf(msg); w_roll(0,7, scr_chrtcol-1,scr_lrow, 1); if (++k == SZUTLOG) k = 0; } printf("%d bad uptimes", bad_uptimes); } #endif extern "C" void start_uptime_clock(void) { #ifndef CLK_86 uptime_offset.set(); #endif } extern "C" Bit32 uptime_cs(void) { PentiumClock now; now.set(); #ifndef CLK_86 now -= uptime_offset; #endif return now.get_seconds()*100.0; } extern "C" Bit32 uptime_s(void) { static long ts; ts = uptime_cs()/100; return ts; } #if OCX_NTM || OC3_NTM extern "C" double uptime(void) /* Since startup, in 'native' ticks */ { PentiumClock now; now.set(); #ifndef CLK_86 now -= uptime_offset; #endif return now.get_seconds()*100.0; } extern "C" double centiseconds(double s) { return s*100.0; } extern "C" double microseconds(double s) { return s*1000000.0; } #else /* PC 32- or 16-bit (Unix meters do this in meter*.c) */ extern "C" counter64 uptime(void) /* Since startup, in 'native' ticks */ { PentiumClock now; counter64 r; now.set(); #ifndef CLK_86 now -= uptime_offset; #endif r.high = now.high; r.low = now.low; return r; } extern "C" double centiseconds(counter64 nt) { PentiumClock now; #if UPTIME_DBG struct utlog_ent *ep; Bit32 rb; now.high = nt.high; now.low = nt.low; rb = now.get_seconds()*100.0; if (rb < last_rb) { ep = &utlog[utlogx]; ep->pkt_interval = ut_count; ep->time = now; ep->last_time = last_clock; if (++utlogx == SZUTLOG) utlogx = 0; ++bad_uptimes; ut_count = 0; } else ++ut_count; last_rb = rb; last_clock = now; return rb; #else now.high = nt.high; now.low = nt.low; return now.get_seconds()*100.0; #endif } extern "C" double microseconds(counter64 nt) { PentiumClock now; now.high = nt.high; now.low = nt.low; return now.get_seconds()*1000000.0; } #endif #define MTICKS 1092L /* 18.20000 per second */ #define HTICKS 65543L /* 18.20639 */ #define DTICKS 1573040L /* 18.20648 */ extern "C" void set_tod(void) { Bit32 tt; tt = biostime(0,0L); tod_h = tt/HTICKS; tt -= (long)tod_h*HTICKS; tod_m = tt/MTICKS; tt -= (long)tod_m*MTICKS; tod_s = (tt*10+91L)/182L; if (tod_s == 60) { ++tod_m; tod_s = 0; } if (tod_m == 60) { ++tod_h; tod_m = 0; } } extern "C" void scinit(void) /* Initialise screen routines */ { struct text_info r; gettextinfo(&r); scr_lrow = r.screenheight - 1; /* Display screen size */ scr_lcol = r.screenwidth - 1; scr_mtrow = 7; /* Top line of status message area */ scr_chrtcol = scr_lcol - 38; /* Leftmost col of chart */ } extern "C" void scpos(int x, int y) /* Set Cursor Position */ { #ifdef __DPMI32__ union REGS regs; regs.h.ah = 2; regs.h.bh = 0; regs.h.dh = y; regs.h.dl = x; regs.w.flags = 0; int386(0x10, ®s, ®s); #else _AH = 2; _BH = 0; _DH = y; _DL = x; geninterrupt(0x10); #endif } static void sputc(int c) /* Write char to screen, don't move cursor */ { // Only used in chart() #ifdef __DPMI32__ union REGS regs; regs.w.flags = 0; regs.h.bh = 0; regs.w.cx = 1; regs.h.ah = 10; regs.h.al = c; int386(0x10, ®s, ®s); #else _BH = 0; _CX = 1; _AH = 10; _AL = c; geninterrupt(0x10); #endif } void swrite(int c) /* Write char to screen */ { #ifdef __DPMI32__ union REGS regs; regs.w.flags = 0; regs.h.ah = 14; regs.h.al = c; int386(0x10, ®s, ®s); #else _AH = 14; _AL = c; geninterrupt(0x10); #endif } #define UP 0x06 /* BIOS scroll parameters */ #define DOWN 0x07 #define CHATR 0x07 /* Screen attribute for chart */ extern "C" void bios_scroll(int way, int tx,int ty, int bx,int by, int nrows, int attr) { #ifdef __DPMI32__ union REGS regs; regs.w.flags = 0; regs.h.ah = (way == UP) ? UP : DOWN; /* Scroll direction */ regs.h.al = nrows; /* Rows to scroll */ regs.h.bh = attr; /* Screen attribute for blank fill */ regs.h.ch = ty; regs.h.cl = tx; /* Top left */ regs.h.dh = by; regs.h.dl = bx; /* Bottom right */ int386(0x10, ®s, ®s); #else _AH = (way == UP) ? UP : DOWN; /* Scroll direction */ _AL = nrows; /* Rows to scroll */ _BH = attr; /* Screen attribute for blank fill */ _CH = ty; _CL = tx; /* Top left */ _DH = by; _DL = bx; /* Bottom right */ geninterrupt(0x10); #endif } extern "C" void sclear(void) { bios_scroll(UP, 0,0, scr_lcol,scr_lrow, 0, CHATR); /* Blank screen */ } extern "C" void w_clear(int tx,int ty, int bx,int by) { bios_scroll(UP, tx,ty, bx,by, 0, CHATR); /* Blank window */ } extern "C" void w_roll(int tx,int ty, int bx,int by, int n) { bios_scroll(UP, tx,ty, bx,by, n, CHATR); /* Roll window up n lines */ scpos(tx,by); /* Leave cursor at start of bottom window line */ } #define DOT 0xFA /* Small dot in centre of char rectangle */ extern "C" void chart(int tx,int ty, int bx,int by, int x1,int x2,int x3) { int w,k; #define TIMEWIDTH 8 char buf[TIMEWIDTH+102], *bar; bios_scroll(UP, tx,ty, bx,by, 1, CHATR); w = bx+1-tx - TIMEWIDTH; /* Plot chars from bar[0] to bar[w-1], 0-org */ bar = &buf[TIMEWIDTH]; if (tod_s%30 == 0) { sprintf(buf, "%02d%02d:%02d +", tod_h,tod_m,tod_s); memset(bar+1,DOT,w-1); } else { memset(buf, ' ',TIMEWIDTH+w); bar[0] = '|'; } for (k = 10; k < w; k += 10) bar[k] = ':'; if (x1 >= w) x1 = w; if (x2 >= w) x2 = w; if (x3 >= w) x3 = w; for (k = x1+1; k < x3; ++k) bar[k] = '-'; for (k = 10; k < w; k += 10) if (bar[k] == '-') bar[k] = '+'; bar[x1] = '<'; bar[x3] = '>'; bar[x2] = '*'; k = bar[w-1]; bar[w-1] = '\0'; scpos(tx,by); for (bar = buf; *bar; bar++) swrite(*bar); sputc(k); /* Leave cursor at (bx,by) */ }