1 /*	nsp_output.c	1.5	82/12/18	*/
2 
3 #include "../h/param.h"
4 #include "../h/systm.h"
5 #include "../h/mbuf.h"
6 #include "../h/protosw.h"
7 #include "../h/socket.h"
8 #include "../h/socketvar.h"
9 #include "../netdecnet/dn_systm.h"
10 #include "../netdecnet/nsp.h"
11 #include "../netdecnet/nsp_var.h"
12 #include <errno.h>
13 
14 /*
15  * NSP output routine: figure out what should be sent and send it.
16  */
17 nsp_output(np)
18 	register struct nspcb *np;
19 {
20 	register struct socket *so = np->n_socket;
21 	register int len;
22 	int off, flags;
23 	register struct mbuf *m;
24 
25 
26 	/*
27 	 * Determine what type of message to send and send it.
28 	 */
29 top:
30 	/* interrupt to be sent? */
31 	if (np->n_flags & NF_INTAVAIL) && np->nf_remint > 0 &&
32 	    (np->n_flags & NF_OTHSENT) == 0) {
33 		register struct nspi *n;
34 
35 		m = m_get(M_CANTWAIT, MT_HEADER);
36 		if (m == 0)
37 			return (0);
38 		if (np->nb_xmt)
39 			len = np->nb_xmt->m_len;
40 		else
41 			len = 0;
42 		m->m_len = sizeof (struct nspi) + len;
43 		m->m_off = MMAXOFF - m->m_len;
44 		n = mtod(m, struct nspi *);
45 		n->nsp_msgflg = NSP_INTR;
46 		n->nsp_dstaddr = np->n_rem;
47 		n->nsp_srcaddr = np->n_loc;
48 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
49 		n->nsp_segnum = np->nn_oth;
50 		if (len)
51 			bcopy((char *)(n + 1), mtod(np->nb_xmt, char *), len);
52 		if (tp_output(m, np->n_node)) {
53 			(void) m_free(m);
54 			return (0);
55 		}
56 		np->n_flags &= ~(NF_INTAVAIL|NF_OTHACK);
57 		np->n_flags |= NF_OTHSENT;
58 		if (len)
59 			(void) m_free(np->nb_xmt);
60 		nsp_insrtq(m, np->nt_oth);
61 		goto top;
62 	}
63 
64 	/* interrupt request to be sent? */
65 	if (np->nf_locint == NFL_SEND && (np->n_flags & NF_OTHSENT) == 0) {
66 		register struct nspls *n;
67 
68 		m = m_get(M_CANTWAIT, MT_HEADER);
69 		if (m == 0)
70 			return (0);
71 		m->m_len = sizeof (struct nspls);
72 		m->m_off = MMAXOFF - m->m_len;
73 		n = mtod(m, struct nspls *);
74 		n->nsp_msgflg = NSP_LS;
75 		n->nsp_dstaddr = np->n_rem;
76 		n->nsp_srcaddr = np->n_loc;
77 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
78 		n->nsp_segnum = np->nn_oth;
79 		n->nsp_lsflags = NSPLS_INTREQ | NSPLS_ON;
80 		n->nsp_fcval = 1;
81 		if (tp_output(m, np->n_node)) {
82 			(void) m_free(m);
83 			return (0);
84 		}
85 		np->n_flags &= ~NF_OTHACK;
86 		np->n_flags |= NF_OTHSENT;
87 		nsp_insrtq(m, np->nt_oth);
88 		goto top;
89 	}
90 
91 	/* data request to be sent? */
92 	if (np->nf_locdat > 0 && (np->n_flags & NF_OTHSENT == 0)) {
93 		register struct nspls *n;
94 
95 		m = m_get(M_CANTWAIT, MT_HEADER);
96 		if (m == 0)
97 			return (0);
98 		m->m_len = sizeof (struct nspls);
99 		m->m_off = MMAXOFF - m->m_len;
100 		n = mtod(m, struct nspls *);
101 		n->nsp_msgflg = NSP_LS;
102 		n->nsp_dstaddr = np->n_rem;
103 		n->nsp_srcaddr = np->n_loc;
104 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
105 		n->nsp_segnum = np->nn_oth;
106 		n->nsp_lsflags = NSPLS_DATREQ | NSPLS_ON;
107 		n->nsp_fcval = np->nf_locdat;
108 		if (tp_output(m, np->n_node)) {
109 			(void) m_free(m);
110 			return (0);
111 		}
112 		np->n_flags &= ~NF_OTHACK;
113 		np->n_flags |= NF_OTHSENT;
114 		nsp_insrtq(m, np->nt_oth);
115 		goto top;
116 	}
117 
118 	/* other data ack to be sent? */
119 	if (np->n_flags & NF_OTHACK) {
120 		register struct nspack *n;
121 
122 		m = m_get(M_CANTWAIT, MT_HEADER);
123 		if (m == 0)
124 			return (0);
125 		m->m_len = sizeof (struct nspack);
126 		m->m_off = MMAXOFF - m->m_len;
127 		n = mtod(m, struct nspack *);
128 		n->nsp_msgflg = NSP_OTHACK;
129 		n->nsp_dstaddr = np->n_rem;
130 		n->nsp_srcaddr = np->n_loc;
131 		n->nsp_acknum = NSPA_ACK | np->na_xmtoth;
132 		if (tp_output(m, np->n_node)) {
133 			(void) m_free(m);
134 			return (0);
135 		}
136 		np->n_flags &= ~NF_OTHACK;
137 		(void) m_free(m);
138 		goto top;
139 	}
140 
141 	/* data to be sent? */
142 	if () {
143 		register struct nspd *n;
144 
145 		m = nsp_mgetcl();
146 		if (m == 0)
147 			return (0);
148 		if (len <= np->n_segsize) {
149 			m->m_next = so->so_snd.sb_mb;
150 			so->so_snd.sb_mb = m->m_next->m_act;
151 		}
152 
153 		/* MORE */
154 
155 	}
156 
157 	/* data ack to be sent? */
158 	if (np->n_flags & NF_DATACK) {
159 		register struct nspack *n;
160 
161 		m = m_get(M_CANTWAIT, MT_HEADER);
162 		if (m == 0)
163 			return (0);
164 		m->m_len = sizeof (struct nspack);
165 		m->m_off = MMAXOFF - m->m_len;
166 		n = mtod(m, struct nspack *);
167 		n->nsp_msgflg = NSP_DATACK;
168 		n->nsp_dstaddr = np->n_rem;
169 		n->nsp_srcaddr = np->n_loc;
170 		n->nsp_acknum = NSPA_ACK | np->na_xmtdat;
171 		if (tp_output(m, np->n_node)) {
172 			(void) m_free(m);
173 			return (0);
174 		}
175 		np->n_flags &= ~NF_DATACK;
176 		(void) m_free(m);
177 		goto top;
178 	}
179 
180 	/*
181 	 * Nothing left to do, return success.
182 	 */
183 	return (1);
184 }
185