/*******************************************************************************
 * (c) Copyright 2015 Microsemi Corporation.  All rights reserved.
 *
 *
 *
 * SVN $Revision: $
 * SVN $Date: $
 */

#ifndef PM_LM_H_
#define PM_LM_H_

/*
 * pm_sl.c
 *
 *  Created on: 13 Apr 2015
 *      Author: Niall.Donovan
 */

#include <api_oam_sdk/common/types/inc/mr_api_types.h>
#include <api_oam_sdk/maintenance_association/inc/ma.h>
#include <api_oam_sdk/performance_monitoring/inc/pm.h>
#include "egl_types.h"

typedef enum
{
	lmLmm = 1,	//LMM SOAM PDU generated and received LMR responses tracked
	lmSlm = 2,	//SLM SOAM PDU generated and received SLR responses tracked
	lmCcm = 3	//CCM SOAM PDU generated and received CCM PDUs tracked
} lossType_t;

typedef struct
{
	uint32_t			availabilityMeasurementInterval;	// specifies the availability Measurement Interval in minutes. A Measurement Interval of 15 minutes is to be supported, other intervals can be supported
	uint32_t			availabilityNumConsecutiveMeasPdus;	// specifies a configurable number of consecutive loss measurement PDUs to be used in evaluating the availability/unavailability status of each availability indicator per MEF 10.2.1
	uint32_t			availabilityFlrThreshold;	// specifies a configurable availability threshold to be used in evaluating the availability/unavailability status of an availability indicator per MEF 10.2.1. The availability threshold range of 0.00 (0) through 1.00 (100000) is supported
	uint16_t			availabilityNumConsecutiveIntervals;// specifies a configurable number of consecutive availability indicators to be used to determine a change in the availability status as indicated by MEF 10.2.1
	uint16_t			availabilityNumConsecutiveHighFlr;	// specifies a configurable number of consecutive availability indicators to be used for assessing CHLI.  This parameter is equivalent to the Resilency parameter of 'p' as specified by MEF 10.2.1
	struct	pmConfig_s	cfg;						// this struct is common to both Loss and Delay configurations
	lossType_t			type;						// specifies what type of Loss Measurement will be performed
} lmCfg_t;

// The bit vectors used to access/modify measurementEnable in pmConfig_s
#define bForwardTransmitedFrames			(0)				// 1
#define bForwardReceivedFrames				(1)				// 1
#define bForwardMinFlr						(2)				// 0
#define bForwardMaxFlr						(3)				// 0
#define bForwardAvgFlr						(4)				// 1
#define bBackwardTransmitedFrames			(5)				// 1
#define bBackwardReceivedFrames				(6)				// 1
#define bBackwardMinFlr						(7)				// 0
#define bBackwardMaxFlr						(8)				// 0
#define bBackwardAvgFlr						(9)				// 1
#define bLmSoamPdusSent						(10)			// 1
#define bLmSoamPdusReceived 				(11)			// 1
#define bAvailForwardHighLoss				(12)			// 0
#define bAvailForwardConsecutiveHighLoss	(13)			// 0
#define bAvailForwardAvailable				(14)			// 0
#define bAvailForwardUnavailable			(15)			// 0
#define bAvailForwardMinFlr					(16)			// 0
#define bAvailForwardMaxFlr					(17)			// 0
#define bAvailForwardAvgFlr					(18)			// 0
#define bAvailBackwardHighLoss				(19)			// 0
#define bAvailBackwardConsecutiveHighLoss	(20)			// 0
#define bAvailBackwardAvailable				(21)			// 0
#define bAvailBackwardUnavailable			(22)			// 0
#define bAvailBackwardMinFlr				(23)			// 0
#define bAvailBackwardMaxFlr				(24)			// 0
#define bAvailBackwardAvgFlr				(25)			// 0
#define bMeasuredStatsForwardMeasuredFlr	(26)			// 1
#define bMeasuredStatsBackwardMeasuredFlr	(27)			// 1
#define bMeasuredStatsAvailForwardStatus	(28)			// 0
#define bMeasuredStatsAvailBackwardStatus	(29)			// 0
#define lossMeasurementEnableDefaultLower	(0x0C000E73)	// TODO: update this later with correct value
#define lossMeasurementEnableDefaultUpper	(0x00000000)

typedef struct lmStatsEntry_s {
	uint32_t	neTxCntr;
	uint32_t	neRxCntr;
	uint32_t	feTxCntr;
	uint32_t	feRxCntr;
} lmStatsEntry_t;

typedef struct
{
	uint32_t			forwardFlr;					// contains the last frame loss ratio in the forward direction calculated by this MEP. Units are in milli-percent, where 1 indicates 0.001 percent
	uint32_t			backwardFlr;				// contains the last frame loss ratio in the backward direction calculated by this MEP. Units are in milli-percent, where 1 indicates 0.001 percent
	lmStatsEntry_t		lmAccumulatedStats;			// (!custom parameter!) Contains the current (accumulated) counter values for the session
	dateAndTime_t		_availForwardLastTransitionTime;	// indicates the time of the last transition between available and unavailable in the forward direction (0 if no transition)
	dateAndTime_t		_availBackwardLastTransitionTime;	// indicates the time of the last transition between available and unavailable in the backward direction (0 if no transition)
	availabilityType_t	_availForwardStatus; 		// indicates the availability status (the outcome of the last known availability indicator) in the forward direction
	availabilityType_t	_availBackwardStatus;		// indicates the availability status (the outcome of the last known availability indicator) in the backward direction
} lmMeasuredStats_t;

typedef struct
{
	uint32_t			index;
	dateAndTime_t		startTime;					// The time that the current Measurement Interval started
	timeInterval_t		elapsedTime;				// The time that the current Measurement Interval has been running, in 0.01 seconds
	uint32_t			forwardHighLoss;			// This object is the number of high loss intervals (HLI) over time in the forward direction
	uint32_t			backwardHighLoss;			// This object is the number of high loss intervals (HLI) over time in the backward direction
	uint32_t			forwardConsecutiveHighLoss;	// This object is the number of consecutive high loss intervals (CHLI) over time in the forward direction
	uint32_t			backwardConsecutiveHighLoss;// This object is the number of consecutive high loss intervals (CHLI) over time in the backward direction
	gauge32_t			forwardAvailable;			// This object contains the number of availability indicators evaluated as available in the forward direction by this MEP during this Measurement Interval
	gauge32_t			backwardAvailable;			// This object contains the number of availability indicators evaluated as available in the backward direction by this MEP during this Measurement Interval
	gauge32_t			forwardUnavailable;			// This object contains the number of availability indicators evaluated as unavailable in the forward direction by this MEP during this Measurement Interval
	gauge32_t			backwardUnavailable;		// This object contains the number of availability indicators evaluated as unavailable in the backward direction by this MEP during this Measurement Interval
	uint32_t			forwardMinFlr;				// (units=0.001%) the minimum one-way availability flr in the forward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			forwardMaxFlr;				// (units=0.001%) the maximum one-way availability flr in the forward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			forwardAvgFlr;				// (units=0.001%) the average one-way availability flr in the forward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			backwardMinFlr;				// (units=0.001%) the minimum one-way availability flr in the backward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			backwardMaxFlr;				// (units=0.001%) the maximum one-way availability flr in the backward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			backwardAvgFlr;				// (units=0.001%) the average one-way availability flr in the backward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	bool				suspect;					// Whether the Measurement Interval has been marked as suspect
} lmAvailStats_t;

typedef struct
{
	uint32_t			index;
	dateAndTime_t		startTime;					// The time that the current Measurement Interval started
	timeInterval_t		elapsedTime;				// The time that the current Measurement Interval has been running, in 0.01 seconds
	gauge32_t			forwardTransmittedFrames;	// contains the number of frames transmitted in the forward direction by this MEP
	gauge32_t			forwardReceivedFrames;		// contains the number of frames received in the forward direction by this MEP
	uint32_t			forwardMinFlr;				// (units=0.001%) the minimum one-way availability flr in the forward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			forwardMaxFlr;				// (units=0.001%) the maximum one-way availability flr in the forward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			forwardAvgFlr;				// (units=0.001%) the average one-way availability flr in the forward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	gauge32_t			backwardTransmittedFrames;	// contains the number of frames transmitted in the backward direction by this MEP
	gauge32_t			backwardReceivedFrames;		// contains the number of frames received in the backward direction by this MEP
	uint32_t			backwardMinFlr;				// (units=0.001%) the minimum one-way availability flr in the backward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			backwardMaxFlr;				// (units=0.001%) the maximum one-way availability flr in the backward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	uint32_t			backwardAvgFlr;				// (units=0.001%) the average one-way availability flr in the backward direction, from among the set of availability flr values calculated by the MEP in this Measurement Interval
	gauge32_t			soamPdusSent;				// contains the count of the number of SOAM PDUs sent during this Measurement Interval
	gauge32_t			soamPdusReceived;			// contains the count of the number of SOAM PDUs PDUs received in this Measurement Interval
	bool				suspect;					// Whether the Measurement Interval has been marked as suspect
} lmStats_t;

typedef struct
{
	bitVector32_t	enable;							// A vector of bits that indicates the type of SOAM LM thresholds notifications that are enabled
	uint32_t		measuredFlrForwardThreshold;	// NA (default=100000)used to set the measured forward frame loss ratio threshold value that will be used to determine if a threshold notification is generated
	uint32_t		maxFlrForwardThreshold;			// NA (default=100000) used to set the maximum forward frame loss ratio threshold value that will be used to determine if a threshold notification is generated
	uint32_t		avgFlrForwardThreshold;			// (default=100000) used to set the average forward frame loss ratio threshold value that will be used to determine if a threshold notification is generated
	uint32_t		measuredFlrBackwardThreshold;	// NA (default=100000)used to set the measured backward frame loss ratio threshold value that will be used to determine if a threshold notification is generated
	uint32_t		maxFlrBackwardThreshold;		// NA (default=100000) used to set the maximum backward frame loss ratio threshold value that will be used to determine if a threshold notification is generated
	uint32_t		avgFlrBackwardThreshold;		// NA (default=100000) used to set the average backward frame loss ratio threshold value that will be used to determine if a threshold notification is generated
	uint32_t		forwardHighLossThreshold;		// NA (default=4294967295)used to set the forward high loss threshold value that will be used to determine if a threshold notification is generated
	uint32_t		forwardConsecutiveHighLossThreshold;// NA (default=4294967295)used to set the consecutive forward high loss threshold value that will be used to determine if a threshold notification is generated
	uint32_t		backwardHighLossThreshold;		// NA (default=4294967295)used to set the backward high loss threshold value that will be used to determine if a threshold notification is generated
	uint32_t		backwardConsecutiveHighLossThreshold;// NA (default=4294967295)used to set the consecutive backward high loss threshold value that will be used to determine if a threshold notification is generated
	uint32_t		forwardUnavailCountThreshold;	// NA (default=4294967295) used to set the forward unavailability threshold value that will be used to determine if a threshold notification is generated
	uint32_t		forwardAvailRatioThreshold;		// NA (default=0) used to set the forward availability/total time ratio threshold value that will be used to determine if a threshold notification is generated if the ratio drops below the configured value
	uint32_t		backwardUnavailCountThreshold;	// NA (default=4294967295) used to set the backward unavailability threshold value that will be used to determine if a threshold notification is generated
	uint32_t		backwardAvailRatioThreshold;	// NA (default=0) used to set the backward availability/total time ratio threshold value that will be used to determine if a threshold notification is generated if the ratio drops below the configured value
} lmThresholdCfg_t;

// The bit vectors used to access/modify enable in lmThresMaskCfg_t
#define bLmMeasuredFlrForwardThres			(0)
#define bLmMaxFlrForwardThres				(1)
#define bLmAvgFlrForwardThres				(2)
#define bLmMeasuredFlrBackwardThres			(3)
#define bLmMaxFlrBackwardThres				(4)
#define bLmAvgFlrBackwardThres				(5)
#define bLmForwardHighLossThres				(6)
#define bLmForwardConsecutiveHighLossThres	(7)
#define bLmBackwardHighLossThres			(8)
#define bLmBackwardConsecutiveHighLossThres	(9)
#define bLmUnavailForwardThres				(10)
#define bLmAvailRatioForwardThres			(11)
#define bLmUnavailBackwardThres				(12)
#define bLmAvailRatioBackwardThres			(13)

/**
 * @brief Sets default values for the Loss Configuration settings
 */
void pmSetLmCfgDefaults(lmCfg_t *lmCfg);

/**
 * @brief Sets the Loss Threshold configuration to their default values
 */
void pmSetLmThresholdDefaults(lmThresholdCfg_t	*lmThresholdCfg);

/**
 * @brief Read the next entry in the Loss Session List
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] nextLmIndex is 0 or a valid Loss Session index for this MEP
 * @return	Index of the next Loss Session or 0 if no more entries
 *
 * Read the next entry in the Loss  Service List for the selected local MEP.
 * If nextLmIndex is 0 it returns the Loss Index of the first session or 0 if
 * there are no sessions on the MEP. If a valid Loss Index is provided for
 * nextLmIndex the function returns the Loss Index of the next session in the
 * list or 0 if the end of the list has been reached.
 */
pmIndex_t lossMeasurementReadList(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t nextPmIndex);

/**
 * @brief Create a loss Session using the configuration provided
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is the index to use for the new Loss Session
 * @param[in] lmCfg is a pointer to a lmCfg_t data struct that provides the configuration info for the session
 * @param[in] lmThresholdCfg is a pointer to a lmThresholdCfg_t data struct that provides the threshold info for the session
 * @return
 * \li	-1: Operation rejected due to insufficient resources
 * \li	 1: Operation rejected because the supplied Index is invalid
 * \li	 2: Operation rejected because one or more Loss Threshold Configuration values are not supported
 * \li	 3: Operation rejected due to invalid configuration value.
 * \li	 4: Operation accepted.
 */
int lossMeasurementCreate(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex,lmCfg_t *lmCfg,lmThresholdCfg_t *lmThresholdCfg);

/**
 * @brief Remove the specified Loss Session from the specified MEP
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is a valid Loss Session index for this MEP
 * @return
 * \li  1: Operation rejected because the supplied Loss Measurement Index is invalid
 * \li  2: Operation accepted
 *
 * Remove the specified Loss Session from the specified MEP
 */
int lossMeasurementDelete(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex);

/**
 * @brief Read the measurement values for a specified loss session
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is the Loss Session index for this MEP
 * @param[in] lmCfg is a pointer to a lmCfg_t data type. If the value is not NULL it is updated with the loss configuration
 * @param[in] measuredStats is a pointer to a lmMeasuredStats_t data type. If the value is not NULL it is updated with the last measured loss values
 * @param[in] currentAvailStats is a pointer to a lmAvailStats_t data type. If the value is not NULL it is updated with the current measured loss availability values
 * @param[in] currentStats is a pointer to a lmAvailStats_t data type. If the value is not NULL it is updated with the current measured loss values
 * @param[in] thresholdCfg is a pointer to a lmThresholdCfg_t data type. If the value is not NULL it is updated with the configured Threshold values
 *
 * @return
 * \li  1: Operation rejected because the supplied Loss Measurement Index is invalid
 * \li  2: Operation accepted
 */
int lossMeasurementRead(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex,
		lmCfg_t				*lmCfg,
		lmMeasuredStats_t	*measuredStats,
		lmAvailStats_t		*currentAvailStats,
		lmStats_t			*currentStats,
		lmThresholdCfg_t	*thresholdCfg);

/**
 * @brief Read the Loss Availability History at the specified measurement index for a specified Loss Session
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is the Loss Session index for this MEP
 * @param[in] availStatsIndex is the index value used to select a saved interval
 * @param[in] historyAvailStats is a pointer to a lmAvailStats_t data type that is updated with the history availability stats for the selected interval

 * @return
 * \li	-1: Operation rejected because the supplied Loss Measurement history Availability Stats pointer is NULL
 * \li   1: Operation rejected because the supplied Loss Measurement Index is invalid
 * \li   2: Operation rejected because the supplied Loss Measurement history Availability Stats Index is invalid
 * \li   3: Operation accepted
 */
int lossMeasurementReadHistoryAvailStats(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex,
		uint32_t			availStatsIndex,
		lmAvailStats_t		*historyAvailStats);

/**
 * @brief Read the Loss History at the specified measurement index for a specified Loss Session
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is the Loss Session index for this MEP
 * @param[in] statsIndex is the index value used to select a saved interval
 * @param[in] historyStats is a pointer to a lmStats_t data type that is updated with the history stats for the selected interval
 * @return
 * \li	-1: Operation rejected because the supplied Loss Measurement historyStats pointer is NULL
 * \li   1: Operation rejected because the supplied Loss Measurement Index is invalid
 * \li   2: Operation rejected because the supplied Loss Measurement history Stats Index is invalid
 * \li   3: Operation accepted
 */
int lossMeasurementReadHistoryStats(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex,
		uint32_t			statsIndex,
		lmStats_t			*historyStats);

/**
 * @brief Enable/disable a specified Loss Session. This starts and stops the session.
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is a valid Loss Session index for this MEP
 * @param[in] enable is used to enable (true) or disable (false) the loss measurement session
 * @return
 * \li  1: Operation rejected because the supplied Loss Measurement Index is invalid
 * \li  2: Operation accepted
 */
int lossMeasurementEnable(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex,bool enable);

/**
 * @brief This will clear any saved Loss history for the specified Loss session
 *
 * @param[in] mdIndex of the parent MD
 * @param[in] maIndex of the parent MA
 * @param[in] lMepId is the local MEPID
 * @param[in] lmIndex is the Loss Session index for this MEP
 * @return
 * \li  1: Operation rejected because the supplied Loss Measurement Index is invalid
 * \li  2: Operation accepted
 */
int lossMeasurementClearHistory(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, pmIndex_t lmIndex);


#endif /* PM_SL_H_ */
