|
|
1.1 root 1: /*
2: * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * Portions Copyright (c) 1999 Apple Computer, Inc. All Rights
7: * Reserved. This file contains Original Code and/or Modifications of
8: * Original Code as defined in and that are subject to the Apple Public
9: * Source License Version 1.1 (the "License"). You may not use this file
10: * except in compliance with the License. Please obtain a copy of the
11: * License at http://www.apple.com/publicsource and read it before using
12: * this file.
13: *
14: * The Original Code and all software distributed under the License are
15: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
16: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
17: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
18: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
19: * License for the specific language governing rights and limitations
20: * under the License.
21: *
22: * @APPLE_LICENSE_HEADER_END@
23: */
24:
25: /*
26: * Copyright (c) University of British Columbia, 1984
27: * Copyright (c) 1990, 1993
28: * The Regents of the University of California. All rights reserved.
29: *
30: * This code is derived from software contributed to Berkeley by
31: * the Laboratory for Computation Vision and the Computer Science Department
32: * of the University of British Columbia.
33: *
34: * Redistribution and use in source and binary forms, with or without
35: * modification, are permitted provided that the following conditions
36: * are met:
37: * 1. Redistributions of source code must retain the above copyright
38: * notice, this list of conditions and the following disclaimer.
39: * 2. Redistributions in binary form must reproduce the above copyright
40: * notice, this list of conditions and the following disclaimer in the
41: * documentation and/or other materials provided with the distribution.
42: * 3. All advertising materials mentioning features or use of this software
43: * must display the following acknowledgement:
44: * This product includes software developed by the University of
45: * California, Berkeley and its contributors.
46: * 4. Neither the name of the University nor the names of its contributors
47: * may be used to endorse or promote products derived from this software
48: * without specific prior written permission.
49: *
50: * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
51: * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
52: * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
53: * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
54: * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
55: * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
56: * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
57: * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
58: * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
59: * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
60: * SUCH DAMAGE.
61: *
62: * @(#)hd_output.c 8.1 (Berkeley) 6/10/93
63: */
64:
65: #include <sys/param.h>
66: #include <sys/systm.h>
67: #include <sys/mbuf.h>
68: #include <sys/domain.h>
69: #include <sys/socket.h>
70: #include <sys/syslog.h>
71: #include <sys/protosw.h>
72: #include <sys/errno.h>
73: #include <sys/time.h>
74: #include <sys/kernel.h>
75:
76: #include <net/if.h>
77:
78: #include <netccitt/hdlc.h>
79: #include <netccitt/hd_var.h>
80: #include <netccitt/x25.h>
81:
82: /*
83: * HDLC OUTPUT INTERFACE
84: *
85: * This routine is called when the X.25 packet layer output routine
86: * has a information frame (iframe) to write. It is also called
87: * by the input and control routines of the HDLC layer.
88: */
89:
90: hd_output (hdp, m0)
91: register struct hdcb *hdp;
92: struct mbuf *m0;
93: {
94: struct x25config *xcp;
95: register struct mbuf *m = m0;
96: int len;
97:
98: if (m == NULL)
99: panic ("hd_output");
100: if ((m->m_flags & M_PKTHDR) == 0)
101: panic ("hd_output 2");
102:
103: if (hdp->hd_state != ABM) {
104: m_freem (m);
105: return;
106: }
107:
108: /*
109: * Make room for the hdlc header either by prepending
110: * another mbuf, or by adjusting the offset and length
111: * of the first mbuf in the mbuf chain.
112: */
113:
114: M_PREPEND(m, HDHEADERLN, M_DONTWAIT);
115: if (m == NULL)
116: return;
117: for (len = 0; m; m = m->m_next)
118: len += m->m_len;
119: m = m0;
120: m->m_pkthdr.len = len;
121:
122: hd_append (&hdp->hd_txq, m);
123: hd_start (hdp);
124: }
125:
126: hd_start (hdp)
127: register struct hdcb *hdp;
128: {
129: register struct mbuf *m;
130:
131: /*
132: * The iframe is only transmitted if all these conditions are FALSE.
133: * The iframe remains queued (hdp->hd_txq) however and will be
134: * transmitted as soon as these conditions are cleared.
135: */
136:
137: while (!(hdp->hd_condition & (TIMER_RECOVERY_CONDITION | REMOTE_RNR_CONDITION | REJ_CONDITION))) {
138: if (hdp->hd_vs == (hdp->hd_lastrxnr + hdp->hd_xcp->xc_lwsize) % MODULUS) {
139:
140: /* We have now exceeded the maximum number of
141: outstanding iframes. Therefore, we must wait
142: until at least one is acknowledged if this
143: condition is not turned off before we are
144: requested to write another iframe. */
145: hdp->hd_window_condition++;
146: break;
147: }
148:
149: /* hd_remove top iframe from transmit queue. */
150: if ((m = hd_remove (&hdp->hd_txq)) == NULL)
151: break;
152:
153: hd_send_iframe (hdp, m, POLLOFF);
154: }
155: }
156:
157: /*
158: * This procedure is passed a buffer descriptor for an iframe. It builds
159: * the rest of the control part of the frame and then writes it out. It
160: * also starts the acknowledgement timer and keeps the iframe in the
161: * Retransmit queue (Retxq) just in case we have to do this again.
162: *
163: * Note: This routine is also called from hd_input.c when retransmission
164: * of old frames is required.
165: */
166:
167: hd_send_iframe (hdp, buf, poll_bit)
168: register struct hdcb *hdp;
169: register struct mbuf *buf;
170: int poll_bit;
171: {
172: register struct Hdlc_iframe *iframe;
173: struct mbuf *m;
174:
175: KILL_TIMER (hdp);
176:
177: if (buf == 0) {
178: printf ("hd_send_iframe: zero arg\n");
179: #ifdef HDLCDEBUG
180: hd_status (hdp);
181: hd_dumptrace (hdp);
182: #endif
183: hdp->hd_vs = (hdp->hd_vs + 7) % MODULUS;
184: return;
185: }
186: iframe = mtod (buf, struct Hdlc_iframe *);
187:
188: iframe -> hdlc_0 = 0;
189: iframe -> nr = hdp->hd_vr;
190: iframe -> pf = poll_bit;
191: iframe -> ns = hdp->hd_vs;
192: iframe -> address = ADDRESS_B;
193: hdp->hd_lasttxnr = hdp->hd_vr;
194: hdp->hd_rrtimer = 0;
195:
196: if (hdp->hd_vs == hdp->hd_retxqi) {
197: /* Check for retransmissions. */
198: /* Put iframe only once in the Retransmission queue. */
199: hdp->hd_retxq[hdp->hd_retxqi] = buf;
200: hdp->hd_retxqi = (hdp->hd_retxqi + 1) % MODULUS;
201: hdp->hd_iframes_out++;
202: }
203:
204: hdp->hd_vs = (hdp->hd_vs + 1) % MODULUS;
205:
206: hd_trace (hdp, TX, (struct Hdlc_frame *)iframe);
207:
208: /* Write buffer on device. */
209: m = hdp->hd_dontcopy ? buf : m_copy(buf, 0, (int)M_COPYALL);
210: if (m == 0) {
211: printf("hdlc: out of mbufs\n");
212: return;
213: }
214: (*hdp->hd_output)(hdp, m);
215: SET_TIMER (hdp);
216: }
217:
218: hd_ifoutput(hdp, m)
219: register struct mbuf *m;
220: register struct hdcb *hdp;
221: {
222: /*
223: * Queue message on interface, and start output if interface
224: * not yet active.
225: */
226: register struct ifnet *ifp = hdp->hd_ifp;
227: int s = splimp();
228:
229: if (IF_QFULL(&ifp->if_snd)) {
230: IF_DROP(&ifp->if_snd);
231: /* printf("%s%d: HDLC says OK to send but queue full, may hang\n",
232: ifp->if_name, ifp->if_unit);*/
233: m_freem(m);
234: } else {
235: IF_ENQUEUE(&ifp->if_snd, m);
236: if ((ifp->if_flags & IFF_OACTIVE) == 0)
237: (*ifp->if_start)(ifp);
238: }
239: splx(s);
240: }
241:
242:
243: /*
244: * This routine gets control when the timer expires because we have not
245: * received an acknowledgement for a iframe.
246: */
247:
248: hd_resend_iframe (hdp)
249: register struct hdcb *hdp;
250: {
251:
252: if (hdp->hd_retxcnt++ < hd_n2) {
253: if (!(hdp->hd_condition & TIMER_RECOVERY_CONDITION)) {
254: hdp->hd_xx = hdp->hd_vs;
255: hdp->hd_condition |= TIMER_RECOVERY_CONDITION;
256: }
257:
258: hdp->hd_vs = hdp->hd_lastrxnr;
259: hd_send_iframe (hdp, hdp->hd_retxq[hdp->hd_vs], POLLON);
260: } else {
261: /* At this point we have not received a RR even after N2
262: retries - attempt to reset link. */
263:
264: hd_initvars (hdp);
265: hd_writeinternal (hdp, SABM, POLLOFF);
266: hdp->hd_state = WAIT_UA;
267: SET_TIMER (hdp);
268: hd_message (hdp, "Timer recovery failed: link down");
269: (void) pk_ctlinput (PRC_LINKDOWN, hdp->hd_pkp);
270: }
271: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.