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

#ifndef MA_TYPES_H_
#define MA_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/maintenance_association/inc/ma.h>
#include "egl_types.h"
#include "egl_log.h"
//#include "cc.h"

#ifndef MAX_RMEPS_PER_LM
#define MAX_RMEPS_PER_LM 		(8)
#endif
#define MAX_NUM_MA				16//32//(64)					// The Maximum number of MAs supported by the system
#define INVALID_MA_NUM			0xFFFF
#define MAX_NUM_MEPS			(MAX_NUM_MA)			// The Maximum number of local MEPs supported by the system
#define MAX_NUM_RMEPS 			(MAX_NUM_MA)			// The Maximum number of remote MEPs supported by the system
#define MAX_MEPIDS_PER_MA		(MAX_RMEPS_PER_LM + 1)	// The number of MEPIDs that can be associated with a MA
#define MAX_NUM_VLANS_PER_MA	(8)						// This defines the maximum number of vlans than can be associated with any MA

typedef struct
{
	maIndex_t	mibIdx;								// The MIB index for this MA
	maNum_t		maNum;								// Hardware index associated with this MA
	mdNum_t		parentMdNum;						// Hardware index associated with this MAs parent MD
	bool		inUse;								// Used to indicate that an entry is in use
} maCtxt_t;

struct maEntry_s
{
	TAILQ_ENTRY(struct maEntry_s,) 	ll;
	maNetInfo_t						maNetInfo;
	maCompInfo_t					maCompInfo;
	maMEFInfo_t						maMEFInfo;
	mepId_t							mepIdList[MAX_MEPIDS_PER_MA+1];	// List of MEP IDs in this MA - value of 0 indicates End Of List
	uint16_t						vLanList[MAX_NUM_VLANS_PER_MA+1];	// Storage for unique Vlan per MEP on the MA
	networkAddress_t 				alarmNetAddress;
	maCtxt_t						maCtxt;
	TAILQ_HEAD(llMepHead_s,struct mepEntry_s,)	llMepHead;	// The Linked list head, used to access the Local MEP list for this MA
};

typedef struct maEntry_s maEntry_t;

typedef uint8_t maid_t[48];

/*
 *
 */
void setMaLogLevel(log_level_t logLevel);

/*
 * @brief Initialise Maintenance Association (MA) module
 *
 * Must be called at device startup to initialise Maintenance Association (MA) module.
 * It is safe to call multiple times.
 */
void maInit(void);

extern maIndex_t _maNumToMibIndex(maNum_t maNum, mdNum_t *parentMdNum);
extern maNum_t	_maMibIndexToMaNum(mdIndex_t mdIndex, maIndex_t maIndex);
extern struct llMepHead_s* _getMepListHead(mdIndex_t mdIndex, maIndex_t maIndex);
extern bool _maIsMepIdOnList(mdIndex_t mdIndex, maIndex_t maIndex, mepId_t mepId);
extern bool _maIsVLanOnList(mdIndex_t mdIndex, maIndex_t maIndex, uint16_t vLan);
extern bool _maGetPrimaryVlanInfo(mdIndex_t mdIndex, maIndex_t maIndex, serviceSelector_t *primarySelectorType, serviceSelectorId_t *primarySelectorIdOrNone);
extern tagType_t _maGetTagType(mdIndex_t mdIndex, maIndex_t maIndex);
extern void generateMaid(mdName_t mdName, mdNameType_t mdNameType, maName_t maName, maNameType_t maNameType, maid_t  maid);
extern void _maUpdateCCMTLVs(mdIndex_t mdIndex, maIndex_t maIndex, iFace_t iFace, tlvType_t type,uint8_t length,void *value);

#endif /* MA_TYPES_H_ */
