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