|
|
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: /*
23: * RxAttn.c
24: *
25: * From v01.12 06/12/90 mbs
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/time.h>
41:
42: #include <netat/sysglue.h>
43: #include <netat/appletalk.h>
44: #include <netat/at_pcb.h>
45: #include <netat/debug.h>
46: #include <netat/adsp.h>
47: #include <netat/adsp_internal.h>
48:
49: /*
50: * Used to search down queue of sessions for a session that matches
51: * sender and source connection ID
52: */
53: typedef struct
54: {
55: AddrUnion addr;
56: word srcCID;
57: } MATCH_SENDER, *MATCH_SENDERPtr;
58:
59: /*
60: * MatchSender
61: *
62: */
63:
64: static boolean MatchSender(sp, m) /* (CCBPtr sp, MATCH_SENDERPtr m) */
65: CCBPtr sp;
66: MATCH_SENDERPtr m;
67: {
68:
69: if (sp->state != sOpen && sp->state != sClosing)
70: return 0;
71:
72: if (sp->remCID != m->srcCID)
73: return 0;
74:
75: if (sp->remoteAddress.a.node != m->addr.a.node)
76: return 0;
77: if (sp->remoteAddress.a.socket != m->addr.a.socket)
78: return 0;
79: if (sp->remoteAddress.a.net && m->addr.a.net &&
80: (sp->remoteAddress.a.net != m->addr.a.net))
81: return 0;
82:
83: return 1;
84: }
85:
86:
87: /*
88: * FindSender
89: *
90: * Given an ADSP Packet, find the stream it is associated with.
91: *
92: * This should only be used for ADSP Packets that could be received
93: * by an OPEN connection.
94: *
95: * INPUTS:
96: * Pointer to ADSP header & address of sender
97: * OUTPUTS:
98: * Pointer to stream if found, else 0
99: */
100: CCBPtr FindSender(f, a) /* (ADSP_FRAMEPtr f, AddrUnion a) */
101: ADSP_FRAMEPtr f;
102: AddrUnion a;
103: {
104: MATCH_SENDER m;
105:
106: m.addr = a;
107: m.srcCID = UAS_VALUE(f->CID);
108: return (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, (ProcPtr)MatchSender);
109: }
110:
111: /*
112: * RXAttention
113: *
114: * We just got an Attention Packet.
115: * See if it came from anybody we know.
116: * Then check to see if it is an attention data packet or acknowledgement
117: *
118: * Interrupts are masked OFF at this point.
119: *
120: * INPUTS:
121: * stream pointer
122: * Pointer to ADSP header,
123: * Length of header plus data
124: * OUTPUTS:
125: * Returns 1 if packet was ignored
126: */
127: int RXAttention(sp, mp, f, len) /* (CCBPtr sp, ADSP_FRAMEPtr f, word len) */
128: CCBPtr sp;
129: gbuf_t *mp;
130: ADSP_FRAMEPtr f;
131: int len;
132: {
133: int offset;
134: struct adspcmd *pb;
135: long diff;
136:
137: if (UAS_VALUE(f->pktRecvWdw)) /* This field must be 0 in attn pkts */
138: return 1;
139:
140: if ((f->descriptor ==
141: (char)(ADSP_ATTENTION_BIT | ADSP_ACK_REQ_BIT)) && /* Attention Data */
142: ((sp->userFlags & eAttention) == 0)) /* & he read the previous */
143: {
144: diff = netdw(UAL_VALUE(f->pktFirstByteSeq)) - sp->attnRecvSeq;
145: if (diff > 0) /* Hey, he missed one */
146: return 1;
147:
148: if (diff == 0) /* This is the one we expected */
149: {
150: len -= ADSP_FRAME_LEN; /* remove adsp header */
151: if (len < 2) /* Poorly formed attn packet */
152: return 1;
153: sp->attnCode = (f->data[0] << 8) + f->data[1]; /* Save attn code */
154: sp->attn_mb = mp;
155: offset = ((unsigned char *)&f->data[2]) - (unsigned char *)gbuf_rptr(mp);
156: gbuf_rinc(mp,offset);
157: sp->attnPtr = (unsigned char *)gbuf_rptr(mp);
158: mp = 0; /* mp has been queued don't free it */
159:
160: /* Interrupts are off here, or otherwise we have to do
161: * these three operations automically.
162: */
163: sp->attnSize = len - 2; /* Tell user how many bytes */
164: ++sp->attnRecvSeq;
165: /* Set flag saying we got attn message */
166: sp->userFlags |= eAttention;
167: UrgentUser(sp); /* Notify user */
168: /* BEFORE sending acknowledge */
169: } /* in sequence */
170:
171: sp->sendAttnAck = 1; /* send attention ack for dupl. &
172: * expected data */
173: sp->callSend = 1;
174: } /* Attn Data */
175:
176: /*
177: * Interrupts are OFF here, otherwise we have to do this atomically
178: */
179: /* Check to see if this acknowledges anything */
180: if ((sp->attnSendSeq + 1) == netdw(UAL_VALUE(f->pktNextRecvSeq))) {
181: sp->attnSendSeq++;
182: if ((pb = sp->sapb) == 0) { /* We never sent data ? !!! */
183: if (mp)
184: gbuf_freem(mp);
185: return 0;
186: }
187:
188: sp->sapb = (struct adspcmd *)pb->qLink; /* Unlink from queue */
189:
190: /* Remove timer */
191: RemoveTimerElem(&adspGlobal.fastTimers, &sp->AttnTimer);
192:
193: pb->ioResult = 0;
194: if (gbuf_cont(pb->mp)) {
195: gbuf_freem(gbuf_cont(pb->mp)); /* free the data */
196: gbuf_cont(pb->mp) = 0;
197: }
198: completepb(sp, pb); /* Done with the send attention */
199:
200: if (sp->sapb) { /* Another send attention pending? */
201: sp->sendAttnData = 1;
202: sp->callSend = 1;
203: } else {
204: if (sp->state == sClosing) /* this ack may allow us to close... */
205: CheckOkToClose(sp);
206: }
207: }
208: if (mp)
209: gbuf_freem(mp);
210: return 0;
211: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.