Plan 9 from Bell Labs’s /usr/web/sources/contrib/rsc/snmp/tcm.c

Copyright © 2021 Plan 9 Foundation.
Distributed under the MIT License.
Download the Plan 9 distribution.


/*
 * Russ Cox, 17 August 1997
 * rsc@research.att.com
 *
 * this program lets you watch the front panel of the
 * modem racks remotely.   just look, no touching.
 *
 * window '0 160 160 300' tcm bait-nmc1
 * window '0 300 160 440' tcm bait-nmc2
 * window '0 440 100 580' tcm -n 6 usrnmc-lh
 *
 * remember:
 * We don't understand the software, and sometimes we don't understand
 * the hardware, but we can *see* the blinking lights!
 */

#include <u.h>
#include <libc.h>
#include <libg.h>
#include "a1.h"

extern void chat(char *, ...);

enum {
	Nlights = 7,
	Ncards = 13,
};

int nmodem = Ncards-1;
int lights[Ncards][Nlights];
Rectangle rlight[Ncards][Nlights];

Bitmap *clr[3];
Bitmap *black, *white;

int nfd;
int chatty;
int timeint = 15;

char *usage = "%s host [-c n b a] [-t secs] [-n nmodem]\n";
char *host;

void getlights(void);
void drawlights(void);

void
main(int argc, char **argv)
{
	int i, pid;
	Rectangle r;
	int c[3] = {204, 0x10, 0xfc};	/* fb/colors */

	ARGBEGIN{
	case 'n':
		nmodem = atoi(ARGF());
		if(nmodem > Ncards-1)
			nmodem = Ncards-1;
		break;
	case 'c':
		for(i=0; i<3; i++)
			c[0] = atoi(ARGF());
		break;
	case 't':
		timeint = atoi(ARGF());
		break;
	default:
		fprint(2, usage, argv0);
		exits("usage");
	}ARGEND;

	if(argc != 1) {
		fprint(2, usage, argv0);
		exits("usage");
	}

	if((nfd = dial(netmkaddr(argv[0], "udp", "161"), 0, 0, 0)) < 0) {
		fprint(2, "cannot dial: %r\n");
		exits("dial");
	}

	host = argv[0];

	getlights();
	binit(0,0,0);
	einit(Emouse);

	r.min = (Point){0,0};
	r.max = (Point){1,1};
	for(i=0; i<3; i++) {
		clr[i] = balloc(r, 3);
		point(clr[i], r.min, c[i], S);
	}

	black = balloc(r, 3);
	white = balloc(r, 3);
	point(black, r.min, 0xff, S);
	point(white, r.min, 0, S);

	ereshaped(screen.r);

	pid = rfork(RFMEM|RFPROC);
	if(pid == 0) {
		for(;;) {
			sleep(timeint*1000);
			getlights();
				drawlights();
		}
		exits(0);
	} else if(pid < 0) {
		fprint(2, "cannot rfork: %r\n");
		exits("rfork");
	} else for(;;){
		emouse();
	}

}

void
drawlights(void) 
{
	int i, j;
	for(i=0; i<Ncards; i++)
	for(j=0; j<Nlights; j++) {
		if(lights[i][j] >= 0 && lights[i][j] <= 3) {
			texture(&screen, rlight[i][j], clr[lights[i][j]], S);
		}
	}
	bflush();
}

void
ereshaped(Rectangle r)
{
	int i, j, y, ht, wid;
	Point pw, textpt, p;
	Rectangle box;
	char msg[10];

	/* clear screen */
	screen.r = r;
	bitblt(&screen, screen.r.min, &screen, r, Zero);

	/* add host label in upper corner */
	p = (Point){5,5};
	p = add(p, screen.r.min);
	string(&screen, p, font, host, S);

	/* width of card slots */
	wid = (Dx(r) - 10 - (nmodem))/(nmodem+1);
	pw = (Point){wid+1, 0};

	/* height of card slots */
	p = strsize(font, "0");
	y = p.y;
	ht = (Dy(r) - 10 - 2*y)/(Nlights);

	/* box is the first card */
	/* cards are wid pixels wide black + 1 pixel white */
	box.min = add(screen.r.min, (Point){5, 5+2*y});
	box.max = add(screen.r.min, (Point){5+wid, 5+2*y+ht*Nlights});

	/* label first card */
	strcpy(msg, "1");
	textpt = add(box.min, (Point){(wid/2-p.x/2), -y});
	string(&screen, textpt, font, msg, S);

	/* draw card */
	texture(&screen, box, black, S);

	/* set up card 1, light 1 */
	rlight[0][0].min = add((Point){wid/4, ht/8}, box.min);
	rlight[0][0].max = add((Point){wid/2, ht*3/4}, rlight[0][0].min);

	/* all the other lights on the card are just offsets */
	for(i=1; i<Nlights; i++) {
		rlight[0][i].min = add((Point){0, ht}, rlight[0][i-1].min);
		rlight[0][i].max = add((Point){0, ht}, rlight[0][i-1].max);
	}

	/* all the other cards and lights are offsets from previous */
	for(i=1; i<nmodem+1; i++) {
		/* label... */
		textpt = add(pw, textpt);
		msg[0] = '0'+(i+1)%10;
		string(&screen, textpt, font, msg, S);

		/* card... */
		box.min = add(pw, box.min);
		box.max = add(pw, box.max);
		texture(&screen, box, black, S);

		/* lights... */
		for(j=0; j<Nlights; j++) {
			rlight[i][j].max = add(pw, rlight[i-1][j].max);
			rlight[i][j].min = add(pw, rlight[i-1][j].min);
		}
	}
 
	drawlights();
}


void
getlights(void)
{
	Snmp ss, *s;
	SnmpPdu *pdu;
	int i, j, bits, nybble;

	chat("getlights()...");

	s = &ss;
	memset(s, 0, sizeof *s);
//	Schkpdu(s, 3);

	s->vers = 0;
	s->private = 0;
	s->type = Pget;
	s->estat = s->eindex = 0;
	s->npdu = 3;

	for(i=0, pdu=s->pdu; i<3; i++, pdu++) {
		/* you are not expected to understand this */
		sprint(pdu->objid, "1.3.6.1.4.1.429.1.1.3.%d.0", i+5);
		pdu->type = Anull;
	}

	memset(lights, 0, sizeof lights);
	if(dosnmp(nfd, s, s) < 0)
		return;

	if(s->estat) {
		chat("error in snmp pkt");
		return;
	}

	pdu = &s->pdu[1];
	if(pdu->len < (Ncards)*6) {
		chat("pdu too short");
		return;
	}

	for(i=0; i<Ncards; i++) {
		chat("card %d...", i);
		for(j=0,nybble=i*12; j<Nlights; j++,nybble++){
			bits = (uchar)pdu->s[nybble/2];
			if((nybble%2)==0)
				bits >>= 4;
			else
				bits &= 0x0f;
			switch(bits){
			case 1: /* busy */
				lights[i][j] = 2;
				break;
			case 3: /* answering */
				lights[i][j] = 1;
				break;
			case 0: /* nothing */
				lights[i][j] = 0;
				break;
			default:
				lights[i][j] = 0;
				break;
			}
			chat("%c", lights[i][j]);
		}
		chat("...");
	}
}

Bell Labs OSI certified Powered by Plan 9

(Return to Plan 9 Home Page)

Copyright © 2021 Plan 9 Foundation. All Rights Reserved.
Comments to webmaster@9p.io.