|
|
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: #include <adsp_local.h>
26: extern atlock_t adspgen_lock;
27:
28:
29: /*
30: * NextCID
31: *
32: * Create a unique connection ID.
33: *
34: * INPUTS:
35: * none
36: * OUTPUTS:
37: * unique connection ID
38: */
39: unsigned short NextCID()
40: {
41: int s;
42: unsigned short num;
43: register CCB *queue;
44:
45: while (1) {
46: ATDISABLE(s, adspgen_lock); /* Disable interrupts */
47: num = ++adspGlobal.lastCID;
48: /* qfind_w below is in 68K assembly */
49: /* point to the first element */
50: queue = (CCB *)AT_ADSP_STREAMS;
51: while (queue) {
52: /* and scan .. */
53: if (queue->locCID == num)
54: break;
55: queue = queue->ccbLink;
56: }
57: ATENABLE(s, adspgen_lock);
58: if (queue == (CCBPtr)NULL)
59: break;
60: }
61: return num;
62: }
63:
64: static byte xlateStateTbl[4] = /* The value to be given to the CCB's state. */
65: { /* indexed by ocMode */
66: sOpening, /* ocRequest */
67: sPassive, /* ocPassive */
68: sOpening, /* ocAccept */
69: sOpen /* ocEstablish */
70: };
71: static byte xlateOpenTbl[4] = /* Value to use for open state. */
72: { /* indexed by ocMode */
73: O_STATE_OPENWAIT, /* ocRequest */
74: O_STATE_LISTEN, /* ocPassive */
75: O_STATE_ESTABLISHED, /* ocAccept */
76: O_STATE_OPEN /* ocEstablish */
77: };
78:
79: /*
80: * adspOpen
81: *
82: * INPUTS:
83: * --> ccbRefNum refnum of connection end
84: * --> remoteCID connection id of remote connection end
85: * --> remoteAddress internet address of remote connection end
86: * --> filterAddress filter for incoming open connection requests
87: * --> sendSeq initial send sequence number to use
88: * --> sendWindow initial size of remote end's receive buffer
89: * --> recvSeq initial receive sequence number to use
90: * --> attnSendSeq initial attention send sequence number
91: * --> attnRecvSeq initial receive sequence number
92: * --> ocMode connection opening mode
93: * --> ocMaximum maximum retries of open connection request
94: *
95: * OUTPUTS:
96: * <-- localCID connection identifier of this connection end
97: * <-- remoteCID connection id of remote connection end
98: * <-- remoteAddress
99: * <-- sendSeq
100: * <-- sendWindow
101: * <-- attnSendSeq
102: *
103: * ERRORS:
104: * errRefNum bad connection refnum
105: * errState connection end must be closed
106: * errOpening open connection attempt failed
107: * errAborted request aborted by a remove or close call
108: */
109: int adspOpen(sp, pb) /* (DSPPBPtr pb) */
110: register CCBPtr sp;
111: register struct adspcmd *pb;
112: {
113: extern int adsp_pidM[];
114: int err;
115: int ocMode;
116: int s;
117: register gbuf_t *mp;
118:
119: if (sp == 0) {
120: pb->ioResult = errRefNum; /* Unknown refnum */
121: return EINVAL;
122: }
123:
124: if ((sp->state != sClosed) ||
125: (sp->removing)) { /* The CCB must be closed */
126: pb->ioResult = errState;
127: return EALREADY;
128: }
129:
130: ocMode = pb->u.openParams.ocMode; /* get a local copy of open mode */
131: if (ocMode == ocRequest)
132: adsp_pidM[pb->socket] = 0;
133:
134: /*
135: * Save parameters. Fill in defaults if zero
136: */
137: if (pb->u.openParams.ocInterval)
138: sp->openInterval = pb->u.openParams.ocInterval;
139: else
140: sp->openInterval = ocIntervalDefault;
141:
142: if (pb->u.openParams.ocMaximum)
143: sp->openRetrys = pb->u.openParams.ocMaximum;
144: else
145: sp->openRetrys = ocMaximumDefault;
146:
147: sp->remoteAddress = *((AddrUnionPtr)&pb->u.openParams.remoteAddress);
148: /* Not used for passive */
149: /*
150: * Clear out send/receive buffers.
151: */
152: if (sp->sbuf_mb) { /* clear the send queue */
153: gbuf_freel(sp->sbuf_mb);
154: sp->sbuf_mb = 0;
155: }
156: if (sp->csbuf_mb) {
157: gbuf_freem(sp->csbuf_mb);
158: sp->csbuf_mb = 0;
159: }
160: if (sp->rbuf_mb) { /* clear the receive queue */
161: gbuf_freel(sp->rbuf_mb);
162: sp->rbuf_mb = 0;
163: }
164: if (sp->crbuf_mb) {
165: gbuf_freem(sp->crbuf_mb);
166: sp->crbuf_mb = 0;
167: }
168:
169: sp->rData = 0; /* Flag both buffers as empty */
170: sp->sData = 0;
171: sp->recvQPending = 0; /* No bytes in receive queue */
172:
173: /*
174: * Clear all of those pesky flags
175: */
176: sp->userFlags = 0;
177: sp->sendDataAck = 0;
178: sp->sendAttnAck = 0;
179: sp->sendAttnData = 0;
180: sp->callSend = 0;
181: sp->removing = 0;
182: sp->writeFlush = 0;
183:
184: /*
185: * Reset round-trip timers
186: */
187: sp->roundTrip = sp->rtmtInterval;
188: sp->deviation = 0;
189:
190: /*
191: * Reset stuff for retransmit advice packet
192: */
193: sp->badSeqCnt = 0;
194: /*
195: * Reset flow control variables
196: */
197: sp->pktSendMax = 1; /* Slow start says we should set this to 1 */
198: sp->pktSendCnt = 0;
199: sp->rbufFull = 0;
200: sp->resentData = 0;
201: sp->noXmitFlow = 0;
202: sp->waitingAck = 0;
203:
204: /*
205: * Copy required information out of parameter block
206: */
207: if (ocMode == ocAccept || ocMode == ocEstablish) {
208: sp->remCID = pb->u.openParams.remoteCID;
209: sp->sendSeq = sp->firstRtmtSeq = pb->u.openParams.sendSeq;
210: sp->sendWdwSeq = sp->sendSeq + pb->u.openParams.sendWindow;
211: sp->attnSendSeq = pb->u.openParams.attnSendSeq;
212: } else { /* accept or establish */
213: sp->remCID = 0;
214: sp->sendSeq = 0;
215: sp->sendWdwSeq = 0;
216: sp->attnSendSeq = 0;
217: }
218:
219: if (ocMode == ocEstablish) { /* Only set these if establish mode */
220: sp->recvSeq = pb->u.openParams.recvSeq;
221: sp->attnRecvSeq = pb->u.openParams.attnRecvSeq;
222: UAS_ASSIGN(sp->f.CID, sp->locCID); /* Preset the CID in the ADSP header */
223: /* This is done elsewhere for all other modes */
224: InsertTimerElem(&adspGlobal.slowTimers, &sp->ProbeTimer,
225: sp->probeInterval);
226: } else { /* establish */
227: /* All other modes need a CID assigned */
228: sp->locCID = NextCID();
229: sp->recvSeq = 0;
230: sp->attnRecvSeq = 0;
231: }
232:
233: /*
234: * Now set the state variables for this CCB.
235: */
236:
237: sp->openState = xlateOpenTbl[ocMode-ocRequest];
238: sp->state = xlateStateTbl[ocMode-ocRequest];
239:
240: if (ocMode == ocEstablish) { /* For establish call, we're done */
241: pb->ioResult = 0;
242: adspioc_ack(0, pb->ioc, pb->gref);
243: return 0;
244: }
245:
246: pb->qLink = 0; /* Clear link field before putting on queue */
247: mp = gbuf_copym(pb->mp); /* Save parameter block to match later */
248:
249: if (mp == 0) {
250: pb->ioResult = errDSPQueueSize;
251: return ENOBUFS;
252: }
253: pb->ioResult = 1; /* not open -> not done */
254: adspioc_ack(0, pb->ioc, pb->gref); /* release user */
255: sp->opb = (struct adspcmd *)gbuf_rptr(mp);
256: sp->opb->ioc = 0; /* unlink saved pb from ioctl block */
257: sp->opb->mp = mp;
258:
259: /*
260: * For request & accept, need to send a packet
261: */
262: if ((ocMode == ocRequest) || (ocMode == ocAccept)) {
263: sp->sendCtl |= (1 << (ocMode == ocRequest ?
264: ADSP_CTL_OREQ : ADSP_CTL_OREQACK));
265: CheckSend(sp);
266: }
267: return 0;
268: }
269:
270: int adspMode(pb)
271: register struct adspcmd *pb;
272: {
273: return pb->u.openParams.ocMode;
274: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.