first pass for new make
[unix-history] / usr / src / sys / netccitt / pk_output.c
CommitLineData
0164bb81
KS
1/* Copyright (c) University of British Columbia, 1984 */
2
3#include "../h/param.h"
4#include "../h/systm.h"
5#include "../h/mbuf.h"
6#include "../h/socket.h"
7#include "../h/socketvar.h"
8#include "../h/protosw.h"
9#include "../h/errno.h"
10
11#include "../net/if.h"
12
13#include "../netccitt/pk.h"
14#include "../netccitt/pk_var.h"
15#include "../netccitt/x25.h"
16
17struct mbuf *nextpk ();
18
19pk_output (lcp)
20register struct pklcd *lcp;
21{
22 register struct x25_packet *xp;
23 register struct mbuf *m;
24 register struct pkcb *pkp = lcp -> lcd_pkp;
25
26 if (lcp == 0 || pkp == 0) {
27 printf ("pk_output: zero arg\n");
28 return;
29 }
30
31 while ((m = nextpk (lcp)) != NULL) {
32 xp = mtod (m, struct x25_packet *);
33
34 switch (pk_decode (xp) + lcp -> lcd_state) {
35 /*
36 * All the work is already done - just set the state and
37 * pass to peer.
38 */
39 case CALL + READY:
40 lcp -> lcd_state = SENT_CALL;
41 lcp -> lcd_timer = pk_t21;
42 break;
43
44 /*
45 * Just set the state to allow packet to flow and send the
46 * confirmation.
47 */
48 case CALL_ACCEPTED + RECEIVED_CALL:
49 lcp -> lcd_state = DATA_TRANSFER;
50 break;
51
52 /*
53 * Just set the state. Keep the LCD around till the clear
54 * confirmation is returned.
55 */
56 case CLEAR + RECEIVED_CALL:
57 case CLEAR + SENT_CALL:
58 case CLEAR + DATA_TRANSFER:
59 lcp -> lcd_state = SENT_CLEAR;
60 lcp -> lcd_retry = 0;
61 /* fall through */
62
63 case CLEAR + SENT_CLEAR:
64 lcp -> lcd_timer = pk_t23;
65 lcp -> lcd_retry++;
66 break;
67
68 case CLEAR_CONF + RECEIVED_CLEAR:
69 case CLEAR_CONF + SENT_CLEAR:
70 case CLEAR_CONF + READY:
71 lcp -> lcd_state = READY;
72 break;
73
74 case DATA + DATA_TRANSFER:
75 PS(xp) = lcp -> lcd_ssn;
76 PR(xp) = lcp -> lcd_input_window;
77 lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
78 lcp -> lcd_ssn = (lcp -> lcd_ssn + 1) % MODULUS;
79 if (lcp -> lcd_ssn == ((lcp -> lcd_output_window + pkp->pk_xcp->xc_pwsize) % MODULUS))
80 lcp -> lcd_window_condition = TRUE;
81 break;
82
83 case INTERRUPT + DATA_TRANSFER:
84 xp -> packet_data = 0;
85 lcp -> lcd_intrconf_pending = TRUE;
86 break;
87
88 case INTERRUPT_CONF + DATA_TRANSFER:
89 break;
90
91 case RR + DATA_TRANSFER:
92 lcp -> lcd_input_window = (lcp -> lcd_input_window + 1) % MODULUS;
93 PR(xp) = lcp -> lcd_input_window;
94 lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
95 break;
96
97 case RNR + DATA_TRANSFER:
98 PR(xp) = lcp -> lcd_input_window;
99 lcp -> lcd_last_transmitted_pr = lcp -> lcd_input_window;
100 break;
101
102 case RESET + DATA_TRANSFER:
103 lcp -> lcd_reset_condition = TRUE;
104 break;
105
106 case RESET_CONF + DATA_TRANSFER:
107 lcp -> lcd_reset_condition = FALSE;
108 break;
109
110 /*
111 * A restart should be only generated internally. Therefore
112 * all logic for restart is in the pk_restart routine.
113 */
114 case RESTART + READY:
115 lcp -> lcd_timer = pk_t20;
116 break;
117
118 /*
119 * Restarts are all handled internally. Therefore all the
120 * logic for the incoming restart packet is handled in the
121 * pk_input routine.
122 */
123 case RESTART_CONF + READY:
124 break;
125
126 default:
127 m_freem (m);
128 return;
129 }
130
131 /* Trace the packet. */
132 pk_trace (pkp -> pk_xcp, xp, "P-Out");
133
134 /* Pass the packet on down to the link layer */
135 (*pkp -> pk_output) (m, pkp -> pk_xcp);
136 }
137}
138
139/*
140 * This procedure returns the next packet to send or null. A
141 * packet is composed of one or more mbufs.
142 */
143
144struct mbuf *
145nextpk (lcp)
146struct pklcd *lcp;
147{
148 register struct socket *so = lcp -> lcd_so;
149 register struct mbuf *m = 0, *n;
150
151 if (lcp -> lcd_template) {
152 m = dtom (lcp -> lcd_template);
153 lcp -> lcd_template = NULL;
154 } else {
155 if (lcp -> lcd_rnr_condition || lcp -> lcd_window_condition ||
156 lcp -> lcd_reset_condition)
157 return (NULL);
158
159 if (so == 0)
160 return (NULL);
161
162 if ((m = so -> so_snd.sb_mb) == 0)
163 return (NULL);
164
165 n = m;
166 while (n) {
167 sbfree (&so -> so_snd, n);
168#ifndef BSD4_3
169 if ((int) n -> m_act == 1)
170 break;
171#endif
172 n = n -> m_next;
173 }
174
175#ifdef BSD4_3
176 so->so_snd.sb_mb = m->m_act;
177 m->m_act = 0;
178#else
179 if (n) {
180 so -> so_snd.sb_mb = n -> m_next;
181 n -> m_next = 0;
182 }
183#endif
184 }
185
186 return (m);
187}