]> git.saurik.com Git - apple/xnu.git/blame - bsd/netat/adsp_RxAttn.c
xnu-344.23.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 *
de355530
A
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.
1c79356b 11 *
de355530
A
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
1c79356b
A
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
de355530
A
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.
1c79356b
A
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*/
53typedef struct
54{
55 AddrUnion addr;
56 word srcCID;
57} MATCH_SENDER, *MATCH_SENDERPtr;
58
59/*
60 * MatchSender
61 *
62 */
63
64static 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 */
100CCBPtr 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 */
127int 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}