]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/adsp_RxAttn.c
xnu-344.21.73.tar.gz
[apple/xnu.git] / bsd / netat / adsp_RxAttn.c
CommitLineData
1c79356b
A
1/*
2 * Copyright (c) 2000 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
d7e50217 6 * Copyright (c) 1999-2003 Apple Computer, Inc. All Rights Reserved.
1c79356b 7 *
d7e50217
A
8 * This file contains Original Code and/or Modifications of Original Code
9 * as defined in and that are subject to the Apple Public Source License
10 * Version 2.0 (the 'License'). You may not use this file except in
11 * compliance with the License. Please obtain a copy of the License at
12 * http://www.opensource.apple.com/apsl/ and read it before using this
13 * file.
14 *
15 * The Original Code and all software distributed under the License are
16 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER
1c79356b
A
17 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
18 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
d7e50217
A
19 * FITNESS FOR A PARTICULAR PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT.
20 * Please see the License for the specific language governing rights and
21 * limitations under the License.
1c79356b
A
22 *
23 * @APPLE_LICENSE_HEADER_END@
24 */
25/*
26 * RxAttn.c
27 *
28 * From v01.12 06/12/90 mbs
29 * Modified, April 9, 1997 by Tuyen Nguyen for MacOSX.
30 */
31
32#include <sys/errno.h>
33#include <sys/types.h>
34#include <sys/param.h>
35#include <machine/spl.h>
36#include <sys/systm.h>
37#include <sys/kernel.h>
38#include <sys/proc.h>
39#include <sys/filedesc.h>
40#include <sys/fcntl.h>
41#include <sys/mbuf.h>
42#include <sys/socket.h>
43#include <sys/time.h>
44
45#include <netat/sysglue.h>
46#include <netat/appletalk.h>
47#include <netat/at_pcb.h>
48#include <netat/debug.h>
49#include <netat/adsp.h>
50#include <netat/adsp_internal.h>
51
52/*
53 * Used to search down queue of sessions for a session that matches
54 * sender and source connection ID
55*/
56typedef struct
57{
58 AddrUnion addr;
59 word srcCID;
60} MATCH_SENDER, *MATCH_SENDERPtr;
61
62/*
63 * MatchSender
64 *
65 */
66
67static boolean MatchSender(sp, m) /* (CCBPtr sp, MATCH_SENDERPtr m) */
68 CCBPtr sp;
69 MATCH_SENDERPtr m;
70{
71
72 if (sp->state != sOpen && sp->state != sClosing)
73 return 0;
74
75 if (sp->remCID != m->srcCID)
76 return 0;
77
78 if (sp->remoteAddress.a.node != m->addr.a.node)
79 return 0;
80 if (sp->remoteAddress.a.socket != m->addr.a.socket)
81 return 0;
82 if (sp->remoteAddress.a.net && m->addr.a.net &&
83 (sp->remoteAddress.a.net != m->addr.a.net))
84 return 0;
85
86 return 1;
87}
88
89
90/*
91 * FindSender
92 *
93 * Given an ADSP Packet, find the stream it is associated with.
94 *
95 * This should only be used for ADSP Packets that could be received
96 * by an OPEN connection.
97 *
98 * INPUTS:
99 * Pointer to ADSP header & address of sender
100 * OUTPUTS:
101 * Pointer to stream if found, else 0
102 */
103CCBPtr FindSender(f, a) /* (ADSP_FRAMEPtr f, AddrUnion a) */
104 ADSP_FRAMEPtr f;
105 AddrUnion a;
106{
107 MATCH_SENDER m;
108
109 m.addr = a;
110 m.srcCID = UAS_VALUE(f->CID);
111 return (CCBPtr)qfind_m(AT_ADSP_STREAMS, &m, (ProcPtr)MatchSender);
112}
113
114/*
115 * RXAttention
116 *
117 * We just got an Attention Packet.
118 * See if it came from anybody we know.
119 * Then check to see if it is an attention data packet or acknowledgement
120 *
121 * Interrupts are masked OFF at this point.
122 *
123 * INPUTS:
124 * stream pointer
125 * Pointer to ADSP header,
126 * Length of header plus data
127 * OUTPUTS:
128 * Returns 1 if packet was ignored
129 */
130int RXAttention(sp, mp, f, len) /* (CCBPtr sp, ADSP_FRAMEPtr f, word len) */
131 CCBPtr sp;
132 gbuf_t *mp;
133 ADSP_FRAMEPtr f;
134 int len;
135{
136 int offset;
137 struct adspcmd *pb;
138 long diff;
139
140 if (UAS_VALUE(f->pktRecvWdw)) /* This field must be 0 in attn pkts */
141 return 1;
142
143 if ((f->descriptor ==
144 (char)(ADSP_ATTENTION_BIT | ADSP_ACK_REQ_BIT)) && /* Attention Data */
145 ((sp->userFlags & eAttention) == 0)) /* & he read the previous */
146 {
147 diff = netdw(UAL_VALUE(f->pktFirstByteSeq)) - sp->attnRecvSeq;
148 if (diff > 0) /* Hey, he missed one */
149 return 1;
150
151 if (diff == 0) /* This is the one we expected */
152 {
153 len -= ADSP_FRAME_LEN; /* remove adsp header */
154 if (len < 2) /* Poorly formed attn packet */
155 return 1;
156 sp->attnCode = (f->data[0] << 8) + f->data[1]; /* Save attn code */
157 sp->attn_mb = mp;
158 offset = ((unsigned char *)&f->data[2]) - (unsigned char *)gbuf_rptr(mp);
159 gbuf_rinc(mp,offset);
160 sp->attnPtr = (unsigned char *)gbuf_rptr(mp);
161 mp = 0; /* mp has been queued don't free it */
162
163 /* Interrupts are off here, or otherwise we have to do
164 * these three operations automically.
165 */
166 sp->attnSize = len - 2; /* Tell user how many bytes */
167 ++sp->attnRecvSeq;
168 /* Set flag saying we got attn message */
169 sp->userFlags |= eAttention;
170 UrgentUser(sp); /* Notify user */
171 /* BEFORE sending acknowledge */
172 } /* in sequence */
173
174 sp->sendAttnAck = 1; /* send attention ack for dupl. &
175 * expected data */
176 sp->callSend = 1;
177 } /* Attn Data */
178
179 /*
180 * Interrupts are OFF here, otherwise we have to do this atomically
181 */
182 /* Check to see if this acknowledges anything */
183 if ((sp->attnSendSeq + 1) == netdw(UAL_VALUE(f->pktNextRecvSeq))) {
184 sp->attnSendSeq++;
185 if ((pb = sp->sapb) == 0) { /* We never sent data ? !!! */
186 if (mp)
187 gbuf_freem(mp);
188 return 0;
189 }
190
191 sp->sapb = (struct adspcmd *)pb->qLink; /* Unlink from queue */
192
193 /* Remove timer */
194 RemoveTimerElem(&adspGlobal.fastTimers, &sp->AttnTimer);
195
196 pb->ioResult = 0;
197 if (gbuf_cont(pb->mp)) {
198 gbuf_freem(gbuf_cont(pb->mp)); /* free the data */
199 gbuf_cont(pb->mp) = 0;
200 }
201 completepb(sp, pb); /* Done with the send attention */
202
203 if (sp->sapb) { /* Another send attention pending? */
204 sp->sendAttnData = 1;
205 sp->callSend = 1;
206 } else {
207 if (sp->state == sClosing) /* this ack may allow us to close... */
208 CheckOkToClose(sp);
209 }
210 }
211 if (mp)
212 gbuf_freem(mp);
213 return 0;
214}