/*
 * Insert the class tab entry into the class id table.
 */
static ClRcT 
omClassEntryReload (ClCharT *pClassName, ClOmClassTypeT classId)
{
	ClRcT		rc = CL_OK;
    ClOmClassControlBlockT *pClassTab = NULL;
    ClCntNodeHandleT nodeHandle = 0;

    CL_FUNC_ENTER();

    if(!pClassName)
    {
        rc = CL_OM_SET_RC(CL_OM_ERR_NULL_PTR);
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("NULL PTR PASSED"));
        CL_FUNC_EXIT();
        return rc;
    }

	CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("OM entry reload for class = %s, class type %d", pClassName, classId));

    /*
     * First check if the class id entry is already present in the om class id table.
     */
    if(clCntNodeFind(ghOmClassHashTbl, (ClCntKeyHandleT)(ClWordT)classId, &nodeHandle) == CL_OK)
        return CL_OK;

	/* Add this class entry into the OM class lookup table */
	rc = clCntNodeFind(ghOmClassNameHashTbl, (ClCntKeyHandleT)pClassName, &nodeHandle);
	if (rc != CL_OK)
    {
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Unable to find OM Class name [%s] entry in om class table",
                                        pClassName));
		return (rc);
    }
    
    rc = clCntNodeUserDataGet(ghOmClassNameHashTbl, nodeHandle, (ClCntDataHandleT*)&pClassTab);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Unable to get data for OM Class [%s] from om class name table",
                                        pClassName));
        return rc;
    }

    /*
     * Insert this entry into the class id table.
     */
    pClassTab->eMyClassType = classId;

    rc = clCntNodeAdd(ghOmClassHashTbl, (ClCntKeyHandleT)(ClWordT)pClassTab->eMyClassType,
                      (ClCntDataHandleT)pClassTab, NULL);
    if(rc != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Unable to add entry [%#x] for class [%s] to OM class id table",
                                        classId, pClassName));
        return rc;
    }

   	CL_FUNC_EXIT();
	return (rc);
}
ClRcT cpmInvocationGetWithLock(ClInvocationT invocationId,
                               ClUint32T *cbType,
                               void **data)
{
    ClRcT rc = CL_OK;
    ClCntNodeHandleT cntNodeHandle = 0;
    ClCpmInvocationT *invocationData = NULL;

    /*
     * Check the input parameter 
     */
    if ((data == NULL) || (cbType == NULL))
        CL_CPM_CHECK(CL_LOG_SEV_ERROR, ("Invalid parameter passed \n"), CL_CPM_RC(CL_ERR_NULL_POINTER));

    rc = clCntNodeFind(gpClCpm->invocationTable, (ClCntKeyHandleT)&invocationId, &cntNodeHandle);
    if (rc != CL_OK)
        goto failure;

    rc = clCntNodeUserDataGet(gpClCpm->invocationTable, cntNodeHandle, (ClCntDataHandleT *) &invocationData);
    if (rc != CL_OK)
        goto failure;

    *data = invocationData->data;
    CL_CPM_INVOCATION_CB_TYPE_GET(invocationId, *cbType);

    return rc;

  failure:
    return rc;
}
/*
 * This api would be called as and when the object is no more and the corresponding entry 
 * within the container needs to be deleted.
 */
ClRcT clAlarmPayloadCntDelete(ClCorMOIdPtrT pMoId, ClAlarmProbableCauseT probCause, ClAlarmSpecificProblemT specificProblem)
{
	ClRcT rc = CL_OK;
	ClCntNodeHandleT nodeH;
    ClAlarmPayloadCntKeyT *pCntKey = clHeapAllocate(sizeof(ClAlarmPayloadCntKeyT));
    if(NULL == pCntKey)
    {
          CL_DEBUG_PRINT (CL_DEBUG_CRITICAL,("Memory allocation failed with rc 0x%x ", rc));
          return (rc);
    }    
    pCntKey->probCause = probCause;
    pCntKey->specificProblem = specificProblem;
    pCntKey->moId = *pMoId;

    clOsalMutexLock(gClAlarmPayloadCntMutex);        
    rc = clCntNodeFind(gPayloadCntHandle,(ClCntKeyHandleT)pCntKey,&nodeH);
	if(CL_OK == rc)
	{
    	rc = clCntAllNodesForKeyDelete(gPayloadCntHandle,(ClCntKeyHandleT)pCntKey);
    	if (CL_OK != rc)
	    {
        	CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("clCntAllNodesForKeyDelete failed w rc:0x%x\n", rc));
	    }        
	}
	else
	{
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Node does not exist with rc:0x%x\n", rc));
	}
    clHeapFree(pCntKey);
	clOsalMutexUnlock(gClAlarmPayloadCntMutex);    
	return rc;
}
ClRcT _clGmsDbFind(
           CL_IN    const ClGmsDbT*  const  gmsDb,
           CL_IN    const ClGmsDbTypeT     type,
           /* Suppressing coverity warning for pass by value with below comment */
           // coverity[pass_by_value]
           CL_IN    const ClGmsDbKeyT      key,
           CL_INOUT void** const           data)
{    
    ClRcT   rc = CL_OK;
    ClCntKeyHandleT cntKey = NULL;
    ClCntNodeHandleT nodeData = NULL;

    if (gmsDb == (const void *)NULL)
        return CL_ERR_NULL_POINTER;
    
    rc = _clGmsDbGetKey(type, key, &cntKey);

    if (rc != CL_OK) return rc;

    rc = clCntNodeFind(gmsDb->htbl[type], cntKey,
                       (ClCntNodeHandleT*) &nodeData);

    if (rc != CL_OK) return rc;

    rc = clCntNodeUserDataGet((ClCntHandleT) gmsDb->htbl[type],
                                    nodeData, (ClCntDataHandleT*)data);
    return rc;
}
ClRcT _clCorNodeNameToMoIdGet(ClNameT *nodeName, ClCorNodeDataPtrT *dataNode)
{
    ClRcT rc = CL_OK;
    ClCntNodeHandleT nodeHandle = 0;
    ClNameT *tempName = NULL;

	if(nodeName == NULL)
		return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);

    /* Get the data from the hash table */

    CL_DEBUG_PRINT(CL_DEBUG_TRACE,(" Node find for node Name  %s", nodeName->value));

    /* Do the node find and get the node handle for a particular node name. Now walk all the 
     * node for that particular node handle type.
     */
    rc = clCntNodeFind(nodeNameToMoIdTableHandle, (ClCntKeyHandleT)nodeName, &nodeHandle);   
    if(CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Failed to get the node Handle for the Node Name %s. rc [0x%x]", nodeName->value, rc));
        return rc;
    }

    while(nodeHandle != 0)
    {
        rc = clCntNodeUserKeyGet(nodeNameToMoIdTableHandle, nodeHandle, (ClCntKeyHandleT *) &tempName);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to get the user key from the node handle. rc[0x%x]", rc));
            break;
        }

        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Got the Nodename %s", tempName->value));
        rc = clCntNodeUserDataGet(nodeNameToMoIdTableHandle, nodeHandle, (ClCntDataHandleT *)dataNode);
        if(rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to get the user data from the node handle. rc [0x%x]", rc));
            break;
        }

        if((strcmp (nodeName->value, (*dataNode)->nodeName.value)) == 0)
        {
            CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Got the MoId for a Node Name %s", (*dataNode)->nodeName.value));
            return CL_OK;
        } 
        
        rc = clCntNextNodeGet(nodeNameToMoIdTableHandle, nodeHandle, &nodeHandle);  
        if(rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_TRACE,("Failed to get the next node handle. rc[0x%x]", rc));
            break;
        }
    }

    if(CL_OK != rc)
        CL_COR_RETURN_ERROR(CL_DEBUG_TRACE, "Could not get MOId from the node name", rc);    
    return CL_OK;
}
ClRcT
clLogClntStreamEntryGet(ClLogClntEoDataT  *pClntEoEntry,
                        SaNameT           *pStreamName,
                        SaNameT           *pNodeName,
                        ClStringT         *pShmName,
                        ClUint32T         shmSize,
                        ClCntNodeHandleT  *phStreamNode,
                        ClBoolT           *pAddedEntry)
{
    ClRcT             rc            = CL_OK;
    ClLogStreamKeyT   *pStreamKey   = NULL;

    CL_LOG_DEBUG_TRACE(("Enter"));

    *pAddedEntry = CL_FALSE;

    rc = clLogClntEoEntryGet(&pClntEoEntry);
    if( CL_OK != rc )
    {
        CL_LOG_DEBUG_ERROR(("clLogClntEoEntryGet(): rc[0x %x]", rc));
        return rc;
    }

    rc = clLogStreamKeyCreate(pStreamName, pNodeName,
                              pClntEoEntry->maxStreams, &pStreamKey);
    if( CL_OK != rc )
    {
        return rc;
    }

    rc = clCntNodeFind(pClntEoEntry->hClntStreamTable,
                       (ClCntKeyHandleT) pStreamKey,
                       phStreamNode);
    if( CL_ERR_NOT_EXIST == CL_GET_ERROR_CODE(rc) )
    {
        rc = clLogClntStreamEntryAdd(pClntEoEntry->hClntStreamTable,
                                     pStreamKey, pShmName, shmSize,
                                     phStreamNode);
        if( CL_OK != rc )
        {
            clLogStreamKeyDestroy(pStreamKey);
        }
        else
        {
            *pAddedEntry = CL_TRUE;
        }
        return rc;
    }
    clLogStreamKeyDestroy(pStreamKey);

    CL_LOG_DEBUG_TRACE(("Exit"));
    return rc;
}
/*
 * The cnt add function
 * The information is read from COR and then populated in the container
 * This api would be called as and when the object is created and the corresponding entry 
 * within the container needs to be added.
 */
ClRcT clAlarmPayloadCntAdd(ClAlarmInfoT *pAlarmInfo)
{
	ClRcT rc = CL_OK;
	ClCntNodeHandleT nodeH;
    ClAlarmPayloadCntT *payloadInfo;
    
    ClAlarmPayloadCntKeyT *pCntKey = clHeapAllocate(sizeof(ClAlarmPayloadCntKeyT));
    if(NULL == pCntKey)
    {
          CL_DEBUG_PRINT (CL_DEBUG_CRITICAL,("Memory allocation failed with rc 0x%x ", rc));
          return CL_ALARM_RC(CL_ALARM_ERR_NO_MEMORY);
    }    

    payloadInfo = NULL;
    pCntKey->probCause = pAlarmInfo->probCause;
    pCntKey->specificProblem = pAlarmInfo->specificProblem;
    pCntKey->moId = pAlarmInfo->moId;

    payloadInfo = clHeapAllocate(sizeof(ClAlarmPayloadCntT)+pAlarmInfo->len);
    if(NULL == payloadInfo)
    {
          CL_DEBUG_PRINT (CL_DEBUG_CRITICAL,("Memory allocation failed with rc 0x%x ", rc));
          clHeapFree(pCntKey);
          return CL_ALARM_RC(CL_ALARM_ERR_NO_MEMORY);
    }    
    payloadInfo->len = pAlarmInfo->len;
    memcpy(payloadInfo->buff, pAlarmInfo->buff, payloadInfo->len);

	clOsalMutexLock(gClAlarmPayloadCntMutex);        
    rc = clCntNodeFind(gPayloadCntHandle,(ClCntKeyHandleT)pCntKey,&nodeH);
	if(rc != CL_OK)
	{
		rc = clCntNodeAdd((ClCntHandleT)gPayloadCntHandle,
							(ClCntKeyHandleT)pCntKey,
							(ClCntDataHandleT)payloadInfo,
							NULL);
		if (CL_OK != rc)
		{
			CL_DEBUG_PRINT(CL_DEBUG_ERROR,("clCntNodeAdd failed with rc = %x\n", rc));
            clHeapFree(payloadInfo);
            clHeapFree(pCntKey);
        }
        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("clCntNodeAdd adding payloadInfo->len : %d\n",payloadInfo->len));
	}
	else
	{
		CL_DEBUG_PRINT(CL_DEBUG_INFO,("Node already exist\n"));
        clHeapFree(payloadInfo);
        clHeapFree(pCntKey);
	}
	clOsalMutexUnlock(gClAlarmPayloadCntMutex);
	return rc;
}
ClRcT cpmNodeFindLocked(SaUint8T *name, ClCpmLT **cpmL)
{
    ClUint16T nodeKey = 0;
    ClCntNodeHandleT hNode = 0;
    ClCpmLT *tempNode = NULL;
    ClUint32T rc = CL_OK, numNode=0;

    rc = clCksm16bitCompute((ClUint8T *) name, strlen((const ClCharT*)name), &nodeKey);
    CL_CPM_CHECK_2(CL_LOG_SEV_ERROR, CL_CPM_LOG_2_CNT_CKSM_ERR, name, rc, rc,
                   CL_LOG_HANDLE_APP);

    rc = clCntNodeFind(gpClCpm->cpmTable, (ClPtrT)(ClWordT)nodeKey, &hNode);
    CL_CPM_CHECK_3(CL_LOG_SEV_ERROR, CL_CPM_LOG_3_CNT_ENTITY_SEARCH_ERR, "node",
                   name, rc, rc, CL_LOG_HANDLE_APP);

    rc = clCntKeySizeGet(gpClCpm->cpmTable, (ClPtrT)(ClWordT)nodeKey,
                         &numNode);
    CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_CNT_KEY_SIZE_GET_ERR, rc, rc,
                   CL_LOG_HANDLE_APP);

    while (numNode > 0)
    {
        rc = clCntNodeUserDataGet(gpClCpm->cpmTable, hNode,
                                  (ClCntDataHandleT *) &tempNode);
        CL_CPM_CHECK_1(CL_LOG_SEV_ERROR, CL_CPM_LOG_1_CNT_NODE_USR_DATA_GET_ERR,
                       rc, rc, CL_LOG_HANDLE_APP);
        if (!strcmp(tempNode->nodeName, (const ClCharT*)name))
        {
            *cpmL = tempNode;
            goto done;
        }
        if(--numNode)
        {
            rc = clCntNextNodeGet(gpClCpm->cpmTable,hNode,&hNode);
            if(rc != CL_OK)
            {
                break;
            }
        }
    }

    rc = CL_CPM_RC(CL_ERR_DOESNT_EXIST);
    CL_CPM_CHECK_3(CL_LOG_SEV_ERROR, CL_CPM_LOG_3_CNT_ENTITY_SEARCH_ERR,
                   "node", name, rc, rc, CL_LOG_HANDLE_APP);

done:
    return CL_OK;

failure:
    return rc;
}
/**
 *  Returns an OM class entry.
 *
 *  This function returns a pointer to an OM class entry given 
 * OM class Id.
 *                                                                        
 *  @param omClassKey - OM class type
 *
 *  @returns 
 *    Pointer to class control block
 */
ClOmClassControlBlockT *
clOmClassEntryGet(ClOmClassTypeT omClassKey)
{
	ClRcT			rc = CL_OK;
#ifdef CL_DEBUG
	ClUint8T		aFuncName[] = "clOmClassEntryGet()";
#endif
	ClCntNodeHandleT tempNodeHandle = 0;
	ClOmClassControlBlockT 		*pClassEntry = 0;

    CL_FUNC_ENTER();

	if ((rc = omClassTypeValidate(omClassKey)) != CL_OK)
	{
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Invalid input OM class (rc = 0x%x)!\r\n", 
			aFuncName, rc));
		CL_ASSERT(NULL);
		CL_FUNC_EXIT();
		return NULL;
	}

	/* find the node for this MO ID */
	if ((rc = clCntNodeFind(ghOmClassHashTbl, 
		(ClCntKeyHandleT)(ClWordT)omClassKey, &tempNodeHandle)) != CL_OK)
		{
		if (CL_GET_ERROR_CODE(rc) == CL_ERR_NOT_EXIST)
			{
			CL_DEBUG_PRINT(CL_DEBUG_INFO, ("%s: Node does not exist for OM class "
				"(0x%x), with rc 0x%x!\r\n", aFuncName, omClassKey, rc));
			}
		else
			{
			CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to find node for OM class "
				"(0x%x), with rc 0x%x!\r\n", aFuncName, omClassKey, rc));
			}
		return NULL;
		}
	/* now get the OM handle for this MO ID */
	if ((rc = clCntNodeUserDataGet(ghOmClassHashTbl, 
		tempNodeHandle, (ClCntDataHandleT *)&pClassEntry)) != CL_OK)
		{
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to get the OM class entry from the "
			"node for OM class 0x%x, with rc 0x%x!\r\n", aFuncName, 
			omClassKey, rc));
		CL_ASSERT(NULL);
		return  NULL;
		}
 	
   	return pClassEntry;
}
ClRcT clCntNonUniqueKeyFind(ClCntHandleT container, ClCntKeyHandleT key, ClCntDataHandleT givenData,
                            ClInt32T (*cmp)(ClCntDataHandleT data1, ClCntDataHandleT data2), 
                            ClCntDataHandleT *pDataHandle)
{
    ClRcT rc = CL_OK;
    ClCntNodeHandleT node = 0;
    ClCntNodeHandleT nextNode = 0;
    ClCntDataHandleT data = 0;
    ClUint32T sz = 0;

    if(!container || !key || !givenData || !cmp || !pDataHandle)
        return CL_CNT_RC(CL_ERR_INVALID_PARAMETER);

    *pDataHandle = 0;

    rc = clCntNodeFind(container, key, &node);
    if(rc != CL_OK) return rc;

    rc = clCntKeySizeGet(container, key, &sz);
    if(rc != CL_OK) return rc;
    
    while(sz-- > 0 && node)
    {
        rc = clCntNodeUserDataGet(container, node, &data);
        if(rc != CL_OK)
            return rc;
        nextNode = 0;
        if(sz > 0)
        {
            rc = clCntNextNodeGet(container, node, &nextNode);
            if(rc != CL_OK)
                nextNode = 0;
        }
        if(!cmp(givenData, data))
        {
            *pDataHandle = data;
            return CL_OK;
        }
        node = nextNode;
    }
    
    return CL_CNT_RC(CL_ERR_NOT_EXIST);
}
ClRcT   _clGmsNameIdDbFind(ClCntHandleT  *dbPtr,
                           ClNameT       *name,
                           ClGmsGroupIdT *id)
{
    ClRcT   rc = CL_OK;
    ClGmsDbKeyT key = {{0}};
    ClCntKeyHandleT cntKey = NULL;
    ClCntNodeHandleT nodeData = NULL;
    ClGmsNodeIdPairT*   node = NULL;

    if (dbPtr == NULL)
    {
        return CL_ERR_NULL_POINTER;
    }

    memcpy(&key.name, name, sizeof(ClNameT));
    rc = _clGmsDbGetKey(CL_GMS_NAME_ID_DB, key, &cntKey);

    if (rc != CL_OK)
    {
        return rc;
    }

    rc = clCntNodeFind(*dbPtr, cntKey, (ClCntNodeHandleT*) &nodeData);

    if (rc != CL_OK)
    {
        return rc;
    }

    rc = clCntNodeUserDataGet(*dbPtr,
            nodeData, (ClCntDataHandleT*)&node);

    if (rc != CL_OK)
    {
        return rc;
    }

    *id =node->groupId;
    return rc;
}
ClRcT
clCntDataForKeyGet(ClCntHandleT      containerHandle,
                   ClCntKeyHandleT   userKey,
                   ClCntDataHandleT  *pUserData)
{
  ClCntNodeHandleT  containerNode = CL_HANDLE_INVALID_VALUE;
  CclContainer_t    *pContainer   = NULL;
  ClRcT             errorCode     = CL_OK;

  nullChkRet(pUserData);
  *pUserData = CL_HANDLE_INVALID_VALUE;

  pContainer = (CclContainer_t *) containerHandle;
  nullChkRet(pContainer);
  if(pContainer->validContainer != CONTAINER_ID)
  {
    returnCntError(CL_ERR_INVALID_HANDLE, "Passed container handle is invalid");
  }

  if(pContainer->isUniqueFlag == 0) 
  {
      returnCntError(CL_ERR_NOT_IMPLEMENTED,
              "This feature is not applicaple for non unique container");
  }

  errorCode = clCntNodeFind(containerHandle, userKey, &containerNode);
  if(errorCode != CL_OK)
  {
      returnCntError(CL_ERR_NOT_EXIST, "Key doesn't exist");
  }

  errorCode = clCntNodeUserDataGet(containerHandle, containerNode, pUserData);
  if(errorCode != CL_OK)
  {
    return(errorCode);
  }

  return(CL_OK);
}
ClRcT cpmInvocationDeleteInvocation(ClInvocationT invocationId)
{
    ClRcT rc = CL_OK;
    ClCntNodeHandleT cntNodeHandle = 0;
    ClCpmInvocationT *invocationData = NULL;

    clOsalMutexLock(gpClCpm->invocationMutex);

    rc = clCntNodeFind(gpClCpm->invocationTable,
                       (ClCntKeyHandleT)&invocationId, &cntNodeHandle);
    if (rc != CL_OK)
        goto withLock;

    rc = clCntNodeUserDataGet(gpClCpm->invocationTable, cntNodeHandle,
                              (ClCntDataHandleT *) &invocationData);
    if (rc != CL_OK)
        goto withLock;

    rc = clCntNodeDelete(gpClCpm->invocationTable, cntNodeHandle);
    if (rc != CL_OK)
        goto withLock;

    if( (invocationData->flags & CL_CPM_INVOCATION_DATA_COPIED))
    {
        clHeapFree(invocationData->data);
    }

    clHeapFree(invocationData);

    clOsalMutexUnlock(gpClCpm->invocationMutex);

    clLogDebug("INVOCATION", "DEL", "Deleted invocation [%#llx]", invocationId);

    return rc;

  withLock:
    clOsalMutexUnlock(gpClCpm->invocationMutex);
    return rc;
}
ClRcT clCntNodeAddAndNodeGet(ClCntHandleT containerHandle,
           ClCntKeyHandleT userKey,
           ClCntDataHandleT userData,
           ClRuleExprT* pExp, ClCntNodeHandleT* pNodeHandle)
{
    ClRcT rc = CL_OK;

    nullChkRet(pNodeHandle);

    rc = clCntNodeAdd(containerHandle, userKey, userData, pExp);
    if(CL_OK != rc)
    {
        return rc;
    }
    rc = clCntNodeFind (containerHandle, userKey, pNodeHandle);
    CL_ASSERT(rc == CL_OK); /* I just added it, so I should be able to find it! */
    
    if(CL_OK != rc)
    {
        return rc;
    }
        
    return CL_OK;
}
ClRcT _clTxnAgentProcessMgrCmd(
        CL_IN   ClBufferHandleT     inMsgHandle,
        CL_IN   ClBufferHandleT     outMsgHandle,
        CL_IN   ClTxnMessageHeaderT *pMsgHdr)
{
    ClRcT   rc  = CL_OK;
    ClTxnCmdT   tCmd = {.resp = CL_OK };
    ClTxnCommHandleT commHandle = NULL;
    ClUint32T   mCount = pMsgHdr->msgCount;
    ClTimeT t1, t2;

    
    CL_FUNC_ENTER();

    clLogDebug("AGT", NULL,
            "Received processing cmd from TM. Message count [%d]", 
            pMsgHdr->msgCount);
    t1 = clOsalStopWatchTimeGet();

    while ( (CL_OK == tCmd.resp) && (pMsgHdr->msgCount > 0) )
    {

        pMsgHdr->msgCount--;

        rc = VDECL_VER(clXdrUnmarshallClTxnCmdT, 4, 0, 0)(inMsgHandle, &tCmd);
        switch (tCmd.cmd)
        {
            case CL_TXN_CMD_INIT:
                rc = clTxnAgentTxnDefnReceive(tCmd, inMsgHandle); 
                if(CL_OK != rc)
                {
                    clLogError("AGT", "MTA",
                            "Failed to process init command from manager, rc=[0x%x]",
                            rc);
                    /* Construct payload to send response back to server */
                    clTxnMutexLock(clTxnAgntCfg->actMtx);
                    
                   /* tCmd.resp = rc; */

                    rc = clTxnCommIfcNewSessionCreate(CL_TXN_MSG_AGNT_RESP, 
                                                      pMsgHdr->srcAddr, 
                                                      CL_TXN_SERVICE_AGENT_RESP_RECV, 
                                                      NULL, CL_TXN_RMD_DFLT_TIMEOUT,  
                                                      CL_TXN_COMMON_ID, /* Value is 0x1 */
                                                      &commHandle);
                    if (CL_OK == rc)
                    {
                        rc = clTxnCommIfcSessionAppendTxnCmd(commHandle, &tCmd);

                        if (CL_OK != rc)
                        {
                            clLogError("AGT", NULL,
                                    "Failed to append cmd in the response with error [0x%x]",
                                    rc); 
                            clTxnMutexUnlock(clTxnAgntCfg->actMtx);
                            break;
                        }
                        rc = clTxnCommIfcSessionRelease(commHandle);
                        if (CL_OK != rc)
                        {
                            clLogError("AGT", NULL,
                                    "Failed to release session with error[0x%x]",
                                    rc); 
                            clTxnMutexUnlock(clTxnAgntCfg->actMtx);
                            break;
                        }
                        clTxnMutexUnlock(clTxnAgntCfg->actMtx);
                    }
                    else
                        clLogError("AGT", "ATM", 
                                "Failed to create new session for key [Node:0x%x,Port:0x%x]", 
                                pMsgHdr->srcAddr.nodeAddress, pMsgHdr->srcAddr.portId);
                    break;

                }
                /* Request for the first time */
                if(mCount == (pMsgHdr->msgCount + 1) )
                {
                    rc = _clTxnAgentTxnStart(tCmd);
                    if(CL_OK != rc)
                    {
                        /*tCmd.resp = rc; */
                        clLogError("AGT", "MTA",
                                "Failed to start transaction[0x%x:0x%x], rc=[0x%x]",
                                tCmd.txnId.txnMgrNodeAddress,
                                tCmd.txnId.txnId,
                                rc);
                        break;
                    }
                    clLogDebug("AGT", "MTA",
                            "Transaction[0x%x:0x%x] started",
                            tCmd.txnId.txnMgrNodeAddress,
                            tCmd.txnId.txnId);
                }
                break;

            case CL_TXN_CMD_PREPARE:
            case CL_TXN_CMD_1PC_COMMIT:
            case CL_TXN_CMD_2PC_COMMIT:
            case CL_TXN_CMD_ROLLBACK:
                rc = clTxnAgentProcessJob(pMsgHdr, tCmd, outMsgHandle, &commHandle);
                if(CL_OK != rc)
                {
                  /*  tCmd.resp = rc; */
                    clLog(CL_LOG_ERROR, "AGT", NULL,
                            "Error in processing cmd [%s] from server. rc [0x%x]", 
                            _clTxnCmdNameGet(tCmd.cmd), rc);
                }
                if(!pMsgHdr->msgCount && 
                    ( (tCmd.cmd == CL_TXN_CMD_ROLLBACK) || 
                      (tCmd.cmd == CL_TXN_CMD_2PC_COMMIT) ) 
                  )
                {
                    rc = _clTxnAgentTxnStop(tCmd);
                    if(CL_OK != rc)
                    {
                       /* tCmd.resp = rc; */
                        clLogError("AGT", "MTA",
                                "Failed to stop transaction[0x%x:0x%x], rc=[0x%x]",
                                tCmd.txnId.txnMgrNodeAddress,
                                tCmd.txnId.txnId, rc);
                    }
                    else
                        clLogDebug("AGT", "MTA",
                                "Transaction[0x%x:0x%x] stopped",
                                tCmd.txnId.txnMgrNodeAddress,
                                tCmd.txnId.txnId);
                }
                
                /* Remove the joblist when ROLLBACK or COMMIT is complete */
                if( (tCmd.cmd == CL_TXN_CMD_ROLLBACK) || 
                    (tCmd.cmd == CL_TXN_CMD_2PC_COMMIT) ) 
                {
                    ClTxnDefnPtrT pTxnDefn = NULL;
                    clLogDebug("AGT", NULL,
                            "Received remove cmd from server");
                    rc = clTxnDbTxnDefnGet(clTxnAgntCfg->activeTxnMap, 
                                    tCmd.txnId, &pTxnDefn);
                    if(CL_OK == rc)
                    {
                        if(1 < pTxnDefn->jobCount)
                        {
                            rc = clTxnAppJobRemove(pTxnDefn, tCmd.jobId);
                            if(CL_OK != rc)
                            {
                                ClNameT name = {0};
                                clCpmComponentNameGet(0, &name);
                                clLog(CL_LOG_ERROR, "AGT", NULL,
                                     "REMOVE cmd received. Error in removing the job information for component [%s] rc [0x%x]", 
                                     name.value, rc);
                                return rc;
                            }

                        }
                        else if(1 == pTxnDefn->jobCount) /* This is the last job, delete the entire txn list */
                        {
                            ClCntNodeHandleT nodeHandle;
                            rc  = clCntNodeFind(
                                    clTxnAgntCfg->activeTxnMap, 
                                    (ClCntKeyHandleT )&(tCmd.txnId), 
                                    &nodeHandle);
                            if(rc == CL_OK)
                            {
                                rc = clCntNodeDelete(clTxnAgntCfg->activeTxnMap, nodeHandle);
                                if(CL_OK != rc)
                                {
                                    clLog(CL_LOG_ERROR, "AGT", NULL, 
                                         "REMOVE cmd received. Error in deleting txn defn for txnId [0x%x] rc [0x%x]", 
                                         tCmd.txnId.txnId, rc);
                                    return rc;
                                }
                            }

                        }
                        else
                        {
                            clLog(CL_LOG_ERROR, "AGT", NULL,
                            "Remove cmd received. There is no txndefn corresponding to txnId [0x%x]. Jobcount [%d]\n",
                             tCmd.txnId.txnId, pTxnDefn->jobCount);
                        }
                    }
                }
                
                break;
                default:
                    clLog(CL_LOG_ERROR, "AGT", NULL, 
                        "Invalid command received from TM [0x%x]", tCmd.cmd);
                    rc = CL_ERR_INVALID_PARAMETER;
                    break;
        }
    }
    if((tCmd.cmd != CL_TXN_CMD_REMOVE_JOB) && commHandle)
    {
        rc = clTxnCommIfcReadMessage(commHandle, outMsgHandle);
        if(CL_OK != rc)
        {
            clLogError("AGT", NULL,
                    "Failed to write the response with error [0x%x]",
                    rc);
        }
        else
            clLogDebug("AGT", "ATM",
                    "Successfully sent response back");
        t2 = clOsalStopWatchTimeGet();
        clLogDebug("AGT", NULL,
                "Time taken to complete command[%d], [%lld]usecs",
                tCmd.cmd, (t2-t1) );
    }

    if (CL_OK != rc)
    {
            rc = CL_GET_ERROR_CODE(rc);
    }

    CL_FUNC_EXIT();
    return (rc);
}
static ClRcT cpmNodeRmv(ClCharT *nodeName)
{
    ClRcT rc = CL_OK;
    ClUint16T nodeKey = 0;
    ClCntNodeHandleT hNode = 0;
    ClUint32T numNode = 0;
    ClCpmLT *cpm = NULL;
    ClBoolT done = CL_NO;
    if (!nodeName)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "NULL pointer passed.");
        goto failure;
    }

    rc = clCksm16bitCompute((ClUint8T *)nodeName,
                            strlen(nodeName),
                            &nodeKey);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to compute checksum for node, "
                   "error [%#x]",
                   rc);
        goto failure;
    }

    clOsalMutexLock(gpClCpm->cpmTableMutex);

    rc = clCntNodeFind(gpClCpm->cpmTable,
                       (ClCntKeyHandleT)(ClWordT)nodeKey,
                       &hNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to find node [%s], error [%#x]",
                   nodeName,
                   rc);
        goto unlock;
    }

    rc = clCntKeySizeGet(gpClCpm->cpmTable,
                         (ClCntKeyHandleT)(ClWordT)nodeKey,
                         &numNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Unable to get key size, error [%#x]",
                   rc);
        goto unlock;
    }

    while (numNode > 0)
    {
        rc = clCntNodeUserDataGet(gpClCpm->cpmTable,
                                  hNode,
                                  (ClCntNodeHandleT *) &cpm);
        if (CL_OK != rc)
        {
            clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                       "Unable to get user data, error [%#x]",
                       rc);
            goto unlock;
        }

        if (!strncmp(nodeName, cpm->nodeName, CL_MAX_NAME_LENGTH-1))
        {
            clCntNodeDelete(gpClCpm->cpmTable, hNode);
            done = CL_YES;
            break;
        }

        if (--numNode)
        {
            rc = clCntNextNodeGet(gpClCpm->cpmTable, hNode, &hNode);
            if (CL_OK != rc)
            {
                break;
            }
        }
    }

    if (!done)
    {
        rc = CL_CPM_RC(CL_ERR_DOESNT_EXIST);
        goto unlock;
    }

    --gpClCpm->noOfCpm;

    clOsalMutexUnlock(gpClCpm->cpmTableMutex);

    /*
     * Delete from slot table
     */
    clOsalMutexLock(&gpClCpm->cpmMutex);
    if(cpmSlotClassDelete(nodeName) != CL_OK)
    {
        clLogWarning("CPM", "MGMT", "Slot class delete failed for node [%s]", nodeName);
    }
    clOsalMutexUnlock(&gpClCpm->cpmMutex);

    return CL_OK;

unlock:
    clOsalMutexUnlock(gpClCpm->cpmTableMutex);
failure:
    return rc;
}
static ClRcT cpmComponentRmv(ClCharT *compName)
{
    ClRcT rc = CL_OK;
    ClUint16T compKey = 0;
    ClCntNodeHandleT hNode = 0;
    ClUint32T numNode = 0;
    ClCpmComponentT *comp = NULL;
    ClBoolT done = CL_NO;
    SaNameT entity = {0};

    if (!compName)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "NULL pointer passed.");
        goto failure;
    }

    rc = clCksm16bitCompute((ClUint8T *)compName,
                            strlen(compName),
                            &compKey);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to compute checksum for component, "
                   "error [%#x]",
                   rc);
        goto failure;
    }
    saNameSet(&entity, compName);
    /*
     * Clear pending invocations for the component being removed.
     */
    (void)cpmInvocationClearCompInvocation(&entity);
    clOsalMutexLock(gpClCpm->compTableMutex);
    clOsalMutexLock(&gpClCpm->compTerminateMutex);

    rc = clCntNodeFind(gpClCpm->compTable,
                       (ClCntKeyHandleT)(ClWordT)compKey,
                       &hNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Failed to find component [%s], error [%#x]",
                   compName,
                   rc);
        goto unlock;
    }

    rc = clCntKeySizeGet(gpClCpm->compTable,
                         (ClCntKeyHandleT)(ClWordT)compKey,
                         &numNode);
    if (CL_OK != rc)
    {
        clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                   "Unable to get key size, error [%#x]",
                   rc);
        goto unlock;
    }

    while (numNode > 0)
    {
        rc = clCntNodeUserDataGet(gpClCpm->compTable,
                                  hNode,
                                  (ClCntNodeHandleT *) &comp);
        if (CL_OK != rc)
        {
            clLogError(CPM_LOG_AREA_CPM, CPM_LOG_CTX_CPM_MGM,
                       "Unable to get user data, error [%#x]",
                       rc);
            goto unlock;
        }

        if (!strncmp(compName,
                     comp->compConfig->compName,
                     CL_MAX_NAME_LENGTH-1))
        {
            clCntNodeDelete(gpClCpm->compTable, hNode);
            done = CL_YES;
            break;
        }

        if (--numNode)
        {
            rc = clCntNextNodeGet(gpClCpm->compTable, hNode, &hNode);
            if (CL_OK != rc)
            {
                break;
            }
        }
    }

    if (!done)
    {
        rc = CL_CPM_RC(CL_ERR_DOESNT_EXIST);
        goto unlock;
    }
    
    --gpClCpm->noOfComponent;

    clOsalMutexUnlock(&gpClCpm->compTerminateMutex);
    clOsalMutexUnlock(gpClCpm->compTableMutex);

    return CL_OK;

unlock:
    clOsalMutexUnlock(&gpClCpm->compTerminateMutex);
    clOsalMutexUnlock(gpClCpm->compTableMutex);
failure:
    return rc;
}
static ClRcT rmdSendTimerFunc(void *pData)
{
    ClCntNodeHandleT    nodeHandle;
    ClRmdRecordSendT    *rec         = NULL;
    ClRcT               rc;
    ClRcT               retCode      = 0;
    ClRmdObjT           *pRmdObject;
    ClRmdAsyncCallbackT fpTempPtr;
    void                *cookie;
    ClBufferHandleT     outMsgHdl;
    ClEoExecutionObjT   *pThis       = NULL;
    ClUint64T           msgId        = (ClUint32T)(ClWordT) pData;

    CL_FUNC_ENTER();
    if (pData == NULL)
    {
        return (CL_RMD_RC(CL_ERR_INVALID_BUFFER));
    }
    rc = clEoMyEoObjectGet(&pThis);

    if ( CL_OK != rc )
    {
        return rc;
    }

    pRmdObject = (ClRmdObjT *) (pThis->rmdObj);
    if (pRmdObject == NULL)
    {
        return (CL_RMD_RC(CL_ERR_INVALID_BUFFER));
    }

    rc = clOsalMutexLock(pRmdObject->semaForSendHashTable);
    CL_ASSERT(rc == CL_OK);
    clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 0");
    rc = clCntNodeFind(pRmdObject->sndRecContainerHandle, (ClPtrT)(ClWordT)msgId,
                       &nodeHandle);
    if (rc == CL_OK)
    {
        clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 1");

        rc = clCntNodeUserDataGet(pRmdObject->sndRecContainerHandle, nodeHandle,
                                  (ClCntDataHandleT *) &rec);
        if (rc == CL_OK)
        {
            clLogNotice("CALLBACK", "TASKS","Enter rmdSendTimerFunc 2");
            if (rec)
            {
                /*
                 * Disabling retries for ASYNC since we dont want
                 * to land up in duplicate send mess as anyway we have
                 * accounted for the retries while creating the async timer.
                 */
                if (0 && rec->recType.asyncRec.noOfRetry > 0)
                {
                    /*
                     * key is part of record so no need to free just reuse
                     */
                    retCode = resendMsg(rec, pRmdObject, pThis);
                }
                else
                {
                    /*
                     * key is part of record so no need to free, it will be
                     * freed by hash delete callback
                     */
                    RMD_STAT_INC(pRmdObject->rmdStats.nCallTimeouts);
                    retCode = clTimerDeleteAsync(&rec->recType.asyncRec.timerID);
                    if (rec->recType.asyncRec.func)
                    {
                        /*
                         * unlocking it as callback func can make the rmd call
                         */
                        ClBufferHandleT message;

                        fpTempPtr = rec->recType.asyncRec.func;
                        cookie = rec->recType.asyncRec.cookie;
                        outMsgHdl = rec->recType.asyncRec.outMsgHdl;
                        message = rec->recType.asyncRec.sndMsgHdl;
                        clBufferHeaderTrim(message, rec->hdrLen);
                        rc = clCntNodeDelete(pRmdObject->sndRecContainerHandle,
                                             nodeHandle);
                        rc = clOsalMutexUnlock(pRmdObject->
                                               semaForSendHashTable);
                        fpTempPtr((CL_RMD_RC(CL_ERR_TIMEOUT)), cookie, message,
                                  outMsgHdl);
                        clBufferDelete(&(message));
                        rc = clOsalMutexLock(pRmdObject->semaForSendHashTable);
                    }
                }
            }
        }
    }

    rc = clOsalMutexUnlock(pRmdObject->semaForSendHashTable);
    CL_ASSERT(rc == CL_OK);
    CL_FUNC_EXIT();
    return CL_OK;

}