|
|
1.1 ! root 1: /* ! 2: * Copyright (c) 2000 Apple Computer, Inc. All rights reserved. ! 3: * ! 4: * @APPLE_LICENSE_HEADER_START@ ! 5: * ! 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. ! 11: * ! 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 ! 14: * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, ! 15: * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, ! 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. ! 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: */ ! 53: typedef struct ! 54: { ! 55: AddrUnion addr; ! 56: word srcCID; ! 57: } MATCH_SENDER, *MATCH_SENDERPtr; ! 58: ! 59: /* ! 60: * MatchSender ! 61: * ! 62: */ ! 63: ! 64: static 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: */ ! 100: CCBPtr 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: */ ! 127: int 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: }
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.