/*
*********************************************************************************
*                                                                               *
* NOTICE:                                                                 *
*                                                                               *
*********************************************************************************
*  
*                                      
*    
*       mgcSap <---------mgcPhyPorts --------> mgcMgInfo
*
*
*/
 

 
    
/*********************************************************************************
 *                              <mgc_mg_info.c>                                                              
 *     This file should provide MG_INFO object APIs
 *
 *    Author                         Date
 *    ------                        ------
 *    Sam Yao                     Aug 2008                                                                                              
 *********************************************************************************/


/*-----------------------------------------------------------------------*/
/*                        INCLUDE HEADER FILES                           */
/*-----------------------------------------------------------------------*/


#include "./include/mgc_mg_info.h"
#include "./include/mgc_phy_port.h"
#include "./include/mgc_8ecp.h"
#include "./include/mgc_internal.h"
#include "./include/mgc_chnl_info.h"
#include "./include/mgc_debug.h"
#include "./include/mgc_mgcp.h"
#include "./include/mgc_conn_info.h"
static	MG_INFO mgcMgInfo[MGC_MAX_NUM_OF_MG];

extern int mgc_get_non_virtual_trk_status(MG_INFO *pMgInfo);


/*-----------------------------------------------------------------------
              MG_INFO   M A N A G E R
 ------------------------------------------------------------------------*/	  



/***************************************************************************
 * mgc_mg_info_init
 * ------------------------------------------------------------------------
 * General: init MG_INFO structure objcet
 * Return Value:  void.
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo- the pointer of the MG_INFO object which should be init
 *	       id - the id of the MG_INFO object
 ***************************************************************************/
void mgc_mg_info_init(MG_INFO *pMgInfo , int id)
{
    int i;
    if((pMgInfo == NULL)||(id < 0))
        return ;
	
	pMgInfo->id = id;	
    pMgInfo->requestId = 0;	
    pMgInfo->created = FALSE;
	pMgInfo->enable = FALSE;
	memset(&pMgInfo->mgAttr , 0 , sizeof(MG_ATTR));
    pMgInfo->mgAttr.ctrlType = MGC_MG_CTRL_TYPE_UNDEF;
	pMgInfo->mgAttr.mgType= MGC_MG_TYPE_UNDEF;
    pMgInfo->auditTimer = 0;
    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        pMgInfo->pPhyPort[i] = NULL ;
    }

	return;
}

void mgc_mg_info_setup(void)
{
    int i;
	MG_INFO *pMgInfo = NULL;
	
    for(i=0 ; i<MGC_MAX_NUM_OF_MG ;i++)
    {
        pMgInfo = &mgcMgInfo[i];
		mgc_mg_info_init(pMgInfo, i);
    }
	
    return;
}


/***************************************************************************
 * mgc_mg_info_clear
 * ------------------------------------------------------------------------
 * General: clear MG_INFO structure objcet
 * Return Value:  void.
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo- the pointer of the MG_INFO object which should be cleared
 ***************************************************************************/
void mgc_mg_info_clear(MG_INFO *pMgInfo)
{
    int i;
	PHY_PORT_INFO *pPhyPort = NULL;

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        pPhyPort = pMgInfo->pPhyPort[i];
		if(pPhyPort == NULL)
		    continue;

		mgc_phy_port_clear(pPhyPort);
    }

	mgc_mg_info_init(pMgInfo, pMgInfo->id);
	return;
}


/***************************************************************************
 * mgc_mg_info_attached_phy_port_num
 * ------------------------------------------------------------------------
 * General: calculate how many phyPort is attached on the MG_INFO objec
 * Return Value:   the number of attached phyPort.
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo- the pointer of the MG_INFO object
 ***************************************************************************/
int mgc_mg_info_attached_phy_port_num(MG_INFO *pMgInfo)
{
    int num , i;

    if(pMgInfo == NULL)	
        return 0;

    num = 0;
    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)	
    {
        if(pMgInfo->pPhyPort[i] != NULL)
		    num++;	
    }

    return num;	
}

/***************************************************************************
 * mgc_mg_info_is_port_already_exist
 * ------------------------------------------------------------------------
 * General: check whether the phyport is already attached on this MG_INFO object
 * Return Value:  if already attached return TRUE, else return FALSE
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo- the pointer of the MG_INFO object
 *           portNo - the phyPort number 
 ***************************************************************************/
BOOL mgc_mg_info_is_port_already_exist(MG_INFO *pMgInfo , int portNo , MGC_SAP *pSap)
{
    int i;

    if(pMgInfo == NULL)
	    return FALSE;	

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        if(pMgInfo->pPhyPort[i] == NULL)
		    continue;

        if(pMgInfo->pPhyPort[i]->pMgcSap != pSap)
		    continue;	
		
		if(pMgInfo->pPhyPort[i]->portNo != portNo)
		    continue;	
		
        if(portNo != ITL_OPERA_PORT_NO)		
        {
	    MGC_WARN("mg[%d] already have Port[%d]" , pMgInfo->id , portNo);
        }
	    return TRUE;
    }

    return FALSE;
}

/***************************************************************************
 * mgc_mg_info_attach_phy_port
 * ------------------------------------------------------------------------
 * General: attach a phyport on the MG_INFO object
 * Return Value:  if failure return FALSE, else return TRUE
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo- the pointer of the MG_INFO object
 *           pPhyPort -  the pointer of the phyPort
 ***************************************************************************/
BOOL mgc_mg_info_attach_phy_port(MG_INFO *pMgInfo , PHY_PORT_INFO *pPhyPort , MGC_SAP *pSap)
{
    int i;

    if((pMgInfo == NULL)||(pPhyPort == NULL))
        return FALSE;

    if(mgc_mg_info_is_port_already_exist(pMgInfo , pPhyPort->portNo , pSap) == TRUE)
	    return FALSE;	
		
    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        if(pMgInfo->pPhyPort[i] != NULL)
		    continue;

		pMgInfo->pPhyPort[i] = pPhyPort;
		return TRUE;
    }

	return FALSE;
}


/***************************************************************************
 * mgc_mg_info_dettach_phy_port
 * ------------------------------------------------------------------------
 * General: remove a phyport from the MG_INFO object
 * Return Value:  void
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo- the pointer of the MG_INFO object
 *           pPhyPort -  the pointer of the phyPort
 ***************************************************************************/
void mgc_mg_info_dettach_phy_port(MG_INFO *pMgInfo , PHY_PORT_INFO *pPhyPort)
{
    int i;

    if((pMgInfo == NULL)||(pPhyPort == NULL))
        return;

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
	    if(pMgInfo->pPhyPort[i] != pPhyPort)
		    continue;

	    pMgInfo->pPhyPort[i] = NULL;
		//MGC_DEBUG("mgcMgInfo[%d] dettach phyport[%d]" , pMgInfo->id , pPhyPort->id);
	    return;
    }

    return ;
}

/***************************************************************************
 * mgc_mg_info_get_unused_mg
 * ------------------------------------------------------------------------
 * General: get unused MG_INFO object
 * Return Value:  if failure return FALSE, else return TRUE
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	void
 ***************************************************************************/
MG_INFO *mgc_mg_info_get_unused_mg(void)
{
    int i;
    MG_INFO *pMgInfo = NULL;

    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
        pMgInfo = &mgcMgInfo[i];

		if(pMgInfo->created == TRUE)
		   continue;	
		
        return pMgInfo;		
    }

    return NULL;	
}

/***************************************************************************
 * mgc_mg_info_get_index_mg
 * ------------------------------------------------------------------------
 * General: get the pointer of the MG_INFO object by index
 * Return Value:  if failure return NULL , else return the pointer
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	index - index of the MG_INFO 
 ***************************************************************************/
MG_INFO *mgc_mg_info_get_index_mg(int index)
{
    if((index < 0)||(index >= MGC_MAX_NUM_OF_MG))	
        return NULL;
	
    return &mgcMgInfo[index];
}


BOOL mgc_mg_info_check_codec_list(MG_INFO *pMgInfo)
{
    int i;
    MGC_CODEC_LIST codecList;
    MGC_CODEC_LIST *pList = NULL;
	
    if(pMgInfo == NULL)
	    return FALSE;	

    mgc_connect_codec_list_init(&codecList);
	pList = &pMgInfo->mgAttr.codecList;

    for(i = 0 ; i<pList->num ; i++)
    {
        if(mgc_mgcp_check_codec_valid(pList->codec[i]) != TRUE)
		    continue;

		codecList.codec[codecList.num] = pList->codec[i];
		codecList.num++;
    }

    if(pList->num != codecList.num)
    {
        MGC_WARN("mg[%d] codeclist rec wrong" , pMgInfo->id);
    }

	if(codecList.num > 0)
	    memcpy(pList , &codecList , sizeof(MGC_CODEC_LIST));

	return TRUE;
}

/***************************************************************************
 * mgc_mg_info_assign_attr
 * ------------------------------------------------------------------------
 * General:  give MG_INFO object attribute
 * Return Value:  if failure return FALSE, else return TRUE
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo - the pointer of the MG_INFO object
 *           pMgAttr -  the pointer of the attribute descprition
 ***************************************************************************/
BOOL mgc_mg_info_assign_attr(MG_INFO *pMgInfo , MG_ATTR *pMgAttr)
{
    if((pMgInfo == NULL)||(pMgAttr == NULL))
        return FALSE;		

    if(strlen(pMgAttr->domain) == 0)
        return FALSE;


    switch(pMgAttr->ctrlType)
    {
        case MGC_MG_CTRL_TYPE_8ECP:
			 mgc_8ecp_create(pMgInfo , pMgAttr);
		    break;	   
		case MGC_MG_CTRL_TYPE_MGCP:			
			memcpy(&pMgInfo->mgAttr , pMgAttr , sizeof(MG_ATTR));
			if(pMgInfo->mgAttr.auditTimer == 0)
			{
			    pMgInfo->mgAttr.auditTimer = MGC_MGCF_TIMER_10S;
			}
			else
			{
			    pMgInfo->mgAttr.auditTimer = pMgInfo->mgAttr.auditTimer*MGC_MGCF_TIMER_1S;
			}
			break;
		default:
			MGC_ERROR("unsupport ctrlType %d" , pMgAttr->ctrlType);
			return FALSE;
    }
	
    mgc_mg_info_check_codec_list(pMgInfo);	
    pMgInfo->auditTimer = pMgInfo->mgAttr.auditTimer;
    pMgInfo->created = TRUE;
    return TRUE;
}

/***************************************************************************
 * mgc_mg_info_state_check
 * ------------------------------------------------------------------------
 * General:  check MG status
 * Return Value: void
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo - the pointer of the MG_INFO object
 ***************************************************************************/
void mgc_mg_info_state_check(MG_INFO *pMgInfo)
{
    if(pMgInfo == NULL)
        return;

    if(pMgInfo->created == FALSE)
        return;

    if(++pMgInfo->auditTimer < pMgInfo->mgAttr.auditTimer)
	    return;	

    switch(pMgInfo->mgAttr.ctrlType)
    {
        case MGC_MG_CTRL_TYPE_MGCP:
			mgc_internal_opera_auep_request(pMgInfo);			
			mgc_get_non_virtual_trk_status(pMgInfo);
			break;
		case MGC_MG_CTRL_TYPE_8ECP:
			break;
		default:
			break;
    }

	
    pMgInfo->auditTimer = 0;
    return;    	
}

/***************************************************************************
 * mgc_mg_info_update_mg_status
 * ------------------------------------------------------------------------
 * General:  update MG_INFO object status
 * Return Value: void
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: 	pMgInfo - the pointer of the MG_INFO object
 *           status - TRUE stand for enable, FALSE stand for disable
 ***************************************************************************/
void mgc_mg_info_update_mg_status(MG_INFO *pMgInfo , BOOL status)
{
    int i;
	PHY_PORT_INFO *pPhyPort = NULL;
	
    if(pMgInfo == NULL)
       return;

    pMgInfo->enable = status;

    if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_AudioCoder)
	    return;

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        pPhyPort = pMgInfo->pPhyPort[i];

		if(pPhyPort == NULL)
		    continue;

		if(status == TRUE)
		    pPhyPort->status = MGC_PHY_PORT_STATUS_ON_LINE;

		if(status == FALSE)
		    pPhyPort->status = MGC_PHY_PORT_STATUS_OFF_LINE;
    }
	return;
}

/***************************************************************************
 * mgc_mg_info_check_mg_is_exsit
 * ------------------------------------------------------------------------
 * General:  check MG_INFO object is already be created
 * Return Value: if already created return the pointer , else return NULL
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: pMgAttr - the pointer of the MG attribute description
 ***************************************************************************/
MG_INFO *mgc_mg_info_check_mg_is_exsit(MG_ATTR *pMgAttr)
{
    int i;
    MG_INFO *pMgInfo= NULL;
	
    if(pMgAttr == NULL)
        return NULL;		

    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
        pMgInfo = &mgcMgInfo[i];

		if(pMgInfo->created == FALSE)
		    continue;

		if(strcmp(pMgInfo->mgAttr.domain , pMgAttr->domain) != 0)
		    continue;

		if(pMgInfo->mgAttr.ip != pMgAttr->ip)
		    continue;

		return pMgInfo;
    }

	return NULL;
}


/***************************************************************************
 * mgc_mg_info_find_port_by_name
 * ------------------------------------------------------------------------
 * General:  find the phyPort by mg name and local port
 * Return Value: if failure return NUL , else return the pointer of the phyPort
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: name - the name of the mg
 *           localPort - the local MGCP port
 ***************************************************************************/
PHY_PORT_INFO *mgc_mg_info_find_port_by_name_and_portNo(char *name , BYTE portNo ,WORD localPort)
{
    int i , j;
	MG_INFO *pMgInfo = NULL;
	PHY_PORT_INFO *pPhyPort = NULL;
    MGC_USER_TYPE usrType ;
	
    if(localPort == MGC_MG_NETWORK_PORT)
    {
        usrType = MGC_USER_TYPE_MG;
    }
	else if(localPort == MGC_MGC_NETWORK_PORT)
	{
	    usrType = MGC_USER_TYPE_MGC;
	}
	else
	{
	     return NULL;
	}
		
		

    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
        pMgInfo = &mgcMgInfo[i];

        if(strcmp(pMgInfo->mgAttr.domain , name) != 0)
		    continue;	

        for(j=0 ; j<MGC_MAX_PHY_PORT_PER_MG ; j++)
        {
            pPhyPort = pMgInfo->pPhyPort[j];

			if(pPhyPort == NULL)
			    continue;

			if(pPhyPort->pMgcSap->usrType != usrType)
			    continue;

			if(pPhyPort->portNo != portNo)
			    continue;
			
			return pPhyPort;
        }
    }
	return NULL;
}


PHY_PORT_INFO *mgc_mg_info_find_port_by_name(char *name ,WORD localPort)
{
    int i , j;
	MG_INFO *pMgInfo = NULL;
	PHY_PORT_INFO *pPhyPort = NULL;
    MGC_USER_TYPE usrType ;
	
    if(localPort == MGC_MG_NETWORK_PORT)
    {
        usrType = MGC_USER_TYPE_MG;
    }
	else if(localPort == MGC_MGC_NETWORK_PORT)
	{
	    usrType = MGC_USER_TYPE_MGC;
	}
	else
	{
	     return NULL;
	}
				

    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
        pMgInfo = &mgcMgInfo[i];

        if(strcmp(pMgInfo->mgAttr.domain , name) != 0)
		    continue;	

        for(j=0 ; j<MGC_MAX_PHY_PORT_PER_MG ; j++)
        {
            pPhyPort = pMgInfo->pPhyPort[j];

			if(pPhyPort == NULL)
			    continue;

			if(pPhyPort->pMgcSap->usrType != usrType)
			    continue;

			return pPhyPort;
        }
    }
	return NULL;
}





MG_INFO *mgc_mg_info_find_mg_by_name(char *name)
{
    int i ;
	MG_INFO *pMgInfo = NULL;

    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
	    pMgInfo = &mgcMgInfo[i];

	    if(strcmp(pMgInfo->mgAttr.domain , name) != 0)
		    continue;	

		return pMgInfo;
    }

	return NULL;
}

/***************************************************************************
 * mgc_mg_info_find_available_mg
 * ------------------------------------------------------------------------
 * General:  find a MG_INFO object which is enabled according to the mgType
 * Return Value: if failure return NUL , else return the pointer of the MG_INFO object
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: mgType - the Type of MG
 ***************************************************************************/
MG_INFO *mgc_mg_info_find_available_mg(MGC_MG_TYPE mgType)
{
    int i;
	MG_INFO *pMgInfo = NULL;

	if(mgType == MGC_MG_TYPE_UNDEF)
	    return NULL;

    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
        pMgInfo = &mgcMgInfo[i];

		if(pMgInfo->mgAttr.mgType != mgType)
		    continue;

		if(pMgInfo->enable == FALSE)
		    continue;

		return pMgInfo;
    }

	return NULL;
}

/***************************************************************************
 * mgc_mg_info_assign_idle_connection
 * ------------------------------------------------------------------------
 * General:  assign a idle connection of the specific MG_INFO objcet
 * Return Value: if failure return NUL , else return the pointer of the connection
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: pMgInfo -  the pointer of the MG_INFO
 ***************************************************************************/
CONNECT_INFO *mgc_mg_info_assign_idle_connection(MG_INFO *pMgInfo)
{
    int i;
    PHY_PORT_INFO *pPhyPort = NULL;
	CONNECT_INFO *pConnect = NULL;
	
    if(pMgInfo == NULL)
        return NULL;

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
	    pPhyPort = pMgInfo->pPhyPort[i];

	    if(pPhyPort == NULL)
		    continue;

	    pConnect = mgc_phy_port_assign_idle_connection(pPhyPort);

	    if(pConnect == NULL)
		    continue;

	    return pConnect;		
    }

    return NULL;
}



/***************************************************************************
 * mgc_mg_info_find_idle_chnl_info
 * ------------------------------------------------------------------------
 * General:  find a idle chnl which is not attached by any connection in the specific MG_INFO object
 * Return Value: if failure return NUL , else return the pointer of the CHNL_INFO
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: pMgInfo -  the pointer of the MG_INFO
 ***************************************************************************/
CHNL_INFO *mgc_mg_info_find_idle_chnl_info(MG_INFO *pMgInfo)
{
    int i;
	PHY_PORT_INFO *pPhyPort = NULL;
	CHNL_INFO *pChnlInfo = NULL;

    if(pMgInfo == NULL)
        return NULL;

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        pPhyPort = pMgInfo->pPhyPort[i];

		if(pPhyPort == NULL)
		    continue;

        pChnlInfo = mgc_phy_port_find_idle_chnl(pPhyPort);
        if(pChnlInfo == NULL)
		    continue;	

		return pChnlInfo;
    }

    return NULL;
}


/***************************************************************************
 * mgc_mg_info_assign_aas_tone_connection
 * ------------------------------------------------------------------------
 * General:  assign a idle connection according to the Tone
 * Return Value: if failure return NUL , else return the pointer of the connection
 * ------------------------------------------------------------------------
 * Arguments:
 * Input: toneNo - tone id
 ***************************************************************************/
CONNECT_INFO *mgc_mg_info_assign_aas_tone_connection(BYTE toneNo)
{
    int i;
    MG_INFO *pMgInfo = NULL;
	CHNL_INFO *pChnlInfo = NULL;
	PHY_PORT_INFO *pPhyPort = NULL;
	CONNECT_INFO *pConnect = NULL;
	
    pMgInfo = mgc_mg_info_find_available_mg(MGC_MG_TYPE_ANN);
    if(pMgInfo == NULL)
	    return NULL;

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        pPhyPort = pMgInfo->pPhyPort[i];

		if(pPhyPort == NULL)
		    continue;

		if(pPhyPort->pMgcSap->usrType != MGC_USER_TYPE_MGC)
		    continue;
		
		break;
    }

    if(pPhyPort == NULL)
	    return NULL;

    pChnlInfo = mgc_chnl_info_find_chnl_of_phy(pPhyPort, toneNo);
	if(pChnlInfo == NULL)
	    return NULL;

	pConnect = mgc_chnl_info_assign_idle_connect(pChnlInfo);
	if(pConnect == NULL)
	    return NULL;

    MGC_DEBUG("aas phyPort[%d] assign chnl[%d] conn[%d] to send tone" , pPhyPort->id, toneNo, pConnect->id);
	return pConnect;	
}

void mgc_mg_info_set_mon(int id , BOOL enable )
{
    MG_INFO *pMgInfo = NULL;

    pMgInfo = mgc_mg_info_get_index_mg(id);
	if(pMgInfo == NULL)
	    return;

	pMgInfo->monFlag = enable;
}

BYTE *mgc_mg_info_get_res_addr(void)
{
    return (BYTE *)mgcMgInfo;
}


static char *mgc_mg_info_print_mg_type(MGC_MG_TYPE type)
{
    switch(type)
    {
        case MGC_MG_TYPE_INTERNAL:
			return "MGC_MG_TYPE_INTERNAL";
		case MGC_MG_TYPE_AudioCoder:
			return "MGC_MG_TYPE_AudioCoder";
		case MGC_MG_TYPE_LGC_MG:
			return "MGC_MG_TYPE_LGC_MG";
		case MGC_MG_TYPE_SSW_CSS:
			return "MGC_MG_TYPE_SSW_CSS";
		case MGC_MG_TYPE_IPBSS:
			return "MGC_MG_TYPE_IPBSS";
		case MGC_MG_TYPE_ANALOG:
			return "MGC_MG_TYPE_ANALOG";
		case MGC_MG_TYPE_TANDEM:
			return "MGC_MG_TYPE_TANDEM";
		case MGC_MG_TYPE_ANN:
			return "MGC_MG_TYPE_ANN";
		default:
			break;
    }

	return "MGC_MG_TYPE_UNDEF"; 
}


static char *mgc_mg_info_print_ip(DWORD addr)
{
	struct sockaddr_in sin;

	sin.sin_addr.s_addr = addr;
	return ((char *) inet_ntoa(sin.sin_addr) );
}


static char *mgc_mg_info_print_ctl_type(MGC_MG_CTRL_TYPE ctlType)
{
    switch(ctlType)
    {
        case MGC_MG_CTRL_TYPE_MGCP:
			return "MGC_MG_CTRL_TYPE_MGCP";
		case MGC_MG_CTRL_TYPE_8ECP:
			return "MGC_MG_CTRL_TYPE_8ECP";
		default:
			break;
    }

	return "MGC_MG_CTRL_TYPE_UNDEF";
}

static char *mgc_mg_info_print_codec_list(MGC_CODEC_LIST  codecList)
{
    int i;
    static char buf[256];

    memset(buf , 0 ,256);

	for(i=0 ; i<codecList.num ; i++)
	{
	    strcat(buf, mgc_mgcp_print_vc_codec(codecList.codec[i]));
		strcat(buf, " ");	
		if(strlen(buf) >= 255)
		    break;	
	}

	return buf;
}

void mgc_mg_info_print_info(MG_INFO *pMgInfo)
{
    MG_ATTR *pAttr;
    int i;
	PHY_PORT_INFO *pPhyPort;
	
    if(pMgInfo == NULL)
	    return;

    if(pMgInfo->created == FALSE)
    {
        MGC_INFO("mgInfo[%d] is not created! " , pMgInfo->id);
		return;
    }

    pAttr = &pMgInfo->mgAttr;

	MGC_INFO("--------mgInfo[%d] %s---------" , pMgInfo->id , pMgInfo->enable?"ENABLE":"DISABLE");
	MGC_INFO("Domain : %s" , pAttr->domain);
	MGC_INFO("Type : %s" , mgc_mg_info_print_mg_type(pAttr->mgType));
	MGC_INFO("Ip : %s" , mgc_mg_info_print_ip(pAttr->ip));
	MGC_INFO("CTL TYPE : %s" , mgc_mg_info_print_ctl_type(pAttr->ctrlType));
	if(pAttr->epDes == MGCP_EP_NAME_UNSTRUCTURED)
	{
	    MGC_INFO("epDes : MGCP_EP_NAME_UNSTRUCTURED");
	}
	else if(pAttr->epDes == MGCP_EP_NAME_STRUCTURED)
	{
	    MGC_INFO("epDes : MGCP_EP_NAME_STRUCTURED");	
	}
	else
	{
	    MGC_INFO("epDes : MGCP_EP_NAME_UNKNOWN");	
	}
	
	MGC_INFO("tonCap : %s" , (pAttr->toneCap == 1)?"ON":"OFF");
	MGC_INFO("ptime : %d" , pAttr->ptime);
	MGC_INFO("audit time : %ld" , pAttr->auditTimer);
	MGC_INFO("e1cardNo : %d" , pAttr->e1cardNo);
	MGC_INFO("maxPort : %d" , pAttr->maxPorts);
	MGC_INFO("maxChnl : %d" , pAttr->maxChnls);
	MGC_INFO("codelist len %d : %s" , pAttr->codecList.num , mgc_mg_info_print_codec_list(pAttr->codecList));

    for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
    {
        pPhyPort = pMgInfo->pPhyPort[i];

		if(pPhyPort ==  NULL)
		    continue;

        if(pPhyPort->portNo == ITL_OPERA_PORT_NO)
		    continue;
		
		mgc_phy_port_print(pPhyPort);
    }
	MGC_INFO("--------mgInfo[%d] end---------" , pMgInfo->id);
	return;
}



#ifdef MGC_TEST_ENABLE
int mgc_mg_info_created_num(void)
{
    int i , num;
	MG_INFO *pMgInfo = NULL;

    num = 0;
    for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
    {
        pMgInfo = &mgcMgInfo[i];

		if(pMgInfo->created)
		    num++;	
    }
    
	return num;
}

#endif
