📄 aal2rxcp.c
字号:
if (cpsPayloadLen) /* PARTIAL OR COMPLETE PAYLOAD ACCOMPANYING */ {#ifdef DCP_DEBUG_1 ksPrintf ("cpsPayloadLen : %d",cpsPayloadLen);#endif /* Else allocate a buffer for the CPS packet payload and store it * in the CPS packet descriptor. */ bufHandle = aal2RxVcTable->bufHandlePtr; if (bufHandle == NOT_ALLOCATED) { /* Check if the pool id of the BufHandle in DMEM table * is same as the CP's pool Id, if YES then reuse this * SDRAM buffer. Otherwise allocate another buffer. The * buffer handle offset should be set to 0 in the first * case. * This is to be done because of error in the length of * previous CPS packet. This could happen because of two * simultaneous cells being dropped and which could go * undetected at the handler. */ /* Allocate a bufHandle */ while (bsError(bufHandle = bsBufferAllocate(poolId))) { bufferAllocFail++; } }#ifdef AAL2_STATISTICS else { rxAal2LengthErr++ ; }#endif aal2RxVcTable->offset = 0; /* Write payload to SDRAM */ bsBufferWrite(rxTempPdu[fwdrScopeNum], 64, bufHandle, 0);#ifdef DEBUG_64 while (!bsBufferWriteComplete ()) ;#endif #ifdef DCP_DEBUG_1 ksPrintf ("extractSpace->li : %d",extractSpace->li);#endif if ((cpsPayloadLen - 1) < extractSpace->li) { aal2RxVcTable->bufHandlePtr = bufHandle; aal2RxVcTable->offset = cpsPayloadLen; /* Incomplete CPS packet */ aal2RxVcTable->cid = extractSpace->cid; aal2RxVcTable->li = extractSpace->li; aal2RxVcTable->uui = extractSpace->uui; }#ifdef AAL2_STATISTICS else { rxAal2LengthErr++ ; }#endif } else /* NO PARTIAL OR COMPLETE PAYLOAD FOUND */ { /* If the cpsHdrLen is non-zero then it is a partial or * full CPS header. * Just store the different fields in the DMEM table and if * complete CPS header has been received, then allocate a * buffer and store it in the DMEM table. */ aal2RxVcTable->cid = extractSpace->cid; aal2RxVcTable->li = extractSpace->li; aal2RxVcTable->uui = extractSpace->uui; if (cpsHdrLen == 3) { if ( aal2RxVcTable->bufHandlePtr == NOT_ALLOCATED) { /* Check if the pool id of the BufHandle in DMEM table * is same as the CP's pool Id, if YES then reuse this * SDRAM buffer. Otherwise allocate another buffer. The * buffer handle offset should be set to 0 in the first * case. * This is to be done because of error in the length of * previous CPS packet. This could happen because of two * simultaneous cells being dropped and which could go * undetected at the handler. */ /* Allocate a bufHandle */ while (bsError(aal2RxVcTable->bufHandlePtr = bsBufferAllocate(poolId))) { bufferAllocFail++; } } aal2RxVcTable->offset = 0; } else aal2RxVcTable->hdrLen = extractSpace->cpsHdrLen; } } else if (cpsPayloadLen != 0) { /* cpsPayloadLen is non-zero and cpsHdrLen is 0 then * this is a partial or complete CPS payload without a * CPS header. * Retrieve the bufHandle, offset from DMEM table, * and just continue. */ bufHandle = aal2RxVcTable->bufHandlePtr; if (bufHandle == NOT_ALLOCATED) { /* Check if the pool id is NOT_ALLOCATED, * if YES then * drop this data, reset DMEM table * entry, reset the ownership of the * extract space and proceed for the * next extract space scope. */ aal2RxVcTable->offset = 0; aal2RxVcTable->hdrLen = 0;#ifdef AAL2_STATISTICS rxAal2LengthErr++ ;#endif } else { offset = AAL2_RX_GetBufOffset(aal2RxVcTable); if ((cpsPayloadLen + offset -1) == aal2RxVcTable->li) { /* Write cpsPayloadLen bytes of data to the SDRAM */ bsBufferWrite(rxTempPdu[fwdrScopeNum], 64 - offset, bufHandle, offset); #ifdef DEBUG_64 while (!bsBufferWriteComplete ()) ;#endif /* Store data in CPS descriptor */ pCpsDesc = gpAal2RxContext->cpsDescArray[NumCpsPckGot]; pCpsDesc->cpsPckPayload = bufHandle; pCpsDesc->li = aal2RxVcTable->li; pCpsDesc->uui = aal2RxVcTable->uui; /* Launch a TLU lookup for the cidIndex */ gpAal2RxContext->aal2ConnectionId = composeCidIndex(inVcIndex, aal2RxVcTable->cid); tsEntryLookup(gpAal2RxContext->tableId, &gpAal2RxContext->key, &gpAal2RxContext->entry[NumCpsPckGot]); NumCpsPckGot++; /* Reset the values stored in DMEM Table */ aal2RxVcTable->bufHandlePtr = NOT_ALLOCATED; aal2RxVcTable->offset = 0; aal2RxVcTable->cid = 0; } else if ((cpsPayloadLen + offset -1) < aal2RxVcTable->li) { /* Write cpsPayloadLen bytes of data to the SDRAM */ bsBufferWrite(rxTempPdu[fwdrScopeNum], 64 - offset, bufHandle, offset);#ifdef DEBUG_64 while (!bsBufferWriteComplete ()) ;#endif /* Do this after writing to SDRAM */ aal2RxVcTable->offset += cpsPayloadLen; }#ifdef AAL2_STATISTICS else { rxAal2LengthErr++ ; }#endif } } } /* CRC5 TEST */ else {#ifdef AAL2_STATISTICS if (extractSpace->crc5Indicator) { Aal2Crc5Err++ ; }#endif } pduRxToDmem(pduHandle, (int32u*) rxTempPdu[fwdrScopeNum]); endOfCell = extractSpace->endOfCell; pduRxFree(pduHandle); fwdrScopeNum ^= 1; } while ((endOfCell == 0) && (NumCpsPckGot <= 3)); /* We have reached the end of cell or all the CPS descriptors * are full. Go and check the TLU responses. */ /* Retrieve the TLU response, store them in the CPS descriptor and * queue the descriptors to the adjacent AAL2 Tx queues */ for (cpsPckCount = 0; cpsPckCount < NumCpsPckGot; cpsPckCount++) { pCpsDesc = gpAal2RxContext->cpsDescArray[cpsPckCount]; while (!tsLookupResponseValid(cpsPckCount * 2)) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxFwdr: Waiting for TLU lookup response");#endif ksContextSwitch (aal2HdlrContext); } cidTableData = (CidTabEntryData *)tsLookupGetResponse(cpsPckCount * 2); if (cidTableData->cid) { pCpsDesc->egressVcIndex = cidTableData->vcIndex; pCpsDesc->cid = cidTableData->cid; pCpsDesc->atmEgressKey = cidTableData->atmEgressKey; lastBufferEnqueued = pCpsDesc->cpsPckPayload; payloadEnqueue = TRUE; qsMessageSend(cidTableData->queueId, (QsMessage *) &gpAal2RxContext->cpsDescriptor[cpsPckCount]); } else { /* * Free the buffer allocated */ ksPrintf ("cid is zero"); bsBufferFree(pCpsDesc->cpsPckPayload);#ifdef AAL2_STATISTICS rxInvalidCid++;#endif } tsLookupRelease(cpsPckCount * 2); } NumCpsPckGot = 0; } while (endOfCell == 0); cur_vccb->lockFlag = 0; fwdrVccb ^= 1; MSG_EVENT("CPRC AAL2 RX FORWARDER CONTEXT: PROCESSING END"); /* We have finished with a cell so give the control to * Handler so that it can do some processing. */ ksContextSwitch (aal2HdlrContext); } return (TRUE);}/********************************************************************** * Function : aal2RxHdlr * * Description : This function is thread started by aal2Rx(). This * Handler function is responsible for dequeueing a * cell descriptor and transmit the cell payload to * TxSDP after processing the STF field for parity * and sequential number. Also, partial header * bytes and partial payload shall be re-circulated by * this Handler module to the TxSDP Byte Processor. * * Parameters : void pointer. * * Returns : int32u * * Traceability : AAL2_Rx_HLD.doc section: 3.11. * **********************************************************************/int32u aal2RxHdlr(void *arg){ AAL2RxVcTable *aal2RxVcTable; AAL2_RX_MERGE *aal2_Rx_Merge; VCCB *vccb, *prevVccb; PduHandle pduHandle; int32u *puPartial ; int16u ingressVcIndex; int8u receivedSTF, receivedSN, receivedOffset, expectedSN; int8u PAY_BYTES, hdlrVccb = 0, iflag; /* This function is itself a new thread so this function should not * return under any circumstances. */ while(1) { MSG_EVENT("CPRC AAL2 RX HANDLER wait for queue message"); /* If no cell descriptor is in the queue for * processing by the handler, then return to the aal2Rx. */ while (!qsQueueGetLength(baseQueueId)) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for descriptor in queue");#endif ksContextSwitch(aal2FwdrContext); } MSG_EVENT("CPRC AAL2 RX HANDLER CONTEXT: PROCESSING START"); /* Get the cell descriptor from the queue. * Currently, while getting a cell descriptor from the queue, * the handler module does not return the control to Aal2Rx . * This also can be done, if required. */ qsMessageReceiveStart(baseQueueId, &cellDescMsg); /* * Select a VCCB and check whether the Forwarder is working * on this Control Block by checking the VCCB flag. */ vccb = &(gpAal2RxContext->vccb[hdlrVccb]); prevVccb = &(gpAal2RxContext->vccb[(hdlrVccb ^ 1)]); while(!qsMessageReceiveComplete(baseQueueId, &cellDescMsg)) {#ifdef DCP_AAL2_DEBUG ksPrintf("Aal2RxHdlr: Waiting for queue receive to complete");#endif ksContextSwitch(aal2FwdrContext); } /* * Read the cell payload from SDRAM to DMEM. */ bsBufferRead(cellDescPtr->Bh, 0, vccb->cellPayload, 48); ingressVcIndex = cellDescPtr->VcIndex; /* Look for the corresponding record in the DMEM table. */ aal2RxVcTable = &gpAal2RxContext->aal2RxVcTable[ingressVcIndex & 0x1FF]; expectedSN = AAL2_RX_getSeqNo(aal2RxVcTable); /* Get the current scope */ pduHandle = pduHandleForScopeNumber(hdlrVccb); /* Check whether the Buffer Read had been completed or not. * If not yet done switch context to forwarder. * If done then free the buffer handle. */ while (!bsBufferReadComplete()) { ;/* Don't do anything here */ } /* * Process the CPS PDU to check whether it has the correct parity or not. * The parity check is as follows: * Right shift the received STF byte by one. Using this as index, get the * corresponding entry in the parity table. This shall give the expected STF. * Compare the received STF and the expected STF.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -