plan 9 kernel history: overview | file list | diff list

1991/01151/port/devnonet.c (diff list | history)

1990/1210/sys/src/9/port/devnonet.c:236,2421990/1214/sys/src/9/port/devnonet.c:236,241 (short | long)
1990/1210    
nonetopen(Chan *c, int omode) 
{ 
	Stream *s; 
	Noconv *cp; 
	Noifc *ifc; 
	int line; 
 
1990/1210/sys/src/9/port/devnonet.c:252,2581990/1214/sys/src/9/port/devnonet.c:251,257
1990/1210    
		 *  get an unused device and open it's control file 
		 */ 
		ifc = &noifc[c->dev]; 
		cp = nonetopenclone(c, ifc); 
1990/1214    
		nonetopenclone(c, ifc); 
1990/1210    
		break; 
	case Nlistenqid: 
		/* 
1990/1210/sys/src/9/port/devnonet.c:866,8741990/1214/sys/src/9/port/devnonet.c:865,871
1990/1210    
queueack(Noconv *cp, int mid) 
{ 
	int next; 
	ulong now; 
 
	now = NOW; 
	next = (cp->anext + 1)&Nmask; 
	if(next != cp->afirst){ 
		cp->ack[cp->anext] = mid; 
1990/1210/sys/src/9/port/devnonet.c:959,9641990/1214/sys/src/9/port/devnonet.c:956,962
1990/1210    
		msgrem = mp->len; 
		pktrem = msgrem > ifc->maxtu ? ifc->maxtu : msgrem; 
		bp = mp->first; 
1990/1214    
		SET(rptr); 
1990/1210    
		if(bp) 
			rptr = bp->rptr; 
		last = pkt = mkhdr(cp, msgrem); 
1990/1210/sys/src/9/port/devnonet.c:1189,11951990/1214/sys/src/9/port/devnonet.c:1187,1192
1990/1210    
int 
nonetcksum(Block *bp, int offset) 
{ 
	Block *nbp = bp; 
	uchar *ep, *p; 
	int n; 
	ulong s; 
1990/1214/sys/src/9/port/devnonet.c:6,211990/1229/sys/src/9/port/devnonet.c:6,22 (short | long)
1990/1210    
#include	"io.h" 
#include	"errno.h" 
 
#define DPRINT if(0) 
1990/1229    
#define DPRINT if(pnonet)print 
1990/1210    
#define NOW (MACHP(0)->ticks*MS2HZ) 
 
static Noifc *noifc; 
1990/1229    
int pnonet; 
1990/1210    
 
enum { 
	/* 
	 *  tuning parameters 
	 */ 
	MSrexmit = 500,	/* retranmission interval in ms */ 
1990/1229    
	MSrexmit = 500,		/* retranmission interval in ms */ 
1990/1210    
	MSack = 50,		/* ms to sit on an ack */ 
 
	/* 
1990/1214/sys/src/9/port/devnonet.c:102,1081990/1229/sys/src/9/port/devnonet.c:103,109
1990/1210    
	 *  allocate the interfaces 
	 */ 
	noifc = (Noifc *)ialloc(sizeof(Noifc) * conf.nnoifc, 0); 
	for(i = 0; i < conf.nnoconv; i++) 
1990/1229    
	for(i = 0; i < conf.nnoifc; i++) 
1990/1210    
		noifc[i].conv = (Noconv *)ialloc(sizeof(Noconv) * conf.nnoconv, 0); 
 
	/* 
1990/1214/sys/src/9/port/devnonet.c:1040,10451990/1229/sys/src/9/port/devnonet.c:1041,1047
1990/1210    
	 *  if a new call request comes in on a connected channel, hang up the call 
	 */ 
	if(h->mid==0 && (f & NO_NEWCALL) && cp->state==Cconnected){ 
1990/1229    
		DPRINT("new call on connected channel\n");  
1990/1210    
		freeb(bp); 
		hangup(cp); 
		return; 
1990/1214/sys/src/9/port/devnonet.c:1227,12301990/1229/sys/src/9/port/devnonet.c:1229,1237
1990/1210    
	hp->sum[1] = s>>8; 
	hp->sum[0] = s; 
	return s & 0xffff; 
1990/1229    
} 
 
nonettoggle() 
{ 
	pnonet ^= 1; 
1990/1210    
} 
1990/1229/sys/src/9/port/devnonet.c:37,421990/1231/sys/src/9/port/devnonet.c:37,43 (short | long)
1990/1210    
static void	sendmsg(Noconv*, Nomsg*); 
static void	startconv(Noconv*, int, char*, int); 
static void	queueack(Noconv*, int); 
1990/1231    
static void	sendack(Noconv*, int); 
1990/1210    
 
static void	nonetiput(Queue*, Block*); 
static void	nonetoput(Queue*, Block*); 
1990/1229/sys/src/9/port/devnonet.c:704,7101990/1231/sys/src/9/port/devnonet.c:705,713
1990/1210    
		cp->hdr->flag |= NO_SERVICE; 
		sprint(buf, "%s %s", service, u->p->pgrp->user); 
		c->qid.path = STREAMQID(STREAMID(c->qid.path), Sdataqid); 
1990/1231    
		print("sending request\n"); 
1990/1210    
		streamwrite(c, buf, strlen(buf), 1); 
1990/1231    
		print("request sent\n"); 
1990/1210    
		c->qid.path = STREAMQID(STREAMID(c->qid.path), Sctlqid); 
	} 
} 
1990/1229/sys/src/9/port/devnonet.c:781,7861990/1231/sys/src/9/port/devnonet.c:784,790
1990/1210    
		 *  stuff the connect message into it 
		 */ 
		f = ((Nohdr *)(call.msg->rptr))->flag; 
1990/1231    
		print("call from %d %s\n", call.circuit, call.raddr); 
1990/1210    
		startconv(cp, call.circuit, call.raddr, Cconnecting); 
		print("rcving %d byte message\n", call.msg->wptr - call.msg->rptr); 
		nonetrcvmsg(cp, call.msg); 
1990/1229/sys/src/9/port/devnonet.c:1013,10181990/1231/sys/src/9/port/devnonet.c:1017,1035
1990/1210    
} 
 
/* 
1990/1231    
 *  send an acknowledgement 
 */ 
static void 
sendack(Noconv *cp, int ack) 
{ 
	cp->ackmsg.len = 0; 
	cp->ackmsg.first = 0; 
	cp->ackmsg.acked = ack; 
	cp->ackmsg.mid = cp->lastacked; 
	sendmsg(cp, &cp->ctl); 
} 
 
/* 
1990/1210    
 *  receive a message (called by the multiplexor; noetheriput, nofddiiput, ...) 
 */ 
void 
1990/1229/sys/src/9/port/devnonet.c:1058,10641990/1231/sys/src/9/port/devnonet.c:1075,1081
1990/1210    
				hangup(cp); 
		} else { 
			if(r>0) 
				queueack(cp, h->mid); 
1990/1231    
				sendack(cp, h->mid); 
1990/1210    
			cp->bad++; 
		} 
		freeb(bp); 
1990/1231/sys/src/9/port/devnonet.c:37,431991/0102/sys/src/9/port/devnonet.c:37,42 (short | long)
1990/1210    
static void	sendmsg(Noconv*, Nomsg*); 
static void	startconv(Noconv*, int, char*, int); 
static void	queueack(Noconv*, int); 
1990/1231    
static void	sendack(Noconv*, int); 
1990/1210    
 
static void	nonetiput(Queue*, Block*); 
static void	nonetoput(Queue*, Block*); 
1990/1231/sys/src/9/port/devnonet.c:921,9271991/0102/sys/src/9/port/devnonet.c:920,926
1990/1210    
	wq = ifc->wq->next; 
 
	/* 
	 *  one transmitter at a time 
1991/0102    
	 *  one transmitter at a time for this connection 
1990/1210    
	 */ 
	qlock(&cp->xlock); 
 
1990/1231/sys/src/9/port/devnonet.c:1005,10351991/0102/sys/src/9/port/devnonet.c:1004,1023
1990/1210    
static void 
sendctlmsg(Noconv *cp, int flag, int new) 
{ 
	cp->ctl.len = 0; 
	cp->ctl.first = 0; 
	cp->ctl.acked = 0; 
1991/0102    
	Nomsg ctl; 
 
	ctl.len = 0; 
	ctl.first = 0; 
	ctl.acked = 0; 
1990/1210    
	if(new) 
		cp->ctl.mid = Nnomsg^cp->out[cp->next].mid; 
1991/0102    
		ctl.mid = Nnomsg^cp->out[cp->next].mid; 
1990/1210    
	else 
		cp->ctl.mid = cp->lastacked; 
1991/0102    
		ctl.mid = cp->lastacked; 
1990/1210    
	cp->hdr->flag |= flag; 
	sendmsg(cp, &cp->ctl); 
1991/0102    
	sendmsg(cp, &ctl); 
1990/1210    
} 
 
/* 
1990/1231    
 *  send an acknowledgement 
 */ 
static void 
sendack(Noconv *cp, int ack) 
{ 
	cp->ackmsg.len = 0; 
	cp->ackmsg.first = 0; 
	cp->ackmsg.acked = ack; 
	cp->ackmsg.mid = cp->lastacked; 
	sendmsg(cp, &cp->ctl); 
} 
                 
/* 
1990/1210    
 *  receive a message (called by the multiplexor; noetheriput, nofddiiput, ...) 
 */ 
void 
1990/1231/sys/src/9/port/devnonet.c:1074,10811991/0102/sys/src/9/port/devnonet.c:1062,1071
1990/1210    
			if(f & NO_HANGUP) 
				hangup(cp); 
		} else { 
			if(r>0) 
1990/1231    
				sendack(cp, h->mid); 
1991/0102    
			if(r>0){ 
				queueack(cp, h->mid); 
				sendctlmsg(cp, 0, 0); 
			} 
1990/1210    
			cp->bad++; 
		} 
		freeb(bp); 
1991/0102/sys/src/9/port/devnonet.c:16,221991/0108/sys/src/9/port/devnonet.c:16,22 (short | long)
1990/1210    
	/* 
	 *  tuning parameters 
	 */ 
1990/1229    
	MSrexmit = 500,		/* retranmission interval in ms */ 
1991/0108    
	MSrexmit = 250,		/* retranmission interval in ms */ 
1990/1210    
	MSack = 50,		/* ms to sit on an ack */ 
 
	/* 
1991/0102/sys/src/9/port/devnonet.c:37,431991/0108/sys/src/9/port/devnonet.c:37,43
1990/1210    
static void	sendmsg(Noconv*, Nomsg*); 
static void	startconv(Noconv*, int, char*, int); 
static void	queueack(Noconv*, int); 
                 
1991/0108    
static void	nonetkproc(void*); 
1990/1210    
static void	nonetiput(Queue*, Block*); 
static void	nonetoput(Queue*, Block*); 
static void	nonetstclose(Queue*); 
1991/0102/sys/src/9/port/devnonet.c:89,941991/0108/sys/src/9/port/devnonet.c:89,100
1990/1210    
}; 
 
/* 
1991/0108    
 *  nonet kproc 
 */ 
static int kstarted; 
static Rendez nonetkr; 
 
/* 
1990/1210    
 *  nonet file system.  most of the calls use dev.c to access the nonet 
 *  directory and stream.c to access the nonet devices. 
 *  create the nonet directory.  the files are `clone' and stream 
1991/0102/sys/src/9/port/devnonet.c:164,1691991/0108/sys/src/9/port/devnonet.c:170,176
1990/1210    
		error(Enoifc); 
	c = devattach('n', spec); 
	c->dev = ifc - noifc; 
1991/0108    
 
1990/1210    
	return c; 
} 
 
1991/0102/sys/src/9/port/devnonet.c:240,2451991/0108/sys/src/9/port/devnonet.c:247,257
1990/1210    
	Noifc *ifc; 
	int line; 
 
1991/0108    
	if(!kstarted){ 
		kproc("nonetack", nonetkproc, 0); 
		kstarted = 1; 
	} 
 
1990/1210    
	if(c->qid.path & CHDIR){ 
		/* 
		 *  directories are read only 
1991/0102/sys/src/9/port/devnonet.c:466,4731991/0108/sys/src/9/port/devnonet.c:478,487
1990/1210    
		} 
	} 
 
1991/0108    
	qlock(cp); 
1990/1210    
	cp->rcvcircuit = -1; 
	cp->state = Cclosed; 
1991/0108    
	qunlock(cp); 
1990/1210    
	poperror(); 
} 
 
1991/0102/sys/src/9/port/devnonet.c:511,5161991/0108/sys/src/9/port/devnonet.c:525,531
1990/1210    
	Noconv *cp; 
	int next; 
	Nomsg *mp; 
1991/0108    
	int retries; 
1990/1210    
 
	cp = (Noconv *)(q->ptr); 
 
1991/0102/sys/src/9/port/devnonet.c:573,5811991/0108/sys/src/9/port/devnonet.c:588,599
1990/1210    
	/* 
	 *  wait for acknowledgement 
	 */ 
1991/0108    
	retries = 0; 
1990/1210    
	while(!mp->acked && cp->state!=Chungup){ 
		sendmsg(cp, mp); 
		tsleep(&mp->r, acked, mp, MSrexmit); 
1991/0108    
		if(retries++ > 100) 
			errors("to many nonet rexmits"); 
1990/1210    
	} 
 
	/* 
1991/0102/sys/src/9/port/devnonet.c:704,7121991/0108/sys/src/9/port/devnonet.c:722,730
1990/1210    
		cp->hdr->flag |= NO_SERVICE; 
		sprint(buf, "%s %s", service, u->p->pgrp->user); 
		c->qid.path = STREAMQID(STREAMID(c->qid.path), Sdataqid); 
1990/1231    
		print("sending request\n"); 
1991/0108    
		DPRINT("sending request\n"); 
1990/1210    
		streamwrite(c, buf, strlen(buf), 1); 
1990/1231    
		print("request sent\n"); 
1991/0108    
		DPRINT("request sent\n"); 
1990/1210    
		c->qid.path = STREAMQID(STREAMID(c->qid.path), Sctlqid); 
	} 
} 
1991/0102/sys/src/9/port/devnonet.c:783,7911991/0108/sys/src/9/port/devnonet.c:801,809
1990/1210    
		 *  stuff the connect message into it 
		 */ 
		f = ((Nohdr *)(call.msg->rptr))->flag; 
1990/1231    
		print("call from %d %s\n", call.circuit, call.raddr); 
1991/0108    
		DPRINT("call from %d %s\n", call.circuit, call.raddr); 
1990/1210    
		startconv(cp, call.circuit, call.raddr, Cconnecting); 
		print("rcving %d byte message\n", call.msg->wptr - call.msg->rptr); 
1991/0108    
		DPRINT("rcving %d byte message\n", call.msg->wptr - call.msg->rptr); 
1990/1210    
		nonetrcvmsg(cp, call.msg); 
		call.msg = 0; 
 
1991/0102/sys/src/9/port/devnonet.c:794,8081991/0108/sys/src/9/port/devnonet.c:812,824
1990/1210    
		 *  grab them 
		 */ 
		if(f & NO_SERVICE){ 
			print("reading service\n"); 
1991/0108    
			DPRINT("reading service\n"); 
1990/1210    
			c->qid.path = STREAMQID(cp - ifc->conv, Sdataqid); 
			n = streamread(c, buf, sizeof(buf)); 
			c->qid.path = STREAMQID(cp - ifc->conv, Sctlqid); 
			print("read %d bytes\n", n); 
			if(n <= 0) 
				error(Ebadctl); 
			buf[n] = 0; 
			print("read %s\n", buf); 
			user = strchr(buf, ' '); 
			if(user){ 
				*user++ = 0; 
1991/0102/sys/src/9/port/devnonet.c:1056,10621991/0108/sys/src/9/port/devnonet.c:1072,1078
1990/1210    
	 *  ignore old messages and process the acknowledgement 
	 */ 
	if(h->mid != mp->mid){ 
		DPRINT("old msg %d instead of %d\n", h->mid, mp->mid); 
1991/0108    
		DPRINT("old msg %d instead of %d r==%d\n", h->mid, mp->mid, r); 
1990/1210    
		if(r == 0){ 
			rcvack(cp, h->ack); 
			if(f & NO_HANGUP) 
1991/0102/sys/src/9/port/devnonet.c:1063,10701991/0108/sys/src/9/port/devnonet.c:1079,1086
1990/1210    
				hangup(cp); 
		} else { 
1991/0102    
			if(r>0){ 
1991/0108    
				rcvack(cp, h->ack); 
1991/0102    
				queueack(cp, h->mid); 
				sendctlmsg(cp, 0, 0); 
			} 
1990/1210    
			cp->bad++; 
		} 
1991/0102/sys/src/9/port/devnonet.c:1238,12441991/0108/sys/src/9/port/devnonet.c:1254,1300
1990/1210    
	return s & 0xffff; 
1990/1229    
} 
 
1991/0108    
/* 
 *  send acknowledges that need to be sent.  this happens at 1/2 
 *  the retransmission interval. 
 */ 
static void 
nonetkproc(void *arg) 
{ 
	Noifc *ifc; 
	Noconv *cp, *ep; 
 
	cp = 0; 
	ifc = 0; 
	if(waserror()){ 
		if(ifc) 
			unlock(ifc); 
		if(cp) 
			qunlock(cp); 
	} 
 
loop: 
	for(ifc = noifc; ifc < &noifc[conf.nnoifc]; ifc++){ 
		if(ifc->wq==0 || !canlock(ifc)) 
			continue; 
		ep = ifc->conv + conf.nnoconv; 
		for(cp = ifc->conv; cp < ep; cp++){ 
			if(cp->state==Cclosed || !canqlock(cp)) 
				continue; 
			if(cp->afirst != cp->anext){ 
				DPRINT("sending ack %d\n", cp->ack[cp->afirst]); 
				sendctlmsg(cp, 0, 0); 
			} 
			qunlock(cp); 
		} 
		unlock(ifc); 
	} 
	tsleep(&nonetkr, return0, 0, MSrexmit/2); 
	goto loop; 
} 
 
1990/1229    
nonettoggle() 
{ 
	pnonet ^= 1; 
1990/1210    
} 
1991/0108    
 
1991/0108/sys/src/9/port/devnonet.c:554,5611991/0109/sys/src/9/port/devnonet.c:554,562 (short | long)
1990/1210    
				mp->first = 0; 
			} 
			mp->inuse = 0; 
		} else 
			qunlock(&cp->mlock); 
1991/0109    
		} 
		qunlock(&cp->mlock); 
		nexterror(); 
1990/1210    
	} 
 
	/* 
1991/0108/sys/src/9/port/devnonet.c:593,6001991/0109/sys/src/9/port/devnonet.c:594,602
1990/1210    
		sendmsg(cp, mp); 
		tsleep(&mp->r, acked, mp, MSrexmit); 
1991/0108    
		if(retries++ > 100) 
			errors("to many nonet rexmits"); 
1991/0109    
			errors("too many nonet rexmits"); 
1990/1210    
	} 
1991/0109    
	poperror(); 
1990/1210    
 
	/* 
	 *  free buffer 
1991/0108/sys/src/9/port/devnonet.c:603,6091991/0109/sys/src/9/port/devnonet.c:605,610
1990/1210    
	mp->first = 0; 
	mp->inuse = 0; 
	wakeup(&cp->r); 
	poperror(); 
} 
 
/* 
1991/0109/sys/src/9/port/devnonet.c:781,7871991/0112/sys/src/9/port/devnonet.c:781,787 (short | long)
1990/1210    
		 */ 
		ep = &ifc->conv[conf.nnoconv]; 
		for(cp = &ifc->conv[0]; cp < ep; cp++){ 
			if(cp->state>Cannounced && call.circuit==cp->rcvcircuit 
1991/0112    
			if(cp->state>Cannounced && (call.circuit^1)==cp->rcvcircuit 
1990/1210    
			&& strcmp(call.raddr, cp->raddr)==0) 
				break; 
		} 
1991/0112/sys/src/9/port/devnonet.c:517,5231991/01151/sys/src/9/port/devnonet.c:517,523 (short | long)
1990/1210    
	Nomsg *mp; 
 
	mp = (Nomsg *)a; 
	return mp->acked; 
1991/01151    
	return mp->inuse; 
1990/1210    
} 
static void 
nonetoput(Queue *q, Block *bp) 
1991/0112/sys/src/9/port/devnonet.c:549,5591991/01151/sys/src/9/port/devnonet.c:549,564
1990/1210    
	mp = 0; 
	if(waserror()){ 
		if(mp){ 
1991/01151    
			q->len = 0; 
			q->first = q->last = 0; 
1990/1210    
			if(mp->first){ 
				freeb(mp->first); 
				mp->first = 0; 
			} 
			mp->inuse = 0; 
1991/01151    
			mp->acked = 0; 
			if(((cp->first+1)%Nnomsg) == cp->next) 
				cp->first = cp->next; 
1991/0109    
		} 
		qunlock(&cp->mlock); 
		nexterror(); 
1991/0112/sys/src/9/port/devnonet.c:584,6101991/01151/sys/src/9/port/devnonet.c:589,601
1990/1210    
	q->len = 0; 
	q->first = q->last = 0; 
	cp->sent++; 
	qunlock(&cp->mlock); 
 
	/* 
	 *  wait for acknowledgement 
1991/01151    
	 *  send the message, the kproc will retry 
1990/1210    
	 */ 
1991/0108    
	retries = 0; 
1990/1210    
	while(!mp->acked && cp->state!=Chungup){ 
		sendmsg(cp, mp); 
		tsleep(&mp->r, acked, mp, MSrexmit); 
1991/0108    
		if(retries++ > 100) 
1991/0109    
			errors("too many nonet rexmits"); 
1990/1210    
	} 
1991/01151    
	sendmsg(cp, mp); 
	qunlock(&cp->mlock); 
1991/0109    
	poperror(); 
1990/1210    
                 
	/* 
	 *  free buffer 
	 */ 
	freeb(mp->first); 
	mp->first = 0; 
	mp->inuse = 0; 
	wakeup(&cp->r); 
} 
 
/* 
1991/0112/sys/src/9/port/devnonet.c:871,8811991/01151/sys/src/9/port/devnonet.c:862,886
1990/1210    
		return; 
 
	/* 
	 *  wakeup the sender 
1991/01151    
 	 *  free it 
1990/1210    
	 */ 
1991/01151    
	cp->rexmit = 0; 
1990/1210    
	mp->acked = 1; 
	wakeup(&mp->r); 
	cp->lastacked = mid; 
1991/01151    
	freeb(mp->first); 
	mp->first = 0; 
	mp->inuse = 0; 
 
	/* 
	 *  advance first if this is the first 
	 */ 
	if((mid&Nmask) == cp->first){ 
		while(cp->first != cp->next){ 
			if(cp->out[cp->first].acked == 0) 
				break; 
			cp->first = (cp->first+1) % Nnomsg; 
		} 
	} 
1990/1210    
} 
 
/* 
1991/0112/sys/src/9/port/devnonet.c:1094,11031991/01151/sys/src/9/port/devnonet.c:1099,1108
1990/1210    
		 *  start of message packet 
		 */ 
		if(mp->first){ 
			DPRINT("mp->mid==%d mp->rem==%d buf r==%d\n", mp->mid, mp->rem, r); 
			cp->bad++; 
			freeb(bp); 
			return; 
1991/01151    
			DPRINT("mp->mid==%d mp->rem==%d r==%d\n", mp->mid, mp->rem, r); 
			freeb(mp->first); 
			mp->first = mp->last = 0; 
			mp->len = 0; 
1990/1210    
		} 
		mp->rem = r; 
	} else { 
1991/0112/sys/src/9/port/devnonet.c:1105,11111991/01151/sys/src/9/port/devnonet.c:1110,1116
1990/1210    
		 *  a continuation 
		 */ 
		if(-r != mp->rem) { 
			DPRINT("mp->mid==%d mp->rem==%d buf r==%d\n", mp->mid, mp->rem, r); 
1991/01151    
			DPRINT("mp->mid==%d mp->rem==%d r==%d\n", mp->mid, mp->rem, r); 
1990/1210    
			cp->bad++; 
			freeb(bp); 
			return; 
1991/0112/sys/src/9/port/devnonet.c:1275,12871991/01151/sys/src/9/port/devnonet.c:1280,1318
1991/0108    
	} 
 
loop: 
1991/01151    
	/* 
	 *  loop through all active interfaces 
	 */ 
1991/0108    
	for(ifc = noifc; ifc < &noifc[conf.nnoifc]; ifc++){ 
		if(ifc->wq==0 || !canlock(ifc)) 
			continue; 
1991/01151    
 
		/* 
		 *  loop through all active conversations 
		 */ 
1991/0108    
		ep = ifc->conv + conf.nnoconv; 
		for(cp = ifc->conv; cp < ep; cp++){ 
			if(cp->state==Cclosed || !canqlock(cp)) 
				continue; 
1991/01151    
			if(cp->state == Cclosed){ 
				qunlock(cp); 
				continue; 
			} 
 
			/* 
			 *  resend the first message 
			 */ 
			if(cp->first!=cp->next && cp->out[cp->first].time>=NOW){ 
				if(cp->rexmit++ > 100){ 
					print("hanging up\n"); 
					hangup(cp); 
				} else 
					sendmsg(cp, &(cp->out[cp->first])); 
			} 
 
			/* 
			 *  resend an acknowledge 
			 */ 
1991/0108    
			if(cp->afirst != cp->anext){ 
				DPRINT("sending ack %d\n", cp->ack[cp->afirst]); 
				sendctlmsg(cp, 0, 0); 
1991/0112/sys/src/9/port/devnonet.c:1294,13001991/01151/sys/src/9/port/devnonet.c:1325,1332
1991/0108    
	goto loop; 
} 
 
1990/1229    
nonettoggle() 
1991/01151    
void 
nonettoggle(void) 
1990/1229    
{ 
	pnonet ^= 1; 
1990/1210    
} 
1991/01151/sys/src/9/port/devnonet.c:86,911991/0118/sys/src/9/port/devnonet.c:86,92 (short | long)
1990/1210    
	Cconnecting, 
	Chungup, 
	Cclosing, 
1991/0118    
	Csuperceded, 
1990/1210    
}; 
 
/* 
1991/01151/sys/src/9/port/devnonet.c:470,4761991/0118/sys/src/9/port/devnonet.c:471,477
1990/1210    
	 *  send hangup messages to the other side 
	 *  until it hangs up or we get tired. 
	 */ 
	if(cp->state >= Cconnected){ 
1991/0118    
	if(cp->state>=Cconnected && cp->state!=Csuperceded){ 
1990/1210    
		sendctlmsg(cp, NO_HANGUP, 1); 
		for(i=0; i<10 && !ishungup(cp); i++){ 
			sendctlmsg(cp, NO_HANGUP, 1); 
1991/01151/sys/src/9/port/devnonet.c:961,9661991/0118/sys/src/9/port/devnonet.c:962,971
1990/1210    
	} 
	cp->hdr->mid = mp->mid; 
 
1991/0118    
	/* 
	 *  package n blocks into m packets.  make sure 
	 *  no packet is < mintu or > maxtu in length. 
	 */ 
1990/1210    
	if(ifc->mintu > mp->len) { 
		/* 
		 *  short message: 
1991/01151/sys/src/9/port/devnonet.c:971,9771991/0118/sys/src/9/port/devnonet.c:976,985
1990/1210    
			memcpy(pkt->wptr, bp->rptr, n = BLEN(bp)); 
			pkt->wptr += n; 
		} 
		memset(pkt->wptr, 0, n = ifc->mintu - mp->len); 
1991/0118    
		/* 
		 *  round up to mintu 
		 */ 
		memset(pkt->wptr, 0, n = ifc->mintu-mp->len); 
1990/1210    
		pkt->wptr += n; 
	} else { 
		/* 
1991/01151/sys/src/9/port/devnonet.c:986,9911991/0118/sys/src/9/port/devnonet.c:994,1000
1990/1210    
		if(bp) 
			rptr = bp->rptr; 
		last = pkt = mkhdr(cp, msgrem); 
1991/0118    
		n = 0; 
1990/1210    
		while(bp){ 
			/* 
			 *  if pkt full, send and create new header block 
1991/01151/sys/src/9/port/devnonet.c:1011,10211991/0118/sys/src/9/port/devnonet.c:1020,1043
1990/1210    
					rptr = bp->rptr; 
			} 
		} 
1991/0118    
		/* 
		 *  round up last packet to mintu 
		 */ 
		if(n < ifc->mintu){ 
			n = ifc->mintu - n; 
			last = last->next = allocb(n); 
			memset(last->wptr, 0, n); 
			last->wptr += n; 
		} 
1990/1210    
	} 
	nonetcksum(pkt, ifc->hsize); 
	last->flags |= S_DELIM; 
1991/0118    
	if(cp->rexmit > 10) 
		mp->time = NOW + 10*MSrexmit; 
	else 
		mp->time = NOW + (cp->rexmit+1)*MSrexmit; 
	DPRINT("xmit %d %lud %lud\n", cp->rexmit, NOW, mp->time); 
1990/1210    
	(*wq->put)(wq, pkt); 
	mp->time = NOW + MSrexmit; 
	qunlock(&cp->xlock); 
	poperror(); 
} 
1991/01151/sys/src/9/port/devnonet.c:1067,10761991/0118/sys/src/9/port/devnonet.c:1089,1102
1990/1210    
	/* 
	 *  if a new call request comes in on a connected channel, hang up the call 
	 */ 
	if(h->mid==0 && (f & NO_NEWCALL) && cp->state==Cconnected){ 
1991/0118    
	if(h->mid==0 && (f & NO_NEWCALL) 
	&& (cp->state==Cconnected || cp->state==Csuperceded)){ 
1990/1229    
		DPRINT("new call on connected channel\n");  
1990/1210    
		freeb(bp); 
		hangup(cp); 
1991/0118    
		if(cp->state != Csuperceded){ 
			cp->state = Csuperceded; 
			hangup(cp); 
		} 
1990/1210    
		return; 
	} 
 
1991/01151/sys/src/9/port/devnonet.c:1269,12741991/0118/sys/src/9/port/devnonet.c:1295,1301
1991/0108    
{ 
	Noifc *ifc; 
	Noconv *cp, *ep; 
1991/0118    
	Nomsg *mp; 
1991/0108    
 
	cp = 0; 
	ifc = 0; 
1991/01151/sys/src/9/port/devnonet.c:1302,13131991/0118/sys/src/9/port/devnonet.c:1329,1342
1991/01151    
			/* 
			 *  resend the first message 
			 */ 
			if(cp->first!=cp->next && cp->out[cp->first].time>=NOW){ 
				if(cp->rexmit++ > 100){ 
1991/0118    
			if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ 
				if(cp->rexmit++ > 60){ 
1991/01151    
					print("hanging up\n"); 
					hangup(cp); 
				} else 
					sendmsg(cp, &(cp->out[cp->first])); 
1991/0118    
				} else { 
					mp = &(cp->out[cp->first]); 
					sendmsg(cp, mp); 
				} 
1991/01151    
			} 
 
			/* 
1991/0118/sys/src/9/port/devnonet.c:27,471991/0119/sys/src/9/port/devnonet.c:27,48 (short | long)
1990/1210    
}; 
 
/* predeclared */ 
static void	hangup(Noconv*); 
static Block*	mkhdr(Noconv*, int); 
static void	listen(Chan*, Noifc*); 
static void	announce(Chan*, char*); 
static void	connect(Chan*, char*); 
static void	rcvack(Noconv*, int); 
static void	sendctlmsg(Noconv*, int, int); 
static void	sendmsg(Noconv*, Nomsg*); 
static void	startconv(Noconv*, int, char*, int); 
static void	queueack(Noconv*, int); 
1991/0108    
static void	nonetkproc(void*); 
1990/1210    
static void	nonetiput(Queue*, Block*); 
static void	nonetoput(Queue*, Block*); 
static void	nonetstclose(Queue*); 
static void	nonetstopen(Queue*, Stream*); 
1991/0119    
static void	nohangup(Noconv*); 
static void	noreset(Noconv*); 
static Block*	nohdr(Noconv*, int); 
static void	nolisten(Chan*, Noifc*); 
static void	noannounce(Chan*, char*); 
static void	noconnect(Chan*, char*); 
static void	norack(Noconv*, int); 
static void	nosendctl(Noconv*, int, int); 
static void	nosend(Noconv*, Nomsg*); 
static void	nostartconv(Noconv*, int, char*, int); 
static void	noqack(Noconv*, int); 
static void	nokproc(void*); 
static void	noiput(Queue*, Block*); 
static void	nooput(Queue*, Block*); 
static void	noclose(Queue*); 
static void	noopen(Queue*, Stream*); 
1990/1210    
 
extern Qinfo	noetherinfo; 
extern Qinfo	nonetinfo; 
1991/0118/sys/src/9/port/devnonet.c:85,921991/0119/sys/src/9/port/devnonet.c:86,92
1990/1210    
	Cconnected, 
	Cconnecting, 
	Chungup, 
	Cclosing, 
1991/0118    
	Csuperceded, 
1991/0119    
	Creset, 
1990/1210    
}; 
 
/* 
1991/0118/sys/src/9/port/devnonet.c:249,2551991/0119/sys/src/9/port/devnonet.c:249,255
1990/1210    
	int line; 
 
1991/0108    
	if(!kstarted){ 
		kproc("nonetack", nonetkproc, 0); 
1991/0119    
		kproc("nonetack", nokproc, 0); 
1991/0108    
		kstarted = 1; 
	} 
 
1991/0118/sys/src/9/port/devnonet.c:276,2821991/0119/sys/src/9/port/devnonet.c:276,282
1990/1210    
		ifc = &noifc[c->dev]; 
		if(ifc->conv[line].state != Cannounced) 
			error(Enoannounce); 
		listen(c, ifc); 
1991/0119    
		nolisten(c, ifc); 
1990/1210    
		break; 
	case Nraddrqid: 
		/* 
1991/0118/sys/src/9/port/devnonet.c:311,3171991/0119/sys/src/9/port/devnonet.c:311,317
1990/1210    
	Noifc *ifc; 
 
	/* 
	 *  real closing happens in nonetstclose 
1991/0119    
	 *  real closing happens in noclose 
1990/1210    
	 */ 
	if(c->qid.path != CHDIR) 
		streamclose(c); 
1991/0118/sys/src/9/port/devnonet.c:374,3801991/0119/sys/src/9/port/devnonet.c:374,380
1990/1210    
		return streamwrite(c, a, n, 0); 
 
	/* 
	 *  easier to do here than in nonetoput 
1991/0119    
	 *  easier to do here than in nooput 
1990/1210    
	 */ 
	if(t == Sctlqid){ 
		strncpy(buf, a, sizeof buf); 
1991/0118/sys/src/9/port/devnonet.c:382,3901991/0119/sys/src/9/port/devnonet.c:382,390
1990/1210    
		if(strcmp(field[0], "connect")==0){ 
			if(m < 2) 
				error(Ebadarg); 
			connect(c, field[1]); 
1991/0119    
			noconnect(c, field[1]); 
1990/1210    
		} else if(strcmp(field[0], "announce")==0){ 
			announce(c, field[1]); 
1991/0119    
			noannounce(c, field[1]); 
1990/1210    
		} else if(strcmp(field[0], "accept")==0){ 
			/* ignore */; 
		} else if(strcmp(field[0], "reject")==0){ 
1991/0118/sys/src/9/port/devnonet.c:414,4231991/0119/sys/src/9/port/devnonet.c:414,423
1990/1210    
 */ 
Qinfo nonetinfo = 
{ 
	nonetiput, 
	nonetoput, 
	nonetstopen, 
	nonetstclose, 
1991/0119    
	noiput, 
	nooput, 
	noopen, 
	noclose, 
1990/1210    
	"nonet" 
}; 
 
1991/0118/sys/src/9/port/devnonet.c:424,4321991/0119/sys/src/9/port/devnonet.c:424,434
1990/1210    
/* 
 *  store the device end of the stream so that the multiplexor can 
 *  send blocks upstream. 
1991/0119    
 * 
 *	State Transition:	Cclosed -> Copen 
1990/1210    
 */ 
static void 
nonetstopen(Queue *q, Stream *s) 
1991/0119    
noopen(Queue *q, Stream *s) 
1990/1210    
{ 
	Noifc *ifc; 
	Noconv *cp; 
1991/0118/sys/src/9/port/devnonet.c:443,4481991/0119/sys/src/9/port/devnonet.c:445,452
1990/1210    
/* 
 *  wait until a hangup is received. 
 *  then send a hangup message (until one is received). 
1991/0119    
 * 
 *	State Transitions:	* -> Cclosed 
1990/1210    
 */ 
static int 
ishungup(void *a) 
1991/0118/sys/src/9/port/devnonet.c:450,4591991/0119/sys/src/9/port/devnonet.c:454,469
1990/1210    
	Noconv *cp; 
 
	cp = (Noconv *)a; 
	return cp->state == Chungup; 
1991/0119    
	switch(cp->state){ 
	case Chungup: 
	case Creset: 
	case Cclosed: 
		return 1; 
	} 
	return 0; 
1990/1210    
} 
static void 
nonetstclose(Queue *q) 
1991/0119    
noclose(Queue *q) 
1990/1210    
{ 
	Noconv *cp; 
	Nomsg *mp; 
1991/0118/sys/src/9/port/devnonet.c:471,4821991/0119/sys/src/9/port/devnonet.c:481,503
1990/1210    
	 *  send hangup messages to the other side 
	 *  until it hangs up or we get tired. 
	 */ 
1991/0118    
	if(cp->state>=Cconnected && cp->state!=Csuperceded){ 
1990/1210    
		sendctlmsg(cp, NO_HANGUP, 1); 
1991/0119    
	switch(cp->state){ 
	case Cconnected: 
		/* 
		 *  send close till we get one back 
		 */ 
		nosendctl(cp, NO_HANGUP, 1); 
1990/1210    
		for(i=0; i<10 && !ishungup(cp); i++){ 
			sendctlmsg(cp, NO_HANGUP, 1); 
1991/0119    
			nosendctl(cp, NO_HANGUP, 1); 
1990/1210    
			tsleep(&cp->r, ishungup, cp, MSrexmit); 
		} 
1991/0119    
		break; 
	case Chungup: 
		/* 
		 *  ack any close 
		 */ 
		nosendctl(cp, NO_HANGUP, 1); 
		break; 
1990/1210    
	} 
 
1991/0108    
	qlock(cp); 
1991/0118/sys/src/9/port/devnonet.c:488,4961991/0119/sys/src/9/port/devnonet.c:509,519
1990/1210    
 
/* 
 *  send all messages up stream.  this should only be control messages 
1991/0119    
 * 
 *	State Transition:	(on M_HANGUP) * -> Chungup 
1990/1210    
 */ 
static void 
nonetiput(Queue *q, Block *bp) 
1991/0119    
noiput(Queue *q, Block *bp) 
1990/1210    
{ 
	Noconv *cp; 
 
1991/0118/sys/src/9/port/devnonet.c:521,5271991/0119/sys/src/9/port/devnonet.c:544,550
1991/01151    
	return mp->inuse; 
1990/1210    
} 
static void 
nonetoput(Queue *q, Block *bp) 
1991/0119    
nooput(Queue *q, Block *bp) 
1990/1210    
{ 
	Noconv *cp; 
	int next; 
1991/0118/sys/src/9/port/devnonet.c:594,6001991/0119/sys/src/9/port/devnonet.c:617,623
1990/1210    
	/* 
1991/01151    
	 *  send the message, the kproc will retry 
1990/1210    
	 */ 
1991/01151    
	sendmsg(cp, mp); 
1991/0119    
	nosend(cp, mp); 
1991/01151    
	qunlock(&cp->mlock); 
1991/0109    
	poperror(); 
1990/1210    
} 
1991/0118/sys/src/9/port/devnonet.c:604,6101991/0119/sys/src/9/port/devnonet.c:627,633
1990/1210    
 *  none already exists for this circuit. 
 */ 
void 
startconv(Noconv *cp, int circuit, char *raddr, int state) 
1991/0119    
nostartconv(Noconv *cp, int circuit, char *raddr, int state) 
1990/1210    
{ 
	int i; 
	char name[32]; 
1991/0118/sys/src/9/port/devnonet.c:647,6531991/0119/sys/src/9/port/devnonet.c:670,677
1990/1210    
	cp->out[0].acked = 1; 
	cp->out[0].rem = 0; 
	cp->first = cp->next = 1; 
	cp->rexmit = cp->bad = cp->sent = cp->rcvd = cp->lastacked = 0; 
1991/0119    
	cp->rexmit = cp->bad = cp->sent = cp->rcvd = 0; 
	cp->lastacked = Nnomsg|(Nnomsg-1); 
1990/1210    
 
	/* 
	 *  used for demultiplexing 
1991/0118/sys/src/9/port/devnonet.c:668,6761991/0119/sys/src/9/port/devnonet.c:692,702
1990/1210    
 
/* 
 *  announce willingness to take calls 
1991/0119    
 * 
 *	State Transition:	Copen -> Chungup 
1990/1210    
 */ 
static void 
announce(Chan *c, char *addr) 
1991/0119    
noannounce(Chan *c, char *addr) 
1990/1210    
{ 
	Noconv *cp; 
 
1991/0118/sys/src/9/port/devnonet.c:684,6921991/0119/sys/src/9/port/devnonet.c:710,720
1990/1210    
 *  connect to the destination whose name is pointed to by bp->rptr. 
 * 
 *  a service is separated from the destination system by a '!' 
1991/0119    
 * 
 *	State Transition:	Copen -> Cconnecting 
1990/1210    
 */ 
static void 
connect(Chan *c, char *addr) 
1991/0119    
noconnect(Chan *c, char *addr) 
1990/1210    
{ 
	Noifc *ifc; 
	Noconv *cp; 
1991/0118/sys/src/9/port/devnonet.c:706,7121991/0119/sys/src/9/port/devnonet.c:734,740
1990/1210    
			error(Ebadctl); 
	} 
 
	startconv(cp, 2*(cp - ifc->conv), addr, Cconnecting); 
1991/0119    
	nostartconv(cp, 2*(cp - ifc->conv), addr, Cconnecting); 
1990/1210    
 
	if(service){ 
		/* 
1991/0118/sys/src/9/port/devnonet.c:715,7231991/0119/sys/src/9/port/devnonet.c:743,749
1990/1210    
		cp->hdr->flag |= NO_SERVICE; 
		sprint(buf, "%s %s", service, u->p->pgrp->user); 
		c->qid.path = STREAMQID(STREAMID(c->qid.path), Sdataqid); 
1991/0108    
		DPRINT("sending request\n"); 
1990/1210    
		streamwrite(c, buf, strlen(buf), 1); 
1991/0108    
		DPRINT("request sent\n"); 
1990/1210    
		c->qid.path = STREAMQID(STREAMID(c->qid.path), Sctlqid); 
	} 
} 
1991/0118/sys/src/9/port/devnonet.c:726,7311991/0119/sys/src/9/port/devnonet.c:752,759
1990/1210    
 *  listen for a call.  There can be many listeners, but only one can sleep 
 *  on the circular queue at a time.  ifc->listenl lets only one at a time into 
 *  the sleep. 
1991/0119    
 * 
 *	State Transition:	Cclosed -> Copen -> Cconnecting 
1990/1210    
 */ 
static int 
iscall(void *a) 
1991/0118/sys/src/9/port/devnonet.c:736,7421991/0119/sys/src/9/port/devnonet.c:764,770
1990/1210    
	return ifc->rptr != ifc->wptr; 
} 
static void 
listen(Chan *c, Noifc *ifc) 
1991/0119    
nolisten(Chan *c, Noifc *ifc) 
1990/1210    
{ 
	Noconv *cp, *ep; 
	Nocall call; 
1991/0118/sys/src/9/port/devnonet.c:795,8011991/0119/sys/src/9/port/devnonet.c:823,829
1990/1210    
		 */ 
		f = ((Nohdr *)(call.msg->rptr))->flag; 
1991/0108    
		DPRINT("call from %d %s\n", call.circuit, call.raddr); 
1990/1210    
		startconv(cp, call.circuit, call.raddr, Cconnecting); 
1991/0119    
		nostartconv(cp, call.circuit, call.raddr, Cconnecting); 
1991/0108    
		DPRINT("rcving %d byte message\n", call.msg->wptr - call.msg->rptr); 
1990/1210    
		nonetrcvmsg(cp, call.msg); 
		call.msg = 0; 
1991/0118/sys/src/9/port/devnonet.c:828,8541991/0119/sys/src/9/port/devnonet.c:856,915
1990/1210    
/* 
 *  send a hangup signal up the stream to get all line disciplines 
 *  to cease and desist 
1991/0119    
 * 
 *	State Transition:	{Cconnected, Cconnecting} -> Chungup 
1990/1210    
 */ 
static void 
hangup(Noconv *cp) 
1991/0119    
nohangup(Noconv *cp) 
1990/1210    
{ 
	Block *bp; 
	Queue *q; 
 
	cp->state = Chungup; 
	bp = allocb(0); 
	bp->type = M_HANGUP; 
	q = cp->rq; 
	PUTNEXT(q, bp); 
1991/0119    
	switch(cp->state){ 
	case Cconnected: 
	case Cconnecting: 
		cp->state = Chungup; 
		bp = allocb(0); 
		bp->type = M_HANGUP; 
		q = cp->rq; 
		PUTNEXT(q, bp); 
		break; 
	} 
1990/1210    
	wakeup(&cp->r); 
} 
 
/* 
1991/0119    
 *  send a hangup signal up the stream to get all line disciplines 
 *  to cease and desist.  The Creset state makes any subsequent close not 
 *  send hangup messages. 
 * 
 *	State Transition:	{Cconnected, Cconnecting} -> Creset 
 */ 
static void 
noreset(Noconv *cp) 
{ 
	Block *bp; 
	Queue *q; 
 
	switch(cp->state){ 
	case Cconnected: 
	case Cconnecting: 
		cp->state = Creset; 
		bp = allocb(0); 
		bp->type = M_HANGUP; 
		q = cp->rq; 
		PUTNEXT(q, bp); 
		break; 
	} 
	wakeup(&cp->r); 
} 
 
/* 
1990/1210    
 *  process a message acknowledgement.  if the message 
 *  has any xmit buffers queued, free them. 
 */ 
static void 
rcvack(Noconv *cp, int mid) 
1991/0119    
norack(Noconv *cp, int mid) 
1990/1210    
{ 
	Nomsg *mp; 
	Block *bp; 
1991/0118/sys/src/9/port/devnonet.c:889,8951991/0119/sys/src/9/port/devnonet.c:950,956
1990/1210    
 *  acknowledgements queued. 
 */ 
static void 
queueack(Noconv *cp, int mid) 
1991/0119    
noqack(Noconv *cp, int mid) 
1990/1210    
{ 
	int next; 
 
1991/0118/sys/src/9/port/devnonet.c:904,9101991/0119/sys/src/9/port/devnonet.c:965,971
1990/1210    
 *  make a packet header 
 */ 
Block * 
mkhdr(Noconv *cp, int rem) 
1991/0119    
nohdr(Noconv *cp, int rem) 
1990/1210    
{ 
	Block *bp; 
	Nohdr *hp; 
1991/0118/sys/src/9/port/devnonet.c:923,9331991/0119/sys/src/9/port/devnonet.c:984,994
1990/1210    
 *  transmit a message.  this involves breaking a possibly multi-block message into 
 *  a train of packets on the media. 
 * 
 *  called by nonetoput().  the qlock(mp) synchronizes these two 
1991/0119    
 *  called by nooput().  the qlock(mp) synchronizes these two 
1990/1210    
 *  processes. 
 */ 
static void 
sendmsg(Noconv *cp, Nomsg *mp) 
1991/0119    
nosend(Noconv *cp, Nomsg *mp) 
1990/1210    
{ 
	Noifc *ifc; 
	Queue *wq; 
1991/0118/sys/src/9/port/devnonet.c:971,9771991/0119/sys/src/9/port/devnonet.c:1032,1038
1990/1210    
		 *  short message: 
		 *  copy the whole message into the header block 
		 */ 
		last = pkt = mkhdr(cp, mp->len); 
1991/0119    
		last = pkt = nohdr(cp, mp->len); 
1990/1210    
		for(bp = mp->first; bp; bp = bp->next){ 
			memcpy(pkt->wptr, bp->rptr, n = BLEN(bp)); 
			pkt->wptr += n; 
1991/0118/sys/src/9/port/devnonet.c:993,9991991/0119/sys/src/9/port/devnonet.c:1054,1060
1990/1214    
		SET(rptr); 
1990/1210    
		if(bp) 
			rptr = bp->rptr; 
		last = pkt = mkhdr(cp, msgrem); 
1991/0119    
		last = pkt = nohdr(cp, msgrem); 
1991/0118    
		n = 0; 
1990/1210    
		while(bp){ 
			/* 
1991/0118/sys/src/9/port/devnonet.c:1003,10091991/0119/sys/src/9/port/devnonet.c:1064,1070
1990/1210    
				nonetcksum(pkt, ifc->hsize); 
				last->flags |= S_DELIM; 
				(*wq->put)(wq, pkt); 
				last = pkt = mkhdr(cp, -msgrem); 
1991/0119    
				last = pkt = nohdr(cp, -msgrem); 
1990/1210    
				pktrem = msgrem > ifc->maxtu ? ifc->maxtu : msgrem; 
			} 
			n = bp->wptr - rptr; 
1991/0118/sys/src/9/port/devnonet.c:1036,10421991/0119/sys/src/9/port/devnonet.c:1097,1102
1991/0118    
		mp->time = NOW + 10*MSrexmit; 
	else 
		mp->time = NOW + (cp->rexmit+1)*MSrexmit; 
	DPRINT("xmit %d %lud %lud\n", cp->rexmit, NOW, mp->time); 
1990/1210    
	(*wq->put)(wq, pkt); 
	qunlock(&cp->xlock); 
	poperror(); 
1991/0118/sys/src/9/port/devnonet.c:1046,10521991/0119/sys/src/9/port/devnonet.c:1106,1112
1990/1210    
 *  send a control message (hangup or acknowledgement). 
 */ 
static void 
sendctlmsg(Noconv *cp, int flag, int new) 
1991/0119    
nosendctl(Noconv *cp, int flag, int new) 
1990/1210    
{ 
1991/0102    
	Nomsg ctl; 
 
1991/0118/sys/src/9/port/devnonet.c:1058,10681991/0119/sys/src/9/port/devnonet.c:1118,1130
1990/1210    
	else 
1991/0102    
		ctl.mid = cp->lastacked; 
1990/1210    
	cp->hdr->flag |= flag; 
1991/0102    
	sendmsg(cp, &ctl); 
1991/0119    
	nosend(cp, &ctl); 
1990/1210    
} 
 
/* 
 *  receive a message (called by the multiplexor; noetheriput, nofddiiput, ...) 
1991/0119    
 * 
 *	State Transition:	(no NO_NEWCALL in msg) Cconnecting -> Cconnected 
1990/1210    
 */ 
void 
nonetrcvmsg(Noconv *cp, Block *bp) 
1991/0118/sys/src/9/port/devnonet.c:1089,11021991/0119/sys/src/9/port/devnonet.c:1151,1160
1990/1210    
	/* 
	 *  if a new call request comes in on a connected channel, hang up the call 
	 */ 
1991/0118    
	if(h->mid==0 && (f & NO_NEWCALL) 
	&& (cp->state==Cconnected || cp->state==Csuperceded)){ 
1991/0119    
	if((f&NO_NEWCALL) && cp->state==Cconnected){ 
1990/1229    
		DPRINT("new call on connected channel\n");  
1990/1210    
		freeb(bp); 
1991/0118    
		if(cp->state != Csuperceded){ 
			cp->state = Csuperceded; 
			hangup(cp); 
		} 
1991/0119    
		noreset(cp); 
1990/1210    
		return; 
	} 
 
1991/0118/sys/src/9/port/devnonet.c:1106,11181991/0119/sys/src/9/port/devnonet.c:1164,1178
1990/1210    
	if(h->mid != mp->mid){ 
1991/0108    
		DPRINT("old msg %d instead of %d r==%d\n", h->mid, mp->mid, r); 
1990/1210    
		if(r == 0){ 
			rcvack(cp, h->ack); 
			if(f & NO_HANGUP) 
				hangup(cp); 
1991/0119    
			norack(cp, h->ack); 
			if(f & NO_RESET) 
				noreset(cp); 
			else if(f & NO_HANGUP) 
				nohangup(cp); 
1990/1210    
		} else { 
1991/0102    
			if(r>0){ 
1991/0108    
				rcvack(cp, h->ack); 
1991/0102    
				queueack(cp, h->mid); 
1991/0119    
				norack(cp, h->ack); 
				noqack(cp, h->mid); 
1991/0102    
			} 
1990/1210    
			cp->bad++; 
		} 
1991/0118/sys/src/9/port/devnonet.c:1163,11711991/0119/sys/src/9/port/devnonet.c:1223,1232
1990/1210    
	 *  if not, strip off the delimiter. 
	 */ 
	if(mp->rem == 0){ 
		rcvack(cp, h->ack); 
1991/0119    
		cp->hdr->flag &= ~(NO_NEWCALL|NO_SERVICE); 
		norack(cp, h->ack); 
1990/1210    
		if(f & NO_ACKME) 
			queueack(cp, h->mid); 
1991/0119    
			noqack(cp, h->mid); 
1990/1210    
		mp->last->flags |= S_DELIM; 
		PUTNEXT(q, mp->first); 
		mp->first = mp->last = 0; 
1991/0118/sys/src/9/port/devnonet.c:1178,11921991/0119/sys/src/9/port/devnonet.c:1239,1265
1990/1210    
		mp->mid ^= Nnomsg; 
 
		/* 
		 *  stop xmitting the NO_NEWCALL flag 
1991/0119    
		 *  any NO_NEWCALL after this is another call 
1990/1210    
		 */ 
		if(cp->state==Cconnecting && !(f & NO_NEWCALL)) 
1991/0119    
		if(cp->state==Cconnecting && !(f&NO_NEWCALL)) 
1990/1210    
			cp->state = Cconnected; 
1991/0119    
 
		/* 
		 *  hangup (after processing message) 
		 */ 
		if(f & NO_RESET){ 
			DPRINT("reset with message\n"); 
			noreset(cp); 
		} else if(f & NO_HANGUP){ 
			DPRINT("hangup with message\n"); 
			nohangup(cp); 
		} 
1990/1210    
	} else 
		mp->last->flags &= ~S_DELIM; 
 
} 
 
1991/0119    
 
1990/1210    
/* 
 *  noifc 
 */ 
1991/0118/sys/src/9/port/devnonet.c:1291,12971991/0119/sys/src/9/port/devnonet.c:1364,1370
1991/0108    
 *  the retransmission interval. 
 */ 
static void 
nonetkproc(void *arg) 
1991/0119    
nokproc(void *arg) 
1991/0108    
{ 
	Noifc *ifc; 
	Noconv *cp, *ep; 
1991/0118/sys/src/9/port/devnonet.c:1332,13411991/0119/sys/src/9/port/devnonet.c:1405,1414
1991/0118    
			if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ 
				if(cp->rexmit++ > 60){ 
1991/01151    
					print("hanging up\n"); 
					hangup(cp); 
1991/0119    
					nohangup(cp); 
1991/0118    
				} else { 
					mp = &(cp->out[cp->first]); 
					sendmsg(cp, mp); 
1991/0119    
					nosend(cp, mp); 
1991/0118    
				} 
1991/01151    
			} 
 
1991/0118/sys/src/9/port/devnonet.c:1344,13501991/0119/sys/src/9/port/devnonet.c:1417,1423
1991/01151    
			 */ 
1991/0108    
			if(cp->afirst != cp->anext){ 
				DPRINT("sending ack %d\n", cp->ack[cp->afirst]); 
				sendctlmsg(cp, 0, 0); 
1991/0119    
				nosendctl(cp, 0, 0); 
1991/0108    
			} 
			qunlock(cp); 
		} 
1991/0119/sys/src/9/port/devnonet.c:8,131991/0206/sys/src/9/port/devnonet.c:8,14 (short | long)
1990/1210    
 
1990/1229    
#define DPRINT if(pnonet)print 
1990/1210    
#define NOW (MACHP(0)->ticks*MS2HZ) 
1991/0206    
#define MSUCC(x) (((x)+1)%Nnomsg) 
1990/1210    
 
static Noifc *noifc; 
1990/1229    
int pnonet; 
1991/0119/sys/src/9/port/devnonet.c:501,5091991/0206/sys/src/9/port/devnonet.c:502,516
1990/1210    
	} 
 
1991/0108    
	qlock(cp); 
1991/0206    
	/* 
	 *  we give up, ack any unacked messages 
	 */ 
	for(i = cp->first; i != cp->next; i = MSUCC(i)) 
		norack(cp, cp->out[i].mid); 
1990/1210    
	cp->rcvcircuit = -1; 
	cp->state = Cclosed; 
1991/0108    
	qunlock(cp); 
1991/0206    
 
1990/1210    
	poperror(); 
} 
 
1991/0119/sys/src/9/port/devnonet.c:533,5481991/0206/sys/src/9/port/devnonet.c:540,547
1990/1210    
	Noconv *cp; 
 
	cp = (Noconv *)a; 
	return cp->out[cp->next].inuse == 0;	 
1991/0206    
	return MSUCC(cp->next) != cp->first;	 
1990/1210    
} 
static int 
acked(void *a) 
{ 
	Nomsg *mp; 
                 
	mp = (Nomsg *)a; 
1991/01151    
	return mp->inuse; 
1990/1210    
} 
static void 
1991/0119    
nooput(Queue *q, Block *bp) 
1990/1210    
{ 
1991/0119/sys/src/9/port/devnonet.c:570,6041991/0206/sys/src/9/port/devnonet.c:569,594
1990/1210    
		return; 
	} 
 
	mp = 0; 
1991/0206    
	/* 
	 *  block till we get an output buffer 
	 */ 
1990/1210    
	if(waserror()){ 
		if(mp){ 
1991/01151    
			q->len = 0; 
			q->first = q->last = 0; 
1990/1210    
			if(mp->first){ 
				freeb(mp->first); 
				mp->first = 0; 
			} 
			mp->inuse = 0; 
1991/01151    
			mp->acked = 0; 
			if(((cp->first+1)%Nnomsg) == cp->next) 
				cp->first = cp->next; 
1991/0109    
		} 
1991/0206    
		/* throw out the message */ 
		while(bp = getb(q)) 
			freeb(bp); 
1991/0109    
		qunlock(&cp->mlock); 
		nexterror(); 
1990/1210    
	} 
                 
	/* 
	 *  block till we get a buffer 
	 */ 
	while(cp->out[cp->next].inuse) 
1991/0206    
	while(!windowopen(cp)) 
1990/1210    
		sleep(&cp->r, windowopen, cp); 
	mp = &cp->out[cp->next]; 
	mp->inuse = 1; 
	cp->next = (cp->next+1)%Nnomsg; 
1991/0206    
	cp->next = MSUCC(cp->next); 
	qlock(cp); 
	qunlock(&cp->mlock); 
	poperror(); 
1990/1210    
 
	/* 
	 *  stick the message in a Nomsg structure 
1991/0206    
	 *  point the output buffer to the message 
1990/1210    
	 */ 
	mp->time = NOW + MSrexmit; 
	mp->first = q->first; 
1991/0119/sys/src/9/port/devnonet.c:608,6161991/0206/sys/src/9/port/devnonet.c:598,606
1990/1210    
	mp->acked = 0; 
 
	/* 
	 *  init the queue for new messages 
1991/0206    
	 *  take the message out of the queue 
1990/1210    
	 */ 
	q->len = 0; 
1991/0206    
	q->len = q->nb = 0; 
1990/1210    
	q->first = q->last = 0; 
	cp->sent++; 
 
1991/0119/sys/src/9/port/devnonet.c:617,6241991/0206/sys/src/9/port/devnonet.c:607,624
1990/1210    
	/* 
1991/01151    
	 *  send the message, the kproc will retry 
1990/1210    
	 */ 
1991/0206    
	if(waserror()){ 
		/* throw out the message */ 
		freeb(mp->first); 
		mp->first = 0; 
		mp->acked = 0; 
		if(MSUCC(cp->first) == cp->next) 
			cp->first = cp->next; 
		qunlock(cp); 
		nexterror(); 
	} 
1991/0119    
	nosend(cp, mp); 
1991/01151    
	qunlock(&cp->mlock); 
1991/0206    
	qunlock(cp); 
1991/0109    
	poperror(); 
1990/1210    
} 
 
1991/0119/sys/src/9/port/devnonet.c:661,6671991/0206/sys/src/9/port/devnonet.c:661,666
1990/1210    
		cp->out[i].mid = i | Nnomsg; 
		cp->out[i].acked = 1; 
		cp->out[i].rem = 0; 
		cp->out[i].inuse = 0; 
	} 
	cp->in[0].mid = Nnomsg; 
	cp->in[0].acked = 0; 
1991/0119/sys/src/9/port/devnonet.c:927,9371991/0206/sys/src/9/port/devnonet.c:926,935
1991/01151    
 	 *  free it 
1990/1210    
	 */ 
1991/01151    
	cp->rexmit = 0; 
1990/1210    
	mp->acked = 1; 
	cp->lastacked = mid; 
1991/0206    
	mp->acked = 1; 
1991/01151    
	freeb(mp->first); 
	mp->first = 0; 
	mp->inuse = 0; 
 
	/* 
	 *  advance first if this is the first 
1991/0119/sys/src/9/port/devnonet.c:940,9471991/0206/sys/src/9/port/devnonet.c:938,946
1991/01151    
		while(cp->first != cp->next){ 
			if(cp->out[cp->first].acked == 0) 
				break; 
			cp->first = (cp->first+1) % Nnomsg; 
1991/0206    
			cp->first = MSUCC(cp->first); 
1991/01151    
		} 
1991/0206    
		wakeup(&cp->r); 
1991/01151    
	} 
1990/1210    
} 
 
1991/0119/sys/src/9/port/devnonet.c:1403,14211991/0206/sys/src/9/port/devnonet.c:1402,1419
1991/01151    
			 *  resend the first message 
			 */ 
1991/0118    
			if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ 
1991/0206    
				mp = &(cp->out[cp->first]); 
1991/0118    
				if(cp->rexmit++ > 60){ 
1991/01151    
					print("hanging up\n"); 
1991/0206    
					norack(cp, mp->mid); 
1991/0119    
					nohangup(cp); 
1991/0118    
				} else { 
					mp = &(cp->out[cp->first]); 
1991/0206    
				} else 
1991/0119    
					nosend(cp, mp); 
1991/0118    
				} 
1991/01151    
			} 
 
			/* 
			 *  resend an acknowledge 
1991/0206    
			 *  get the acknowledges out 
1991/01151    
			 */ 
1991/0108    
			if(cp->afirst != cp->anext){ 
1991/0206    
			while(cp->afirst != cp->anext){ 
1991/0108    
				DPRINT("sending ack %d\n", cp->ack[cp->afirst]); 
1991/0119    
				nosendctl(cp, 0, 0); 
1991/0108    
			} 
1991/0206/sys/src/9/port/devnonet.c:538,5461991/0207/sys/src/9/port/devnonet.c:538,552 (short | long)
1990/1210    
windowopen(void *a) 
{ 
	Noconv *cp; 
1991/0207    
	int i; 
1990/1210    
 
	cp = (Noconv *)a; 
1991/0206    
	return MSUCC(cp->next) != cp->first;	 
1991/0207    
	i = cp->next - cp->first; 
	if(i>=0 && i<32)	 
		return 1; 
	if(i<0 && Nnomsg+i<32) 
		return 1; 
	return 0;	 
1990/1210    
} 
static void 
1991/0119    
nooput(Queue *q, Block *bp) 
1991/0206/sys/src/9/port/devnonet.c:1413,14191991/0207/sys/src/9/port/devnonet.c:1419,1425
1991/01151    
			/* 
1991/0206    
			 *  get the acknowledges out 
1991/01151    
			 */ 
1991/0206    
			while(cp->afirst != cp->anext){ 
1991/0207    
			while(cp->afirst!=cp->anext && cp->rq->next->len<16*1024){ 
1991/0108    
				DPRINT("sending ack %d\n", cp->ack[cp->afirst]); 
1991/0119    
				nosendctl(cp, 0, 0); 
1991/0108    
			} 
1991/0207/sys/src/9/port/devnonet.c:489,4951991/0209/sys/src/9/port/devnonet.c:489,495 (short | long)
1991/0119    
		 */ 
		nosendctl(cp, NO_HANGUP, 1); 
1990/1210    
		for(i=0; i<10 && !ishungup(cp); i++){ 
1991/0119    
			nosendctl(cp, NO_HANGUP, 1); 
1991/0209    
			nosendctl(cp, NO_HANGUP, 0); 
1990/1210    
			tsleep(&cp->r, ishungup, cp, MSrexmit); 
		} 
1991/0119    
		break; 
1991/0207/sys/src/9/port/devnonet.c:1009,10281991/0209/sys/src/9/port/devnonet.c:1009,1018
1990/1210    
	wq = ifc->wq->next; 
 
	/* 
1991/0102    
	 *  one transmitter at a time for this connection 
1990/1210    
	 */ 
	qlock(&cp->xlock); 
                 
	if(waserror()){ 
		qunlock(&cp->xlock); 
		return; 
	} 
                 
	/* 
	 *  get the next acknowledge to use if the next queue up 
	 *  is not full. 
	 */ 
	if(cp->afirst != cp->anext && cp->rq->next->len < 16*1024){ 
1991/0209    
	if(cp->afirst!=cp->anext && cp->rq->next->len<16*1024){ 
1990/1210    
		cp->hdr->ack = cp->ack[cp->afirst]; 
		cp->afirst = (cp->afirst+1)&Nmask; 
	} 
1991/0207/sys/src/9/port/devnonet.c:1103,11101991/0209/sys/src/9/port/devnonet.c:1093,1098
1991/0118    
	else 
		mp->time = NOW + (cp->rexmit+1)*MSrexmit; 
1990/1210    
	(*wq->put)(wq, pkt); 
	qunlock(&cp->xlock); 
	poperror(); 
} 
 
/* 
1991/0207/sys/src/9/port/devnonet.c:1409,14171991/0209/sys/src/9/port/devnonet.c:1397,1405
1991/01151    
			 */ 
1991/0118    
			if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ 
1991/0206    
				mp = &(cp->out[cp->first]); 
1991/0118    
				if(cp->rexmit++ > 60){ 
1991/0209    
				if(cp->rexmit++ > 15){ 
1991/0206    
					norack(cp, mp->mid); 
1991/0119    
					nohangup(cp); 
1991/0209    
					noreset(cp); 
1991/0206    
				} else 
1991/0119    
					nosend(cp, mp); 
1991/01151    
			} 
1991/0209/sys/src/9/port/devnonet.c:276,2821991/0316/sys/src/9/port/devnonet.c:276,282 (short | long)
1990/1210    
		line = STREAMID(c->qid.path); 
		ifc = &noifc[c->dev]; 
		if(ifc->conv[line].state != Cannounced) 
			error(Enoannounce); 
1991/0316    
			errors("channel not announced"); 
1991/0119    
		nolisten(c, ifc); 
1990/1210    
		break; 
	case Nraddrqid: 
1991/0316/sys/src/9/port/devnonet.c:976,9871991/0318/sys/src/9/port/devnonet.c:976,988 (short | long)
1990/1210    
	Nohdr *hp; 
 
	bp = allocb(cp->ifc->hsize + NO_HDRSIZE + cp->ifc->mintu); 
	memcpy(bp->wptr, cp->media->rptr, cp->ifc->hsize + NO_HDRSIZE); 
1991/0318    
	memmove(bp->wptr, cp->media->rptr, cp->ifc->hsize + NO_HDRSIZE); 
1990/1210    
	bp->wptr += cp->ifc->hsize + NO_HDRSIZE; 
	hp = (Nohdr *)(bp->rptr + cp->ifc->hsize); 
	hp->remain[1] = rem>>8; 
	hp->remain[0] = rem; 
	hp->sum[0] = hp->sum[1] = 0; 
1991/0318    
 
1990/1210    
	return bp; 
} 
 
1991/0316/sys/src/9/port/devnonet.c:1029,10351991/0318/sys/src/9/port/devnonet.c:1030,1036
1990/1210    
		 */ 
1991/0119    
		last = pkt = nohdr(cp, mp->len); 
1990/1210    
		for(bp = mp->first; bp; bp = bp->next){ 
			memcpy(pkt->wptr, bp->rptr, n = BLEN(bp)); 
1991/0318    
			memmove(pkt->wptr, bp->rptr, n = BLEN(bp)); 
1990/1210    
			pkt->wptr += n; 
		} 
1991/0118    
		/* 
1991/0316/sys/src/9/port/devnonet.c:1092,10971991/0318/sys/src/9/port/devnonet.c:1093,1099
1991/0118    
		mp->time = NOW + 10*MSrexmit; 
	else 
		mp->time = NOW + (cp->rexmit+1)*MSrexmit; 
1991/0318    
 
1990/1210    
	(*wq->put)(wq, pkt); 
} 
 
1991/0318/sys/src/9/port/devnonet.c:443,4541991/0320/sys/src/9/port/devnonet.c:443,449 (short | long)
1990/1210    
	RD(q)->ptr = WR(q)->ptr = (void *)cp; 
} 
 
/* 
 *  wait until a hangup is received. 
 *  then send a hangup message (until one is received). 
1991/0119    
 * 
 *	State Transitions:	* -> Cclosed 
1990/1210    
 */ 
1991/0320    
 
1990/1210    
static int 
ishungup(void *a) 
{ 
1991/0318/sys/src/9/port/devnonet.c:463,4681991/0320/sys/src/9/port/devnonet.c:458,469
1991/0119    
	} 
	return 0; 
1990/1210    
} 
1991/0320    
/* 
 *  wait until a hangup is received. 
 *  then send a hangup message (until one is received). 
 * 
 *	State Transitions:	* -> Cclosed 
 */ 
1990/1210    
static void 
1991/0119    
noclose(Queue *q) 
1990/1210    
{ 
1991/0318/sys/src/9/port/devnonet.c:1147,11531991/0320/sys/src/9/port/devnonet.c:1148,1154
1990/1210    
	 *  if a new call request comes in on a connected channel, hang up the call 
	 */ 
1991/0119    
	if((f&NO_NEWCALL) && cp->state==Cconnected){ 
1990/1229    
		DPRINT("new call on connected channel\n");  
1991/0320    
		print("new call on connected channel\n");  
1990/1210    
		freeb(bp); 
1991/0119    
		noreset(cp); 
1990/1210    
		return; 
1991/0320/sys/src/9/port/devnonet.c:5,101991/0328/sys/src/9/port/devnonet.c:5,11 (short | long)
1990/1210    
#include	"fns.h" 
#include	"io.h" 
#include	"errno.h" 
1991/0328    
#include	"../port/nonet.h" 
1990/1210    
 
1990/1229    
#define DPRINT if(pnonet)print 
1990/1210    
#define NOW (MACHP(0)->ticks*MS2HZ) 
1991/0320/sys/src/9/port/devnonet.c:510,5151991/0328/sys/src/9/port/devnonet.c:511,520
1991/0206    
		norack(cp, cp->out[i].mid); 
1990/1210    
	cp->rcvcircuit = -1; 
	cp->state = Cclosed; 
1991/0328    
	if(cp->media){ 
		freeb(cp->media); 
		cp->media = 0; 
	} 
1991/0108    
	qunlock(cp); 
1991/0206    
 
1990/1210    
	poperror(); 
1991/0320/sys/src/9/port/devnonet.c:885,8951991/0328/sys/src/9/port/devnonet.c:890,901
1990/1210    
} 
 
/* 
1991/0119    
 *  send a hangup signal up the stream to get all line disciplines 
 *  to cease and desist.  The Creset state makes any subsequent close not 
 *  send hangup messages. 
1991/0328    
 *  Send a hangup signal up the stream to get all line disciplines 
 *  to cease and desist.  Disassociate this conversation from a circuit 
 *  number.  Any subsequent close of the conversation will 
 *  not send hangup messages. 
1991/0119    
 * 
 *	State Transition:	{Cconnected, Cconnecting} -> Creset 
1991/0328    
 *	State Transition:	{Cconnected, Cconnecting, Chungup} -> Creset 
1991/0119    
 */ 
static void 
noreset(Noconv *cp) 
1991/0320/sys/src/9/port/devnonet.c:900,9071991/0328/sys/src/9/port/devnonet.c:906,916
1991/0119    
	switch(cp->state){ 
	case Cconnected: 
	case Cconnecting: 
1991/0328    
	case Chungup: 
		print("resetting connection\n"); 
1991/0119    
		cp->state = Creset; 
		bp = allocb(0); 
1991/0328    
		cp->rcvcircuit = -1; 
 		bp = allocb(0); 
1991/0119    
		bp->type = M_HANGUP; 
		q = cp->rq; 
		PUTNEXT(q, bp); 
1991/0320/sys/src/9/port/devnonet.c:1145,11601991/0328/sys/src/9/port/devnonet.c:1154,1202
1990/1210    
	f = h->flag; 
 
	/* 
	 *  if a new call request comes in on a connected channel, hang up the call 
1991/0328    
	 *  Obey reset even if the message id is bogus 
1990/1210    
	 */ 
1991/0119    
	if((f&NO_NEWCALL) && cp->state==Cconnected){ 
1991/0320    
		print("new call on connected channel\n");  
1990/1210    
		freeb(bp); 
1991/0328    
	if(f & NO_RESET){ 
		print("reset received\n"); 
1991/0119    
		noreset(cp); 
1991/0328    
		freeb(bp); 
1990/1210    
		return; 
	} 
 
	/* 
1991/0328    
	 *  A new call request (maybe), treat it as a reset if seen on a 
	 *  connected, hungup, or reset channel. 
	 * 
 	 *  On a connecting channel, treat as a reset if this is an 
	 *  invalid message ID. 
	 */ 
	if(f & NO_NEWCALL){ 
		switch(cp->state){ 
		case Cclosed: 
		case Copen: 
		case Cannounced: 
		case Creset: 
			panic("nonetrcvmsg %d %d\n", cp->rcvcircuit, cp - cp->ifc->conv); 
		case Chungup: 
		case Cconnected: 
			print("Nonet call on connected/hanging-up circ %d conv %d\n", 
				cp->rcvcircuit, cp - cp->ifc->conv);  
			freeb(bp); 
			noreset(cp); 
			return; 
		case Cconnecting: 
			if(h->mid != mp->mid){ 
				print("Nonet call on connecting circ %d conv %d\n", 
					cp->rcvcircuit, cp - cp->ifc->conv);  
				freeb(bp); 
				noreset(cp); 
				return; 
			} 
			break; 
		} 
	} 
 
	/* 
1990/1210    
	 *  ignore old messages and process the acknowledgement 
	 */ 
	if(h->mid != mp->mid){ 
1991/0320/sys/src/9/port/devnonet.c:1161,11691991/0328/sys/src/9/port/devnonet.c:1203,1209
1991/0108    
		DPRINT("old msg %d instead of %d r==%d\n", h->mid, mp->mid, r); 
1990/1210    
		if(r == 0){ 
1991/0119    
			norack(cp, h->ack); 
			if(f & NO_RESET) 
				noreset(cp); 
			else if(f & NO_HANGUP) 
1991/0328    
			if(f & NO_HANGUP) 
1991/0119    
				nohangup(cp); 
1990/1210    
		} else { 
1991/0102    
			if(r>0){ 
1991/0320/sys/src/9/port/devnonet.c:1243,12521991/0328/sys/src/9/port/devnonet.c:1283,1289
1991/0119    
		/* 
		 *  hangup (after processing message) 
		 */ 
		if(f & NO_RESET){ 
			DPRINT("reset with message\n"); 
			noreset(cp); 
		} else if(f & NO_HANGUP){ 
1991/0328    
		if(f & NO_HANGUP){ 
1991/0119    
			DPRINT("hangup with message\n"); 
			nohangup(cp); 
		} 
1991/0328/sys/src/9/port/devnonet.c:325,3311991/0411/sys/src/9/port/devnonet.c:325,331 (short | long)
1990/1210    
} 
 
long	  
nonetread(Chan *c, void *a, long n) 
1991/0411    
nonetread(Chan *c, void *a, long n, ulong offset) 
1990/1210    
{ 
	int t; 
	Noconv *cp; 
1991/0328/sys/src/9/port/devnonet.c:346,3661991/0411/sys/src/9/port/devnonet.c:346,366
1990/1210    
	cp = &noifc[c->dev].conv[STREAMID(c->qid.path)]; 
	switch(t){ 
	case Nraddrqid: 
		return stringread(c, a, n, cp->raddr); 
1991/0411    
		return stringread(c, a, n, cp->raddr, offset); 
1990/1210    
	case Naddrqid: 
		return stringread(c, a, n, cp->addr); 
1991/0411    
		return stringread(c, a, n, cp->addr, offset); 
1990/1210    
	case Nruserqid: 
		return stringread(c, a, n, cp->ruser); 
1991/0411    
		return stringread(c, a, n, cp->ruser, offset); 
1990/1210    
	case Nstatsqid: 
		sprint(stats, "sent: %d\nrcved: %d\nrexmit: %d\nbad: %d\n", 
			cp->sent, cp->rcvd, cp->rexmit, cp->bad); 
		return stringread(c, a, n, stats); 
1991/0411    
		return stringread(c, a, n, stats, offset); 
1990/1210    
	} 
	error(Eperm); 
} 
 
long	  
nonetwrite(Chan *c, void *a, long n) 
1991/0411    
nonetwrite(Chan *c, void *a, long n, ulong offset) 
1990/1210    
{ 
	int t; 
	int m; 
1991/0411/sys/src/9/port/devnonet.c:208,2141991/0412/sys/src/9/port/devnonet.c:208,214 (short | long)
1990/1210    
	if(c->qid.path == CHDIR) 
		devstat(c, dp, nonetdir, conf.nnoconv+1, devgen); 
	else if(c->qid.path == Ncloneqid) 
		devstat(c, dp, nonetdir, 1, devgen); 
1991/0412    
		devstat(c, dp, &nonetdir[conf.nnoconv], 1, devgen); 
1990/1210    
	else 
		devstat(c, dp, nosubdir, Nsubdir, streamgen); 
} 
1991/0412/sys/src/9/port/devnonet.c:82,941991/0413/sys/src/9/port/devnonet.c:82,94 (short | long)
1990/1210    
 *  Nonet conversation states (for Noconv.state) 
 */ 
enum { 
	Cclosed, 
	Copen, 
	Cannounced, 
	Cconnected, 
	Cconnecting, 
	Chungup, 
1991/0119    
	Creset, 
1991/0413    
	Cclosed=	0, 
	Copen=		1, 
	Cannounced=	2, 
	Cconnected=	3, 
	Cconnecting=	4, 
	Chungup=	5, 
	Creset=		6, 
1990/1210    
}; 
 
/* 
1991/0412/sys/src/9/port/devnonet.c:680,6851991/0413/sys/src/9/port/devnonet.c:680,686
1990/1210    
	cp->out[0].mid = 0; 
	cp->out[0].acked = 1; 
	cp->out[0].rem = 0; 
1991/0413    
	cp->afirst = cp->anext = 0; 
1990/1210    
	cp->first = cp->next = 1; 
1991/0119    
	cp->rexmit = cp->bad = cp->sent = cp->rcvd = 0; 
	cp->lastacked = Nnomsg|(Nnomsg-1); 
1991/0412/sys/src/9/port/devnonet.c:1425,14331991/0413/sys/src/9/port/devnonet.c:1426,1434
1991/01151    
		 */ 
1991/0108    
		ep = ifc->conv + conf.nnoconv; 
		for(cp = ifc->conv; cp < ep; cp++){ 
			if(cp->state==Cclosed || !canqlock(cp)) 
1991/0413    
			if(cp->state<=Copen || !canqlock(cp)) 
1991/0108    
				continue; 
1991/01151    
			if(cp->state == Cclosed){ 
1991/0413    
			if(cp->state <= Copen){ 
1991/01151    
				qunlock(cp); 
				continue; 
			} 
1991/0413/sys/src/9/port/devnonet.c:202,2071991/0419/sys/src/9/port/devnonet.c:202,213 (short | long)
1990/1210    
		return devwalk(c, name, nosubdir, Nsubdir, streamgen); 
} 
 
1991/0419    
Chan* 
nonetclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
 
1990/1210    
void	  
nonetstat(Chan *c, char *dp) 
{ 
1991/0419/sys/src/9/port/devnonet.c:202,2131991/0427/sys/src/9/port/devnonet.c:202,207 (short | long)
1990/1210    
		return devwalk(c, name, nosubdir, Nsubdir, streamgen); 
} 
 
1991/0419    
Chan* 
nonetclwalk(Chan *c, char *name) 
{ 
	return devclwalk(c, name); 
} 
                 
1990/1210    
void	  
nonetstat(Chan *c, char *dp) 
{ 
1991/0427/sys/src/9/port/devnonet.c:540,5451991/0502/sys/src/9/port/devnonet.c:540,549 (short | long)
1990/1210    
/* 
 *  queue a block 
 */ 
1991/0502    
enum { 
	Window=	1, 
}; 
 
1990/1210    
static int 
windowopen(void *a) 
{ 
1991/0427/sys/src/9/port/devnonet.c:548,5561991/0502/sys/src/9/port/devnonet.c:552,560
1990/1210    
 
	cp = (Noconv *)a; 
1991/0207    
	i = cp->next - cp->first; 
	if(i>=0 && i<32)	 
1991/0502    
	if(i>=0 && i<Window)	 
1991/0207    
		return 1; 
	if(i<0 && Nnomsg+i<32) 
1991/0502    
	if(i<0 && Nnomsg+i<Window) 
1991/0207    
		return 1; 
	return 0;	 
1990/1210    
} 
1991/0427/sys/src/9/port/devnonet.c:1355,13601991/0502/sys/src/9/port/devnonet.c:1359,1365
1990/1210    
	int n; 
	ulong s; 
	Nohdr *hp; 
1991/0502    
	Block *first; 
1990/1210    
 
	s = 0; 
	p = bp->rptr + offset; 
1991/0427/sys/src/9/port/devnonet.c:1390,13961991/0502/sys/src/9/port/devnonet.c:1395,1414
1990/1210    
	s = (s&0xffff) + (s>>16); 
	hp->sum[1] = s>>8; 
	hp->sum[0] = s; 
	return s & 0xffff; 
1991/0502    
	s &= 0xffff; 
	switch(s){ 
	case 0xac9f: 
	case 0xc1a4: 
	case 0xc41c: 
	case 0xc46d: 
		{ int i; 
		print("%lux s,", s); 
		for(bp = first; bp; bp = bp->next) 
			for(i = 0; i < BLEN(bp); i++) 
				print(" %ux", bp->rptr[i]); 
		} 
	} 
	return s; 
1990/1229    
} 
 
1991/0108    
/* 
1991/0502/sys/src/9/port/devnonet.c:1396,14011991/0503/sys/src/9/port/devnonet.c:1396,1402 (short | long)
1990/1210    
	hp->sum[1] = s>>8; 
	hp->sum[0] = s; 
1991/0502    
	s &= 0xffff; 
1991/0503    
if(0) 
1991/0502    
	switch(s){ 
	case 0xac9f: 
	case 0xc1a4: 
1991/0503/sys/src/9/port/devnonet.c:1457,14661991/0604/sys/src/9/port/devnonet.c:1457,1466 (short | long)
1991/01151    
			 */ 
1991/0118    
			if(cp->first!=cp->next && NOW>=cp->out[cp->first].time){ 
1991/0206    
				mp = &(cp->out[cp->first]); 
1991/0209    
				if(cp->rexmit++ > 15){ 
1991/0604    
/*				if(cp->rexmit++ > 15){ 
1991/0206    
					norack(cp, mp->mid); 
1991/0209    
					noreset(cp); 
1991/0206    
				} else 
1991/0604    
				} else /**/ 
1991/0119    
					nosend(cp, mp); 
1991/01151    
			} 
 
Too many diffs (26 > 25). Stopping.


source code copyright © 1990-2005 Lucent Technologies; see license
Plan 9 distribution
comments to russ cox (rsc@swtch.com)