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

#ifndef MEP_TYPES_H_
#define MEP_TYPES_H_

#include <api_oam_sdk/common/types/inc/linked_list.h>
#include <api_oam_sdk/common/types/inc/mr_api_types.h>
#include <api_oam_sdk/fault_notification_generator/inc/fng.h>
#include <api_oam_sdk/link_trace/src/link_trace_types.h>
#include <api_oam_sdk/mep/inc/mep.h>
#include <api_oam_sdk/performance_monitoring/src/pm_types.h>
#include "egl_types.h"

#include "egl_log.h"

typedef int16_t	mepNum_t;

typedef struct
{
	mepId_t		mepId;									// The MIB index for this MEP
	mepNum_t	mepNum;									// Hardware index associated with this MEP
	maNum_t		parentMaNum;							// Hardware index associated with this MEPs parent MA
	bool		inUse;									// Used to indicate that an entry is in use
	uint16_t	rxLMepAddr;								// The address of the MEP in the rxLMep table
} mepCtxt_t;

typedef struct mibRMepIndices_s mepParentIndices_t;

struct mepEntry_s
{
	TAILQ_ENTRY(struct mepEntry_s,) 	ll;
	mepInfo_t							mepInfo;
	mepCcInfo_t							mepCcInfo;
	_mepLtInfo_t						mepLtInfo;
	mepMefInfo_t						mepMefInfo;
	mepCtxt_t							mepCtxt;
	TAILQ_HEAD(llRMepHead_s,struct rMepEntry_s,)	llRMepHead;	// The Linked list head, used to access the RMEP list for this MEP
	TAILQ_HEAD(llPmSvcHead_s,struct pmEntry_s,)		llLmSvcHead, llDmSvcHead;	// The Linked list head, used to access the PM Loss services associated with this MEP
};

typedef struct mepEntry_s mepEntry_t;

#define INVALID_MEP_NUM		0xFFFF

extern void setMepLogLevel(log_level_t logLevel);

/*
 * @brief	Called at device startup to initialise MEP module
 *
 * This must be called at device startup to initialise the MEP and all associated Modules
 * including:
 * 		rMepDBInit()		: This initialises the Remote MEP Database Module
 *		fngInit()			: This initialises the Fault Notification Generation Module and starts an OS thread
 *		ccInit()			: This initialises the Continuity Check Module
 *		lbInit()			: This initialises the Loopback Module
 *		linkTraceInit()		: This initialises the Link Trace Module and starts an OS thread
 *
 * Safe to call repeatedly.
 */
extern void mepInit(void);


extern uint16_t _getPrimaryLanForMep(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t mepId, iFace_t iFace);
extern mepId_t _mepNumToMepId(lMepNum_t mepNum, maNum_t *parentMaNum);
extern lMepNum_t _mepIdToMepNum(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t mepId);
extern struct llRMepHead_s* _getRMepDBListHead(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern struct llPmSvcHead_s* _getPmListHead(bool isDm, mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _mepRdiStatusUpdate(mepNum_t lMepNum, bool rdiSet);
extern bool _mepIsActive(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _lMepAppendRMepDB(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, mepId_t rMepId);
extern void _lMepRemoveRMepDB(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, mepId_t rMepId);
extern mepConnStatus_t	_lMepGetConnStatus(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern bool	_lMepIsAnyRxRdiSet(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _lMepGetParentsIndices(lMepNum_t lMepNum, mepParentIndices_t *mepParentIndices);
extern bool	_lMepAreAllPSNotUpOrAnyISNotUp(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _mepIncrementOperNextIndex(mepNum_t lMepNum, pmIndex_t lastPmIdx);
extern void _setMepLastDefectSentStatus(lMepNum_t lMepNum, fngDefect_t lastDefect);
extern fngDefect_t _getMepLastDefectSentStatus(lMepNum_t lMepNum);
extern void _setMepRdiTransmitStatus(lMepNum_t lMepNum, bool rdiIsSet);
extern bool _lMepNumIsValid(lMepNum_t lMepNum);
extern void _lMepUpdateCcmInterval(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, ccmInterval_t newCcmInterval);
extern void _lMepUpdateCCMTLV(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, iFace_t iFace, tlvType_t type,uint8_t length,void *value);
extern iFace_t _getMepInterface(lMepNum_t lMepNum);
extern int	_readMepLtInfo(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, _mepLtInfo_t *mepLtInfo, macAddress_t mepMAC);

extern void _incUnexpectedLtrIn(lMepNum_t lMepNum);
extern void _incLtmTransmitted(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _incLtmReceived(lMepNum_t lMepNum);
extern void _incLtrTransmitted(lMepNum_t lMepNum);
extern void _incLtrReceived(lMepNum_t lMepNum);

extern void _setTxLtmResult(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, bool value);
extern uint32_t _getNextLtmSeqNum(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _incNextLtmSeqNumber(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId);
extern void _setTxLtmSeqNumber(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t lMepId, uint32_t seqNum);

#endif /* MEP_TYPES_H_ */
