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

#ifndef SVC_COS_H_
#define SVC_COS_H_

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

typedef uint32_t		cosIndex_t;

typedef enum {
	cosType_interface	= 1,		// This value indicates that the CoS ID profile is associated with the interface, i.e. UNI or ENNI
	cosType_vc			= 2,		// This value indicates that the CoS ID profile is associated with the virtual channel, i.e. COS or OVC
	cosType_pcp			= 3,		// This value indicates that the CoS ID profile is associated with the outer tag's Priority Code Point (priority bits)
	cosType_dscp		= 4,		// This value indicates that the CoS ID profile is associated the IP's frames DSCP (priority) setting
	cosType_l2cp		= 5,		// This value indicates that the CoS ID profile is associated a Layer 2 Control Protocol
} cosType_t;

typedef enum {
	cosParam_cosIdentifierList = 1
} cosWrParam_t;

typedef enum {
	col_pcp		= 1,
	col_evc		= 2,
	col_dei		= 3,
	col_dscp	= 4
} colourId_t;


typedef struct svcCosCfg_s {
	//char			identifier[45];			// Not supported.
	char			identifierList[256];	// This object indicates the list of CoS identifiers associated with the specific CoS ID profile.
											/*
											default value is "0:7"
											For each of the cosType types valid range is:
											interface - the value of this object is ignored for the 'interface'type
											vc        - the value of this object is ignored for the 'vc' type
											pcp       - the value of this object has a range of '0:7'
											dscp      - the value of this object has a range of '0:63' for IPv4 and '0:16384' for IPv6
											l2cp      - the value of this object indicates the matching criteria:
											'1' - destination MAC address only
											'2' - destination MAC address plus Ethernet protocol
											'3' - destination MAC address plus Ethernet protocol plus subtype
											CoS identifier list can be a single value or multiple values separated by a delimiter.
											Some valid values are:'1', '1:3', '1,3,5', '0:7'. In the first example
											only one item, '1', is included in the CoS ID list. In the second example
											values 1, 2, and 3 are included in the CoS ID list (range of values). In
											the third example three individual values are included. In the fourth
											example eight values are included:0 through 7 (range of values).
											*/
	uint32_t		protocol;				// This object configures the L2CP Ethernet protocol for CoS Identifier type of 'l2cp' and is ignored for other types.
											// It is also ignored if identifierList has a value of '1'.
	uint32_t		subType;				// This object configures the L2CP subtype protocol for CoS Identifier type of 'l2cp' and is ignored for other types.
											// It is also ignored if mefServiceCosCfgIdentifierList has a value of '1' or '2'.
	cosType_t		cosType;				// This object configures the CoS ID type and indicates the interpretation of the identifierList object.
	macAddress_t	macAddress;				// This object configures the L2CP Destination MAC address for CoS Identifier type of 'l2cp' and is ignored for other types.

} svcCosCfg_t;


typedef struct svcCosEglCfg_s {
	char		colourMap[32];				// This lists the colours associated with the COS listed by 'identifierList'. The number of colours must match the number of COS. default value is "0'7"
	prio_t		outerTagCos;				// This is used to set the egress COS to use for all ingress COS specified in 'identifierList'
	bool		colourAware;				// This set if the profile should be treated as colour aware (true) or not (false)
	bool		colourForward;				// This is used to override the colour mapping of the profile. If true the ingress colour is forwarded
	colourId_t	colourId;					// This object configures the colour handling type for the profile.
} svcCosEglCfg_t;
/*
 * @brief Returns the next available COS index
 *
 * @return The next available COS index.
 */
cosIndex_t	svcCosGetNextIndex(void);

/**
 * @brief Read the next entry in the list of configured COSs.
 *
 * Read the next entry in the list of configured COSs. If cosIndex is 0 it
 * returns the cosIndex of the first COS entry or 0 if there are
 * no COS entries. If a valid cosIndex is provided it returns
 * the mdIndex of the next MD in the list.
 *
 * @param[in] nextCosIdx The COS Index from a previous call to this function or 0.
 * @return	cosIndex of the next entry or 0 if no more entries.
 *
 */
cosIndex_t svcCosReadList(cosIndex_t prevCosIndex);

/**
 * @brief Create a new service COS .
 *
 * Create a new service COS using the configuration
 * parameters provided.
 *
 * @param[in] cosIndex the index value of the COS to create. Usually obtained by calling svcCosGetNextIndex()
 * @param[in] svcCosCfg A pointer to a svcCosCfg_t data type containing configuration values.
 * @param[in] svcCosEglCfg A pointer to a svcCosEglCfg_t data type containing configuration values.
 * @return
 * \li -2: Operation rejected due to insufficient resources
 * \li -1: Operation rejected due to invalid/NULL svcCosCfg or svcCosEglCfg pointer
 * \li  1: Operation rejected due to invalid or nonexistent COS index.
 * \li  2: Operation rejected due to invalid COS type
 * \li  3: Operation rejected due to invalid COS identifier list
 * \li  4: Operation rejected due to invalid colourMap list
 * \li  5: Operation accepted
 */
int svcCosCreate(cosIndex_t cosIndex, svcCosCfg_t *svcCosCfg, svcCosEglCfg_t *svcCosEglCfg);

/**
 * @brief	Delete the COS with the supplied cosIndex.
 *
 * This will delete the selected COS and its associations with all EVCs.
 *
 * @param[in] cosIndex the index value of COS to delete.
 * @return
 * \li  1: Operation rejected due to invalid or nonexistent COS index.
 * \li  2: Operation rejected because the cosIndex is in use by an EVC or Interface
 * \li  3: Operation accepted
 *
 */
int svcCosDelete(cosIndex_t cosIndex);

/**
 * @brief Read the service COS configuration.
 *
 * Read information related to this service COS. If a NULL pointer is supplied for
 * svcCosCfg then no information is returned for that parameter.
 * Information is only valid if the return value is 2.
 *
 * @param[in] cosIndex the index value of COS to read from.
 * @param[out] svcCosCfg A pointer to a svcCosCfg_t data type or NULL. If not NULL its values will be updated.
 * @param[out] svcCosEglCfg A pointer to a svcCosEglCfg_t data type or NULL. If not NULL its values will be updated.
 * @return
 * \li  1: Operation rejected due to invalid or nonexistent COS index.
 * \li  2: Operation accepted
 */
int svcCosRead(cosIndex_t cosIndex, svcCosCfg_t *svcCosCfg, svcCosEglCfg_t *svcCosEglCfg);

/**
 * @brief	Write a new value to the selected service COS parameter.
 *
 * The writable parameters for an service COS and the associated data type are:
	cosParam_cosIdentifierList		char
 *
 * Write a new value to a writable parameter of the service COS. The wrParam 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] cosIndex the index value of COS to write to.
 * @param[in] wrParam is an enum value that identifies the service UNI parameter to write to.
 * @param[in] paramValue Is a pointer to the new value for the selected parameter
 * @return
 * \li 1: Operation rejected due to invalid or nonexistent COS index.
 * \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 svcCosWrite(cosIndex_t cosIndex, cosWrParam_t wrParam, void *paramValue);

#endif /* SVC_COS_H_ */
