|
|
1.1 root 1: /*
2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3: *
4: * @APPLE_LICENSE_HEADER_START@
5: *
6: * The contents of this file constitute Original Code as defined in and
7: * are subject to the Apple Public Source License Version 1.1 (the
8: * "License"). You may not use this file except in compliance with the
9: * License. Please obtain a copy of the License at
10: * http://www.apple.com/publicsource and read it before using this file.
11: *
12: * This Original Code and all software distributed under the License are
13: * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16: * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17: * License for the specific language governing rights and limitations
18: * under the License.
19: *
20: * @APPLE_LICENSE_HEADER_END@
21: */
22: /* adspOpen.c v01.20
23: *
24: * From v01.20 08/23/90 Mike Shoemaker for MacOS
25: * Modified for MP, 1996 by Tuyen Nguyen
26: * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
27: */
28:
29: #include <sys/errno.h>
30: #include <sys/types.h>
31: #include <sys/param.h>
32: #include <machine/spl.h>
33: #include <sys/systm.h>
34: #include <sys/kernel.h>
35: #include <sys/proc.h>
36: #include <sys/filedesc.h>
37: #include <sys/fcntl.h>
38: #include <sys/mbuf.h>
39: #include <sys/socket.h>
40: #include <sys/socketvar.h>
41: #include <sys/time.h>
42:
43: #include <netat/sysglue.h>
44: #include <netat/appletalk.h>
45: #include <netat/at_pcb.h>
46: #include <netat/debug.h>
47: #include <netat/adsp.h>
48: #include <netat/adsp_internal.h>
49:
50: extern atlock_t adspgen_lock;
51:
52: /*
53: * NextCID
54: *
55: * Create a unique connection ID.
56: *
57: * INPUTS:
58: * none
59: * OUTPUTS:
60: * unique connection ID
61: */
62: unsigned short NextCID()
63: {
64: int s;
65: unsigned short num;
66: register CCB *queue;
67:
68: while (1) {
69: ATDISABLE(s, adspgen_lock); /* Disable interrupts */
70: num = ++adspGlobal.lastCID;
71: /* qfind_w below is in 68K assembly */
72: /* point to the first element */
73: queue = (CCB *)AT_ADSP_STREAMS;
74: while (queue) {
75: /* and scan .. */
76: if (queue->locCID == num)
77: break;
78: queue = queue->ccbLink;
79: }
80: ATENABLE(s, adspgen_lock);
81: if (queue == (CCBPtr)NULL)
82: break;
83: }
84: return num;
85: }
86:
87: static byte xlateStateTbl[4] = /* The value to be given to the CCB's state. */
88: { /* indexed by ocMode */
89: sOpening, /* ocRequest */
90: sPassive, /* ocPassive */
91: sOpening, /* ocAccept */
92: sOpen /* ocEstablish */
93: };
94: static byte xlateOpenTbl[4] = /* Value to use for open state. */
95: { /* indexed by ocMode */
96: O_STATE_OPENWAIT, /* ocRequest */
97: O_STATE_LISTEN, /* ocPassive */
98: O_STATE_ESTABLISHED, /* ocAccept */
99: O_STATE_OPEN /* ocEstablish */
100: };
101:
102: /*
103: * adspOpen
104: *
105: * INPUTS:
106: * --> ccbRefNum refnum of connection end
107: * --> remoteCID connection id of remote connection end
108: * --> remoteAddress internet address of remote connection end
109: * --> filterAddress filter for incoming open connection requests
110: * --> sendSeq initial send sequence number to use
111: * --> sendWindow initial size of remote end's receive buffer
112: * --> recvSeq initial receive sequence number to use
113: * --> attnSendSeq initial attention send sequence number
114: * --> attnRecvSeq initial receive sequence number
115: * --> ocMode connection opening mode
116: * --> ocMaximum maximum retries of open connection request
117: *
118: * OUTPUTS:
119: * <-- localCID connection identifier of this connection end
120: * <-- remoteCID connection id of remote connection end
121: * <-- remoteAddress
122: * <-- sendSeq
123: * <-- sendWindow
124: * <-- attnSendSeq
125: *
126: * ERRORS:
127: * errRefNum bad connection refnum
128: * errState connection end must be closed
129: * errOpening open connection attempt failed
130: * errAborted request aborted by a remove or close call
131: */
132: int adspOpen(sp, pb) /* (DSPPBPtr pb) */
133: register CCBPtr sp;
134: register struct adspcmd *pb;
135: {
136: extern int adsp_pidM[];
137:
138: int ocMode;
139: register gbuf_t *mp;
140:
141: if (sp == 0) {
142: pb->ioResult = errRefNum; /* Unknown refnum */
143: return EINVAL;
144: }
145:
146: if ((sp->state != sClosed) ||
147: (sp->removing)) { /* The CCB must be closed */
148: pb->ioResult = errState;
149: return EALREADY;
150: }
151:
152: ocMode = pb->u.openParams.ocMode; /* get a local copy of open mode */
153: if (ocMode == ocRequest)
154: adsp_pidM[pb->socket] = 0;
155:
156: /*
157: * Save parameters. Fill in defaults if zero
158: */
159: if (pb->u.openParams.ocInterval)
160: sp->openInterval = pb->u.openParams.ocInterval;
161: else
162: sp->openInterval = ocIntervalDefault;
163:
164: if (pb->u.openParams.ocMaximum)
165: sp->openRetrys = pb->u.openParams.ocMaximum;
166: else
167: sp->openRetrys = ocMaximumDefault;
168:
169: sp->remoteAddress = *((AddrUnionPtr)&pb->u.openParams.remoteAddress);
170: /* Not used for passive */
171: /*
172: * Clear out send/receive buffers.
173: */
174: if (sp->sbuf_mb) { /* clear the send queue */
175: gbuf_freel(sp->sbuf_mb);
176: sp->sbuf_mb = 0;
177: }
178: if (sp->csbuf_mb) {
179: gbuf_freem(sp->csbuf_mb);
180: sp->csbuf_mb = 0;
181: }
182: if (sp->rbuf_mb) { /* clear the receive queue */
183: gbuf_freel(sp->rbuf_mb);
184: sp->rbuf_mb = 0;
185: }
186: if (sp->crbuf_mb) {
187: gbuf_freem(sp->crbuf_mb);
188: sp->crbuf_mb = 0;
189: }
190:
191: sp->rData = 0; /* Flag both buffers as empty */
192: sp->sData = 0;
193: sp->recvQPending = 0; /* No bytes in receive queue */
194:
195: /*
196: * Clear all of those pesky flags
197: */
198: sp->userFlags = 0;
199: sp->sendDataAck = 0;
200: sp->sendAttnAck = 0;
201: sp->sendAttnData = 0;
202: sp->callSend = 0;
203: sp->removing = 0;
204: sp->writeFlush = 0;
205:
206: /*
207: * Reset round-trip timers
208: */
209: sp->roundTrip = sp->rtmtInterval;
210: sp->deviation = 0;
211:
212: /*
213: * Reset stuff for retransmit advice packet
214: */
215: sp->badSeqCnt = 0;
216: /*
217: * Reset flow control variables
218: */
219: sp->pktSendMax = 1; /* Slow start says we should set this to 1 */
220: sp->pktSendCnt = 0;
221: sp->rbufFull = 0;
222: sp->resentData = 0;
223: sp->noXmitFlow = 0;
224: sp->waitingAck = 0;
225:
226: /*
227: * Copy required information out of parameter block
228: */
229: if (ocMode == ocAccept || ocMode == ocEstablish) {
230: sp->remCID = pb->u.openParams.remoteCID;
231: sp->sendSeq = sp->firstRtmtSeq = pb->u.openParams.sendSeq;
232: sp->sendWdwSeq = sp->sendSeq + pb->u.openParams.sendWindow;
233: sp->attnSendSeq = pb->u.openParams.attnSendSeq;
234: } else { /* accept or establish */
235: sp->remCID = 0;
236: sp->sendSeq = 0;
237: sp->sendWdwSeq = 0;
238: sp->attnSendSeq = 0;
239: }
240:
241: if (ocMode == ocEstablish) { /* Only set these if establish mode */
242: sp->recvSeq = pb->u.openParams.recvSeq;
243: sp->attnRecvSeq = pb->u.openParams.attnRecvSeq;
244: UAS_ASSIGN(sp->f.CID, sp->locCID); /* Preset the CID in the ADSP header */
245: /* This is done elsewhere for all other modes */
246: InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
247: sp->probeInterval);
248: } else { /* establish */
249: /* All other modes need a CID assigned */
250: sp->locCID = NextCID();
251: sp->recvSeq = 0;
252: sp->attnRecvSeq = 0;
253: }
254:
255: /*
256: * Now set the state variables for this CCB.
257: */
258:
259: sp->openState = xlateOpenTbl[ocMode-ocRequest];
260: sp->state = xlateStateTbl[ocMode-ocRequest];
261:
262: if (ocMode == ocEstablish) { /* For establish call, we're done */
263: pb->ioResult = 0;
264: adspioc_ack(0, pb->ioc, pb->gref);
265: return 0;
266: }
267:
268: pb->qLink = 0; /* Clear link field before putting on queue */
269: mp = gbuf_copym(pb->mp); /* Save parameter block to match later */
270:
271: if (mp == 0) {
272: pb->ioResult = errDSPQueueSize;
273: return ENOBUFS;
274: }
275: pb->ioResult = 1; /* not open -> not done */
276: adspioc_ack(0, pb->ioc, pb->gref); /* release user */
277: sp->opb = (struct adspcmd *)gbuf_rptr(mp);
278: sp->opb->ioc = 0; /* unlink saved pb from ioctl block */
279: sp->opb->mp = mp;
280:
281: /*
282: * For request & accept, need to send a packet
283: */
284: if ((ocMode == ocRequest) || (ocMode == ocAccept)) {
285: sp->sendCtl |= (1 << (ocMode == ocRequest ?
286: ADSP_CTL_OREQ : ADSP_CTL_OREQACK));
287: CheckSend(sp);
288: }
289: return 0;
290: }
291:
292: int adspMode(pb)
293: register struct adspcmd *pb;
294: {
295: return pb->u.openParams.ocMode;
296: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.