ANSC_STATUS
DslhWmpdoReset
(
    ANSC_HANDLE                 hThisObject
)
{
    ANSC_STATUS                     returnStatus   = ANSC_STATUS_SUCCESS;
    PDSLH_WMP_DATABASE_OBJECT       pMyObject      = (PDSLH_WMP_DATABASE_OBJECT  )hThisObject;
    PDSLH_WMP_DATABASE_PROPERTY     pProperty      = (PDSLH_WMP_DATABASE_PROPERTY)&pMyObject->Property;
    PDSLH_OBJ_RECORD_OBJECT         pRootObjRecord = (PDSLH_OBJ_RECORD_OBJECT    )pMyObject->hRootObjRecord;
    PDSLH_OBJ_ENTITY_OBJECT         pRootObjEntity = (PDSLH_OBJ_ENTITY_OBJECT    )pMyObject->hRootObjEntity;
    PDSLH_WMPDO_MONITOR_PARAM       pMonitorParam  = (PDSLH_WMPDO_MONITOR_PARAM  )NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry    = (PSINGLE_LINK_ENTRY         )NULL;

    pMyObject->ResetObjVarArray(hThisObject);

    if ( pMyObject->LockedEntity )
    {
        AnscFreeMemory(pMyObject->LockedEntity);

        pMyObject->LockedEntity = NULL;
    }

    if ( pMyObject->pRootObjName)
    {
        AnscFreeMemory(pMyObject->pRootObjName);

        pMyObject->pRootObjName = NULL;
    }

    if ( pRootObjRecord )
    {
        pRootObjRecord->Remove((ANSC_HANDLE)pRootObjRecord);

        pMyObject->hRootObjRecord = (ANSC_HANDLE)NULL;
    }

    if ( pRootObjEntity )
    {
        pRootObjEntity->Remove((ANSC_HANDLE)pRootObjEntity);

        pMyObject->hRootObjEntity = (ANSC_HANDLE)NULL;
    }

    AnscAcquireLock(&pMyObject->MpoQueueLock);

    pSLinkEntry = AnscQueuePopEntry(&pMyObject->MpoQueue);

    while ( pSLinkEntry )
    {
        pMonitorParam = ACCESS_DSLH_WMPDO_MONITOR_PARAM(pSLinkEntry);
        pSLinkEntry   = AnscQueuePopEntry(&pMyObject->MpoQueue);

        DslhWmpdoFreeMonitorParam(pMonitorParam);
    }

    AnscReleaseLock(&pMyObject->MpoQueueLock);

    return  ANSC_STATUS_SUCCESS;
}
ANSC_STATUS
DslhWmpdoMonitorTimerInvoke
    (
        ANSC_HANDLE                 hThisObject
    )
{
    ANSC_STATUS                     returnStatus       = ANSC_STATUS_SUCCESS;
    PDSLH_WMP_DATABASE_OBJECT       pMyObject          = (PDSLH_WMP_DATABASE_OBJECT  )hThisObject;
    PDSLH_WMP_DATABASE_PROPERTY     pProperty          = (PDSLH_WMP_DATABASE_PROPERTY)&pMyObject->Property;
    PDSLH_CPE_CONTROLLER_OBJECT     pDslhCpeController = (PDSLH_CPE_CONTROLLER_OBJECT)pMyObject->hDslhCpeController;
    PDSLH_WMPDO_MONITOR_PARAM       pMonitorParam      = (PDSLH_WMPDO_MONITOR_PARAM  )NULL;
    PDSLH_VAR_RECORD_OBJECT         pDslhVarRecord     = (PDSLH_VAR_RECORD_OBJECT    )NULL;
    PDSLH_VAR_ENTITY_OBJECT         pDslhVarEntity     = (PDSLH_VAR_ENTITY_OBJECT    )NULL;
    PDSLH_CWMP_PARAM_DESCR          pParamDesp         = (PDSLH_CWMP_PARAM_DESCR     )NULL;
    PSLAP_VARIABLE                  pNewParamValue     = (PSLAP_VARIABLE             )NULL;
    BOOL                            bValueNotUpdated   = (BOOL                       )TRUE;
    char*                           pParamFullName     = (char*                      )NULL;
    PSINGLE_LINK_ENTRY              pSLinkEntry        = (PSINGLE_LINK_ENTRY         )NULL;
    BOOL                            bActiveNotify      = FALSE;
    int                             oldValue           = 0; /* Only for notification with threshold */
    int                             newValue           = 0; /* Only for notification with threshold */

    AnscAcquireLock(&pMyObject->MpoQueueLock);

    pSLinkEntry = AnscQueueGetFirstEntry(&pMyObject->MpoQueue);

    while ( pSLinkEntry )
    {
        pMonitorParam  = ACCESS_DSLH_WMPDO_MONITOR_PARAM(pSLinkEntry);
        pDslhVarRecord = (PDSLH_VAR_RECORD_OBJECT)pMonitorParam->hVarRecord;
        pSLinkEntry    = AnscQueueGetNextEntry(pSLinkEntry);

        /*
         * DO NOT synchronize the value if value-changing is in progress...
         */
        if ( pDslhVarRecord->TempParamValue )
        {
            continue;
        }

        /*
         * DO NOT synchronize the value if the active notification parameter is rate-regulated and
         * the last update was notified less than "NotificationLimit" seconds ago.
         */
        if ( (pDslhVarRecord->Notification      == DSLH_CWMP_NOTIFICATION_active) &&
             (pMonitorParam ->NotificationLimit >  0                            ) )
        {
            if ( (AnscGetTickInSeconds() - pMonitorParam->Timestamp) < pMonitorParam->NotificationLimit )
            {
                continue;
            }
        }

        if ( pMonitorParam->PreviousValue )
        {
            pNewParamValue   = pDslhVarRecord->GetValue((ANSC_HANDLE)pDslhVarRecord);
            bValueNotUpdated = TRUE;

            if ( !pNewParamValue )
            {
                continue;
            }
            else
            {
            	SlapEqualVariables(pMonitorParam->PreviousValue, pNewParamValue, bValueNotUpdated);
            }

            if ( !bValueNotUpdated )
            {
                /* Notificatoin with threshold check */
                pDslhVarEntity = (PDSLH_VAR_ENTITY_OBJECT)pDslhVarRecord->hDslhVarEntity;
                pParamDesp     = (PDSLH_CWMP_PARAM_DESCR )pDslhVarEntity->ParamDescr;
                
                if ( pParamDesp && pParamDesp->bThresholdEnabled == TRUE )
                {
                    oldValue  = pMonitorParam ->PreviousValue->Variant.varInt;
                    newValue  = pNewParamValue->Variant.varInt;
                    
                    if ( 
                           (oldValue < pParamDesp->NotifyThresholdMin && newValue < pParamDesp->NotifyThresholdMin) ||
                           (oldValue > pParamDesp->NotifyThresholdMax && newValue > pParamDesp->NotifyThresholdMax) ||
                           (oldValue >= pParamDesp->NotifyThresholdMin && oldValue <= pParamDesp->NotifyThresholdMax && newValue >= pParamDesp->NotifyThresholdMin && newValue <= pParamDesp->NotifyThresholdMax)
                       )
                    {
                        if ( pMonitorParam->PreviousValue )
                        {
                            SlapFreeVariable(pMonitorParam->PreviousValue);
                        }
                        
                        pMonitorParam->PreviousValue = pNewParamValue;
                        continue;
                    }
                }
                
                /* save the previous value as old */
                if( pDslhVarRecord->OldParamValue != NULL)
                {
                    SlapFreeVariable(pDslhVarRecord->OldParamValue);
                }

                pDslhVarRecord->OldParamValue = pMonitorParam->PreviousValue;
                /* SlapFreeVariable(pMonitorParam->PreviousValue); */

                pMonitorParam->PreviousValue = pNewParamValue;
                pParamFullName               = pDslhVarRecord->GetFullName((ANSC_HANDLE)pDslhVarRecord);

                if ( pParamFullName )
                {
                    bActiveNotify |= (pDslhVarRecord->Notification == DSLH_CWMP_NOTIFICATION_active);					 
                    pMonitorParam->Timestamp = AnscGetTickInSeconds();

                    pDslhVarRecord->NotifyValueChanged(pDslhVarRecord);

                    AnscTraceWarning(("DslhWmpdoMonitorTimerInvoke - value change detected on parameter <%s>.\n", pParamFullName));
					pDslhVarRecord->ReqSenderID = 0;
					pMonitorParam->PreviousValue->ReqSenderID = 0;
                    AnscFreeMemory(pParamFullName);
                }
            }
            else
            {
                SlapFreeVariable(pNewParamValue);
            }
        }
        else
        {
            pMonitorParam->PreviousValue = pDslhVarRecord->GetValue((ANSC_HANDLE)pDslhVarRecord);
        }
    }

    AnscReleaseLock(&pMyObject->MpoQueueLock);

    return  ANSC_STATUS_SUCCESS;
}