/*
 * This function needs to be written for every table in the MIB.
 * The information for MIB table index is stored in container, so the user
 * needs to provide logic for key comparison of the container.
 */
ClInt32T  clSnmpsaAmfProxyProxiedTableInstCompare (CL_IN ClCntKeyHandleT key1,
                            CL_IN ClCntKeyHandleT key2)
{
    ClSNMPRequestInfoT *pTabIdx1 = NULL;
    ClSNMPRequestInfoT *pTabIdx2 = NULL;
    ClInt32T retVal = 0;
    
    if (key1 != 0) pTabIdx1 = (ClSNMPRequestInfoT *)key1;
    if (key2 != 0) pTabIdx2 = (ClSNMPRequestInfoT *)key2;

    if(!pTabIdx1 || !pTabIdx2)
    {
        /* return non-zero value  in case of error condition. */
        return(-1);
    }

    clLogDebug(CL_SNMP_AREA, CL_SNMP_GEN_CMP_COTX, "Index value1 : [%u], Index value2: [%u].", 
        (ClUint32T) pTabIdx1->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxyNameId, (ClUint32T) pTabIdx2->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxyNameId);

	if ( (retVal = ((ClUint32T) pTabIdx1->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxyNameId - (ClUint32T) pTabIdx2->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxyNameId)) != 0)
	    return retVal;

    clLogDebug(CL_SNMP_AREA, CL_SNMP_GEN_CMP_COTX, "Index value1 : [%u], Index value2: [%u].", 
        (ClUint32T) pTabIdx1->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxiedNameId, (ClUint32T) pTabIdx2->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxiedNameId);

	if ( (retVal = ((ClUint32T) pTabIdx1->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxiedNameId - (ClUint32T) pTabIdx2->index.saAmfProxyProxiedTableInfo.saAmfProxyProxiedProxiedNameId)) != 0)
	    return retVal;

    return 0;
}
void clSnmpUndo(void)
{
    ClUint32T arrIndex = 0;
    clSnmpMutexLock(gOper.mtx);

    gOper.refCount--;
    if(!gOper.refCount)
    {
        clLogDebug("SNM","OPE",
                "Ref count 0 ,removing store");
        /* Remove the error list */
        if(gOper.medErrList.count)
        {
            clLogDebug("SNM","OPE",
                    "ErrList count[%d], removing errlist", gOper.medErrList.count);
            for(arrIndex = 0; arrIndex < gOper.medErrList.count; arrIndex++)
            {
                clHeapFree(gOper.medErrList.pErrorList[arrIndex].oidInfo.id);
            }
            gOper.medErrList.count = 0;
            clHeapFree(gOper.medErrList.pErrorList);
            gOper.medErrList.pErrorList = NULL;
        }
        /* Remove the var bind information */
        if(gOper.opInfo.varCount)
        {
            clLogDebug("SNM","OPE",
                    "VarBind count[%d], removing varbinds", gOper.opInfo.varCount);
            for(arrIndex = 0; arrIndex < gOper.opInfo.varCount; arrIndex++)
            {
                clHeapFree(gOper.opInfo.varInfo[arrIndex].pVal);
                clHeapFree(gOper.opInfo.varInfo[arrIndex].pInst);
				clHeapFree(gOper.opInfo.varInfo[arrIndex].attrId.id);
            }
            gOper.opInfo.varCount = 0; 
            clHeapFree (gOper.opInfo.varInfo);
            gOper.opInfo.varInfo = NULL; /* Next operation would see this and return */
            if (gOper.pOpAddData != NULL)
            {
                clHeapFree(gOper.pOpAddData);
                gOper.pOpAddData = NULL;
            }
            gOper.cmtd = CL_FALSE;
        }
    }

    clSnmpMutexUnlock(gOper.mtx);
}
ClRcT clMsgFinalizeBlocker(void)
{
    ClRcT rc = CL_OK;
    SaTimeT timeout = (SaTimeT)(CL_MSG_FIN_BLOCK_TIME * 1000000000LL);
    ClTimerTimeOutT tempTime = {0};

    CL_OSAL_MUTEX_LOCK(&gFinBlockMutex);

    if(gMsgMoveStatus == MSG_MOVE_DONE)
        goto out;

    clLogDebug("FIN", "BLOCK", "Message service finalize will be blocked for [%llu ns].", timeout);

    if(gMsgMoveStatus == MSG_MOVE_FIN_UNINIT)
    {
        rc = clOsalTaskCreateDetached("allClosedQueueMoverThread", CL_OSAL_SCHED_OTHER, CL_OSAL_THREAD_PRI_NOT_APPLICABLE, 0, clMsgClosedQueueMoveThread, NULL);
        if(rc != CL_OK)
        {
            clLogError("FIN", "BLOCK", "Failed to create a Queue mover thread. error code [0x%x].", rc);
            goto error_out;
        }
        clMsgTimeConvert(&tempTime, timeout);

        rc = clOsalCondWait(gFinBlockCond, &gFinBlockMutex, tempTime);
        if(CL_GET_ERROR_CODE(rc) == CL_ERR_TIMEOUT)
        {   
            clLogError("FIN", "BLOCK", "Finalize blocking timed out. Timeout is [%lld ns]. error code [0x%x].", timeout, rc);
        }   
        else if(rc != CL_OK)
        {
            clLogError("FIN", "BLOCK", "Failed at Conditional Wait. error code [0x%x].", rc);
        }
        else
        {
            clLogDebug("FIN", "BLOCK", "Message queues are failed over to [0x%x] node.", gQMoveDestNode);
        }
    }

    gMsgMoveStatus = MSG_MOVE_DONE;

    goto out;

    error_out:
    out:
    CL_OSAL_MUTEX_UNLOCK(&gFinBlockMutex);
     
    return rc;
}
/**
 * API to restore status of transaction-service from check-point
 */
ClRcT clTxnServiceCkptAppStateRestore()
{
    ClRcT       rc = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        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);

        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Restoring transaction-service state"));

        clLogDebug("SER", NULL,
                   "Ckpt exists, reading data");
        rc = clCkptLibraryCkptDataSetRead(clTxnServiceCfg->txnCkptHandle, &txnCkptName,
                                          CL_TXN_SERVICE_DATA_SET, 0x0);

        if (CL_OK != rc)
        {
            clLogError("SER", NULL,
                       "Failed to restore transaction-service state, rc [0x%x]", rc);
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
static void clMsgEventCallbackFunc(ClEventSubscriptionIdT subscriptionId, ClEventHandleT eventHandle, ClSizeT eventDataSize)
{
    ClRcT rc;
    ClCpmEventNodePayLoadT nodePayload = {{0}};

    rc = clCpmEventPayLoadExtract(eventHandle, eventDataSize, CL_CPM_NODE_EVENT, (void *)&nodePayload);
    if(rc != CL_OK)
    {
        clLogError("EVT", "Cbk", "Failed to get event payload data. error code [0x%x].", rc);
        goto error_out;
    }

    if(nodePayload.operation != CL_CPM_NODE_DEPARTURE)
        goto out;

    clLogDebug("EVT", "Cbk", "Node [0x%x] is going down. Message queues are going to be failed over.", nodePayload.nodeIocAddress);

    if(nodePayload.nodeIocAddress == gLocalAddress)
    {
        CL_OSAL_MUTEX_LOCK(&gFinBlockMutex);
        rc = clMsgFinBlockStatusSet(MSG_MOVE_FIN_BLOCKED);
        CL_OSAL_MUTEX_UNLOCK(&gFinBlockMutex);
        if(rc != CL_OK)
            clLogError("EVT", "Cbk", "Failed at block the message finalize on this node. error code [0x%x].", rc);
    }

error_out:
out:
    clEventFree(eventHandle);
    return;
}
/**
 * API to restore recovery logs of previously active transactions
 * from check-point
 */
ClRcT clTxnServiceCkptRecoveryLogRestore()
{
    ClRcT       rc = CL_OK;
    if(!clTxnServiceCfg->dsblCkpt)
    {
        SaNameT     txnCkptName;

        CL_FUNC_ENTER();

        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);

        CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Restoring transaction-recovery logs"));

        /* AD-1: To use the checkpoint exists api to check whether its recovery or
         * normal startup */
        clLogDebug("SER", NULL,
                   "Checkpoint exists, reading data for recovery");
        rc = clCkptLibraryCkptDataSetRead(clTxnServiceCfg->txnCkptHandle, &txnCkptName,
                                          CL_TXN_RECOVERY_DATA_SET, 0x0);

        if (CL_OK != rc)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Failed to restore transaction-service state. rc:0x%x", rc));
            rc = CL_GET_ERROR_CODE(rc);
        }
    }

    CL_FUNC_EXIT();
    return (rc);
}
ClRcT clMsgQueueFreeByHandle(SaMsgQueueHandleT qHandle)
{
    ClRcT rc;
    ClMsgQueueInfoT *pQInfo;

    CL_OSAL_MUTEX_LOCK(&gClLocalQsLock);

    rc = clHandleCheckout(gClMsgQDatabase, qHandle, (ClPtrT *)&pQInfo);
    if(rc != CL_OK)
    {
        CL_OSAL_MUTEX_UNLOCK(&gClLocalQsLock);
        clLogError("QUE", "FREE", "Failed at checkout the passed queue handle. error code [0x%x].", rc);
        goto error_out;
    }

    clMsgQueueFree(pQInfo);
    clLogDebug("QUE", "FREE", "Queue is freed through its handle."); 

    CL_OSAL_MUTEX_UNLOCK(&gClLocalQsLock);

    rc = clHandleCheckin(gClMsgQDatabase, qHandle);
    if(rc != CL_OK)
        clLogError("QUE", "FREE", "Failed to checkin a queue handle. error code [0x%x].", rc);

    rc = clHandleDestroy(gClMsgQDatabase, qHandle);
    if(rc != CL_OK)
        clLogError("QUE", "FREE", "Failed to destroy a queue handle. error code [0x%x].", rc);

error_out:
    return rc;

}
ClRcT
clNameContextCkptNameUnpack(ClBufferHandleT  inMsg)
{
    ClRcT             rc      = CL_OK;
    ClUint32T         key     = 0;
    ClUint32T         size    = 0;
    ClUint32T         count   = 0;
    ClIocNodeAddressT localAddr = 0;
    ClIocNodeAddressT masterAddr = 0;

    CL_NAME_DEBUG_TRACE(("Enter"));
    rc = clXdrUnmarshallClUint32T(inMsg, &size);
    if( CL_OK != rc )
    {
        CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                ("clXdrUnmarshallClUint32T(): rc[0x %x]", rc));
        return rc;
    }    
    clLogDebug("SVR", "CKP", "Num of contexts: %d", size);
    for( count = 0; count < size; count++)
    {    
        rc = clXdrUnmarshallClUint32T(inMsg, &key);
        if( CL_OK != rc )
        {
            return rc;
        }    
        if( (key > CL_NS_DEFAULT_GLOBAL_CONTEXT) && 
            (key < CL_NS_BASE_NODELOCAL_CONTEXT) )
        {
            localAddr = clIocLocalAddressGet();
            rc = clCpmMasterAddressGet(&masterAddr);
            if (rc != CL_OK)
            {
                CL_DEBUG_PRINT(CL_DEBUG_ERROR,("clCpmMasterAddressGet failed with rc 0x%x",rc));
                return rc;
            }

            if( masterAddr == localAddr )
            {
                rc = clNameSvcCtxRecreate(key);
                if( CL_OK != rc )
                {
                    return rc;
                }    
            }    
        }    
        else
        {    
            rc = clNameSvcCtxRecreate(key);
            if( CL_OK != rc )
            {
                return rc;
            }    
        } 
    }
    
    CL_NAME_DEBUG_TRACE(("Exit"));
    return rc;
}    
ClRcT clMsgFinBlockStatusSet(ClMsgMoveStatusT status)
{
    ClRcT rc;
    ClIocNodeAddressT node;


    switch(status)
    {
        case MSG_MOVE_FIN_BLOCKED :

            if(gMsgMoveStatus == MSG_MOVE_FIN_BLOCKED)
            {
                goto out;
            }

            rc = clMsgNextNodeGet(gLocalAddress, &node);
            if(rc != CL_OK)
            {
                clLogError("QUE", "FAI", "Failed to get the next node's address. error code [0x%x].", rc);
                goto error_out;
            }
            else if(node == gLocalAddress)
            {
                clLogDebug("QUE", "FAI", "Only one/this node is present in the cluster.");
                gMsgMoveStatus = MSG_MOVE_DONE;
                clOsalCondSignal(gFinBlockCond);
                goto error_out;
            }

            gQMoveDestNode = node;
            gMsgMoveStatus = MSG_MOVE_FIN_BLOCKED;

            /* Find closed queues and move */
            clMsgFailoverQueuesMove(gQMoveDestNode, &gMsgNumOfOpenQs);


error_out:
out:
            if(gMsgNumOfOpenQs != 0)
                break;

        case MSG_MOVE_DONE:
            if(gMsgNumOfOpenQs != 0)
                gMsgNumOfOpenQs--;
            if(gMsgNumOfOpenQs == 0)
            {
                gMsgMoveStatus = MSG_MOVE_DONE;
                clOsalCondSignal(gFinBlockCond);
            }
            break;

        default:
            break;
    }

    return CL_OK;
}
/**
 * Process the get request. This is called in the mode end callback.
 */
int 
clSnmpProcessRequest(netsnmp_request_info *requests)
{
    ClRcT               rc = CL_SNMP_ERR_NOERROR;
    ClUint32T           i = 0;
    ClMedErrorListT     medErrList = {0};
    _ClSnmpGetReqInfoT  *pReqInfo = NULL;

    clLogDebug("SNP", NULL, "Calling the snmpCommit now.");

    rc = clSnmpCommit (&medErrList);
    if (CL_OK != rc)
    {
        clSnmpDataReset();
        clLogError("SNP", NULL, "Failed while committing the get request. rc[0x%x]", rc);
        if (CL_ERR_NO_MEMORY == rc)
            rc = CL_SNMP_ERR_NOCREATION;
        else
            rc = CL_SNMP_ERR_GENERR;
        netsnmp_request_set_error(requests, rc);
        return rc;
    }

    for (i = 0 ; i < gOper.opInfo.varCount ; i++)
    {
        pReqInfo = ((_ClSnmpGetReqInfoT *)(gOper.pOpAddData) + i);
        clLogDebug("SNP", NULL, "Processing the agentId [%s]", gOper.opInfo.varInfo[i].attrId.id);

        if (gOper.opInfo.varInfo[i].errId == CL_OK)
        {

            snmp_set_var_typed_value(pReqInfo->pRequest->requestvb, pReqInfo->columnType, 
                    gOper.opInfo.varInfo[i].pVal, gOper.opInfo.varInfo[i].len);
        }
        else
        {
            clLogDebug("SNP", NULL, "Job failed with error [0x%x]", gOper.opInfo.varInfo[i].errId);
            netsnmp_request_set_error(pReqInfo->pRequest, gOper.opInfo.varInfo[i].errId);
        }
    }

    clSnmpDataReset();
    return rc;
}
static void __compNotify(ClInt32T wd, const ClCharT *compName, ClIocNotificationIdT notification)
{
    ClTransportNotifyMapT *notify;
    ClInt32T port = -1;
    const ClCharT *s = compName;
    ClIocPhysicalAddressT compAddr;
    if(s && ( s = strrchr(s, '_')))
        port = atoi(s+1);
    if(notification == CL_IOC_COMP_ARRIVAL_NOTIFICATION)
    {
        notify = addNotifyMap(wd, port);
        if(notify)
        {
            compAddr.nodeAddress = clIocLocalAddressGet();
            compAddr.portId = port;
            clIocCompStatusSet(compAddr, CL_IOC_NODE_UP);
            /*
             * Invoke all registrants with the event.
             */
            transportNotifyRegistrants(&compAddr, CL_IOC_NODE_UP);
            clLogDebug("XPORT", "NOTIFY", "Comp arrival marked for port [%#x], id [%s]", port, compName);
        }
    }
    else
    {
        if(delNotifyMap(wd, port) == CL_OK)
        {
            compAddr.nodeAddress = clIocLocalAddressGet();
            compAddr.portId = port;
            if(compName)
            {
                transportNotifyLocRemove(compName);
            }
            clIocCompStatusSet(compAddr, CL_IOC_NODE_DOWN);
            /*
             * Invoke all registrants with the event.
             */
            transportNotifyRegistrants(&compAddr, CL_IOC_NODE_DOWN);
            clLogDebug("XPORT", "NOTIFY", "Comp death marked for port [%#x], id [%s]", port, compName);
        }
    }
}
void clMsgQueueFree(ClMsgQueueInfoT *pQInfo)
{
    ClRcT rc = CL_OK;
    SaNameT qName = {strlen("--Unknow--"), "--Unknow--"};
    ClUint32T i;

    CL_OSAL_MUTEX_LOCK(&pQInfo->qLock);

    (void)clMsgUnblockThreadsOfQueue(pQInfo);

    if(pQInfo->unlinkFlag == CL_FALSE && pQInfo->pQueueEntry != NULL)
    {
        saNameCopy(&qName, &pQInfo->pQueueEntry->qName);
    }
    
    if(pQInfo->timerHandle != 0)
    {
        rc = clTimerDelete(&pQInfo->timerHandle);
        if(rc != CL_OK)
            clLogError("QUE", "FREE", "Failed to delete [%.*s]'s timer handle. error code [0x%x].", 
                       qName.length, qName.value, rc);
    }
    
    clMsgQueueEmpty(pQInfo);

    for(i = 0; i < CL_MSG_QUEUE_PRIORITIES ; i++)
    {
        rc = clCntDelete(pQInfo->pPriorityContainer[i]);
        if(rc != CL_OK)
            clLogError("QUE", "FREE", "Failed to delete the [%.*s]'s [%d] priority container. error code [0x%x].", 
                       qName.length, qName.value, i, rc);
        else
            pQInfo->pPriorityContainer[i] = 0;
    }

    rc = clOsalCondDelete(pQInfo->qCondVar);
    if(rc != CL_OK)
        clLogError("QUE",  "FREE", "Failed to delete the [%.*s]'s condtional variable. error code [0x%x].",
                   qName.length, qName.value, rc);

    pQInfo->qCondVar = 0;

    CL_OSAL_MUTEX_UNLOCK(&pQInfo->qLock);

    rc = clOsalMutexDestroy(&pQInfo->qLock);
    if(rc != CL_OK)
        clLogError("QUE",  "FREE", "Failed to delete the [%.*s]'s lock. error code [0x%x].",
                   qName.length, qName.value, rc);

    clLogDebug("QUE", "FREE", "Freed the queue [%.*s].", qName.length, qName.value);

    return;
}
/*
 * This function needs to be written for every table in the MIB.
 * The information for MIB table index is stored in container, so the user
 * needs to provide logic for key comparison of the container.
 */
ClInt32T  clSnmpsaAmfHealthCheckTableInstCompare (CL_IN ClCntKeyHandleT key1,
                            CL_IN ClCntKeyHandleT key2)
{
    ClSNMPRequestInfoT *pTabIdx1 = NULL;
    ClSNMPRequestInfoT *pTabIdx2 = NULL;
    ClInt32T retVal = 0;
    
    if (key1 != 0) pTabIdx1 = (ClSNMPRequestInfoT *)key1;
    if (key2 != 0) pTabIdx2 = (ClSNMPRequestInfoT *)key2;

    if(!pTabIdx1 || !pTabIdx2)
    {
        /* return non-zero value  in case of error condition. */
        return(-1);
    }

    clLogDebug(CL_SNMP_AREA, CL_SNMP_GEN_CMP_COTX, "Index value1 : [%u], Index value2: [%u].", 
        (ClUint32T) pTabIdx1->index.saAmfHealthCheckTableInfo.saAmfHealthCompNameId, (ClUint32T) pTabIdx2->index.saAmfHealthCheckTableInfo.saAmfHealthCompNameId);

	if ( (retVal = ((ClUint32T) pTabIdx1->index.saAmfHealthCheckTableInfo.saAmfHealthCompNameId - (ClUint32T) pTabIdx2->index.saAmfHealthCheckTableInfo.saAmfHealthCompNameId)) != 0)
	    return retVal;

    {
    ClInt32T len1 = strlen(pTabIdx1->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey);
    ClInt32T len2 = strlen(pTabIdx2->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey);

    clLogDebug(CL_SNMP_AREA, CL_SNMP_GEN_CMP_COTX, "String Lenght1 : [%d] Lenght2 : [%d] Str1 : [%s] Str2 : [%s] ",
        len1, len2, pTabIdx1->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey, pTabIdx2->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey); 

    if(len1 != len2)
        return (len1 - len2);
    }

    if((retVal = strncmp(pTabIdx1->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey,
                    pTabIdx2->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey,
                    sizeof(pTabIdx1->index.saAmfHealthCheckTableInfo.saAmfHealthCheckKey))) != 0)
        return retVal;

    return 0;
}
ClRcT cpmInvocationAdd(ClUint32T cbType,
                       void *data,
                       ClInvocationT *invocationId,
                       ClUint32T flags)
{
    ClRcT rc = CL_OK;
    ClCpmInvocationT *temp = NULL;
    ClUint32T invocationKey = 0;

    if (cbType < 0x1LL || cbType >= CL_CPM_MAX_CALLBACK || invocationId == NULL)
        CL_CPM_CHECK(CL_LOG_SEV_ERROR, ("Invalid parameter passed \n"),
                     CL_CPM_RC(CL_ERR_INVALID_PARAMETER));

    temp =
            (ClCpmInvocationT *) clHeapAllocate(sizeof(ClCpmInvocationT));
    if (temp == NULL)
        CL_CPM_CHECK(CL_LOG_SEV_ERROR, ("Unable to allocate memory \n"),
                     CL_CPM_RC(CL_ERR_NO_MEMORY));

    clOsalMutexLock(gpClCpm->invocationMutex);

    invocationKey = gpClCpm->invocationKey++;
    CL_CPM_INVOCATION_ID_GET((ClUint64T) cbType, (ClUint64T) invocationKey,
                             *invocationId);

    temp->invocation = *invocationId;
    temp->data = data;
    temp->flags = flags;

    rc = clCntNodeAdd(gpClCpm->invocationTable, (ClCntKeyHandleT)&temp->invocation,
                      (ClCntDataHandleT) temp, NULL);
    if (rc != CL_OK)
    {
        clLogError("NEW", "INVOCATION", "Invocation add for key [%#llx] returned [%#x]", 
                   temp->invocation, rc);
        goto withLock;
    }

    clLogDebug("NEW", "INVOCATION", "Added entry for invocation [%#llx]", temp->invocation);

    clOsalMutexUnlock(gpClCpm->invocationMutex);
    return rc;

  withLock:
    clOsalMutexUnlock(gpClCpm->invocationMutex);
  failure:
    if (temp != NULL)
        clHeapFree(temp);

    return rc;
}
ClRcT clProvResourcesGet(ClCorMOIdListT** ppMoIdList)
{
    if (!pProvMoIdList)
    {
        clLogDebug("PRV", "RESLISTGET", "No prov resources configured.");
        return CL_OK;
    }

    *ppMoIdList = clHeapAllocate(sizeof(ClCorMOIdListT) + pProvMoIdList->moIdCnt * sizeof(ClCorMOIdT));
    if (!(*ppMoIdList))
    {
        clLogError("PRV", "RESLISTGET", "Failed to allocate memory.");
        return CL_PROV_RC(CL_ERR_NO_MEMORY);
    }

    memcpy(*ppMoIdList, pProvMoIdList, sizeof(ClCorMOIdListT) + pProvMoIdList->moIdCnt * sizeof(ClCorMOIdT));

    return CL_OK;
}
ClRcT clTransportNotifyOpen(ClIocPortT port)
{
    ClCharT pathname[FILENAME_MAX];
    ClCharT *compName = getenv("ASP_COMPNAME");
    ClInt32T fd;
    if(!compName) compName = "COMPNAME";
    snprintf(pathname, sizeof(pathname), "%s/%s_%d", transportNotifyLocGet(), compName, port);
    unlink(pathname);
    fd = open(pathname, O_CREAT | O_RDONLY, 0777);
    if(fd < 0)
    {
        clLogError("XPORT", "NOTIFY", "Xport notify open for path [%s] failed with [%s]",
                   pathname, strerror(errno));
        return CL_ERR_LIBRARY;
    }
    else
        clLogDebug("XPORT", "NOTIFY", "Xport notify opened for path [%s]", pathname);
    return CL_OK;
}
ClRcT
clLogFlushIntervalThreadJoin(ClLogSvrStreamDataT  *pStreamData, 
                             ClOsalTaskIdT        taskId)
{
    ClRcT  rc = CL_OK;

    rc = clOsalMutexLock_L(&pStreamData->flushIntervalMutex);
    if( CL_OK != rc )
    {
        pStreamData->flushIntervalThreadStatus =
            CL_LOG_FLUSH_INTERVAL_STATUS_CLOSE;
        clLogError("SVR", "FLU", "Failed acquire the lock rc [0x %x]", rc);
        goto exitOnError;
    }
    if( pStreamData->flushIntervalThreadStatus !=
            CL_LOG_FLUSH_INTERVAL_STATUS_CLOSE )
    {
        /* still that thread is there */
        pStreamData->flushIntervalThreadStatus =
            CL_LOG_FLUSH_INTERVAL_STATUS_CLOSE;
        /* Unlock & signal the thread */
        clOsalCondSignal_L(&pStreamData->flushIntervalCondvar);
        clOsalMutexUnlock_L(&pStreamData->flushIntervalMutex);
        /* Join the thread*/
        clLogDebug("SVR", "FLU", "Joining thread [%llu]", taskId);
        rc = clOsalTaskJoin(taskId);
        if( CL_OK != rc )
        {
            clLogError("SVR", "FLU", "Joining flush interval thread failed rc[0x %x]" ,rc);
        }
    }
    else
    {
        /* Unlock & signal the thread */
        clOsalMutexUnlock_L(&pStreamData->flushIntervalMutex);
    }
    /* so flushThread is done with its work, delete the mutex & taskId */
exitOnError:
    clOsalCondDestroy_L(&pStreamData->flushIntervalCondvar);
    clOsalMutexDestroy_L(&pStreamData->flushIntervalMutex);
    return rc; 
}
ClRcT
clNameSvcBindingEntryRecreate(ClNameSvcContextInfoT  *pCtxData,
                              /* Suppressing coverity warning for pass by value with below comment */
                              // coverity[pass_by_value]
                              ClNsEntryPackT         nsEntryInfo)
{
    ClRcT              rc        = CL_OK;
    
    clLogDebug("SVR", "RESTART", "Binding entry type: %d", nsEntryInfo.type);
    switch( nsEntryInfo.type )
    {
        case CL_NAME_SVC_CTX_INFO:
            {
                rc = clNameSvcPerCtxInfoUpdate(pCtxData, &nsEntryInfo.nsInfo);
                break;
            }    
        case CL_NAME_SVC_ENTRY:
            {
              rc = clNameSvcBindingEntryCreate(pCtxData,
                     &nsEntryInfo.nsInfo);
              break;
            }    
        case CL_NAME_SVC_BINDING_DATA:
            {
              rc = clNameSvcBindingDetailEntryCreate(pCtxData,
                             &nsEntryInfo.nsInfo); 
              break;
            }                    
        case CL_NAME_SVC_COMP_INFO :
            {
                rc = clNameSvcCompInfoAdd(pCtxData, &nsEntryInfo.nsInfo);
                break;
            }                
        default:
            CL_DEBUG_PRINT(CL_DEBUG_ERROR,
                    ("Invalid type of data"));
            return CL_NS_RC(CL_ERR_INVALID_PARAMETER);
    }    

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

    clOsalMutexLock(gpClCpm->invocationMutex);

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

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

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

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

    clHeapFree(invocationData);

    clOsalMutexUnlock(gpClCpm->invocationMutex);

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

    return rc;

  withLock:
    clOsalMutexUnlock(gpClCpm->invocationMutex);
    return rc;
}
static ClRcT clMsgEventInitTimerThread(void *pParam)
{
    ClRcT rc = CL_OK;

    rc = clMsgEventInitialize();
    if(rc != CL_OK)
    {
        clLogError("FIN", "BLOCK", "Failed to initialize event client. error code [0x%x].", rc);
        if(gClMsgInit && gMsgEvtTimerHdl)
            clTimerStart(gMsgEvtTimerHdl); /*restart the timer again*/
        goto error_out;
    }

    clLogDebug("FIN", "BLOCK", "Event library is initialized.");

    rc = clTimerDelete(&gMsgEvtTimerHdl);
    if(rc != CL_OK)
        clLogError("FIN", "BLOCK", "Failed to delete event timer. error code [0x%x].", rc);

error_out:
    return rc;
}
/**
 * Add newly created job to transaction.
 * FIXME: THIS IS NOT MULTITHREAD SAFE
 */
ClRcT clTxnNewAppJobAdd(
        CL_IN   ClTxnDefnT          *pTxnDefn, 
        CL_IN   ClTxnAppJobDefnT    *pNewTxnJob)
{
    ClRcT   rc  = CL_OK;

    CL_FUNC_ENTER();

    if ( (NULL == pTxnDefn) || (NULL == pNewTxnJob) )
    {
        CL_FUNC_EXIT();
        return (CL_ERR_NULL_POINTER);
    }

    CL_DEBUG_PRINT(CL_DEBUG_TRACE, ("Inserting new job for txn %p\n", (ClPtrT) pTxnDefn));

    /* With RC2 enhancements, generate unique id for this job and update accordingly */
    clLogDebug("CMN", NULL,  
            "PID[%d], Adding job JOBID : {jobid: [0x%x] ]} for txn with TXNID: { txnId: [0x%x], mgrAdd : [0x%x]}",
            (int)getpid(),
            pNewTxnJob->jobId.jobId,
            pTxnDefn->clientTxnId.txnId,
            pTxnDefn->clientTxnId.txnMgrNodeAddress);

    rc = clCntNodeAdd(pTxnDefn->jobList, 
                      (ClCntKeyHandleT) &(pNewTxnJob->jobId), 
                      (ClCntDataHandleT) pNewTxnJob, 0);
    if (CL_OK != rc)
    {
        rc = CL_GET_ERROR_CODE(rc);
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, 
                ("Adding to the job list failed, [0x%x]", rc));
        return rc;
    }
    pTxnDefn->jobCount++;
    CL_FUNC_EXIT();
    return (rc);
}
static ClRcT clNodeCacheOpen(void)
{
    ClRcT rc = CL_OK;
    ClFdT fd;

    clLogDebug("NODE", "CACHE", "Opening existing node cache segment [%s]", gClNodeCacheSegment);
    
    rc = clOsalShmOpen(gClNodeCacheSegment, O_RDWR, 0666, &fd);
    if(rc != CL_OK)
    {
        clLogError("NODE", "CACHE", "Node cache [%s] segment open returned [%#x]",
                   gClNodeCacheSegment, rc);
        goto out;
    }

    rc = clOsalMmap(0, CL_NODE_CACHE_SEGMENT_SIZE, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0, 
                    (ClPtrT*)&gpClNodeCache);

    if(rc != CL_OK)
    {
        clLogError("NODE", "CACHE", "Node cache segment mmap returned [%#x]", rc);
        close((ClInt32T)fd);
        goto out;
    }

    gClNodeCacheFd = fd;

    rc = clOsalSemIdGet((ClUint8T*)gClNodeCacheSegment, &gClNodeCacheSem);

    if(rc != CL_OK)
    {
        clLogError("NODE", "CACHE", "Node cache semid get returned [%#x]", rc);
        close((ClInt32T)fd);
    }

    out:
    return rc;
}
/**
 * The mode end function which is called after every mode is finished.
 * This is used currently to do bulk get. When the vbcount of the requests
 * is equal to the varcount.
 */
int
clSnmpModeEndCallback(
        netsnmp_mib_handler               *handler,
        netsnmp_handler_registration      *reginfo,
        netsnmp_agent_request_info        *reqinfo,
        netsnmp_request_info              *requests)
{
    ClRcT   rc = CL_SNMP_ERR_NOERROR;
    netsnmp_request_info * request = NULL;
    static ClUint16T noOfOps = 0;

    clLogDebug("SNM","OPE", "Inside MODE-END callback [%s] ...mode [%d]", 
            __FUNCTION__, reqinfo->mode );
    
        switch (reqinfo->mode)
    {
        case MODE_GETBULK:
            clLogDebug("SNM","OPE", "Inside mode BULK-GET");
            break;
        case MODE_GETNEXT:
        case MODE_GET:
            {
                for (request = requests; request != NULL; request = request->next)
                {
                    noOfOps++;
                }

                clLogDebug("SNM","OPE", "Inside mode [%s] vbC[%d] noOfOps [%d]",
                        reqinfo->mode == MODE_GET ? "GET": "GET-NEXT", reqinfo->asp->vbcount, noOfOps);

                if (gErrorHappened == CL_TRUE)
                {
                    noOfOps = 0;
                    clSnmpDataReset();
                    gErrorHappened = CL_FALSE;
                    clLogNotice("SNM","OPE", "Error happened in the validating the request.");
                    netsnmp_request_set_error(requests, CL_SNMP_ERR_NOSUCHNAME);
                    return CL_SNMP_ERR_NOSUCHNAME;
                }
                        
                if (reqinfo->asp->vbcount == noOfOps)
                {
                    clLogDebug("SNP","OPE", "Sending the get request now as the vbCount and varCount are equal.");
                    rc = clSnmpProcessRequest(requests);
                    if (CL_OK != rc)
                        clLogError("SNP","OPE", "Failed while processing the GET request. rc[0x%x]", rc);
  		            noOfOps = 0;
                }
            }
            break;
        case MODE_SET_RESERVE1:
            clLogDebug("SNM","OPE", "Inside mode RESERVE1");
            break;
        case MODE_SET_RESERVE2:
            clLogDebug("SNM","OPE", "Inside mode RESERVE2");
            break;
        case MODE_SET_ACTION:
            clLogDebug("SNM","OPE", "Inside mode ACTION");
            break;
        case MODE_SET_COMMIT:
            clLogDebug("SNM","OPE", "Inside mode COMMIT");
            break;
        case MODE_SET_UNDO:
            clLogDebug("SNM","OPE", "Inside mode UNDO");
            break;
        case MODE_SET_FREE:
            clLogDebug("SNM","OPE", "Inside mode FREE");
            break;
        default:
            clLogDebug("SNM","OPE", "Inside default case");
    }

   return rc;
}
ClRcT clSnmpSendSyncRequestToServer (void **my_loop_context, 
        void **my_data_context, 
        netsnmp_variable_list *put_index_data, 
        ClUint32T tableType,
        ClSnmpOpCodeT opCode)
{
    netsnmp_variable_list *vptr = NULL;
    ClInt32T errorCode = 0;
    ClInt32T retVal = 0;
    ClSnmpReqInfoT reqInfo = {0};
    ClUint32T count = 0;
    ClUint32T tblIndex = 0;
    ClCharT *sendData = NULL;
    ClRcT rc = CL_OK;
    ClSnmpOidInfoT *appOidInfo = NULL;

    /*Set my_loop_context to an application specific iterator context.
     * Typically it will be a linked list of values where each node
     * corresponds to a row in the table. But here we are not maintaining any
     * linked list.*/
    /*Actually we can set my_loop_context to NULL pointer also as we are not
     * maintaining a linked list of rows in a table here. All the required
     * things are maintained in COR. And net-SNMP uses the index we set by
     * calling snmp_set_var_value() function for the next index. So just set
     * it to &reqInfo here*/
    *my_loop_context = &gReqInfo;
    *my_data_context = &gReqInfo;

    memset(&reqInfo, 0, sizeof(ClSnmpReqInfoT));

    vptr = put_index_data;

    sendData = (ClCharT*) &reqInfo.index;


    extern ClRcT snmpBuildAppOIDInfo(ClSnmpOidInfoT **);
    rc = snmpBuildAppOIDInfo(&appOidInfo);
    if (rc != CL_OK)
    {
        return rc;
    }
    
    /* Get table entry from appOidInfo[] */
    while (appOidInfo[tblIndex].numAttr != 0)
    {
        if (appOidInfo[tblIndex].tableType == tableType)
        {
            break;
        }
        tblIndex++;
    }

    clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Finding Index Information for OID[%s] with SNMP GET_FIRST[%d]/GET-NEXT[%d] CURRENT[%d]", appOidInfo[tblIndex].oid, CL_SNMP_GET_FIRST, CL_SNMP_GET_NEXT, opCode );

    if (appOidInfo[tblIndex].numAttr == 0)
    {
        /* Table entry not found after entries being exhausted */
        retVal = CL_MED_SET_RC(CL_ERR_NOT_EXIST);
        clLog(CL_LOG_SEV_ERROR, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "appOidInfo don't have necessary index information");
        return retVal;
    }

    if((opCode ==  CL_SNMP_GET_NEXT) || (my_loop_context !=  NULL && (*(ClInt32T*)*my_loop_context)!= 1))
    {
        for(count =0; (count < appOidInfo[tblIndex].numAttr) && sendData; count++)
        {
            /*We are assuming that the ClSnmpReqInfoT structure is
             * properly completed by the application writer and the union part
             * contains all indices*/

            /*Copy the index got from snmp agent*/
            /*COR supports only Integer / array of character types (string).
             * So we are not handling the case for float/bitstring/double etc
             * which are part of the put_index_data->val union*/
            switch(appOidInfo[tblIndex].attr[count].type)
            {
                case CL_SNMP_STRING_ATTR:
                    clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Input : Possion[%d] AttrType[STRING] Value [%s] Size[%d]",count, vptr->val.string, appOidInfo[tblIndex].attr[count].size);
                    memcpy(sendData, vptr->val.string, (vptr->val_len + 1));
                    /*Add 1 here so that when
                     * vptr->val_len is added after the
                     * switch() it makes up for the
                     * length copied above*/
                    sendData += 1;     
                    break;
                case CL_SNMP_NON_STRING_ATTR:
                    clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Input : Possion[%d] AttrType[NON-STRING] Value[%d] Size[%d]",count, *(ClUint32T*)vptr->val.integer, appOidInfo[tblIndex].attr[count].size);
                    memcpy(sendData, vptr->val.integer, appOidInfo[tblIndex].attr[count].size);
                    break;
                default:
                    break;
            }
            sendData += appOidInfo[tblIndex].attr[count].size;
            vptr = vptr->next_variable;
        }
    }

    {

        ClUint32T oidLen = strlen(appOidInfo[tblIndex].oid) + 1;
        if( oidLen > sizeof reqInfo.oid)
        {
            return CL_ERR_NO_SPACE;
        }
        else
            strncpy(reqInfo.oid, appOidInfo[tblIndex].oid, oidLen);
    }


    reqInfo.oidLen = strlen(reqInfo.oid);
    reqInfo.opCode = opCode;
    reqInfo.tableType = tableType;
    reqInfo.dataLen = sizeof(reqInfo.index);

    clLogInfo("SNMP", "SUB", "Before calling execute SNMP, oid is [%s]", reqInfo.oid);

    /*Now call clExecuteSnmp which talks to mediation library and fills the
     * index information for the next data or first data based on request
     * opcode*/
    retVal = clExecuteSnmp( &reqInfo,
            &reqInfo.index,
            NULL,
            &errorCode);
    vptr = put_index_data;
    /*Now set the result in vptr*/
    switch (retVal)
    {
        case CL_OK:   /* No errors : successful operation */
            {
                clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Successfully got index information for OID[%s]",appOidInfo[tblIndex].oid);
                put_index_data->val.string = NULL;
                memset(vptr->buf, '\0', sizeof(vptr->buf));

                sendData = (ClCharT*) &reqInfo.index;
                for(count =0; (count < appOidInfo[tblIndex].numAttr) && sendData; count++)
                {
                    switch(appOidInfo[tblIndex].attr[count].type)
                    {
                        case CL_SNMP_STRING_ATTR:
                            clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Output : Possion[%d] AttrType[STRING] Value[%s] Size[%d] ",count, sendData, appOidInfo[tblIndex].attr[count].size);
                            snmp_set_var_value(vptr, (u_char *) sendData, strlen(sendData) + 1);
                            sendData += 1;
                            break;
                        case CL_SNMP_NON_STRING_ATTR:
                            clLog(CL_LOG_SEV_DEBUG, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "Index Info Output : Possion[%d] AttrType[NON-STRING] Value[%d] Size[%d]",count, *(ClUint32T*)sendData, appOidInfo[tblIndex].attr[count].size);
                            snmp_set_var_value(vptr, (u_char *)sendData, appOidInfo[tblIndex].attr[count].size);
                            break;
                        default:
                            clLog(CL_LOG_SEV_ERROR, CL_SNMP_AREA, CL_SNMP_CTX_SOP, "AttrType is not Supported");
                    }
                    sendData += appOidInfo[tblIndex].attr[count].size;
                    vptr = vptr->next_variable;
                }
                break;
            }
        default:                 /* Failed due to other reasons */
            clLogDebug("SNP", "OPE", "Failed while getting next entry. rc[0x%x]", retVal);
            return retVal;
    }
    return CL_OK;
}
static void clSnmpDataReset(void)
{
    clLogDebug("SNP","OPE", "Reseting the static data structure.");
    gOper.refCount = 1;
    clSnmpUndo();
}
/** 
 * 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;
}
ClRcT clSnmpCommit(
        ClMedErrorListT *pMedErrList)
{
    ClMedOpT    opInfo = {0};
    ClRcT       errorCode = CL_OK;
    ClUint32T   count = 0;

    clSnmpMutexLock(gOper.mtx); /* Might as well check if the operation is complete before locking */
    if(!gOper.cmtd) /* CL_FALSE means not committed */ 
    {
        opInfo = gOper.opInfo;
        gOper.cmtd = CL_TRUE; /* Indicates that the request is executed */

        clLogDebug("SNP","OPE",
                "Calling med to execute operation, no of ops[%d]", opInfo.varCount);
        errorCode = clMedOperationExecute (gSubAgentInfo.medHdl, &opInfo);
        if(CL_OK != errorCode)
        {
            clLogError("SNM","OPE",
                    "Failed to execute operation, rc=[0x%x]", errorCode);
            for(count = 0; count < opInfo.varCount; count++)
            {
                if(opInfo.varInfo[count].errId != CL_OK)
                {
                    clLogError("SNM","OPE",
                            "Setting errorCode [0x%x] to OID [%s]", 
                            opInfo.varInfo[count].errId, 
                            opInfo.varInfo[count].attrId.id);
                    /*pErrCode = opInfo.varInfo[count].errId;*/

                    /* Construct error list here */ 
                    gOper.medErrList.pErrorList = (ClMedErrorIdT *)clHeapRealloc(gOper.medErrList.pErrorList, 
                            (gOper.medErrList.count + 1)*sizeof(ClMedErrorIdT));
                    if(!gOper.medErrList.pErrorList)
                    {
                        errorCode = CL_ERR_NO_MEMORY;
                        goto exitOnError;
                    }

                    gOper.medErrList.pErrorList[gOper.medErrList.count].errId = opInfo.varInfo[count].errId;

                    gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.id = 
                        (ClUint8T*)clHeapAllocate(opInfo.varInfo[count].attrId.len);
                    if(!gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.id)
                    {
                        errorCode = CL_ERR_NO_MEMORY;
                        goto exitOnError;   
                    }

                    memcpy(gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.id, 
                        opInfo.varInfo[count].attrId.id, opInfo.varInfo[count].attrId.len);
                    gOper.medErrList.pErrorList[gOper.medErrList.count].oidInfo.len = opInfo.varInfo[count].attrId.len;
                    gOper.medErrList.count++;
                }
            }
            *pMedErrList = gOper.medErrList; /* Copy the error list, this is freed at clSnmpUndo() */

        }
#if 0
        for(arrIndex = 0; arrIndex < opInfo.varCount; arrIndex++)
        {
            clHeapFree(opInfo.varInfo[arrIndex].pVal);
            clHeapFree(opInfo.varInfo[arrIndex].pInst);
        }
        gOper.opInfo.varCount = 0; 
        clHeapFree (gOper.opInfo.varInfo);
        gOper.opInfo.varInfo = NULL; /* Next operation would see this and return */
#endif
    }
    else if (gOper.medErrList.count)
    {
        clLogDebug("SNM","OPE", 
                "Already committed, return error list");
        *pMedErrList = gOper.medErrList; /* Copy the error list, this is freed at clSnmpUndo() */
        errorCode = CL_SNMP_ERR_GENERR; /* Return a general error, this is not set to the varbin var */

    }
exitOnError:
    clSnmpMutexUnlock(gOper.mtx);
    return errorCode; /* Return error code */ 
}
/*
ClUint32T clSetTableAttr(  ClSnmpReqInfoT* reqInfo,
        void* data,
        ClInt32T *pOpNum,
        ClInt32T *pErrCode)
{
    ClMedOpT opInfo;
    static ClMedVarBindT *tempVarInfo = NULL;
    static ClInt32T arrIndex = 0;
    ClInt32T count = 0;
    ClInt32T errorCode = CL_OK;

    if(NULL == tempVarInfo)
    {
        tempVarInfo = (ClMedVarBindT *) clHeapCalloc(1,*pOpNum * sizeof (ClMedVarBindT));
        if(NULL == tempVarInfo)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Bulk set for %d objects", *pOpNum) );
            return CL_SNMP_ERR_NOCREATION;
        }
    }
    opInfo.varInfo = tempVarInfo;
    if(arrIndex < *pOpNum)
    {
        opInfo.varInfo[arrIndex].errId = CL_OK;
        opInfo.varInfo[arrIndex].attrId.len = (ClUint32T)strlen(reqInfo->oid) + 1;
        opInfo.varInfo[arrIndex].attrId.id = (ClUint8T *)clHeapCalloc(1,opInfo.varInfo[arrIndex].attrId.len);
        if(NULL == opInfo.varInfo[arrIndex].attrId.id)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Size asked for %d", opInfo.varInfo[arrIndex].attrId.len) );
            return CL_SNMP_ERR_NOCREATION;
        }
        memcpy(opInfo.varInfo[arrIndex].attrId.id, reqInfo->oid, opInfo.varInfo[arrIndex].attrId.len);
        opInfo.varInfo[arrIndex].len = reqInfo->dataLen;
        opInfo.varInfo[arrIndex].pVal = clHeapCalloc(1,reqInfo->dataLen);
        if(NULL == opInfo.varInfo[arrIndex].pVal)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Size asked for %d",reqInfo->dataLen) );
            return CL_SNMP_ERR_NOCREATION;
        }
        memcpy(opInfo.varInfo[arrIndex].pVal, data, reqInfo->dataLen);
        opInfo.varInfo[arrIndex].pInst = (ClSnmpReqInfoT *)clHeapCalloc(1,sizeof(ClSnmpReqInfoT) );
        if(NULL == opInfo.varInfo[arrIndex].pInst)
        {
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Could not allocate memory. Size asked for %u", (ClUint32T)sizeof(ClSnmpReqInfoT) ) );
            return CL_SNMP_ERR_NOCREATION;
        }
        memcpy(opInfo.varInfo[arrIndex].pInst, reqInfo, sizeof(ClSnmpReqInfoT) );

        if(arrIndex == (*pOpNum - 1) )
        {
            opInfo.opCode = reqInfo->opCode;
            opInfo.varCount = *pOpNum;
            errorCode = clMedOperationExecute (gSubAgentInfo.medHdl, &opInfo);
            if(CL_OK != errorCode)
            {
                for(count = 0; count <= arrIndex; count++)
                {
                    if(opInfo.varInfo[count].errId != CL_OK)
                    {
                        *pErrCode = opInfo.varInfo[count].errId;
                        *pOpNum = count;
                        break;
                    }
                }

            }
            arrIndex = 0;
            for(arrIndex = 0; arrIndex < *pOpNum; arrIndex++)
            {
                clHeapFree(opInfo.varInfo[arrIndex].pVal);
                clHeapFree(opInfo.varInfo[arrIndex].pInst);
            }
            arrIndex = 0;
            clHeapFree (tempVarInfo);
            tempVarInfo = NULL;
            return errorCode;
        }
        arrIndex++;
        return CL_OK;
    }
    return errorCode;
}
*/
ClUint32T clSnmpJobTableAttrAdd(  
        ClSnmpReqInfoT* reqInfo,
        void* data,
        ClInt32T *pOpNum,
        ClInt32T *pErrCode, 
        ClPtrT pReqAddInfo)
{
    ClInt32T arrIndex = 0;
    ClRcT    rc = CL_OK;

    clSnmpMutexLock(gOper.mtx);
    
    gOper.opInfo.varInfo = (ClMedVarBindT *) clHeapRealloc(gOper.opInfo.varInfo, 
    (gOper.opInfo.varCount+1) * sizeof (ClMedVarBindT));
    if(NULL == gOper.opInfo.varInfo)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Bulk set for [%d] objects", *pOpNum) ;
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    arrIndex = gOper.opInfo.varCount;
    clLogDebug("SNP","OPE",
            "Adding request[%d] into store", arrIndex);
    gOper.opInfo.varInfo[arrIndex].errId = CL_OK;
    gOper.opInfo.varInfo[arrIndex].attrId.len = (ClUint32T)strlen(reqInfo->oid) + 1;
    gOper.opInfo.varInfo[arrIndex].attrId.id = (ClUint8T *)clHeapCalloc(1, gOper.opInfo.varInfo[arrIndex].attrId.len);
    if(NULL == gOper.opInfo.varInfo[arrIndex].attrId.id)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Size asked for [%d]", 
                gOper.opInfo.varInfo[arrIndex].attrId.len);
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    memcpy(gOper.opInfo.varInfo[arrIndex].attrId.id, reqInfo->oid, gOper.opInfo.varInfo[arrIndex].attrId.len);
    gOper.opInfo.varInfo[arrIndex].len = reqInfo->dataLen;
    gOper.opInfo.varInfo[arrIndex].pVal = clHeapAllocate(reqInfo->dataLen);
    if(NULL == gOper.opInfo.varInfo[arrIndex].pVal)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Size asked for [%d]",
                reqInfo->dataLen);
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    memset(gOper.opInfo.varInfo[arrIndex].pVal, 0, reqInfo->dataLen);
    if (data)
    {
        memcpy(gOper.opInfo.varInfo[arrIndex].pVal, data, reqInfo->dataLen);
    }
    gOper.opInfo.varInfo[arrIndex].pInst = (ClSnmpReqInfoT *)clHeapCalloc(1,sizeof(ClSnmpReqInfoT) );
    if(NULL == gOper.opInfo.varInfo[arrIndex].pInst)
    {
        clLogError("SNP","OPE", 
                "Could not allocate memory. Size asked for [%u]", 
                (ClUint32T)sizeof(ClSnmpReqInfoT) );
        clSnmpMutexUnlock(gOper.mtx);
        return CL_SNMP_ERR_NOCREATION;
    }
    memcpy(gOper.opInfo.varInfo[arrIndex].pInst, reqInfo, sizeof(ClSnmpReqInfoT) );

    gOper.opInfo.opCode = reqInfo->opCode; /* This could be a problem if a SET and a CREATE comes */

    /* Validate here */
    clLogDebug("SNP","OPE",
            "Validating instance, tableType [%d],oid [%s], oidLen[%d], opCode [%d]",
            reqInfo->tableType, reqInfo->oid, reqInfo->oidLen, reqInfo->opCode); 
    if(CL_SNMP_CREATE != reqInfo->opCode) /* Dont validate instance for CREATE as it wont be there */
    {
        rc = clMedInstValidate(gSubAgentInfo.medHdl, &gOper.opInfo.varInfo[arrIndex]);
        if(CL_OK != rc)
        {
            clLogError("SNM","OPE",
                    "Failed to validate instance information, rc=[0x%x], errorCode=[0x%x]",
                    rc, gOper.opInfo.varInfo[arrIndex].errId);
            *pErrCode = gOper.opInfo.varInfo[arrIndex].errId;
            gErrorHappened = CL_TRUE;
        }
        
        if (reqInfo->opCode == CL_SNMP_GET)
        {
            clLogDebug("SNM","OPE", "Adding the get job.");
            gOper.pOpAddData = (_ClSnmpGetReqInfoT *) clHeapRealloc (gOper.pOpAddData, 
                                        (arrIndex + 1)* sizeof(_ClSnmpGetReqInfoT));
            if (NULL == gOper.pOpAddData)
            {
                clLogError("SNP","OPE",
                        "Could not allocate memory for the get info object. ");
                clSnmpMutexUnlock(gOper.mtx);
                return CL_SNMP_ERR_NOCREATION;
            }

            (((_ClSnmpGetReqInfoT *)gOper.pOpAddData) + arrIndex)->pRequest = 
                                ((_ClSnmpGetReqInfoT *)pReqAddInfo)->pRequest;
            (((_ClSnmpGetReqInfoT *)gOper.pOpAddData) + arrIndex)->columnType = 
                                ((_ClSnmpGetReqInfoT *)pReqAddInfo)->columnType;
        }
    }

    arrIndex++; /* Should this be incremented when inst validation failed? */
    gOper.opInfo.varCount = arrIndex;
    gOper.cmtd = CL_FALSE; /* Not committed */
    gOper.refCount = arrIndex; /* Ref count to delete this global structure */
    clLogDebug("SNP","OPE",
            "No of operations in store [%d]", gOper.opInfo.varCount);

    clSnmpMutexUnlock(gOper.mtx);
    return rc;
}
int
clSnmpsaAmfClusterAdminStateTriggerHandler(netsnmp_mib_handler *handler,
        netsnmp_handler_registration *reginfo,
        netsnmp_agent_request_info   *reqinfo,
        netsnmp_request_info         *requests)
{
    ClSNMPRequestInfoT requestInfo;
    netsnmp_variable_list *reqVar = NULL;

    if(!requests || !reqinfo)
        return SNMP_ERR_GENERR;


    reqVar = requests->requestvb;

    /* We are never called for a GETNEXT if it's registered as a
       "instance", as it's "magically" handled for us.  */

    /* An instance handler also only hands us one request at a time, so
       we don't need to loop over a list of requests; we'll only get one. */

    memset(&requestInfo, 0, sizeof(ClSNMPRequestInfoT));

    /* Extract the scalar OID, convert it to string form and assign it to requestInfo.oid */

    requestInfo.oidLen = OID_LENGTH(saAmfClusterAdminStateTriggerOid);
    clSnmpOidCpy(&requestInfo, reqVar->name);

    requestInfo.tableType = CL_SAFAMF_SCALARS;

    switch(reqinfo->mode) {

    case MODE_GET:
    {
        ClInt32T retVal = 0, errorCode = 0;
        _ClSnmpGetReqInfoT  reqAddInfo = {0};
        void * pVal = NULL;
        ClInt32T    saAmfClusterAdminStateTriggerVal = 0;

        requestInfo.dataLen = sizeof(ClInt32T);
        pVal = &saAmfClusterAdminStateTriggerVal;

        requestInfo.index.scalarType = 0;
        requestInfo.opCode = CL_SNMP_GET;
        reqAddInfo.pRequest = requests;
        reqAddInfo.columnType = ASN_INTEGER;
        clLogDebug("SUB", "SCL",
                   "Received GET request");

        retVal = clRequestAdd(&requestInfo, pVal, NULL, &errorCode, &reqAddInfo);

        if(retVal != 0 || errorCode < 0)
        {
            netsnmp_request_set_error (requests, errorCode);
            return errorCode;
        }
        break;
    }

    /*
     * SET REQUEST
     *
     * multiple states in the transaction.  See:
     * http://www.net-snmp.org/tutorial-5/toolkit/mib_module/set-actions.jpg
     */
    case MODE_SET_RESERVE1:
    {
        ClInt32T retVal = 0;
        clLogDebug("SUB", "SCL",
                   "Received RESERVE1 request");
        retVal = netsnmp_check_vb_type(reqVar, ASN_INTEGER);
        if(retVal != SNMP_ERR_NOERROR )
        {
            netsnmp_request_set_error(requests, retVal );
            return retVal;
        }

        switch(*(reqVar->val.integer))
        {
        case SAAMFCLUSTERADMINSTATETRIGGER_STABLE:
            break;
        case SAAMFCLUSTERADMINSTATETRIGGER_UNLOCK:
            break;
        case SAAMFCLUSTERADMINSTATETRIGGER_LOCK:
            break;
        case SAAMFCLUSTERADMINSTATETRIGGER_LOCKINSTANTIATION:
            break;
        case SAAMFCLUSTERADMINSTATETRIGGER_UNLOCKINSTANTIATION:
            break;
        case SAAMFCLUSTERADMINSTATETRIGGER_SHUTDOWN:
            break;
        /** not a legal enum value.  return an error */
        default:
            CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("Inconsistent value."));
            netsnmp_request_set_error(requests, SNMP_ERR_WRONGVALUE);
            return SNMP_ERR_WRONGVALUE;
        }
        break;
    }
    case MODE_SET_RESERVE2:
    {
        ClInt32T retVal = 0, errorCode = 0, noOfOp = 1;
        ClPtrT pVal = NULL;


        ClInt32T    Val = 0;

        pVal = &Val;
        requestInfo.dataLen = sizeof(ClInt32T);
        requestInfo.opCode = CL_SNMP_SET;
        requestInfo.index.scalarType = 0;

        memcpy(pVal, (void *)reqVar->val.integer, requestInfo.dataLen);

        clLogDebug("SUB", "SCL",
                   "Calling request add");
        retVal = clRequestAdd( &requestInfo, pVal, &noOfOp, &errorCode, NULL);
        if(CL_OK != retVal)
        {
            clLogError("SUB", "SCL",
                       "Failed to add request to store, rc=[0x%x], errorCode=[0x%x]",
                       retVal, errorCode);
            netsnmp_request_set_error(requests, errorCode);
            return retVal;
        }
        clLogDebug("SUB", "SCL",
                   "Successfully added request in store");
        break;
    }

    case MODE_SET_FREE:
    {
        clLogDebug("SUB", "SCL",
                   "Received FREE request");
        clSnmpUndo();
        break;
    }

    case MODE_SET_ACTION:
    {
        ClInt32T    retVal = 0;
        ClMedErrorListT    medErrList;

        clLogDebug("SUB", "SCL",
                   "Received ACTION request for oid[%s] ",requestInfo.oid);
        retVal = clSnmpCommit(&medErrList);
        if (retVal != 0)
        {
            clLogDebug("SUB", "SCL",
                       "Error in commit errCount[%d]",
                       medErrList.count);
            if(retVal == CL_ERR_NO_MEMORY)
            {
                retVal = CL_SNMP_ERR_NOCREATION; /* Set SNMP equivalent error from oidErrMapTable in clSnmpInit.c */
                clLogError("SUB", "SCL",
                           "ACTION phase failed, setting errorCode[0x%x] for oid[%s]",
                           retVal, requestInfo.oid);
                netsnmp_request_set_error(requests, retVal);
                return retVal;
            }
            else
            {

                ClUint32T   i;
                for(i = 0; i < medErrList.count; i++)
                {
                    /* the oid matches the request, set error and return*/
                    if(!memcmp((ClUint8T*)requestInfo.oid,
                               medErrList.pErrorList[i].oidInfo.id, medErrList.pErrorList[i].oidInfo.len))
                    {
                        clLogError("SUB", "SCL",
                                   "ACTION phase failed, setting errorCode[0x%x] for oid[%s]",
                                   medErrList.pErrorList[i].errId, requestInfo.oid);
                        netsnmp_request_set_error(requests, medErrList.pErrorList[i].errId);
                        return retVal;

                    }

                }
            }
        }
        break;
    }
    case MODE_SET_COMMIT:
    {
        clLogDebug("SUB", "SCL",
                   "Received COMMIT request");
        clSnmpUndo();
        break;
    }
    case MODE_SET_UNDO:
    {
        clLogDebug("SUB", "SCL",
                   "Received UNDO request");
        clSnmpUndo();
        break;
    }

    default:
        /* we should never get here, so this is a really bad error */
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("unknown mode (%d) in clSnmpsaAmfClusterAdminStateTriggerHandler\n", reqinfo->mode) );
        return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}
int
clSnmpsaAmfClusterAdminStateHandler(netsnmp_mib_handler *handler,
                                    netsnmp_handler_registration *reginfo,
                                    netsnmp_agent_request_info   *reqinfo,
                                    netsnmp_request_info         *requests)
{
    ClSNMPRequestInfoT requestInfo;
    netsnmp_variable_list *reqVar = NULL;

    if(!requests || !reqinfo)
        return SNMP_ERR_GENERR;


    reqVar = requests->requestvb;

    /* We are never called for a GETNEXT if it's registered as a
       "instance", as it's "magically" handled for us.  */

    /* An instance handler also only hands us one request at a time, so
       we don't need to loop over a list of requests; we'll only get one. */

    memset(&requestInfo, 0, sizeof(ClSNMPRequestInfoT));

    /* Extract the scalar OID, convert it to string form and assign it to requestInfo.oid */

    requestInfo.oidLen = OID_LENGTH(saAmfClusterAdminStateOid);
    clSnmpOidCpy(&requestInfo, reqVar->name);

    requestInfo.tableType = CL_SAFAMF_SCALARS;

    switch(reqinfo->mode) {

    case MODE_GET:
    {
        ClInt32T retVal = 0, errorCode = 0;
        _ClSnmpGetReqInfoT  reqAddInfo = {0};
        void * pVal = NULL;
        ClInt32T    saAmfClusterAdminStateVal = 0;

        requestInfo.dataLen = sizeof(ClInt32T);
        pVal = &saAmfClusterAdminStateVal;

        requestInfo.index.scalarType = 0;
        requestInfo.opCode = CL_SNMP_GET;
        reqAddInfo.pRequest = requests;
        reqAddInfo.columnType = ASN_INTEGER;
        clLogDebug("SUB", "SCL",
                   "Received GET request");

        retVal = clRequestAdd(&requestInfo, pVal, NULL, &errorCode, &reqAddInfo);

        if(retVal != 0 || errorCode < 0)
        {
            netsnmp_request_set_error (requests, errorCode);
            return errorCode;
        }
        break;
    }


    default:
        /* we should never get here, so this is a really bad error */
        CL_DEBUG_PRINT(CL_DEBUG_ERROR, ("unknown mode (%d) in clSnmpsaAmfClusterAdminStateHandler\n", reqinfo->mode) );
        return SNMP_ERR_GENERR;
    }

    return SNMP_ERR_NOERROR;
}