/**
 * This function receives control message from transaction-manager for coordinating
 * for a given transaction-job. Parameters identify transaction-job and the control
 * information necessary to execute the next step.
 */
ClRcT 
VDECL(clTxnAgentCntrlMsgReceive)(
        CL_IN   ClEoDataT               eoArg, 
        CL_IN   ClBufferHandleT  inMsg, 
        CL_IN   ClBufferHandleT  outMsg)
{
    ClRcT                   rc = CL_OK;
    ClTxnMessageHeaderT     msgHeader = {{0}};
    ClTxnMessageHeaderIDLT  msgHeadIDL = {{0}};
    
    CL_FUNC_ENTER();

    rc = VDECL_VER(clXdrUnmarshallClTxnMessageHeaderIDLT, 4, 0, 0)(inMsg, &msgHeadIDL);
    if(CL_OK != rc)
    {
        clLogError("AGT", NULL,
                "Error in unmarshalling msgHeadIDL, rc [0x%x]", rc);
        return rc;
    }

    _clTxnCopyIDLToMsgHead(&msgHeader, &msgHeadIDL);
    CL_ASSERT(msgHeader.msgCount);

    /* Check/Validate server version */
    rc = clVersionVerify (&clTxnMgmtVersionDb, &(msgHeader.version));
    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Un-supported version. rc:0x%x\n", rc));
        CL_FUNC_EXIT();
        return (CL_GET_ERROR_CODE(rc));
    }

    clLogDebug("AGT", NULL, "Receiving control-msg from txn-manager");

    /* 
       Based on msg-type, 
       - If this is TXN_DEFN, then extract the txn and job-defn and do initialize.
         Respond CL_OK, if everything is fine.

       - If this is TXN_CMD, then for each txn and job (if mentioned), execute 
         and intended operation

       - If TXN_STATUS_CHANGE, take action accordingly
    */

    switch (msgHeader.msgType)
    {
        case CL_TXN_MSG_MGR_CMD:
            rc = _clTxnAgentProcessMgrCmd(inMsg, outMsg, &msgHeader);
            break;

        case CL_TXN_MSG_CLIENT_REQ_TO_AGNT:
            rc = _clTxnAgentProcessClientCmd(inMsg, outMsg, &msgHeader);
            break;
        
        case CL_TXN_MSG_COMP_STATUS_UPDATE:
            rc = CL_ERR_NOT_IMPLEMENTED;
            break;

        default:
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, 
                ("Invalid msg-type received 0x%x\n", msgHeader.msgType));
            rc = CL_ERR_INVALID_PARAMETER;
            break;
    }
/* This is to be replaced by clTxnCommIfcReadMessage(). clTxnCommIfcReadMessage()
 * writes to the outMsgHdl which is either received by the client or server depending
 * on where the async request came from 
 */
#if 0
    rc = clTxnCommIfcAllSessionClose();

    if (CL_OK != rc)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to process received msg. rc:0x%x\n", rc));
        /* FIXME: Do logging */
        rc = CL_GET_ERROR_CODE(rc);
    }
#endif

    CL_FUNC_EXIT();
    return (rc);
}
/** 
 *  Class Type create API.
 *
 *  Creates a new class type with the given information like class id,
 *  number of attributes, max and minimum instances for the class.
 *  NOTE: What happens in case of different versions?? need to figure
 *  out.
 *
 *  @param id            class id
 *  @param nAttrs        Number of attributes in class.
 *
 *  @returns 
 *    CORClass_h   (non-null) valid class handle
 *      null(0)    on failure.
 * 
 */
ClRcT
dmClassCreate(ClCorClassTypeT id,
              ClCorClassTypeT inhId)
{
    CORClass_h tmp = 0;
    CORClass_h tmp1 = 0;
    ClRcT ret = CL_OK;

    CL_FUNC_ENTER();

    if(!dmGlobal)
    {
        CL_FUNC_EXIT();  
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassCreate (Class:%04x, Inh:%04x)", id, inhId));
    
    /* check if id & inhId is already present 
     */
    HASH_GET(dmGlobal->classTable, id, tmp);
    if(inhId > 0) 
    {
        HASH_GET(dmGlobal->classTable, inhId, tmp1);
    }
    
    if(tmp) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassCreate (Class:%04x, Inh:%04x) [Class present]", id, inhId));
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_PRESENT);
    } 
    else if(tmp1 == 0 && inhId > 0) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassCreate (Class:%04x, Inh:%04x) [Superclass unknown]", id, inhId));
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT);
    } 
    else 
    {
        /* Create the new class
         */
        tmp = (CORClass_h) clHeapAllocate(sizeof(CORClass_t));
        if(tmp != 0) 
        {
            /* init stuff here */
            tmp->classId = id;
            tmp->superClassId = inhId; 
            tmp->size = -1;
            tmp->version.releaseCode = CL_RELEASE_VERSION;
            tmp->version.majorVersion = CL_MAJOR_VERSION;
            tmp->version.minorVersion = CL_MINOR_VERSION;
            tmp->flags = 0;
            tmp->moClassInstances = 0;

            if (CL_OK != (ret = HASH_CREATE(&tmp->attrList)))
            { 
                  clHeapFree(tmp);
                  CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to create hash table for Attributes [rc 0x%x]", ret));
                  CL_FUNC_EXIT();  
                  return (ret);
            }
        
            if (CL_OK != (ret = COR_LLIST_CREATE(&tmp->objFreeList)))
            {
                clHeapFree(tmp);
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to create hash table for free objects [rc 0x%x]", ret));
                CL_FUNC_EXIT();
                return (ret);
            }

            tmp->nAttrs = 0;
            tmp->noOfChildren = 0;
            tmp->recordId = 1;
            tmp->objCount = 0;
            tmp->objBlockSz = COR_OBJ_DEF_BLOCK_SIZE;

            /* init the vector, check the return value
             * and remove class/hashtable
             */
            if (CL_OK != (ret = corVectorInit(&tmp->attrs, 
                          sizeof(CORAttr_t),
                          COR_CLASS_DEF_BLOCK_SIZE)))
            {
                HASH_FREE(tmp->attrList);
                COR_LLIST_FREE(tmp->objFreeList);
                clHeapFree(tmp);
    	        CL_FUNC_EXIT();  
     	        return (ret);
	        }

            /* add the newly created class to the class table */
            if (CL_OK != (ret = HASH_PUT(dmGlobal->classTable, id, tmp)))
	        {
              corVectorRemoveAll(&tmp->attrs);
              HASH_FREE(tmp->attrList);
              COR_LLIST_FREE(tmp->objFreeList);
              clHeapFree(tmp);
       	      CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to add class in Data Manager [rc 0x%x]", ret));
    	      CL_FUNC_EXIT();  
     	      return (ret);
	        }
            /* declare the inh class as base class */
            if(inhId > 0) 
            {
                tmp1->noOfChildren++;
                COR_CLASS_SETAS_BASE(*tmp1);
            }
        } 
        else 
        {
	        clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
				CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
                CL_DEBUG_PRINT(CL_DEBUG_CRITICAL, (CL_COR_ERR_STR_MEM_ALLOC_FAIL)); 
            ret = CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
        }
    }

    CL_FUNC_EXIT();  
    return (ret);
}
/** 
 * Compute size for the given class.
 *
 * API to compute size for all the class definitions. This function is
 * used by hashtable
 *
 *  @param this       object handle
 *  @param 
 * 
 *  @returns 
 *    ClRcT  CL_OK on success <br>
 *     CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) on null parameter.
 *
 *  @todo      need to fix the order in which its initialized.
 *
 */
ClRcT
dmClassSize(CORHashKey_h   key, 
            CORHashValue_h classBuf, 
            void *         userArg,
            ClUint32T dataLength
            )
{
    CORClass_h tmp = 0;
    ClInt32T sz = 0;
    ClInt32T* val = 0;
    ClUint16T Id = 0;
    ClUint16T* attrIdx = &Id;
    ClRcT rc = CL_OK;

    CL_FUNC_ENTER();

    if(!classBuf)
      {
        CL_FUNC_EXIT();  
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
      }

    tmp = (CORClass_h) classBuf; 
    if(tmp->size < 0) 
      {
        /* compute the full size */
        clLogDebug("DM", "ATR", "Computing class size for class id : [0x%x]", tmp->classId);

        val = &sz;
        rc = dmClassAttrWalk(tmp, NULL, dmClassAttrSize, (Byte_h*) &val);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Class Attr Walk failed. Failed to compute the size of the attributes. rc [0x%x]", rc));
            CL_FUNC_EXIT();
            return rc;
        }
		
        sz = (sz + sizeof(ClWordT)-1) & ~(sizeof(ClWordT)-1);

   /* Assign indexes to attributes. To be used in compressed 
         * DM Object Handle */
        rc = dmClassAttrWalk(tmp,
   				NULL,
   				dmObjectAttrIndexSet,
   				(Byte_h*)&attrIdx);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Class Attr Walk failed. Failed to find the indexes of the attributes. rc [0x%x]", rc));
            CL_FUNC_EXIT();
            return rc;
        }

        tmp->size = sz;
        clLogDebug("DM", "ATR", "Size of the class [0x%x] is : [%d]", tmp->classId, tmp->size);

        /* initialize the objects vector */
        
        /* todo: check the return value
         */
      }

    CL_FUNC_EXIT();
    return CL_OK;
}
/**
 * Initializes Checkpoint for transaction-service.
 * This function initializes checkpoint service with check-point name
 * and creates default data-set to hold transaction-service-state.
 */
ClRcT clTxnServiceCkptInitialize()
{
    ClRcT       rc      = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        rc = clCkptLibraryInitialize(&(clTxnServiceCfg->txnCkptHandle) );

        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to initialize transaction ckpt library. rc:0x%x", rc));
            CL_FUNC_EXIT();
            return CL_GET_ERROR_CODE(rc);
        }

        /* Initialize check-point name and create checkpoint for txn-service */
        txnCkptName.length = strlen(CL_TXN_CKPT_NAME) + 1;
        memset(&(txnCkptName.value[0]), '\0', txnCkptName.length);
        strncpy(&(txnCkptName.value[0]), CL_TXN_CKPT_NAME, txnCkptName.length);

        clCkptLibraryDoesCkptExist(clTxnServiceCfg->txnCkptHandle, &txnCkptName, &(clTxnServiceCfg->retVal));
        rc = clCkptLibraryCkptCreate(clTxnServiceCfg->txnCkptHandle, &txnCkptName);

        if (CL_OK == rc)
        {
            rc = clCkptLibraryCkptDataSetCreate(clTxnServiceCfg->txnCkptHandle,
                                                &txnCkptName, CL_TXN_SERVICE_DATA_SET,
                                                0, 0,
                                                _clTxnServiceCkptAppStatePack,
                                                _clTxnServiceCkptAppStateUnpack);
        }

        if (CL_OK == rc)
        {
            /* Create data-set for transaction logs requied for recovery */
            rc = clCkptLibraryCkptDataSetCreate(clTxnServiceCfg->txnCkptHandle,
                                                &txnCkptName, CL_TXN_RECOVERY_DATA_SET,
                                                0, 0,
                                                _clTxnCkptDummyPackFn,  /* Dummy fn */
                                                _clTxnCkptDummyUnpackFn);   /* Dummy fn */
        }

        if (CL_OK == rc)
        {
            /* Create elements of this data-set */
            rc = clCkptLibraryCkptElementCreate(clTxnServiceCfg->txnCkptHandle,
                                                &txnCkptName, CL_TXN_RECOVERY_DATA_SET,
                                                _clTxnServiceCkptTxnStatePack,
                                                _clTxnServiceCkptTxnStateUnpack);
        }

        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to create checkpoint/data-set. rc:0x%x", rc));
            clCkptLibraryCkptDelete(clTxnServiceCfg->txnCkptHandle, &txnCkptName);
            clCkptLibraryFinalize(clTxnServiceCfg->txnCkptHandle);
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
/**
 * Internal function to pack/prepare state oa given transaction
 */
static ClRcT _clTxnServiceCkptTxnPack(
    CL_IN   ClUint32T   dataSetId,
    CL_OUT  ClAddrT     *ppData,
    CL_OUT  ClUint32T   *pDataLen,
    CL_IN   ClPtrT      cookie)
{
    ClRcT                   rc = CL_OK;
    ClTxnDefnT              *pTxnDefn;
    ClBufferHandleT  txnStateBuf;
    ClUint32T               msgLen;

    CL_FUNC_ENTER();

    pTxnDefn = (ClTxnDefnT *) cookie;

    if (pTxnDefn == NULL)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Null argument"));
        CL_FUNC_EXIT();
        return (CL_ERR_NULL_POINTER);
    }

    CL_DEBUG_PRINT(CL_DEBUG_TRACE,
                   ("Packing for data-set 0x%x for txn[0x%x:0x%x]", dataSetId,
                    pTxnDefn->serverTxnId.txnMgrNodeAddress, pTxnDefn->serverTxnId.txnId));

    /* Validate between dataSetId and txn-Id */
#if 0
    if ( (dataSetId  - CL_TXN_CKPT_TXN_DATA_SET_ID_OFFSET) != pTxnId->txnId)
    {
        CL_TXN_RETURN_RC(CL_ERR_INVALID_PARAMETER,
                         ("Invalid data-set(0x%x) for transaction-id(0x%x)\n",
                          dataSetId, pTxnId->txnId));
    }
#endif

    rc = clBufferCreate (&txnStateBuf);

    if (CL_OK == rc)
    {
        rc = clTxnStreamTxnCfgInfoPack (pTxnDefn, txnStateBuf);

        *ppData = NULL;
        *pDataLen = 0;

        if (CL_OK == rc)
        {
            /* Copy the state-information from message-buffer to ppData */
            rc = clBufferLengthGet(txnStateBuf, &msgLen);
        }

        if (CL_OK == rc)
        {
            *pDataLen = msgLen;
            *ppData = (ClInt8T *) clHeapAllocate(msgLen);
            if ( *ppData == NULL )
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to allocate memory"));
                rc = CL_ERR_NO_MEMORY;
            }
        }

        if (CL_OK == rc)
        {
            rc = clBufferNBytesRead(txnStateBuf, (ClUint8T *) *ppData, &msgLen);
            if (CL_OK != rc)
            {
                clHeapFree(*ppData);
                *pDataLen = 0x0;
                CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                               ("Failed to pack/serialize txn-defn[0x%x:0x%x] for ckpt. rc:0x%x",
                                pTxnDefn->serverTxnId.txnMgrNodeAddress, pTxnDefn->serverTxnId.txnId, rc));
                rc = CL_GET_ERROR_CODE(rc);
            }


        }

        rc = clBufferDelete(&txnStateBuf);

    }
    CL_FUNC_EXIT();
    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;

}
/** 
 *  Initialize COR notification module.
 *
 *  This routine initializes COR notification module. It creates
 * the COR event channel in EM. This routine is called during
 * COR initialization from corInit. This is not an external API.
 *
 *  @param  N/A
 *
 *  @returns CL_OK  on success<br>
 *       value returned by #emEventCreate on failure.
 */
ClRcT 
corEventInit(void)
{
	ClRcT rc;
	ClNameT evtChannelName;
	ClVersionT ver = CL_EVENT_VERSION;
    ClUint32T                 compDeathPattern   = htonl(CL_CPM_COMP_DEATH_PATTERN);
    ClUint32T                 compDeparturePattern   = htonl(CL_CPM_COMP_DEPART_PATTERN);

    ClUint32T                 nodeDeathPattern = htonl(CL_CPM_NODE_DEATH_PATTERN);
    ClUint32T                 nodeDeparturePattern = htonl(CL_CPM_NODE_DEPART_PATTERN);

    ClEventFilterT            compDeathFilter[]  = {{CL_EVENT_EXACT_FILTER, 
                                                {0, (ClSizeT)sizeof(compDeathPattern), (ClUint8T*)&compDeathPattern}}
    };
    ClEventFilterArrayT       compDeathFilterArray = {sizeof(compDeathFilter)/sizeof(compDeathFilter[0]), 
                                                     compDeathFilter
    };

    ClEventFilterT            compDepartureFilter[]  = {{CL_EVENT_EXACT_FILTER, 
                                                {0, (ClSizeT)sizeof(compDeparturePattern), (ClUint8T*)&compDeparturePattern}}
    };
    ClEventFilterArrayT       compDepartureFilterArray = {sizeof(compDepartureFilter)/sizeof(compDepartureFilter[0]), 
                                                     compDepartureFilter
    };

    ClEventFilterT            nodeDeathFilter[]         = { {CL_EVENT_EXACT_FILTER,
                                                                {0, (ClSizeT)sizeof(nodeDeathPattern),
                                                                (ClUint8T*)&nodeDeathPattern}}
    };
    ClEventFilterArrayT       nodeDeathFilterArray = {sizeof(nodeDeathFilter)/sizeof(nodeDeathFilter[0]),
                                                          nodeDeathFilter 
    };

    ClEventFilterT            nodeDepartureFilter[]         = { {CL_EVENT_EXACT_FILTER,
                                                                {0, (ClSizeT)sizeof(nodeDeparturePattern),
                                                                (ClUint8T*)&nodeDeparturePattern}}
    };
    ClEventFilterArrayT       nodeDepartureFilterArray = {sizeof(nodeDepartureFilter)/sizeof(nodeDepartureFilter[0]),
                                                          nodeDepartureFilter 
    };

	CL_FUNC_ENTER();
	
	/* First call the function to initialize COR events */
	rc = clEventInitialize(&corEventHandle,&corEvtCallbacks, &ver);

	if(CL_OK != rc)
	{
               clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ALERT, NULL, 
					CL_LOG_MESSAGE_2_INIT, "Event Client", rc);
		CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("Event Client init failed rc => [0x%x]\n", rc));
		return rc;
	}


	/**** Open Publish Channel for COR */
	evtChannelName.length = strlen(clCorEventName);
	memcpy(evtChannelName.value, clCorEventName, evtChannelName.length+1);
		
	rc = clEventChannelOpen(corEventHandle, &evtChannelName, 
			CL_EVENT_GLOBAL_CHANNEL | CL_EVENT_CHANNEL_PUBLISHER, 
			COR_EVT_TIMEOUT, 
			&corEventChannelHandle);
	
	if(CL_OK != rc)
	{
               clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ALERT, NULL,
					CL_LOG_MESSAGE_1_EVENT_PUBLISH_CHANNEL_OPEN, rc); 
		CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("\n Event Publish Channel Open failed for COR rc => [0x%x]\n", rc));
		return rc;
	}

	/**
     * Open component event channel of CPM 
     */
	evtChannelName.length = strlen(CL_CPM_EVENT_CHANNEL_NAME);
        strcpy(evtChannelName.value, CL_CPM_EVENT_CHANNEL_NAME);
		
	rc = clEventChannelOpen(corEventHandle, &evtChannelName, 
			CL_EVENT_GLOBAL_CHANNEL | CL_EVENT_CHANNEL_SUBSCRIBER, 
			(ClTimeT)-1, 
			&cpmEventChannelHandle);
	if(CL_OK != rc)
	{
                clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ALERT, NULL, 
						CL_LOG_MESSAGE_1_CHANNEL_OPEN_COMP_TERMINATION, rc);
		CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("\n Event Subscribe Channel Open failed for CPM rc => [0x%x]\n", rc));
		return rc;
	}

    /*
     * Subscribe for component death event.
     */
    rc = clEventSubscribe(cpmEventChannelHandle, &compDeathFilterArray, CL_COR_COMP_DEATH_SUBSCRIPTION_ID, NULL);
    if(CL_OK != rc)
    {
        clLogError("NOTIFY", "SUBSCRIBE", "Failed to subscribe for component death event. rc [0x%x]", rc);
        return rc;
    }

	/*
     * Subscribe for component departure event. 
     */
    rc = clEventSubscribe(cpmEventChannelHandle, &compDepartureFilterArray, CL_COR_COMP_DEPARTURE_SUBSCRIPTION_ID, NULL);
    if(CL_OK != rc)
    {
        clLogError("NOTIFY", "SUBSCRIBE", "Failed to subscribe for component departure event. rc [0x%x]", rc);
        return rc;
    }
	
    /**
     * Open node event channel of CPM.
     */
	evtChannelName.length = strlen(CL_CPM_NODE_EVENT_CHANNEL_NAME);
    strcpy(evtChannelName.value, CL_CPM_NODE_EVENT_CHANNEL_NAME);
		
	rc = clEventChannelOpen(corEventHandle, &evtChannelName, 
			CL_EVENT_GLOBAL_CHANNEL | CL_EVENT_CHANNEL_SUBSCRIBER, 
			(ClTimeT)-1, 
			&cpmEventNodeChannelHandle);
	if(CL_OK != rc)
	{
             clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ALERT, NULL, 
					CL_LOG_MESSAGE_1_CHANNEL_OPEN_NODE_ARRIVAL, rc);
             CL_DEBUG_PRINT (CL_DEBUG_ERROR, ("\n Event Subscribe Channel Open failed for CPM rc => [0x%x]\n", rc));
	     return rc;
	}

    /*
     * Subscribe for node death event.
     */
    rc = clEventSubscribe(cpmEventNodeChannelHandle, &nodeDeathFilterArray, 
                          CL_COR_NODE_DEATH_SUBSCRIPTION_ID, NULL);
    if(CL_OK != rc)
    {
        clLogError("NOTIFY", "SUBSCRIBE", "Failed to subscribe for node death event. rc [0x%x]", rc);
        return rc;
    }

    /*
     * Subscribe for node departure event.
     */
    rc = clEventSubscribe(cpmEventNodeChannelHandle, &nodeDepartureFilterArray, 
                          CL_COR_NODE_DEPARTURE_SUBSCRIPTION_ID, NULL);
    if(CL_OK != rc)
    {
        clLogError("NOTIFY", "SUBSCRIBE", "Failed to subscribe for node departure event. rc [0x%x]", rc);
        return rc;
    }

    CL_FUNC_EXIT();
    return (rc);
}
ClRcT VDECL(_corObjectWalkOp) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                                  ClBufferHandleT  outMsgHandle)
{
    ClRcT rc = CL_OK;
    corObjFlagNWalkInfoT* pData = NULL;
    CL_FUNC_ENTER();

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("OBW", "EOF", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }

    pData = clHeapAllocate(sizeof(corObjFlagNWalkInfoT));
    if(!pData)
    {
          clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, gCorClientLibName,
                    CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
           CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
           return (CL_COR_SET_RC(CL_COR_ERR_NO_MEM));
    }

    if((rc = VDECL_VER(clXdrUnmarshallcorObjFlagNWalkInfoT, 4, 0, 0)(inMsgHandle, (void *)pData)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to Unmarshall corObjFlagNWalkInfoT"));
            clHeapFree(pData);
        return rc;
    }

	clCorClientToServerVersionValidate(pData->version, rc);
    if(rc != CL_OK)
	{
		clHeapFree(pData);	
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED); 
	}

    switch(pData->operation)
    {
        case COR_OBJ_WALK_DATA_GET:
            clOsalMutexLock(gCorMutexes.gCorServerMutex);

#if 0            
            objHdlCount = 0;
            rc = _corObjectCountGet(&iCount);
            pObjHdlList = (char *) clHeapAllocate(iCount*sizeof(ClCorObjectHandleT));
	   	    if(pObjHdlList == NULL)
	        {
       			 clHeapFree(pData);
            	 clOsalMutexUnlock(gCorMutexes.gCorServerMutex); 
			  	 clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_DEBUG, NULL,
					CL_LOG_MESSAGE_0_MEMORY_ALLOCATION_FAILED);
 				 CL_DEBUG_PRINT(CL_DEBUG_ERROR,(CL_COR_ERR_STR(CL_COR_ERR_NO_MEM)));
				 return CL_COR_SET_RC(CL_COR_ERR_NO_MEM);
	    	}

            clLogTrace("OBW", "EFN", "Going for the object walk now");
#endif

            rc = _clCorObjectWalk(&pData->moId, &pData->moIdWithWC, _corObjHdlListGet, pData->flags, outMsgHandle);
            if (CL_OK != rc)
            {
                clLogError("OBW", "EFN", 
                        "Failed to do the object walk on server. rc[0x%x]", rc);
            }
#if 0
            else
            {
	            rc = clBufferNBytesWrite(outMsgHandle, (ClUint8T *)pObjHdlList,
            	                (ClUint32T)objHdlCount * sizeof(ClCorObjectHandleT));
                if (CL_OK != rc)
                    clLogError("OBW", "EFN", 
                            "Failed to write the object walk information into the out buffer. rc[0x%x]", rc);
            }

            clLogTrace("OBW", "EFN", "Done with the object walk");

            clHeapFree(pObjHdlList);
#endif
            clOsalMutexUnlock(gCorMutexes.gCorServerMutex); 
        break;
        case COR_OBJ_SUBTREE_DELETE:
           clOsalMutexLock(gCorMutexes.gCorServerMutex);
           rc = _clCorSubTreeDelete(pData->moId);
           clOsalMutexUnlock(gCorMutexes.gCorServerMutex); 
        break;
        default:
             CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "INVALID OPERATION, rc = %x", rc) );
             rc = CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
        break;
    }
   
    CL_FUNC_EXIT();
    clHeapFree(pData);
    return rc;
}
static ClRcT  
cdbGDBMOpen(ClDBFileT    dbFile,
        ClDBNameT    dbName, 
        ClDBFlagT    dbFlag,
        ClUint32T   maxKeySize,
        ClUint32T   maxRecordSize,
        ClDBHandleT* pDBHandle)
{
  ClRcT errorCode = CL_OK;
  GDBMHandle_t* pGDBMHandle = NULL;
  ClUint32T read_write = 0;
  ClDBTypeT  dbType = CL_DB_TYPE_BTREE;

  CL_FUNC_ENTER();
  NULL_CHECK(pDBHandle);

  NULL_CHECK(dbName);

  /* Validate the flag */
  if(dbFlag >= CL_DB_MAX_FLAG) {
    errorCode = CL_DBAL_RC(CL_ERR_INVALID_PARAMETER);
    CL_DEBUG_PRINT (CL_DEBUG_WARN,("Invalid Flag"));
    CL_FUNC_EXIT();
    return(errorCode);
  }
  
  /* Validate database type */
  if(dbType >= CL_DB_MAX_TYPE) {
    errorCode = CL_DBAL_RC(CL_ERR_INVALID_PARAMETER);
    CL_DEBUG_PRINT (CL_DEBUG_WARN,("Invalid DB Type"));
    CL_FUNC_EXIT();
    return(errorCode);
  }

  pGDBMHandle = (GDBMHandle_t*)clHeapCalloc(1,sizeof(GDBMHandle_t));

  if(NULL == pGDBMHandle) {
    errorCode = CL_DBAL_RC(CL_ERR_NO_MEMORY);
    CL_DEBUG_PRINT (CL_DEBUG_TRACE,("Memory allocation failed."));
    CL_FUNC_EXIT();
    return(errorCode);
  }

  pGDBMHandle->syncMode = CL_FALSE;

  if(CL_DB_SYNC & dbFlag)
  {
      dbFlag &= ~(CL_DB_SYNC);
      pGDBMHandle->syncMode = CL_TRUE;
  }

  /* Let the env variable override the coded behaviour */
  if (getenv("ASP_DB_SYNC"))
  {
      if (clParseEnvBoolean("ASP_DB_SYNC") == CL_TRUE)
      {
          pGDBMHandle->syncMode = CL_TRUE;
      }
      else
      {
          pGDBMHandle->syncMode = CL_FALSE;
      }
  }

  if(CL_DB_CREAT == dbFlag) {
    read_write = GDBM_NEWDB | GDBM_NOLOCK;
  }
  else {
    pGDBMHandle->gdbmInstance = gdbm_open((ClCharT*)dbName, CL_GDBM_BLOCK_SIZE, GDBM_READER, CL_GDBM_FILE_MODE, NULL);
    if ((NULL == pGDBMHandle->gdbmInstance) && (CL_DB_APPEND != dbFlag)) {
        clHeapFree(pGDBMHandle);
        errorCode = CL_DBAL_RC(CL_ERR_NOT_EXIST);
        CL_DEBUG_PRINT ( CL_DEBUG_WARN,("\nGDBM Open failed."));
        CL_FUNC_EXIT();
        return(errorCode);
    }
    if (NULL != pGDBMHandle->gdbmInstance)   gdbm_close(pGDBMHandle->gdbmInstance);  
    if (CL_DB_OPEN == dbFlag)
        read_write = GDBM_WRITER;
    else if (CL_DB_APPEND == dbFlag)
        read_write = GDBM_WRCREAT;
    else
    {
        clHeapFree(pGDBMHandle);
        errorCode = CL_DBAL_RC(CL_ERR_BAD_FLAG);
        CL_DEBUG_PRINT (CL_DEBUG_WARN,("\nInvalid DB flag. GDBM open failed."));
        CL_FUNC_EXIT();
        return(errorCode);
    }
  }

  if(CL_TRUE == pGDBMHandle->syncMode)
  {
      read_write |= GDBM_SYNC;
  }
  
  /* Create/Open the GDBM database */
  pGDBMHandle->gdbmInstance = gdbm_open((ClCharT*)dbName, CL_GDBM_BLOCK_SIZE, read_write, CL_GDBM_FILE_MODE, NULL);

  if(NULL == (pGDBMHandle->gdbmInstance)) {
    /* if the creation failed, return error */
    clHeapFree(pGDBMHandle);
    errorCode = CL_DBAL_RC(CL_DBAL_ERR_DB_ERROR);
    CL_DEBUG_PRINT ( CL_DEBUG_WARN,("\nGDBM Open failed."));
    CL_FUNC_EXIT();
    return(errorCode);
  }
  pGDBMHandle->deleteRecCnt = 0;

  /* Return the handle to the created/opened database */  
  *pDBHandle = (ClDBHandleT)pGDBMHandle;
  CL_FUNC_EXIT();
  return(CL_OK);

}
ClRcT
cosSysvShmCreate(ClUint8T* pName, ClUint32T size, ClOsalShmIdT* pShmId)
{
    struct shmid_ds shmPerm ;
    ClInt32T retCode = CL_OK;
    ClUint32T len = 0;
    ClUint32T key = 0;
    ClInt32T shmId = -1;

    CL_FUNC_ENTER();

    if(NULL == pShmId)
    {
        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nShared Memory Create: FAILED"));
        retCode = CL_OSAL_RC(CL_ERR_NULL_POINTER);
        CL_FUNC_EXIT();
        return(retCode);
    }

    if(NULL == pName)
    {
        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nShared Memory Create: FAILED"));
        retCode = CL_OSAL_RC(CL_ERR_NULL_POINTER);
        CL_FUNC_EXIT();
        return(retCode);
    }

    len = (ClUint32T)strlen ((ClCharT*) pName);

    retCode = (ClInt32T)clCrc32bitCompute (pName, len, &key, NULL);

    if(CL_OK != retCode)
    {
        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nShared Memory Create: FAILED"));
        retCode = CL_OSAL_RC(CL_OSAL_ERR_SHM_CREATE);
        CL_FUNC_EXIT();
        return(retCode);
    }

    shmId = shmget ((key_t)key, size, (0666 | IPC_CREAT));

    if(shmId < 0)
    {
        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nShared Memory Create: FAILED"));
        retCode = CL_OSAL_RC(CL_OSAL_ERR_SHM_CREATE);
        CL_FUNC_EXIT();
        return(retCode);
    }


    retCode = shmctl (shmId, IPC_STAT, &shmPerm);

    if(0 != retCode)
    {
        retCode = shmctl (shmId, IPC_RMID, NULL);

        if(0 != retCode)
        {
            /*debug messages if any */
        }

        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nShared Memory Create: FAILED"));
        retCode = CL_OSAL_RC(CL_OSAL_ERR_SHM_CREATE);
        CL_FUNC_EXIT();
        return(retCode);
    }

    shmPerm.shm_perm.uid = getuid();
    shmPerm.shm_perm.gid = getgid();

    retCode = shmctl (shmId, IPC_SET, &shmPerm);

    if(0 != retCode)
    {
        retCode = shmctl (shmId, IPC_RMID, NULL);

        if(0 != retCode)
        {
            /*debug messages if any */
        }

        CL_DEBUG_PRINT (CL_DEBUG_INFO,("\nShared Memory Create: FAILED"));
        retCode = CL_OSAL_RC(CL_OSAL_ERR_SHM_CREATE);
        CL_FUNC_EXIT();
        return(retCode);
    }

    *pShmId = (ClOsalSemIdT)shmId;

    CL_DEBUG_PRINT (CL_DEBUG_TRACE,("\nShared Memory Create: DONE"));
    CL_FUNC_EXIT();
    return (CL_OK);
}
/*
 *  TODO:
 * 1 - walk everything
 * 2 - MSO Walk
 * 3 - top down
 * 4 - bottom up 
 * make the return of the function to ClRcT, so it can be stopped
 */
ClRcT _clCorObjectWalk( ClCorMOIdPtrT cAddr, 
	    ClCorMOIdPtrT           cAddrWC,
        CORObjWalkFP            fp,
        ClCorObjWalkFlagsT      flags,
        ClBufferHandleT         bufferHandle
)
{
    ClCorMOIdT tmpMOId;
    ClCorMOIdPtrT cookie = &tmpMOId;  
    ObjTree_t tmpTree;
    MArrayWalk_t tmpWalkDetails={0};
    MArrayWalk_h walkCookie = &tmpWalkDetails;
    ClRuleExprT* pRbeExpr = NULL;
    ClRcT rc = CL_OK;
    
    CL_FUNC_ENTER();

    /* todo: The cookie can be OH instead of ClCorMOId for optimizations
     */
    if(!objTree)
         return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      tmpTree = *objTree;

    /* do some validations to parameters */
    if(!fp)
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_NULL_PTR);
    }
    
    if(cAddr && cAddr->depth == 0)
        cAddr = NULL;

    if(cAddrWC &&  cAddrWC->depth == 0)
        cAddrWC = NULL;

    if((flags > CL_COR_MSO_WALK_UP) || (flags < CL_COR_MO_WALK))
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
    }

    if(cAddr &&
       (((cAddr->svcId != CL_COR_INVALID_SVC_ID) &&
         ((flags == CL_COR_MO_WALK) || (flags == CL_COR_MO_WALK_UP))) ||
        ((cAddr->svcId < CL_COR_INVALID_SVC_ID || cAddr->svcId >= CL_COR_SVC_ID_MAX) &&
         ((flags == CL_COR_MSO_WALK) || (flags == CL_COR_MSO_WALK_UP)))))
    {
        CL_FUNC_EXIT();
        return CL_COR_SET_RC(CL_COR_SVC_ERR_INVALID_ID);
    }

    /* set the root of the walk here */
    if(cAddr)
    {
        if(cAddr->depth>0)
          {
            tmpTree.root = corObjTreeNodeFind(objTree, cAddr);
          }
        *cookie = *cAddr; 
    }
    else
    {
        clCorMoIdInitialize(cookie);
    }
     
    if(tmpTree.root)
    {
		int idx = 0;
        switch(flags)
        {
            case CL_COR_MO_SUBTREE_WALK:
                tmpWalkDetails.flags = CL_COR_MO_SUBTREE_WALK;
                tmpWalkDetails.fpNode = (MArrayNodeFP)fp;
                tmpWalkDetails.fpData = 0;
            break;

            case CL_COR_MO_WALK:
            case CL_COR_MO_WALK_UP:
                tmpWalkDetails.fpNode = (MArrayNodeFP)fp;
                tmpWalkDetails.fpData = 0;
            break;

            case CL_COR_MSO_SUBTREE_WALK:
                tmpWalkDetails.flags = CL_COR_MSO_SUBTREE_WALK;
                tmpWalkDetails.fpNode = 0;
                tmpWalkDetails.fpData = (MArrayNodeFP)fp;
                break;

            case CL_COR_MSO_WALK:
            case CL_COR_MSO_WALK_UP:
                tmpWalkDetails.fpNode = 0;
                tmpWalkDetails.fpData = (MArrayNodeFP)fp;
                break;

            default:
                return CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM);
        } 

        if (bufferHandle)
            tmpWalkDetails.pMsg  =  &bufferHandle;

        tmpWalkDetails.flags =  flags;
        tmpWalkDetails.cookie = (void **) &cookie;

        if(cAddrWC && corMOIdExprCreate(cAddrWC,&pRbeExpr) != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("MOId to Expression Creation Failed : [0x%x]",rc));
            return rc;
        }

        tmpWalkDetails.expr = pRbeExpr;

        if(cookie && cookie->depth)
            idx = clCorMoIdToInstanceGet(cookie);

        mArrayWalk(idx,
                   &tmpTree, 
                   _corObjWalkFun, 
                   _corObjWalkFun, 
                   (void **)&walkCookie,
                   rc);
    }

    if(pRbeExpr)
    	clRuleExprDeallocate(pRbeExpr);

    CL_FUNC_EXIT();
    return 0;
}
/**
 *NOT AN EXTERNAL API. PLEASE DO NOT DOCUMENT.
 *
 * This routine validates the handle argument, and frees the memory held
 * by the object. It does not free the object if it was allocated by an
 * external memory pool, but removes it from the repository.
 */
static ClRcT
omCommonDeleteObj(ClHandleT handle, ClUint32T numInstances, int flag,
                  void *pUsrData, ClUint32T usrDataLen)
{
    ClOmClassControlBlockT 	*pTab = NULL;
    ClOmClassTypeT	classId = CL_OM_INVALID_CLASS;
    ClUint32T	instId = 0;
    ClUint32T	idx = 0;
    ClUint8T*	tmpPtr = NULL;
#ifdef CL_DEBUG
    ClInt8T	aFuncName[] = "omCommonDeleteObj()";
#endif
    ClRcT		rc = CL_OK;

    CL_FUNC_ENTER();

    if (omValidateHandle(handle) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid input handle argument"));
        return (CL_OM_SET_RC(CL_OM_ERR_INVALID_OBJ_HANDLE));
    }

    classId = CL_OM_HANDLE_TO_CLASSID(handle);
    instId  = CL_OM_HANDLE_TO_INSTANCEID(handle);
    pTab = clOmClassEntryGet(classId);
    CL_ASSERT(pTab);

    /* Validate the numInstances agrument */
    if (!numInstances || (numInstances > pTab->curObjCount))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid numInstances specified"));
        return (CL_OM_SET_RC(CL_OM_ERR_INVALID_OBJ_INSTANCE));
    }

    /* Do checks to ensure the call combination is allowed */
    if ((flag == CL_OM_DELETE_FLAG) &&
            (!mALLOC_BY_OM(pTab->pInstTab[instId])))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                       ("Deleting an object not allocated from OM memory pool"));
        return (CL_OM_SET_RC(CL_OM_ERR_OBJ_NOT_ALLOCATED_BY_OM));
    }
    else if ((flag == CL_OM_REMOVE_FLAG) &&
             (mALLOC_BY_OM(pTab->pInstTab[instId])))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                       ("Removing an object allocated in OM pool"));
        return (CL_OM_SET_RC(CL_OM_ERR_OBJ_ALLOCATED_BY_OM));
    }

    /* In a loop, delete an object instance at a time, and cleanup */
    tmpPtr = (ClUint8T *)mGET_REAL_ADDR(pTab->pInstTab[instId]);
    for (idx = instId; idx < (numInstances + instId); idx++)
    {
        /* Now call the finilize method for all the object in the hierarchy */
        rc = omFiniObjHierarchy(classId,
                                (void *)mGET_REAL_ADDR(pTab->pInstTab[idx]), pUsrData,
                                usrDataLen);
        if (rc != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Call to OM object's destructor "
                                            "failed, rc 0x%x!!!\r\n", aFuncName, rc));
            CL_FUNC_EXIT();
            return rc;
        }

        /* TODO: lockId = osLock(); */
        pTab->pInstTab[idx] = (ClUint32T *)NULL;
        pTab->curObjCount--;

#if (CW_PROFILER == YES)
        /* TODO: pOM->perfStat.objectDeleted++; */
#endif
        /* TODO: osUnLock(lockId); */
    }

    /* Free the allocated buffer */
    if (tmpPtr)
        clHeapFree(tmpPtr);

    CL_FUNC_EXIT();
    return rc;
}
/**
 * NOT AN EXTERNAL API. PLEASE DO NOT DOCUMENT.
 *
 * This routine creates an object instance in the calling context, and
 * sets the object type the one specified as the argument. Also, the
 * object instance is added to the object manager database.
 */
void *
omCommonCreateObj(ClOmClassTypeT classId, ClUint32T numInstances,
                  ClHandleT *handle, void *pExtObj, int flag, ClRcT *rc,
                  void *pUsrData, ClUint32T usrDataLen)
{
    int 		  idx;
    char         *pObjPtr = NULL;
    ClUint32T **pInst;
    ClUint32T   instIdx = 0;
    ClOmClassControlBlockT *      pTab;
    char         *tmpPtr;
    ClUint32T	instBlkLen = 0;

    CL_FUNC_ENTER();

    if (NULL == rc)
    {
        clLogError("OMG", "OMC", "Null value passed for return code");
        return (NULL);
    }

    if(NULL == handle || ( (flag == CL_OM_ADD_FLAG) && (NULL == pExtObj) ) )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("NULL handle is passed."));
        *rc = CL_OM_SET_RC(CL_OM_ERR_NULL_PTR);
        return (NULL);
    }

    *rc = 0;
    /* validate the input arguments */
    if (omClassTypeValidate(classId) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid input classId arguments"));
        *rc = CL_OM_SET_RC(CL_OM_ERR_INVALID_CLASS);
        return (NULL);
    }
    pTab = clOmClassEntryGet(classId);
    CL_ASSERT(pTab);

    if (!numInstances)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid input numInstances arguments"));
        *rc = CL_OM_SET_RC(CL_OM_ERR_INVALID_OBJ_INSTANCE);
        return (NULL);
    }

    /* Get obj memory block length */
    instBlkLen = pTab->size * numInstances;

Reallocate:
    /*
     * Check if the class control structure is initalized with the instance
     * table. This is done during the initialization of the class table.
     */
    if (!(pInst = pTab->pInstTab))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Instance table for the class does not exist"));
        *rc = CL_OM_SET_RC(CL_OM_ERR_INSTANCE_TAB_NOT_EXISTS);
        return (NULL);
    }

    /* Find the first empty slot in the instance table */
    *rc = omGetFreeInstSlot(pInst, pTab->maxObjInst, &instIdx);
    if (CL_GET_ERROR_CODE(*rc) == CL_ERR_NOT_EXIST)
    {
        ClUint32T **tmp_ptr = NULL;
        ClUint32T  tmp_size = 0;

        clLogDebug("OMC", "OBC", "No free slot found in the OM class [0x%x] buffer for this object. "
                   "Reallocating the class buffer size.", classId);

        /* No free slot found. Need to allocate maInstances number of slots more */
        pTab->maxObjInst = pTab->maxObjInst * 2 ; /* Double the size of max instances */
        tmp_size = (pTab->maxObjInst * sizeof(ClUint32T *));

        tmp_ptr = pTab->pInstTab;

        tmp_ptr = (ClUint32T **) clHeapRealloc(tmp_ptr, tmp_size);

        if (NULL == tmp_ptr)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to allocate memory for Instance Table"));
            *rc = CL_OM_SET_RC(CL_OM_ERR_NO_MEMORY);
            return (NULL);
        }

        pTab->pInstTab = tmp_ptr;

        goto Reallocate;
    }

    clLogTrace("OMC", "OBC", "Allocating the index [%u] in the OM class [0x%x] buffer.",
               instIdx, classId);

    /* Check if we have room for the contiguous instance available to
     * allocate the object instances requested by the user.
     * NOTE: We could enhance this later to allow dis-contiguous slots
     */
    for (idx = instIdx; idx < (instIdx + numInstances); idx++)
    {
        if (mGET_REAL_ADDR(pInst[idx]))
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Unable to fit requested num instances"));
            *rc = CL_OM_SET_RC(CL_OM_ERR_INSTANCE_TAB_NOSLOTS);
            return (NULL);
        }
    }

    /* Allocate the memory for the object instances */
    if (flag == CL_OM_CREATE_FLAG)
    {
        pObjPtr = (char*)clHeapAllocate(instBlkLen);

        if(NULL == pObjPtr)
        {
            /*
             * TODO: To check if we have to go a free the instances
             *       that were allocated when (numInstances > 1) req.
             */
#if (CW_PROFILER == YES)
            /* TODO: lockId = osLock(); */
            /* TODO: pOM->perfStat.memoryAllocFail++; */
            /* TODO: osUnLock(lockId); */
#endif
            CL_DEBUG_PRINT(CL_DEBUG_CRITICAL, ("unable to allocate memory from heap!!"));
            CL_FUNC_EXIT();
            *rc = CL_ERR_NO_MEMORY;
            return (NULL);
        }
        /* Reset object block contents to 0 */
        memset(pObjPtr, 0, instBlkLen);

        tmpPtr = pObjPtr;
    }
    else if (flag == CL_OM_ADD_FLAG)
    {
        tmpPtr = pExtObj;
    }
    else
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Unknown flag argument passed"));
        *rc = CL_ERR_INVALID_PARAMETER;
        return (NULL);
    }

    /* Now, add it to the instance table */
    for (idx = instIdx; idx < (instIdx + numInstances); idx++)
    {
        /*
         * Cautionary check, if the address is *NOT* aligned on a four
         * byte boundry
         */
        if ((ClWordT)tmpPtr & INST_BITS_MASK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_CRITICAL, ("Allocated buffer not on word aligned boundry"));
            *rc = CL_OM_SET_RC(CL_OM_ERR_ALOC_BUF_NOT_ALIGNED);
            return (NULL);
        }

        /* Start adding the object to the instance table */
        ((struct CL_OM_BASE_CLASS *)tmpPtr)->__objType = CL_OM_FORM_HANDLE(classId, instIdx);

        /* TODO: lockId = osLock(); */
        if (flag == CL_OM_CREATE_FLAG)
            pInst[idx] = (ClUint32T *)mSET_ALLOC_BY_OM(tmpPtr);
        else
            pInst[idx] = (ClUint32T *)tmpPtr;
        pTab->curObjCount++;

#if (CW_PROFILER == YES)
        /* pOM->perfStat.objectCreated++; */
#endif
        /* TODO: osUnLock(lockId); */

        /* Now, start calling the initializer method for the class hierarchy */
        *rc = omInitObjHierarchy(pTab, classId, (void *)tmpPtr, pUsrData, usrDataLen);
        tmpPtr += pTab->size;
    }

    /* return the handle argument */
    *handle = CL_OM_FORM_HANDLE(classId, instIdx);
    CL_FUNC_EXIT();

    if (flag == CL_OM_CREATE_FLAG)
        return((void *)pObjPtr);
    else
        return(NULL);
}
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);
}
ClRcT  VDECL(_corMOTreeClassOpRmd) (ClEoDataT cData, ClBufferHandleT  inMsgHandle,
                                  ClBufferHandleT  outMsgHandle)
{
    ClRcT rc = CL_OK;
    corClassDetails_t *pClassInfo = NULL;
    CORMOClass_h moClassHandle;
    CORMSOClass_h msoClassHandle;

    CL_FUNC_ENTER();

    if(gCorInitStage == CL_COR_INIT_INCOMPLETE)
    {
        clLogError("MOT", "EOF", "The COR server Initialization is in progress....");
        return CL_COR_SET_RC(CL_COR_ERR_TRY_AGAIN);
    }
    
    pClassInfo = clHeapAllocate(sizeof(corClassDetails_t));
    if(pClassInfo == NULL) 
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    }

	if((rc = VDECL_VER(clXdrUnmarshallcorClassDetails_t, 4, 0, 0)(inMsgHandle, (void *)pClassInfo)) != CL_OK)
	{
		clHeapFree(pClassInfo);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,("Failed to Unmarshall corClassDetails_t "));
		return rc;
	}
    /* if((rc = clBufferFlatten(inMsgHandle, (ClUint8T **)&pClassInfo))!= CL_OK)
    {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to flatten the Message"));
                CL_FUNC_EXIT();
	        return rc;
    }*/	
    /* if(pClassInfo->version > CL_COR_VERSION_NO)
    {
		clHeapFree(pClassInfo);
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Version mismatch"));
        CL_FUNC_EXIT();
        return CL_ERR_VERSION_MISMATCH;
    }*/

	clCorClientToServerVersionValidate(pClassInfo->version, rc);
    if(rc != CL_OK)
	{
		clHeapFree(pClassInfo);	
		return CL_COR_SET_RC(CL_COR_ERR_VERSION_UNSUPPORTED); 
	}
  
    switch(pClassInfo->operation)
    {
        case COR_CLASS_OP_CREATE:
            if(pClassInfo->classType == MO_CLASS)
            {
                rc = _corMOClassCreate(&(pClassInfo->corPath), pClassInfo->maxInstances, &moClassHandle);
                if(rc != CL_OK)
                {
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
						CL_LOG_MESSAGE_1_MOCLASS_CREATE, rc);
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassCreate failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            else
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                {
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOClassHandleGet failure"));
                }
                else
                {
                	rc = _corMSOClassCreate(moClassHandle, pClassInfo->svcId,
                       	                pClassInfo->objClass, &msoClassHandle);
                    if(rc != CL_OK)
               			CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMSOClassCreate failure"));
                }

               	if(rc != CL_OK)
               	{
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
					CL_LOG_MESSAGE_1_MSOCLASS_CREATE, rc);
               		CL_FUNC_EXIT();
               		return rc;
                }
            }
            break;
        case COR_CLASS_OP_DELETE:
            if(pClassInfo->classType == MO_CLASS)
            {
                rc = _corMOClassDelete(&(pClassInfo->corPath));
                if(rc != CL_OK)
                {
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
					CL_LOG_MESSAGE_1_MOCLASS_DELETE, rc);
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassDelete failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            else
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                    CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "corMOClassHandleGet failure"));
                else
                {
                    rc = _corMSOClassDelete(moClassHandle, pClassInfo->svcId);
                    if(rc != CL_OK)
                        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMSOClassDelete failure"));
                }

                if(rc != CL_OK)
               	{
                    clHeapFree(pClassInfo);
                    clLogWrite(CL_LOG_HANDLE_APP, CL_LOG_ERROR, NULL,
						CL_LOG_MESSAGE_1_MSOCLASS_DELETE, rc);
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            break;
        case COR_CLASS_OP_EXISTANCE:
            if(pClassInfo->classType == MO_CLASS)
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                {
					clHeapFree(pClassInfo);
                    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMOClassHandleGet failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            else
            {
                rc = corMOClassHandleGet(&(pClassInfo->corPath), &moClassHandle);
                if(rc != CL_OK)
                {
					clHeapFree(pClassInfo);
                    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMOClassHandleGet failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
                rc = corMSOClassHandleGet(moClassHandle, pClassInfo->svcId, &msoClassHandle);
                if(rc != CL_OK)
                {
					clHeapFree(pClassInfo);
                    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMSOClassHandleGet failure"));
                    CL_FUNC_EXIT();
                    return rc;
                }
            }
            break;
        case COR_CLASS_OP_CLASSID_GET:
            rc = _corMOPathToClassIdGet(&(pClassInfo->corPath), pClassInfo->svcId, &(pClassInfo->objClass));
            if(rc != CL_OK)
            {
				clHeapFree(pClassInfo);
                CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "corMSOClassHandleGet failure"));
                CL_FUNC_EXIT();
                return rc;
            }
            /*Write to the message.*/
            /* clBufferNBytesWrite (outMsgHandle, (ClUint8T *)pClassInfo, sizeof(corClassDetails_t)); */
			VDECL_VER(clXdrMarshallcorClassDetails_t, 4, 0, 0)(pClassInfo, outMsgHandle, 0);
            break;
        case COR_CLASS_OP_FIRSTCHILD_GET:
            rc = _clCorMoClassPathFirstChildGet(&(pClassInfo->corPath));
            if(rc != CL_OK)
            {
				clHeapFree(pClassInfo);
                CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "_clCorMoPathFirstChildGet failure"));
                CL_FUNC_EXIT();
                return rc;
            }
            /*Write to the message.*/
            /* clBufferNBytesWrite (outMsgHandle, (ClUint8T *)pClassInfo, sizeof(corClassDetails_t)); */
			VDECL_VER(clXdrMarshallcorClassDetails_t, 4, 0, 0)(pClassInfo, outMsgHandle, 0);
            break;
        case COR_CLASS_OP_NEXTSIBLING_GET:
            rc = _clCorMoClassPathNextSiblingGet(&(pClassInfo->corPath));
            if(rc != CL_OK)
            {
				clHeapFree(pClassInfo);
                CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "_clCorMoPathNextSiblingGet failure"));
                CL_FUNC_EXIT();
                return rc;
            }
            /*Write to the message.*/
            /* clBufferNBytesWrite (outMsgHandle, (ClUint8T *)pClassInfo, sizeof(corClassDetails_t)); */
			VDECL_VER(clXdrMarshallcorClassDetails_t, 4, 0, 0)(pClassInfo, outMsgHandle, 0);
            break;
        default:
			CL_DEBUG_PRINT(CL_DEBUG_ERROR,("MOClass Request Type %d", pClassInfo->operation));
            break;
    }

    if (pClassInfo->operation == COR_CLASS_OP_CREATE ||
            pClassInfo->operation == COR_CLASS_OP_DELETE)
    {
        if (gCorSlaveSyncUpDone == CL_TRUE)
        {
            ClRcT retCode = CL_OK;

            retCode = clCorSyncDataWithSlave(COR_EO_MOTREE_OP, inMsgHandle);
            if (retCode != CL_OK)
            {
                clLogError("SYNC", "", "Failed to sync data with slave COR. rc [0x%x]", rc);
                /* Ignore the error code. */
            }
        }
    }

    CL_FUNC_EXIT();
	clHeapFree(pClassInfo);
    return rc;
}
ClRcT
clOmObjectWalk(ClOmClassTypeT classId, ClRcT (*fp)(void *, void *), void *arg)
{
	int         idx;
	ClOmClassControlBlockT * pTab = NULL;
	ClUint32T i = 0, maxCount = 0;
	ClRcT rc;

	CL_FUNC_ENTER();

	if(fp == NULL)
	{
		CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                				("NULL pointer passed for function pointer"));
		return CL_ERR_NULL_POINTER;
	}

	if(classId)
	{
		if (omClassTypeValidate(classId) != CL_OK)
    	{
        	CL_DEBUG_PRINT(CL_DEBUG_ERROR,
            	    ("Invalid classID"));
		return (CL_OM_SET_RC(CL_OM_ERR_INVALID_CLASS));
    	}
		i = classId;
		maxCount = classId + 1;
	}
	else
	{
		i = 1;
		maxCount = gOmCfgData.maxAppOmClassType;
	} 
	for (;i < maxCount; i++)
	{
		pTab= clOmClassEntryGet(i); 
		if( pTab == NULL ) {
			continue;
		}

		if (!pTab->pInstTab)
		{
			CL_DEBUG_PRINT(CL_DEBUG_ERROR,
					("Instance table not initialized"));
			return (CL_OM_SET_RC(CL_OM_ERR_INSTANCE_TAB_NOINIT));
		}

		for (idx =0; idx < pTab->maxObjInst; idx++)
		{
			if (mGET_REAL_ADDR(pTab->pInstTab[idx]))
			{
				if ((rc = fp((void *)mGET_REAL_ADDR(pTab->pInstTab[idx]), arg)) != CL_OK)
				{
					CL_FUNC_EXIT();
					return (rc);
				}
			}
		}
	}
	CL_FUNC_EXIT();
	return (CL_OK);
}
/*
 * Paket are added in the record after converting them in the nw order so msgid
 * here is network order. Called with lock held.
 */
ClRcT clRmdCreateAndAddRmdSendRecord(ClEoExecutionObjT *pThis,
                                     ClIocAddressT destAddr,
                                     ClUint32T hdrLen,
                                     ClBufferHandleT outMsgHdl,
                                     ClUint32T flags, ClRmdOptionsT *pOptions,
                                     ClRmdAsyncOptionsT *pAsyncOptions,
                                     ClBufferHandleT message,
                                     ClUint64T msgId, ClUint32T payloadLen,
                                     ClRmdRecordSendT ** ppSendRec)
{
    ClRmdRecordSendT *rec;

    ClRcT retVal = CL_OK;
    ClRcT retCode = 0;

    /*
     * it will be called only for async
     */
    CL_FUNC_ENTER();
    rec = (ClRmdRecordSendT*) clHeapAllocate((ClUint32T) sizeof(ClRmdRecordSendT));
    if (rec == NULL)
    {
        CL_FUNC_EXIT();
        return (CL_RMD_RC(CL_ERR_NO_MEMORY));
    }

    rec->flags = flags;
    rec->hdrLen = hdrLen;
    rec->recType.asyncRec.rcvMsg = NULL;
    rec->recType.asyncRec.outLen = payloadLen;
    rec->recType.asyncRec.priority = pOptions->priority;
    rec->recType.asyncRec.destAddr = destAddr;
    rec->recType.asyncRec.sndMsgHdl = message;
    rec->recType.asyncRec.timerID   = 0;
    rec->recType.asyncRec.outMsgHdl = outMsgHdl;

    /*
     * options can't be 0 as we are creating and passing it
     */
    rec->recType.asyncRec.noOfRetry = pOptions->retries;
    rec->recType.asyncRec.timeout = pOptions->timeout;
    rec->recType.asyncRec.cookie = pAsyncOptions->pCookie;
    rec->recType.asyncRec.func = pAsyncOptions->fpCallback;

    RMD_DBG4((" RMD CALL is Async and reply needed create the timer\n"));
    retVal =
        createAsyncSendTimer(&rec->recType.asyncRec,(ClPtrT)(ClWordT)msgId);

    if (retVal != CL_OK)
    {
        clHeapFree(rec);
        CL_FUNC_EXIT();
        return retVal;

    }

    retVal =
        clCntNodeAdd(((ClRmdObjT *) pThis->rmdObj)->sndRecContainerHandle,
                     (ClPtrT)(ClWordT)msgId, (ClCntDataHandleT) rec, NULL);
    if (retVal == CL_OK) *ppSendRec = rec;
    else
    {
        RMD_DBG4((" RMD  createandaddrec:node add failed1."
                  " Delete timer and return.\n"));

        /*
         * Free the timer additionally for Async Call
         */
        if (flags & CL_RMD_CALL_ASYNC)
            retCode = clTimerDeleteAsync(&rec->recType.asyncRec.timerID);

        clHeapFree(rec);
    }

    CL_FUNC_EXIT();
    return retVal;
}
ClRcT clOmLibInitializeExtended(void)
{
    ClRcT		rc = CL_OK;
    ClUint32T	classIdx = 0;
    ClUint32T	omCfgDataSz = sizeof(ClOmConfigDataT);
    ClOmClassControlBlockT	*pOmClassEntry = NULL;
    ClCharT oiClassFile[CL_MAX_NAME_LENGTH] = {0};
    ClCharT oiRouteFile[CL_MAX_NAME_LENGTH] = {0};
    ClCharT *pOIClassFile = oiClassFile;
    ClCharT *pOIRouteFile = oiRouteFile;
    extern ClRcT showMgrModAdd(char *, char *, void (*fp)(char**));
    extern void omShow (char ** );


    CL_FUNC_ENTER();

    /*
     *First load the OI class configuration. into COR
     */
    if(!gClOIConfig.pOIClassFile)
    {
        clLogError("OI", "CONFIG", "No OI class file is specified to configure the OI classes");
        return CL_OM_SET_RC(CL_ERR_INVALID_PARAMETER);
    }
    if(!gClOIConfig.pOIRouteFile)
    {
        clLogError("OI", "CONFIG", "No OI route file is specified to configure the OI objects");
        return CL_OM_SET_RC(CL_ERR_INVALID_PARAMETER);
    }

    if(gClOIConfig.pOIClassPath)
        snprintf(oiClassFile, sizeof(oiClassFile), "%s/%s", gClOIConfig.pOIClassPath, 
                 gClOIConfig.pOIClassFile);
    else
        pOIClassFile = (ClCharT*)gClOIConfig.pOIClassFile;

    if(gClOIConfig.pOIRoutePath)
        snprintf(oiRouteFile, sizeof(oiRouteFile), "%s/%s", gClOIConfig.pOIRoutePath,
                 gClOIConfig.pOIRouteFile);
    else
        pOIRouteFile = (ClCharT*)gClOIConfig.pOIRouteFile;

    rc = clCorConfigLoad(pOIClassFile, pOIRouteFile);
    if(rc != CL_OK)
    {
        clLogError("OI", "CONFIG", "Loading OI class configuration [%s] to COR returned with error [%#x]",
                   pOIClassFile, rc);
        return rc;
    }

    /* 
       Initialize config data struct and make a 
       copy of the configuration data. 
    */
    memset(&gOmCfgData, 0, omCfgDataSz);
    /* Fill up the gOmCfgData */
    gOmCfgData.maxOmClassBuckets = OM_CLASS_TABLE_MAX_BUCKETS;
    gOmCfgData.minAppOmClassType = OM_APP_MIN_CLASS_TYPE;
    gOmCfgData.maxAppOmClassType = OM_APP_MAX_CLASS_TYPE;
    gOmCfgData.numOfOmClasses = 0;

    /* Create a hash table for storing OM classes */
    rc = clCntHashtblCreate(gOmCfgData.maxOmClassBuckets, omClassKeyCompare, 
                            omClassHashFn, omClassEntryDelCallBack, 
                            omClassEntryDestroyCallBack, CL_CNT_NON_UNIQUE_KEY, &ghOmClassHashTbl);

    rc |= clCntHashtblCreate(gOmCfgData.maxOmClassBuckets, omClassNameKeyCompare, 
                            omClassNameHashFn, omClassEntryDelCallBack, 
                            omClassEntryDestroyCallBack, CL_CNT_NON_UNIQUE_KEY, &ghOmClassNameHashTbl);

    if ((rc != CL_OK) || (ghOmClassHashTbl == 0) 
        || (ghOmClassNameHashTbl == 0))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("%s: Failed to create a hash table "
                                       "for OM classes (rc = 0x%x)!!!\n\r", __FUNCTION__, rc));
        return (rc);
    }


    /* Consolidate OM class tables into a hash table */
    /* Configure the common OM class table */

    /* Initialize the base class here */


    if ((rc = clOmClassInitialize (&gBaseClassTable, 
                                   gBaseClassTable.eMyClassType, 
                                   gBaseClassTable.maxObjInst,
                                   gBaseClassTable.maxSlots)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to initialize OM with rc = "
                                        "0x%x!\r\n", __FUNCTION__, rc));
        return (rc);
    }


    /* Accumulate the number of classes registered w/ OM */
    /*omClassCnt = classIdx;*/
    pOmClassEntry = NULL;

    /* Configure the application OM class table */
    classIdx = 0;

    if (appOmClassCnt > 0)
    {
        for (; classIdx < appOmClassCnt; classIdx++)
        {
            pOmClassEntry = &(pAppOmClassTbl[classIdx]);
            if (pOmClassEntry->eMyClassType == CL_OM_INVALID_CLASS)
            {
                /* skip invalid class */
                /* 
                   This way invalid classes and missing, i.e. a table
                   size if bigger than the number of classes
                   are allowed in the table.
                */
                /*skippedClassCnt++;*/
                continue;
            }

            if ((rc = clOmClassNameInitialize (pOmClassEntry, 
                                               pOmClassEntry->className,
                                               pOmClassEntry->maxObjInst,
                                               pOmClassEntry->maxSlots)) != CL_OK)
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to initialize OM with rc = "
                                                "0x%x!\r\n", __FUNCTION__, rc));
                return (rc);
            }
        }
    }
    else
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("%s: Not initializing OM Application class "
                                        "table because it does not exist...ignoring.\r\n",
                                        __FUNCTION__));
    }

    /* Get the total number of classes registered w/ OM */
    /*gOmCfgData.numOfOmClasses = omClassCnt + classIdx - skippedClassCnt;*/

    /* Initialize the COR/OM handle translation table */
    if (rc == CL_OK)
    {
        if((rc = omCORTableInit()) != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to setup the COR translation "
                                            "table with rc = 0x%x\r\n", rc));
        }
    }

#ifdef DEBUG
    /* Add OM into the debug agent */
    if (!omClassInitState)
        dbgAddComponent(COMP_PREFIX, COMP_NAME, COMP_DEBUG_VAR_PTR);
#endif

    omClassInitState = CL_TRUE;
    /* add the om to show manager */ 
    /*@todo: Navdeep (show manager dependency) 
      showMgrModAdd(COMP_PREFIX, COMP_NAME, omShow); 
    */
    CL_FUNC_EXIT();
    return (rc);
}
ClRcT clRmdCreateRmdMessageToSend(ClVersionT *version,
                                  ClUint32T funcId, /* Function ID to invoke */
                                  ClBufferHandleT inMsgHdl,
                                  ClUint32T flags,  /* Flags */
                                  ClUint64T msgId, ClUint32T payloadLen,
                                  ClUint32T outputLen, ClUint32T maxRetries,
                                  ClUint32T callTimeOut,
                                  ClUint32T *pHdrLen)
{
    ClRmdHdrT ClRmdHdr = { {0} };
    ClUint8T hdrBuffer[sizeof(ClRmdHdrT)*2] = {0};
    ClUint32T hdrLen = 0;
    ClUint32T rc = CL_OK;

    CL_FUNC_ENTER();

    CL_RMD_VERSION_SET_NEW(ClRmdHdr, version);
    ClRmdHdr.protoVersion = CL_RMD_HEADER_VERSION;

    if (((flags & CL_RMD_CALL_ATMOST_ONCE) == 0) || (maxRetries == 0) ||
            ((ClInt32T) callTimeOut == CL_RMD_TIMEOUT_FOREVER) || (callTimeOut == 0))
    {
        if ((callTimeOut == 0) || ( (ClInt32T) callTimeOut == CL_RMD_TIMEOUT_FOREVER))
        {
            /*
             * only if timeout forever, then pass 0 as the timeout. Why? - this
             * timeout is passed to the IOC, for IOC, 0 is best effort and
             * passing -1 from the server to IOC will block the server thread
             * till send done. This is not desirable
             */
            ClRmdHdr.callTimeout = 0;
        }
        else
        {
            /*
             * pass normal timeout through the header so this timeout can be
             * given to the IOC by server
             */
            ClRmdHdr.callTimeout = callTimeOut;
        }

        ClRmdHdr.flags = flags & ~(CL_RMD_CALL_ATMOST_ONCE);
        ClRmdHdr.callTimeout = 0;
        ClRmdHdr.maxNumTries = 0;
    }
    else
    {
        ClRmdHdr.callTimeout = callTimeOut;
        ClRmdHdr.maxNumTries = maxRetries + 1;
        ClRmdHdr.flags = flags;
    }

    ClRmdHdr.msgId = msgId;
    ClRmdHdr.fnID = funcId;
    clRmdMarshallRmdHdr(&ClRmdHdr, hdrBuffer, &hdrLen);
    rc = clBufferDataPrepend(inMsgHdl, (ClUint8T *) hdrBuffer, hdrLen);
    clBufferReadOffsetSet(inMsgHdl, 0, CL_BUFFER_SEEK_SET);
    if(pHdrLen)
        *pHdrLen = hdrLen;
    CL_FUNC_EXIT();
    return rc;
}
/**
 *  Initializes the OM class table.                          
 *
 *  This API initializes the OM class lookup table from the pre-configured<br>
 *    tables: common and application.  It also initializes other tables <br>
 *    and prepares the OM library for usage by other components.
 *
 *  @param pOmCfgData Configuration data for OM
 *
 *  @returns
 *    CL_OK - everything is ok<br>
 *    ==>FIXME:Define(==>FIXME:Define(CL_ERR_INVLD_STATE)<==)<== - wrong initialization state<br>
 *    Runlevel error code - please reference the Runlevel error codes
 *
 */
ClRcT clOmLibInitialize()
{
    ClRcT		rc = CL_OK;
    ClUint32T	classIdx = 0;
    ClUint32T	omCfgDataSz = sizeof(ClOmConfigDataT);
    ClOmClassControlBlockT	*pOmClassEntry = NULL;

    /*
      ClUint32T      cmnOmClassCnt = 0; 
    */
    /*ClUint32T	omClassCnt = 0;
      ClUint32T	skippedClassCnt = 0;*/
    extern ClRcT showMgrModAdd(char *, char *, void (*fp)(char**));
    extern void omShow (char ** );


    CL_FUNC_ENTER();

    /*
     * Check if the OI has its own DB and reload its db
     */
    if(gClOIConfig.oiDBReload)
        return CL_OK;

    /* Get a count of the common classes */


    /* 
       Initialize config data struct and make a 
       copy of the configuration data. 
    */
    memset(&gOmCfgData, 0, omCfgDataSz);
    /* Fill up the gOmCfgData */
    gOmCfgData.maxOmClassBuckets = OM_CLASS_TABLE_MAX_BUCKETS;
    gOmCfgData.minAppOmClassType = OM_APP_MIN_CLASS_TYPE;
    gOmCfgData.maxAppOmClassType = OM_APP_MAX_CLASS_TYPE;
    gOmCfgData.numOfOmClasses = 0;

    /* Create a hash table for storing OM classes */
    rc = clCntHashtblCreate(gOmCfgData.maxOmClassBuckets, omClassKeyCompare, 
                            omClassHashFn, omClassEntryDelCallBack, 
                            omClassEntryDestroyCallBack, CL_CNT_NON_UNIQUE_KEY, &ghOmClassHashTbl);

    if ((rc != CL_OK) || (ghOmClassHashTbl == 0))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("%s: Failed to create a hash table "
                                       "for OM classes (rc = 0x%x)!!!\n\r", 
                                       __FUNCTION__, rc));
        return (rc);
    }


    /* Consolidate OM class tables into a hash table */
    /* Configure the common OM class table */

    /* Initialize the base class here */


    if ((rc = clOmClassInitialize (&gBaseClassTable, 
                                   gBaseClassTable.eMyClassType, 
                                   gBaseClassTable.maxObjInst,
                                   gBaseClassTable.maxSlots)) != CL_OK)
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to initialize OM with rc = "
                                        "0x%x!\r\n", __FUNCTION__, rc));
        return (rc);
    }




    /* Accumulate the number of classes registered w/ OM */
    /*omClassCnt = classIdx;*/
    pOmClassEntry = NULL;

    /* Configure the application OM class table */
    classIdx = 0;

    if (appOmClassCnt > 0)
    {
        for (; classIdx < appOmClassCnt; classIdx++)
        {
            pOmClassEntry = &(pAppOmClassTbl[classIdx]);
            if (pOmClassEntry->eMyClassType == CL_OM_INVALID_CLASS)
            {
                /* skip invalid class */
                /* 
                   This way invalid classes and missing, i.e. a table
                   size if bigger than the number of classes
                   are allowed in the table.
                */
                /*skippedClassCnt++;*/
                continue;
            }

            if ((rc = clOmClassInitialize (pOmClassEntry, 
                                           pOmClassEntry->eMyClassType, 
                                           pOmClassEntry->maxObjInst,
                                           pOmClassEntry->maxSlots)) != CL_OK)
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to initialize OM with rc = "
                                                "0x%x!\r\n", __FUNCTION__, rc));
                return (rc);
            }
        }
    }
    else
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("%s: Not initializing OM Application class "
                                        "table because it does not exist...ignoring.\r\n",
                                        __FUNCTION__));
    }

    /* Get the total number of classes registered w/ OM */
    /*gOmCfgData.numOfOmClasses = omClassCnt + classIdx - skippedClassCnt;*/

    /* Initialize the COR/OM handle translation table */
    if (rc == CL_OK)
    {
        if((rc = omCORTableInit()) != CL_OK)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to setup the COR translation "
                                            "table with rc = 0x%x\r\n", rc));
        }
    }

#ifdef DEBUG
    /* Add OM into the debug agent */
    if (!omClassInitState)
        dbgAddComponent(COMP_PREFIX, COMP_NAME, COMP_DEBUG_VAR_PTR);
#endif

    omClassInitState = CL_TRUE;
    /* add the om to show manager */ 
    /*@todo: Navdeep (show manager dependency) 
      showMgrModAdd(COMP_PREFIX, COMP_NAME, omShow); 
    */
    CL_FUNC_EXIT();
    return (rc);
}
/**
 *  Create a new State machine type.
 *
 *  API to create a new State macine Type. Maximum states in the
 *  state machine is passed in the parameter. Each state is 
 *  identified by a state id (index) and captures the transition
 *  table at each table.
 *                                                                        
 *  @param maxStates maximum states in State Machine 
 *  @param sm        [out] handle to the newly created state machine type
 *
 *  @returns 
 *    CL_OK on CL_OK <br/>
 *    CL_SM_RC(CL_ERR_NO_MEMORY) on memory allocation FAILURE <br/>
 *    CL_SM_RC(CL_ERR_NULL_POINTER) on invalid/null state machine handle <br/>
 *
 *  @see #clSmTypeDelete
 */
ClRcT
clSmTypeCreate(ClUint16T maxStates,
             ClSmTemplatePtrT* sm
             )
{
  ClRcT ret = CL_OK;
  int sz = 0;

  CL_FUNC_ENTER();
  CL_ASSERT(sm);  

  CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Create State Machine Type [%d]", maxStates));

  if(sm && (maxStates > 0)) {
    /* allocate the states and assign to top */
    *sm = (ClSmTemplatePtrT) mALLOC(sizeof(ClSmTemplateT));
    if(*sm!=0) 
      {
        sz = sizeof(ClSmStatePtrT)*(int)maxStates;
        /* allocate space to hold maxStates handles  */
        (*sm)->top = (ClSmStatePtrT*) mALLOC((size_t)sz);
        if((*sm)->top) 
          {
            (*sm)->maxStates = maxStates;
            (*sm)->objects = 0;
            /* Introduced a semaphore for handling concurrent
             * SM Instance creation/deletion
             */
            ret = clOsalMutexCreate( &((*sm)->sem));
            if (CL_OK != ret)
            {
                mFREE((*sm)->top);
                mFREE(*sm);
                ret = SM_ERR_NO_SEMA;
            }
            else
            {
                /* 
                 * default initial state to first state
                 */
                (*sm)->init = (*sm)->top[0];
                (*sm)->type = SIMPLE_STATE_MACHINE;
#ifdef DEBUG
                (*sm)->name[0] = 0;
#endif
            }
          }
        else
          {
            mFREE(*sm);
          }
      }
    if(!(*sm) || !(*sm)->top)
      {
        ret = CL_SM_RC(CL_ERR_NO_MEMORY);
      }
  } else 
    {
      ret = CL_SM_RC(CL_ERR_NULL_POINTER);
    }

  CL_FUNC_EXIT();
  return ret;
}
static ClRcT 
clOmClassNameInitialize (ClOmClassControlBlockT *pClassTab, char *pClassName, ClUint32T maxInstances, 
                         ClUint32T maxSlots)
{
	ClUint32T **tmp_ptr;
	ClUint32T  tmp_size;
	ClRcT		rc = CL_OK;

	CL_ASSERT(pClassTab);
    CL_FUNC_ENTER();

    /* Sanity check for pClassTab */
    if(pClassTab == NULL || !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, ("pClassTab = %p, Class = %s, maxInstances = %d, "
                                    "maxSlots = %d", (void *)pClassTab, pClassName, 
                                    (ClUint32T)maxInstances, maxSlots));

	/*  CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("eClass = %d",(ClUint32T)classId)); */

	/*
	 * @todo: To validate the maxSlots field, it is not used 
     * in this release.
	 */

	/* Validate the input arguments */
	if (!maxInstances)
	{
		rc = CL_OM_SET_RC(CL_OM_ERR_INVALID_MAX_INSTANCE);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Invalid (zero) max instances argument "
                                        "(rc = 0x%x)!\r\n", rc)); 
		return (rc);
	}

	/*
	 * Check if the instance table for the specified class is already
	 * allocated. If allocated take either of two actions.
	 * 1. Return an error ot the user and indicate already allocated
	 * 2. Run thru' all the instances and free up the objects that are
 	 *    allocated in the OM context. and release the instance table
	 *    to make room for the new one.
	 */
	if (pClassTab->pInstTab)
	{
		rc = CL_OM_SET_RC(CL_OM_ERR_INSTANCE_TAB_EXISTS);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, 
                       ("The Instance Table for this class already exists "
                        "(rc = 0x%x)!\r\n", rc));
		return (rc);
	}

	/* Allocate memory for the instance table for the specified class. */
	tmp_size = (maxInstances * sizeof(ClUint32T*));
	if ((tmp_ptr = (ClUint32T **)clHeapAllocate(tmp_size)) == NULL)
	{
		rc = CL_OM_SET_RC(CL_OM_ERR_NO_MEMORY);
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Not enough memory available in the "
                                        "system (rc = 0x%x)\r\n", rc));
		return (rc);
	}

	/* Now setup the Peer class table */
	pClassTab->pInstTab = tmp_ptr;

	/* Add this class entry into the OM class lookup table */
	rc = clCntNodeAdd(ghOmClassNameHashTbl, 
                      (ClCntKeyHandleT)pClassName, (ClCntDataHandleT)pClassTab, NULL);
	if (rc != CL_OK)
    {
		CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("%s: Failed to add OM class to hash table, "
                                        "w/ rc 0x%x!\r\n", __FUNCTION__, rc));
		return (rc);
    }
	gOmCfgData.numOfOmClasses++;
   	CL_FUNC_EXIT();
	return (rc);
}
/**
 * Internal Function - used to pack/prepare data-set for checkpointing
 * transaction-service
 */
static ClRcT _clTxnServiceCkptAppStatePack(
    CL_IN   ClUint32T   dataSetId,
    CL_OUT  ClAddrT     *ppData,
    CL_OUT  ClUint32T   *pDataLen,
    CL_IN   ClPtrT      cookie)
{
    ClRcT                       rc = CL_OK;
    ClBufferHandleT      txnSrvcStateBuff;

    CL_FUNC_ENTER();
    /* Walk through the list of transactions available in activeTxnMap.
       For each transaction, call clTxnStreamTxnCfgInfoPack()
       For the received message-buffer, append it to the master message-buffer.
    */

    if ( (ppData == NULL) || (pDataLen == NULL) )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Null arguements"));
        CL_FUNC_EXIT();
        return CL_ERR_NULL_POINTER;
    }

    rc = clBufferCreate (&txnSrvcStateBuff);

    if (CL_OK == rc)
    {
        clXdrMarshallClUint32T( &(clTxnServiceCfg->txnIdCounter), txnSrvcStateBuff, 0);

        /* Copy to buffer */
        *pDataLen = 0;
        *ppData = NULL;

        if (CL_OK == rc)
        {
            ClUint32T   ckptDataLen;

            rc = clBufferLengthGet(txnSrvcStateBuff, &ckptDataLen);

            if ( (CL_OK == rc) && ( ckptDataLen != 0) )
            {
                *ppData = (ClAddrT) clHeapAllocate(ckptDataLen);
                *pDataLen = ckptDataLen;
                if ( *ppData != NULL )
                {
                    rc = clBufferNBytesRead(txnSrvcStateBuff,
                                            (ClUint8T *) *ppData, &ckptDataLen);
                    if (CL_OK != rc)
                    {
                        *pDataLen = 0x0;
                        clHeapFree(*ppData);
                        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to create txn-service checkpoint. rc:0x%x", rc));
                        rc = CL_GET_ERROR_CODE(rc);
                    }


                }
                else
                {
                    rc = CL_ERR_NO_MEMORY;
                }
            }
            else
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                               ("Error while packing or no data rc:0x%x data-len:0%x", rc, ckptDataLen));
            }
        }

        rc = clBufferDelete(&txnSrvcStateBuff);

    }
    CL_FUNC_EXIT();
    return (rc);
}
ClRcT clEvtCpmReplyCb(ClUint32T data, ClBufferHandleT inMsgHandle,
                      ClBufferHandleT outMsgHandle)
{
    ClUint32T rc = CL_OK;

#if 0
    ClCpmLcmResponseT response = { {0, 0}, 0 };
    ClUint32T msgLength = 0;
    ClCharT logmsg[CL_MAX_NAME_LENGTH] = { 0 };
    ClCharT requesttype[CL_MAX_NAME_LENGTH] = { 0 };

    CL_FUNC_ENTER();
    rc = clBufferLengthGet(inMsgHandle, &msgLength);
    if (msgLength == sizeof(ClCpmLcmResponseT))
    {
        rc = clBufferNBytesRead(inMsgHandle, (ClUint8T *) &response,
                                &msgLength);
        if (rc != CL_OK)
        {
            clOsalPrintf("Unable to read the message. \n");
            goto failure;
        }
    }
    else
    {
        clOsalPrintf("Buffer read failure !\n");
        goto failure;
    }

    printf("Received reply for %s...\n", response.name);

    switch (response.requestType)
    {
    case CL_CPM_HEALTHCHECK:
        strcpy(requesttype, "CL_CPM_HEALTHCHECK");
        break;
    case CL_CPM_TERMINATE:
        strcpy(requesttype, "CL_CPM_TERMINATE");
        break;
    case CL_CPM_PROXIED_INSTANTIATE:
        strcpy(requesttype, "CL_CPM_PROXIED_INSTANTIATE");
        break;
    case CL_CPM_PROXIED_CLEANUP:
        strcpy(requesttype, "CL_CPM_PROXIED_CLEANUP");
        break;
    case CL_CPM_EXTN_HEALTHCHECK:
        strcpy(requesttype, "CL_CPM_EXTN_HEALTHCHECK");
        break;
    case CL_CPM_INSTANTIATE:
        strcpy(requesttype, "CL_CPM_INSTANTIATE");
        break;
    case CL_CPM_CLEANUP:
        strcpy(requesttype, "CL_CPM_CLEANUP");
        break;
    case CL_CPM_RESTART:
        strcpy(requesttype, "CL_CPM_RESTART");
        break;
    default:
        strcpy(requesttype, "Invalid request");
        break;
    }

    sprintf(logmsg, "%s %s request %s.\n", response.name, requesttype,
            response.returnCode == CL_OK ? "success" : "failure");
    printf(logmsg);

    CL_FUNC_EXIT();
    return CL_OK;

failure:
    CL_FUNC_EXIT();
#endif

    printf("Invoked the Callback for CPM API succesfully\n\r\n");

    return rc;
}
/**
 * Serializer function for transaction state
 */
static ClRcT _clTxnServiceCkptTxnStatePack(
    CL_IN   ClUint32T   dataSetId,
    CL_OUT  ClAddrT     *ppData,
    CL_OUT  ClUint32T   *pDataLen,
    CL_IN   ClPtrT      cookie)
{
    ClRcT                   rc  = CL_OK;
    ClTxnTransactionIdT     *pTxnId;
    ClBufferHandleT  msgHandle;
    ClUint32T               msgLen;

    CL_FUNC_ENTER();

    pTxnId = (ClTxnTransactionIdT *) cookie;

    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("To checkpoint recovery-log of txn 0x%x:0x%x",
                                    pTxnId->txnMgrNodeAddress, pTxnId->txnId));

    rc = clBufferCreate(&msgHandle);

    if (CL_OK == rc)
    {
        rc = clTxnRecoveryLogPack(pTxnId, msgHandle);

        *ppData = NULL;
        *pDataLen = 0;
        if (CL_OK == rc)
        {
            /* Copy the state-information from message-buffer to ppData */
            rc = clBufferLengthGet(msgHandle, &msgLen);
        }

        if (CL_OK == rc)
        {
            *pDataLen = msgLen;
            *ppData = (ClInt8T *) clHeapAllocate(msgLen);
            if ( *ppData == NULL )
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to allocate memory"));
                rc = CL_ERR_NO_MEMORY;
            }
        }

        if (CL_OK == rc)
        {
            rc = clBufferNBytesRead(msgHandle, (ClUint8T *) *ppData, &msgLen);
            if (CL_OK != rc)
            {
                clHeapFree(*ppData);
                *pDataLen = 0x0;
                CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                               ("Failed to pack/serialize txn-defn[0x%x:0x%x] for ckpt. rc:0x%x",
                                pTxnId->txnMgrNodeAddress, pTxnId->txnId, rc));
                rc = CL_GET_ERROR_CODE(rc);
            }
        }
        rc = clBufferDelete(&msgHandle);
    }
    CL_FUNC_EXIT();
    return (rc);
}
/**
 *  Create the specified Managed Object type.
 *
 *  API to create a new MO type and add it to the meta structure in
 *  COR. 'class' specified should be already defined.
 * 
 *  @param moPath        		Path of the class in MO Tree. e.g. /chassis/blade
 *  @param maxInstances       	Max imum instances of this MO class type that can be created
 *  @param moClassHandle 	[out] Handle to the class type created
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH) when path specified is invalid
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT) when class definition for the class is not present
 *    CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_TO_ADD_NODE) when addition to MO Tree fails
 *
 */
ClRcT 
_corMOClassCreate(ClCorMOClassPathPtrT moClassPath, 
                 ClInt32T maxInstances, 
                 CORMOClass_h* moClassHandle
                 )
{
    ClCorClassTypeT moClassType;
     CORClass_h corClassHandle;
    ClRcT  rc = CL_OK;

    CL_FUNC_ENTER();
    
    if(!moTree)
      return (CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "Max instances %d", (ClUint32T)maxInstances));

    if ((moClassPath == NULL) || (moClassHandle == NULL))
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassCreate: NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    if ( ( 0 > maxInstances ) )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassCreate: Negative Max Instance"));
        CL_FUNC_EXIT();
        return (CL_COR_SET_RC(CL_COR_ERR_INVALID_PARAM));
    }
    
    
    if (clCorMoClassPathValidate(moClassPath) != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to validate the moClassPath argument"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH));
      }
    
    moClassType = clCorMoClassPathToMoClassGet(moClassPath);
    
    /* Validate with data manager, the final class ID */
    if (dmClassIsPresent(moClassType) != CL_TRUE)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Invalid class type specified"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_NOT_PRESENT));
      }

	/*Get the DM class first*/
	corClassHandle = dmClassGet(moClassType);
	if(NULL != corClassHandle)
		{
		corClassHandle->moClassInstances++;
		}
    
    rc = corMOTreeAdd(moTree, moClassPath, maxInstances);
    if (rc != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to Add node by path"));
        return(CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_TO_ADD_NODE));
      }
    
    if (moClassHandle)
      *moClassHandle = corMOTreeFind(moClassPath);
    
    CL_FUNC_ENTER();
    return(CL_OK);
}
/** 
 * Delete a class from class handle.
 *
 * API to dmClassByHandleDelete <Deailed desc>. 
 *
 *  @param this       object handle
 *  @param 
 * 
 *  @returns 
 *    ClRcT  CL_OK on success <br>
 *     CL_COR_SET_RC(CL_COR_ERR_NULL_PTR) on null parameter.
 *
 *  @todo      
 *
 */
ClRcT
dmClassByHandleDelete(CORClass_h classHandle
                      )
{
    ClRcT ret = CL_OK;
    CORClass_h tmp = 0;

    CL_FUNC_ENTER();

    if((!classHandle) || (!dmGlobal))
      {
        CL_FUNC_EXIT();  
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "ClassDelete (Class:%04x)", 
                          classHandle->classId));


    /* check if instances are there and also base classes
     * by default cannot be deleted, they may be in other
     * inherited classes.
     */
    if (COR_CLASS_IS_BASE(*classHandle))
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassDelete (Class:%04x) [Class is base]", classHandle->classId));
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_IS_BASE);
    }
    else if(classHandle->objCount == 0 && 
           (classHandle->moClassInstances == 0))
      {
        
        /* get the handle to the parent class */
        HASH_GET(dmGlobal->classTable,classHandle->superClassId, tmp);
        if(tmp)
        {
            tmp->noOfChildren--;
            if(tmp->noOfChildren == 0)
                COR_CLASS_RESETAS_BASE(*tmp);
        }
        /* now we can remove from hash table & free it 
         */
        HASH_REMOVE(dmGlobal->classTable, classHandle->classId);
        /* free the attribute list hashtable and the elements in
         * the vector 
         */
        HASH_FREE(classHandle->attrList);
        COR_LLIST_FREE(classHandle->objFreeList);

        corVectorRemoveAll(&classHandle->attrs);
        /* nothing to remove in the objects vector */
        clHeapFree(classHandle);
      } 
    else 
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "ClassDelete (Class:%04x) [Instances present]", 
                              classHandle->classId));
        
        ret = CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT);
      }
    
    CL_FUNC_EXIT();
    return (ret);
}
/**
 *  Delete the last node in the MO hierarchy.
 *
 *  API to delete the class type specified if there are no instances
 *  in the COR.  NOTE: This API shall delete the class specified in
 *  the ClCorMOClassPath and the subtree of classes, including the service
 *  class ids.
 *                                                                        
 *  @param 	moPath  path to the class to be deleted from MO Tree
 *
 *  @returns 
 *    CL_OK on success <br/>
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH)	when path specified is not valid
 *    CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT)	When class instance is present you can not delete class.
 *    CL_COR_SET_RC(CL_COR_MO_TREE_ERR_FAILED_TO_DEL_NODE)	When failed to delete node from MO Tree
 *
 */
ClRcT 
_corMOClassDelete(ClCorMOClassPathPtrT moClassPath)
{
    ClRcT rc;
    ClCorClassTypeT moClassType;
	MOTreeNode_h node;
	ClUint32T numChildNode; 
	CORClass_h corClassHandle;
	

    CL_FUNC_ENTER();
    
    if (moClassPath == NULL)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "_corMOClassDelete: NULL argument"));
        CL_FUNC_EXIT();
        return(CL_COR_SET_RC(CL_COR_ERR_NULL_PTR));
      }
    
    if (clCorMoClassPathValidate(moClassPath) != CL_OK)
      {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to validate the moClassPath argument"));
        return(CL_COR_SET_RC(CL_COR_ERR_CLASS_INVALID_PATH));
      }

#ifdef DEBUG
    CL_DEBUG_PRINT(CL_DEBUG_INFO, ( "Delete MOTree object: "));
    clCorMoClassPathShow(moClassPath);
#endif

    moClassType = clCorMoClassPathToMoClassGet(moClassPath);
#if 0
    /* This check is not required. In case if a COR class is used by TWO
  	MOs, We won't be able to delete one MO even if instance of other
  	is present. 

  	Instead we need to look into MO Class Handle to determine how many
  	objects of MO are present*/
  	
    moClassType = clCorMoClassPathToMoClassGet(&nCorPath);
    if ( dmClassInstanceCountGet(moClassType) > 1 )
    {
        CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Class instance already present or is a base-class"));
        CL_FUNC_EXIT();
        return (CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT));
    }
#endif

   	node = corMOTreeFind(moClassPath);
	if(NULL == node)
	{
       	CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Could not find node information in the tree."));
       	CL_FUNC_EXIT();
       	return (CL_COR_SET_RC(CL_COR_MO_TREE_ERR_NODE_NOT_FOUND));
	}
	
	if( ((_CORMOClass_h)node->data)->instances > 0)
		{
		/* Object Instances present */
		CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Class instance already present"));
		CL_FUNC_EXIT();
		return (CL_COR_SET_RC(CL_COR_ERR_CLASS_INSTANCES_PRESENT));
		}
	
	numChildNode = ( (_CORMOClass_h)(node->data) )->numChildren;
	if(numChildNode > 1)
	{
       	CL_DEBUG_PRINT (CL_DEBUG_ERROR, ( "Class has children classes. Deletion is not possible."));
       	CL_FUNC_EXIT();
       	return (CL_COR_SET_RC(CL_COR_MO_TREE_ERR_CHILD_CLASS_EXIST));
	}
    rc = corMOTreeDel(moClassPath);
    if ( rc != CL_OK )
	{
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ( "Failed to delete node by path"));
        return rc;
	}
    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ( "\nDeleted MO Class node from hierarchy"));

		/*Get the DM class first*/
	corClassHandle = dmClassGet(moClassType);
	if(NULL != corClassHandle)
		{
		corClassHandle->moClassInstances--;
                                
		}
    CL_FUNC_EXIT();
    return(CL_OK);
}
ClRcT halObjCreate(ClUint32T omId,
                   ClCorMOIdPtrT moId,
                   ClHalObjectHandleT *const phalObjHandle)
{
    HalObjectT * phalObject = NULL;
    ClRcT ret=CL_OK;
#ifdef CL_DEBUG
    char aFunction[]="halObjCreate";
#endif

    CL_FUNC_ENTER();

    if (NULL == phalObjHandle)
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("\n %s Error NULL Pointer  \n ",aFunction));
        CL_FUNC_EXIT();
        return (CL_HAL_SET_RC(CL_ERR_NULL_POINTER));
    }
    phalObject =(HalObjectT*) clHeapAllocate((ClUint32T)sizeof(HalObjectT));

    if (NULL == phalObject)
    {
        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("\n %s Error Malloc Failed\n ",aFunction));
        CL_FUNC_EXIT();
        return (CL_HAL_SET_RC( CL_ERR_NO_MEMORY)) ;
    }

    memset(phalObject,0,sizeof(HalObjectT));

    phalObject->omId=omId;

    if(NULL != moId)
    {
        phalObject->moId = (ClCorMOIdPtrT) clHeapAllocate ((ClUint32T)sizeof(ClCorMOIdT));

        if (NULL == phalObject->moId)
        {
            clHeapFree (phalObject);
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,("\n %s Error Malloc Failed\n ",aFunction));
            CL_FUNC_EXIT();
            return (CL_HAL_SET_RC( CL_ERR_NO_MEMORY)) ;
        }

        memset (phalObject->moId,0,sizeof(ClCorMOIdT));
        memcpy (phalObject->moId, moId, sizeof(ClCorMOIdT));
    }
    else
    {
        /* Error Condition */
        /* This needs to be uncommented after fixing the call to clOmObjectCreate &
        clOmCorAndOmObjectsCreate by passing hMOId ,sizeof(ClCorMOIdT) as the last 2parameters.
        As of now  NULL is being passed */
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,("\n %s Error Invalid Parameter \n ",aFunction));
        CL_FUNC_EXIT();
        return (CL_HAL_SET_RC(CL_ERR_INVALID_PARAMETER));
    }

    ret = clCntLlistCreate(halKeyCompare,NULL,halObjContainerDestroy,CL_CNT_UNIQUE_KEY,
                           &(phalObject->hTableRefDevObject));
    if (CL_OK !=ret)
    {
        clHeapFree (phalObject);
        phalObject =NULL;
        CL_DEBUG_PRINT(CL_DEBUG_TRACE,("\n %s Error returned by \
        clCntLlistCreate \n ", aFunction));
        CL_FUNC_EXIT();
        return ret;
    }
/**
  This function recieves the debug CLI command through the transaction manager
  and send back the job status and registered service details. 
*/
static ClRcT 
VDECL(clTxnAgentDebugMsgReceive)(
        CL_IN   ClEoDataT               eoArg, 
        CL_IN   ClBufferHandleT  inMsg, 
        CL_IN   ClBufferHandleT  outMsg)
{
    ClRcT                   rc = CL_OK;

    CL_FUNC_ENTER();
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_NEWLINE,
                                        CL_TXN_AGT_CLI_DISP_NEWLINE_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *) CL_TXN_AGT_CLI_DISP_JOB_LIST_HEADER,
                                        CL_TXN_AGT_CLI_DISP_JOB_LIST_HEADER_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);
    
    rc = _clTxnAgentAppendActiveJob(outMsg);
    if(CL_OK != rc)
    {
        clLogError("AGT", "CLI",
                "Appending active job failed with error [0x%x]. Failed to handle Txn Mgr debug cmd", rc);
        return rc;
    }
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_NEWLINE,
                                        CL_TXN_AGT_CLI_DISP_NEWLINE_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *) CL_TXN_AGT_CLI_DISP_SRC_INFO_HEADER,
                                        CL_TXN_AGT_CLI_DISP_SRC_INFO_HEADER_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);

    rc = _clTxnAgentAppendServices(outMsg);
    if(CL_OK != rc)
    {
        clLogError("AGT", "CLI",
                "Appending services failed with error [0x%x]. Failed to handle Txn Mgr debug cmd", rc);
        return rc;
    }
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_SHORT_SEP,
                                        CL_TXN_AGT_CLI_DISP_SHORT_SEP_SIZE,
                                        outMsg,0);
    
    rc = clXdrMarshallArrayClUint8T((ClUint8T *)CL_TXN_AGT_CLI_DISP_NEWLINE,
                                        CL_TXN_AGT_CLI_DISP_NEWLINE_SIZE,
                                        outMsg,0);
    CL_FUNC_EXIT();
    return(rc);
}