|
|
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.