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