1*9833Ssam /*	nsp_output.c	1.5	82/12/18	*/
26827Ssam 
36827Ssam #include "../h/param.h"
46827Ssam #include "../h/systm.h"
56827Ssam #include "../h/mbuf.h"
66827Ssam #include "../h/protosw.h"
76827Ssam #include "../h/socket.h"
86827Ssam #include "../h/socketvar.h"
98408Swnj #include "../netdecnet/dn_systm.h"
108408Swnj #include "../netdecnet/nsp.h"
118408Swnj #include "../netdecnet/nsp_var.h"
128408Swnj #include <errno.h>
136827Ssam 
146827Ssam /*
156827Ssam  * NSP output routine: figure out what should be sent and send it.
166827Ssam  */
nsp_output(np)176827Ssam nsp_output(np)
186827Ssam 	register struct nspcb *np;
196827Ssam {
206827Ssam 	register struct socket *so = np->n_socket;
216827Ssam 	register int len;
226827Ssam 	int off, flags;
236827Ssam 	register struct mbuf *m;
246827Ssam 
256827Ssam 
266827Ssam 	/*
276827Ssam 	 * Determine what type of message to send and send it.
286827Ssam 	 */
296827Ssam top:
306827Ssam 	/* interrupt to be sent? */
316827Ssam 	if (np->n_flags & NF_INTAVAIL) && np->nf_remint > 0 &&
326827Ssam 	    (np->n_flags & NF_OTHSENT) == 0) {
336827Ssam 		register struct nspi *n;
346827Ssam 
35*9833Ssam 		m = m_get(M_CANTWAIT, MT_HEADER);
366827Ssam 		if (m == 0)
376827Ssam 			return (0);
386827Ssam 		if (np->nb_xmt)
396827Ssam 			len = np->nb_xmt->m_len;
406827Ssam 		else
416827Ssam 			len = 0;
426827Ssam 		m->m_len = sizeof (struct nspi) + len;
436827Ssam 		m->m_off = MMAXOFF - m->m_len;
446827Ssam 		n = mtod(m, struct nspi *);
456827Ssam 		n->nsp_msgflg = NSP_INTR;
466827Ssam 		n->nsp_dstaddr = np->n_rem;
476827Ssam 		n->nsp_srcaddr = np->n_loc;
486827Ssam 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
496827Ssam 		n->nsp_segnum = np->nn_oth;
506827Ssam 		if (len)
516827Ssam 			bcopy((char *)(n + 1), mtod(np->nb_xmt, char *), len);
526827Ssam 		if (tp_output(m, np->n_node)) {
538774Sroot 			(void) m_free(m);
546827Ssam 			return (0);
556827Ssam 		}
566827Ssam 		np->n_flags &= ~(NF_INTAVAIL|NF_OTHACK);
576827Ssam 		np->n_flags |= NF_OTHSENT;
586827Ssam 		if (len)
598774Sroot 			(void) m_free(np->nb_xmt);
606827Ssam 		nsp_insrtq(m, np->nt_oth);
616827Ssam 		goto top;
626827Ssam 	}
636827Ssam 
646827Ssam 	/* interrupt request to be sent? */
656827Ssam 	if (np->nf_locint == NFL_SEND && (np->n_flags & NF_OTHSENT) == 0) {
666827Ssam 		register struct nspls *n;
676827Ssam 
68*9833Ssam 		m = m_get(M_CANTWAIT, MT_HEADER);
696827Ssam 		if (m == 0)
706827Ssam 			return (0);
716827Ssam 		m->m_len = sizeof (struct nspls);
726827Ssam 		m->m_off = MMAXOFF - m->m_len;
736827Ssam 		n = mtod(m, struct nspls *);
746827Ssam 		n->nsp_msgflg = NSP_LS;
756827Ssam 		n->nsp_dstaddr = np->n_rem;
766827Ssam 		n->nsp_srcaddr = np->n_loc;
776827Ssam 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
786827Ssam 		n->nsp_segnum = np->nn_oth;
796827Ssam 		n->nsp_lsflags = NSPLS_INTREQ | NSPLS_ON;
806827Ssam 		n->nsp_fcval = 1;
816827Ssam 		if (tp_output(m, np->n_node)) {
828774Sroot 			(void) m_free(m);
836827Ssam 			return (0);
846827Ssam 		}
856827Ssam 		np->n_flags &= ~NF_OTHACK;
866827Ssam 		np->n_flags |= NF_OTHSENT;
876827Ssam 		nsp_insrtq(m, np->nt_oth);
886827Ssam 		goto top;
896827Ssam 	}
906827Ssam 
916827Ssam 	/* data request to be sent? */
926827Ssam 	if (np->nf_locdat > 0 && (np->n_flags & NF_OTHSENT == 0)) {
936827Ssam 		register struct nspls *n;
946827Ssam 
95*9833Ssam 		m = m_get(M_CANTWAIT, MT_HEADER);
966827Ssam 		if (m == 0)
976827Ssam 			return (0);
986827Ssam 		m->m_len = sizeof (struct nspls);
996827Ssam 		m->m_off = MMAXOFF - m->m_len;
1006827Ssam 		n = mtod(m, struct nspls *);
1016827Ssam 		n->nsp_msgflg = NSP_LS;
1026827Ssam 		n->nsp_dstaddr = np->n_rem;
1036827Ssam 		n->nsp_srcaddr = np->n_loc;
1046827Ssam 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
1056827Ssam 		n->nsp_segnum = np->nn_oth;
1066827Ssam 		n->nsp_lsflags = NSPLS_DATREQ | NSPLS_ON;
1076827Ssam 		n->nsp_fcval = np->nf_locdat;
1086827Ssam 		if (tp_output(m, np->n_node)) {
1098774Sroot 			(void) m_free(m);
1106827Ssam 			return (0);
1116827Ssam 		}
1126827Ssam 		np->n_flags &= ~NF_OTHACK;
1136827Ssam 		np->n_flags |= NF_OTHSENT;
1146827Ssam 		nsp_insrtq(m, np->nt_oth);
1156827Ssam 		goto top;
1166827Ssam 	}
1176827Ssam 
1186827Ssam 	/* other data ack to be sent? */
1196827Ssam 	if (np->n_flags & NF_OTHACK) {
1206827Ssam 		register struct nspack *n;
1216827Ssam 
122*9833Ssam 		m = m_get(M_CANTWAIT, MT_HEADER);
1236827Ssam 		if (m == 0)
1246827Ssam 			return (0);
1256827Ssam 		m->m_len = sizeof (struct nspack);
1266827Ssam 		m->m_off = MMAXOFF - m->m_len;
1276827Ssam 		n = mtod(m, struct nspack *);
1286827Ssam 		n->nsp_msgflg = NSP_OTHACK;
1296827Ssam 		n->nsp_dstaddr = np->n_rem;
1306827Ssam 		n->nsp_srcaddr = np->n_loc;
1316827Ssam 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
1326827Ssam 		if (tp_output(m, np->n_node)) {
1338774Sroot 			(void) m_free(m);
1346827Ssam 			return (0);
1356827Ssam 		}
1366827Ssam 		np->n_flags &= ~NF_OTHACK;
1378774Sroot 		(void) m_free(m);
1386827Ssam 		goto top;
1396827Ssam 	}
1406827Ssam 
1416827Ssam 	/* data to be sent? */
1426827Ssam 	if () {
1436827Ssam 		register struct nspd *n;
1446827Ssam 
1456827Ssam 		m = nsp_mgetcl();
1466827Ssam 		if (m == 0)
1476827Ssam 			return (0);
1486827Ssam 		if (len <= np->n_segsize) {
1496827Ssam 			m->m_next = so->so_snd.sb_mb;
1506827Ssam 			so->so_snd.sb_mb = m->m_next->m_act;
1516827Ssam 		}
1526827Ssam 
1536827Ssam 		/* MORE */
1546827Ssam 
1556827Ssam 	}
1566827Ssam 
1576827Ssam 	/* data ack to be sent? */
1586827Ssam 	if (np->n_flags & NF_DATACK) {
1596827Ssam 		register struct nspack *n;
1606827Ssam 
161*9833Ssam 		m = m_get(M_CANTWAIT, MT_HEADER);
1626827Ssam 		if (m == 0)
1636827Ssam 			return (0);
1646827Ssam 		m->m_len = sizeof (struct nspack);
1656827Ssam 		m->m_off = MMAXOFF - m->m_len;
1666827Ssam 		n = mtod(m, struct nspack *);
1676827Ssam 		n->nsp_msgflg = NSP_DATACK;
1686827Ssam 		n->nsp_dstaddr = np->n_rem;
1696827Ssam 		n->nsp_srcaddr = np->n_loc;
1706827Ssam 		n->nsp_acknum = NSPA_ACK | np->na_xmtdat;
1716827Ssam 		if (tp_output(m, np->n_node)) {
1728774Sroot 			(void) m_free(m);
1736827Ssam 			return (0);
1746827Ssam 		}
1756827Ssam 		np->n_flags &= ~NF_DATACK;
1768774Sroot 		(void) m_free(m);
1776827Ssam 		goto top;
1786827Ssam 	}
1796827Ssam 
1806827Ssam 	/*
1816827Ssam 	 * Nothing left to do, return success.
1826827Ssam 	 */
1836827Ssam 	return (1);
1846827Ssam }
185