📄 ixoamcodelet.c
字号:
* N.B. OAM traffic for all ports is received on this VC */ /*Set thread attributes*/ threadAttr.name = pThreadName; threadAttr.stackSize = IX_ATMCODELET_QMGR_DISPATCHER_THREAD_STACK_SIZE; threadAttr.priority = IX_ATMCODELET_QMGR_DISPATCHER_PRIORITY; /* start a receive task */ if (ixOsalThreadCreate(&tid, &threadAttr, (IxOsalVoidFnVoidPtr)ixOamCellRxTask, NULL) != IX_SUCCESS) { IX_OAM_CODELET_LOG_ERROR ("Error spawning SduSend task\n"); return IX_FAIL; } if(IX_SUCCESS != ixOsalThreadStart(&tid)) { printf("Error starting dispatch task\n"); return IX_FAIL; } ixOsalMemSet(&rxVc, 0, sizeof(rxVc)); /* Setup Rx Vc descriptor */ rxVc.vpi = IX_ATMDACC_OAM_RX_VPI; rxVc.vci = IX_ATMDACC_OAM_RX_VCI; rxVc.direction = IX_ATMM_VC_DIRECTION_RX; rxVc.trafficDesc.atmService = IX_ATM_UBR; rxVc.trafficDesc.pcr = 0; /* Ignored for Rx */ /* Setup rx VC, N.B. RxVcId not used in this codelet, * would typically be used for Vc Deregister */ retval = ixAtmmVcRegister (IX_ATMDACC_OAM_RX_PORT, &rxVc, &rxVcId); if (retval != IX_SUCCESS) { IX_OAM_CODELET_LOG_ERROR("Failed to register Rx Channel\n"); return IX_FAIL; } /* Connect Rx VC, N.B. npeRxVcId not used again */ retval = ixAtmdAccRxVcConnect (IX_ATMDACC_OAM_RX_PORT, IX_ATMDACC_OAM_RX_VPI, IX_ATMDACC_OAM_RX_VCI, IX_ATMDACC_OAM, IX_ATM_RX_B, /* low priority Q */ oamRxUserId, ixOamCellRxCallback, IX_ATMDACC_DEFAULT_REPLENISH_COUNT, &oamRxConnId, &npeRxVcId); if (retval != IX_SUCCESS) { IX_OAM_CODELET_LOG_ERROR("Failed to connect Rx Channel\n"); return IX_FAIL; } /* Replenish Rx then register replenish callback */ ixOamRxFreeLowReplenishCallback (oamRxUserId); retval = ixAtmdAccRxVcFreeLowCallbackRegister (oamRxConnId, IX_OAM_REPLENISH_WATERMARK, ixOamRxFreeLowReplenishCallback); if (retval != IX_SUCCESS) { IX_OAM_CODELET_LOG_ERROR("Failed to register Rx replenish callback\n"); return IX_FAIL; } /* enable the oam vc */ retval = ixAtmdAccRxVcEnable (oamRxConnId); if (retval != IX_SUCCESS) { ixOsalLog(IX_OSAL_LOG_LVL_ERROR,IX_OSAL_LOG_DEV_STDERR, "Failed to enable Rx VC \n", 0, 0, 0, 0, 0, 0); return retval; } /* Set the number of ports configured */ ixOamCodeletNumPortsConfigured = numPorts; /* set initialised flag */ ixOamCodeletInitialized = TRUE; IX_OAM_CODELET_LOG ("Initialization Phase Complete\n"); return IX_SUCCESS;}PUBLIC IX_STATUSixOamCodeletOamF5EtePing(IxAtmLogicalPort port, UINT32 vpi, UINT32 vci, UINT32 numCells){ return ixOamCodeletOamPing(port, vpi, vci, IX_OAM_ITU610_F5_ETE_PTI, numCells);}PUBLIC IX_STATUSixOamCodeletOamF5SegPing(IxAtmLogicalPort port, UINT32 vpi, UINT32 vci, UINT32 numCells){ return ixOamCodeletOamPing(port, vpi, vci, IX_OAM_ITU610_F5_SEG_PTI, numCells);}PUBLIC IX_STATUSixOamCodeletOamF4EtePing(IxAtmLogicalPort port, UINT32 vpi, UINT32 numCells){ return ixOamCodeletOamPing(port, vpi, IX_OAM_ITU610_F4_ETE_VCI, 0, /* PTI is don't care for F4, use 0 */ numCells);}PUBLIC IX_STATUSixOamCodeletOamF4SegPing(IxAtmLogicalPort port, UINT32 vpi, UINT32 numCells){ return ixOamCodeletOamPing(port, vpi, IX_OAM_ITU610_F4_SEG_VCI, 0, /* PTI is don't care for F4, use 0 */ numCells);}PRIVATE IX_STATUSixOamCodeletOamPing(IxAtmLogicalPort port, UINT32 vpi, UINT32 vci, UINT32 pti, UINT32 numCells){ UINT32 sendCount = 0; if (!ixOamCodeletInitialized) { IX_OAM_CODELET_LOG_ERROR("Codelet not initialized\n"); return IX_FAIL; } if (port >= (IxAtmLogicalPort)ixOamCodeletNumPortsConfigured) { IX_OAM_CODELET_LOG_ERROR("Port not configured\n"); return IX_FAIL; } if (numCells == 0) { IX_OAM_CODELET_LOG_ERROR("numCells should be > 0\n"); return IX_FAIL; } /* Setup LB info */ lbVpi = vpi; lbVci = vci; lbPti = pti; lbPort = port; while (numCells--) { /* Notify user that a loopback cell is being sent */ IX_OAM_CODELET_LOG ("Sending loopback cell %u\n", sendCount++); /* Send the first cell */ if( ixOamParentLbCellTx (port, vpi, vci, pti) != IX_SUCCESS ) { IX_OAM_CODELET_LOG_ERROR("Failed to send parent loopback cell #%u",sendCount); return IX_FAIL; } /* * A message is displayed at the command shell if a correct loopback child cell has been received in * response to the sending of the parent cell. No message is displayed if no correct child cell * has been received */ /* Wait for 5 seconds for response, see ITU-610 */ ixOsalSleep (IX_OAM_ITU610_LB_TIMEOUT_PERIOD_MSECS); } return IX_SUCCESS;}voidixOamCodeletShow (void){ UINT32 i; IX_OAM_CODELET_LOG("replenishCallbackCount = %u\n", replenishCallbackCount); for (i = 0; i < ixOamCodeletNumPortsConfigured; i++) { IX_OAM_CODELET_LOG("OAM codelet stats for Port %u\n", i); IX_OAM_CODELET_LOG("parentLbCellTxCount \t= %u\n", parentLbCellTxCount[i]); IX_OAM_CODELET_LOG("childLbCellTxCount \t= %u\n", childLbCellTxCount[i]); IX_OAM_CODELET_LOG("parentLbCellRxCount \t= %u\n", parentLbCellRxCount[i]); IX_OAM_CODELET_LOG("childLbCellRxCount \t= %u\n", childLbCellRxCount[i]); IX_OAM_CODELET_LOG("childLbCellRxErrCount \t= %u\n", childLbCellRxErrCount[i]); IX_OAM_CODELET_LOG("parentLbCellRxErrCount \t= %u\n", parentLbCellRxErrCount[i]); IX_OAM_CODELET_LOG("unsupportedOamRxCount \t= %u\n", unsupportedOamRxCount[i]); IX_OAM_CODELET_LOG("txDoneCallbackCount \t= %u\n", txDoneCallbackCount[i]); IX_OAM_CODELET_LOG("\n"); }}PRIVATE void ixOamCellRxTask( void ){ IxOamITU610Cell *rxCell; UINT32 pti; UINT32 vci; UINT32 vpi; UINT32 oamRxHdr=0x0; IX_OSAL_MBUF *rxMbuf; int port; while(1) { for( port=0; port<ixOamCodeletNumPorts; port++ ) { if(!ixOamQueueEmptyQuery(&ixOamSwQueue[port])) { rxMbuf = ixOamMBufQueueGet(&ixOamSwQueue[port]); IX_OSAL_ASSERT( rxMbuf != NULL ); /* invalidate cache */ ixOamRxInvalidate( rxMbuf ); rxCell = (IxOamITU610Cell *)(IX_OSAL_MBUF_MDATA(rxMbuf)); /* Read the VCI & Payload Type */ IX_OAM_HEADER_GET(rxCell, oamRxHdr); vci = IX_OAM_VCI_GET(oamRxHdr); vpi = IX_OAM_VPI_GET(oamRxHdr); pti = IX_OAM_PTI_GET(oamRxHdr); /* Ensure access layer delivered a correct OAM cell */ IX_OSAL_ASSERT ((vci == IX_OAM_ITU610_F4_SEG_VCI) || (vci == IX_OAM_ITU610_F4_ETE_VCI) || (pti == IX_OAM_ITU610_F5_ETE_PTI) || (pti == IX_OAM_ITU610_F5_SEG_PTI)); /* Is it an Loopback cell ? */ if ( (IX_OAM_TYPE_AND_FUNC_GET(rxCell)) == IX_OAM_ITU610_TYPE_FAULT_MAN_LB ) { /* Is Parent Loopback Indication field in cell set? */ if ( (IX_OAM_LOOPBACK_INDICATION_GET(rxCell)) == IX_OAM_ITU610_LB_INDICATION_PARENT ) { ixOamParentLbCellRx (port, rxMbuf); } /* Otherwise child cell, i.e. response to loopback cell sent earlier */ else { ixOamChildLbCellRx(port, rxMbuf); } } else { unsupportedOamRxCount[port]++; /* free the buffer */ ixAtmUtilsMbufFree (rxMbuf); } } } /* share the CPU */ ixOsalSleep(IX_OAM_RX_QUEUE_POLL_INTERVAL); }}PRIVATE voidixOamCellRxCallback (IxAtmLogicalPort port, IxAtmdAccUserId userId, IxAtmdAccPduStatus status, IxAtmdAccClpStatus clp, IX_OSAL_MBUF *rxMbuf){ IX_OSAL_ASSERT(userId == oamRxUserId); /* Status should always be OAM Valid */ IX_OSAL_ASSERT(status == IX_ATMDACC_OAM_VALID); /* queue the mbuf to an rx task */ ixOamQueuePut( &ixOamSwQueue[port], rxMbuf ); } PRIVATE voidixOamChildLbCellRx (IxAtmLogicalPort port, IX_OSAL_MBUF *rxMbuf){ UINT32 pti; UINT32 vpi; UINT32 vci; UINT32 oamHdr = 0x0; IxOamITU610Cell *rxCell; IxOamITU610LbPayload *lbPayload; rxCell = (IxOamITU610Cell *)(IX_OSAL_MBUF_MDATA(rxMbuf)); /* Read the VPI, VCI & Payload Type */ IX_OAM_HEADER_GET(rxCell, oamHdr); vci = IX_OAM_VCI_GET(oamHdr); vpi = IX_OAM_VPI_GET(oamHdr); pti = IX_OAM_PTI_GET(oamHdr); /* Check if the VPI, VCI and Port match */ if ((vpi == lbVpi) && (vci == lbVci) && (port == (IxAtmLogicalPort)lbPort)) { /* Check if F4 flow (F4 VCI) or PTI matches */ if ((vci == IX_OAM_ITU610_F4_SEG_VCI) || (vci == IX_OAM_ITU610_F4_ETE_VCI) || (pti == lbPti)) { /* Setup the data pointers */ lbPayload = &(((IxOamITU610Cell *)(IX_OSAL_MBUF_MDATA(rxMbuf)))->payload.lbPayload); /* Source Id correct, all Ones supported only in this codelet */ if ( ixOamMemCmp(lbPayload->sourceId, (UCHAR *)allOnesLocId, IX_OAM_ITU610_LOCATION_ID_LEN) == 0 ) { /* Correlation tag correct? */ if ( ixOamMemCmp(lbPayload->correlationTag, (UCHAR *)(&lbCorrelationTag), IX_OAM_ITU610_LB_CORRELATION_TAG_LEN) == 0) { /* Notify user that a ping has been successful, * N.B. the user is not notified if ping has failed */ IX_OAM_CODELET_LOG ("OAM ping reply for VPI:%u VCI:%u PTI:%u on Port:%u\n", lbVpi, lbVci, lbPti, lbPort); /* free the buffer */ ixAtmUtilsMbufFree (rxMbuf); childLbCellRxCount[port]++; return; } } } } /* free the buffer */ ixAtmUtilsMbufFree (rxMbuf); childLbCellRxErrCount[port]++;}/* * * Transmit loopback parent cell */PRIVATE IX_STATUSixOamParentLbCellTx (IxAtmLogicalPort port, UINT32 vpi, UINT32 vci, UINT32 pti){ IxOamITU610Cell *txCell; IxOamITU610LbPayload *lbPayload; IX_OSAL_MBUF *txMbuf; IX_STATUS retval = IX_FAIL; UINT32 lockKey; UINT32 oamHdr = 0x0;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -