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

#ifndef MD_H_
#define MD_H_

/**
 * @file
 * @brief The Maintenance Domain API.
 *
 * md.h defines the structs, data types and functions used to interact with
 * Maintenance Domain (MD) objects.
 */

#include <api_oam_sdk/common/types/inc/mr_api_types.h>
#include "egl_types.h"

/**
 * @brief Defines indices for 'Writable' parameters in an MD.
 *
 * This data type defines the indices for valid writable
 * parameters that can be selected when writing to an MD object.
 */
typedef enum
{
	mdParam_mdMhfCreation = 1,				//!< Mep Half Function creation option.
	mdParam_mdMhfIdPermission,				//!< What, if anything, is to be included in the Sender ID TLV.
	mdParam_mdFaultAlarmNetAddress			//!< The network address to which Fault Alarms (12.14.7.7) are to be transmitted.
} mdWrParam_t;

/**
 * @brief Defines the valid levels that can be chosen for the MD level.
 *
 * This data type defines the valid levels that
 * can be selected when creating a MD object.
 */
typedef enum
{
	level0 = 0,
	level1 = 1,
	level2 = 2,
	level3 = 3,
	level4 = 4,
	level5 = 5,
	level6 = 6,
	level7 = 7
} mdLevel_t;

/**
 * @brief Defines the valid MD name types.
 *
 * This data type defines the valid MD name types that can
 * be used when creating a MD object.
 */
typedef enum {
	md_none 				= 1,
	md_dnsLikeName 			= 2,
	md_macaddressAndUInt	= 3,
	md_characterString		= 4
} mdNameType_t;

/**
 * @brief Defines the valid MEP Half Function creation actions
 */
typedef enum {
	md_defMHFnone 			= 1,
	md_defMHFdefault 		= 2,
	md_defMHFexplicit		= 3
} mdMhfCreation_t;

/**
 * @brief The set of Sender ID TLV options
 *
 * Each value indicates what, if anything, is to be included in the Sender ID TLV
 */
typedef enum
{
	md_sendIdNone			= 1,
	md_sendIdChassis		= 2,
	md_sendIdManage			= 3,
	md_sendIdChassisManage	= 4
} mdMhfIdPermission_t;

typedef char		mdName_t[43+1];			//!< Character array to hold the MD name. The last character must always be 0.
typedef uint32_t	mdIndex_t;				//!< Defines the type for a MD MIB Index. A value of 0 is an invalid Index.

/**
 * @brief This is used when reading information about the MD .
 *
 */
typedef struct
{
	mdName_t			name;				//!< The MD name
	mdNameType_t		type;				//!< The MD name type
	mdLevel_t			level;				//!< The MD Level
	mdMhfCreation_t		mhfCreation;		//!< Mep Half Function creation
	mdMhfIdPermission_t	mhfIdPermission;	//!< Determines what if anything to put in sender ID TLV
	uint32_t			maNextMibIdx;		//!< The index of the next MA
} mdMibInfo_t;

/**
 * @brief Return the next MD MIB Index to use
 * @return The MIB index to use when creating a new MD
 */
mdIndex_t mdListReadNextMdIndex(void);

/**
 * @brief	Create a new Maintenance Domain (MD).
 *
 * Create a new Maintenance Domain (MD). The MD Index to use to access this MD
 * is supplied as mdIndex.
 * The mdName and type must be provided to identify the MD.
 * The level of this MD is identified by mdLevel.
 * NOTE: If a Y1731 MEG group is required then the MD should be created with a 'type'
 * equal to 'md_none' and the value of mdLevel set to the MEG level. When creating
 * the associated MA, the y1731Compliant parameter must be set to true.
 *
 * @param[in]	mdIndex The MD MIB index to use for this MD
 * @param[in]	mdName The character array the holds the MD name
 * @param[in]	type The MD name type
 * @param[in]	mdLevel Specify one of 8 levels for the MD
 * @returns
 * \li  1: Operation rejected due to invalid Maintenance Domain Name
 * \li  2: Operation rejected because Maintenance Domain Name already exists
 * \li  3: Operation rejected due to invalid MD Level
 * \li  4: Operation accepted
 * \li -1: Operation rejected due to invalid MD Index
 * \li -2: Operation rejected due to insufficient resources
 */
int mdCreate(mdIndex_t mdIndex, mdName_t mdName, mdNameType_t type, mdLevel_t mdLevel);

/**
 * @brief Read the next entry in the MD List.
 *
 * Read the next entry in the MD List. If mdIndex is 0 it
 * returns the mdIndex of the first MD entry or 0 if there are
 * no MD entries. If a valid mdIndex is provided it returns
 * the mdIndex of the next MD in the list.
 *
 * @param[in] prevMdIdx The MD Index from a previous call to this function or 0.
 * @return	mdIndex of the next entry or 0 if no more entries.
 *
 */
mdIndex_t mdReadList(mdIndex_t prevMdIdx);

/**
 * @brief	Delete the MD with the supplied MIB index.
 *
 * This will delete the selected MD and all its child objects.
 *
 * @param[in] mdIndex The MD Index of the MD to delete
 * @returns
 * \li 1: Operation rejected due to invalid or nonexistent Maintenance Domain
 * \li 2: Operation accepted
 *
 */
int mdDelete(mdIndex_t mdIndex);

/**
 * @brief	Delete all MDs on the MD List.
 *
 * This will delete all the MDs in the device and all their child objects.
 *
 * @returns
 * \li 2: Operation accepted
 *
 */
int mdDeleteMdList(void);

/**
 * @brief	Read the information for the MD	selected by mdIndex.
 *
 * Read information related to this MD. If a NULL pointer is supplied for mdMibInfo,
 * then no information is returned.
 * Information is only valid if the return value is 2.
 *
 * @param[in] mdIndex The MD Index of the MD to delete
 * @param[out] mdMibInfo A pointer to a mdMibInfo data type or NULL. If not NULL its values will be updated
 * @param[out] faultAlarmNetAddr A pointer to a macAddress_t data type or NULL. If not NULL its values will be updated
 * @return
 * \li 1: Operation rejected due to invalid or nonexistent Maintenance Domain
 * \li 2: Operation accepted
 */
int mdRead(mdIndex_t mdIndex, mdMibInfo_t *mdMibInfo, networkAddress_t *faultAlarmNetAddr);

/**
 * @brief	Write a new value to the selected MD parameter.
 *
 * The writable parameters for an MD and the associated data type are:
 * mdParam_mdMhfCreation			type = serviceSelector_t
 * mdParam_mdMhfIdPermission 		serviceSelectorId_t
 * mdParam_mdFaultAlarmNetAddress	networkAddress_t
 *
 * Write a new value to a writable parameter of the MD. The mdParm value is used to
 * select one of the valid writable parameters (listed above) and the paramValue is
 * a pointer to the new value. The data type of the parameter (also listed above)
 * must be valid for the parameter or errors/misconfigurations may occur.
 *
 * @param[in] mdIndex The MD Index of the selected MD to read from
 * @param[in] mdParam Is an enum value that identifies the MD parameter to write to
 * @param[in] paramValue Is a pointer to the new value for the selected parameter
 * @returns
 * \li 1: Operation rejected due to invalid or nonexistent Maintenance Domain
 * \li 2: Operation rejected due to the selected managed object being Read-Only
 * \li 3: Operation rejected due to invalid value for parameter
 * \li 4: Operation accepted
 *
 */
int mdWrite(mdIndex_t mdIndex, mdWrParam_t mdParam, void *paramValue);

/**
 * @brief	Test if the MD index selects a valid MD.
 *
 * Test if the MD index selects a valid MD on this device.
 *
 * @param[in] mdIndex Specifies the MD index to verify is a valid MD on this device
 * @returns True if the index selects a valid MD on device, otherwise False.
 *
 */
bool mdIsMdMibIdxValid(mdIndex_t mdIndex);

#endif /* MD_H_ */
