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 */
nsp_output(np)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