/****************************************************************/
/*  MGC Implementation Program                                  */
/*  Version 9.0.1                                               */
/*  Designed By Ying Min                                        */
/*  Last Update: 2007-4-17                                      */
/****************************************************************/

#include "./include/mgc_pub.h"
#include "./include/mgc.h"
#include "./include/mgc_const.h"
#include "./include/mgc_def.h"
#include "./include/mgc_struct.h"
#include "./include/mgc_fsm.h"
#include "./include/mgc_debug.h"
#include "./include/mgc_sess_ctl.h"
#include "../../snmp/src/include/snmp.h"
#include "../../public/src/include/license_id.h"

int mgc_is_non_virtual_mg(BYTE mgType)
{
    if ((mgType > MGC_MG_TYPE_INTERNAL) && (mgType < MGC_MG_TYPE_ANN))
    {
        return 1;
    }
    else
    {
        return 0;
    }
    
}

int mgc_codec_to_payload(BYTE codec)
{
    if (codec== MGC_VCTYPE_GSM)
        return 3;
    else if (codec == MGC_VCTYPE_GSM_EFR)
        return 84;
    else if (codec == MGC_VCTYPE_AMR_12_2)
        return 71;
    else if (codec== MGC_VCTYPE_G729B)
        return 118;
    else if (codec== MGC_VCTYPE_PCMU)
        return 0;
    else if(codec == MGC_VCTYPE_AMR_10_2)
		return 70;
    else if(codec == MGC_VCTYPE_AMR_7_95)
		return 69;
    else if(codec == MGC_VCTYPE_AMR_7_4)
		return 68;
    else if(codec == MGC_VCTYPE_AMR_6_7)
		return 67;
    else if(codec == MGC_VCTYPE_AMR_5_15)
		return 65;
    else if(codec == MGC_VCTYPE_AMR_5_9)
		return 66;	
    else if(codec == MGC_VCTYPE_AMR_4_75)
		return 64;		
    return 8;
}

int mgc_8ecp_update_mg_status(BYTE mgNo, BYTE status)
{
    char    tmpStr[128];
    
    if (mgcMgInfo[mgNo].created == 0)
    {
        sprintf(tmpStr, "mgc_8ecp_update_mg_status: MG not created, mgNo = %d\n\r", mgNo);
        mgc_log_err(tmpStr);
        return -1;
    }
    
    mgcMgInfo[mgNo].stLast = status;
    
    if (1 == mgcMgInfo[mgNo].mgAttr.e1cardNo)
    {
       if ((1 == status) 
           && ((0 == mgc_e1card0_mgNo) || (0 == mgcMgInfo[mgc_e1card0_mgNo].stLast)))
       {
           mgc_8k_tone_card_silent = 1;
       }
       else
       {
           mgc_8k_tone_card_silent = 0;
       }     
    }
    else if (0 == mgcMgInfo[mgNo].mgAttr.e1cardNo)
    {
        if ((0 == status)  
            && (0 != mgc_e1card1_mgNo) && (1 == mgcMgInfo[mgc_e1card1_mgNo].stLast))
        {
            mgc_8k_tone_card_silent = 1;
        }
        else
        {
            mgc_8k_tone_card_silent = 0;
        }       
    }   
    
    return 0;
}

int mgc_8ecp_update_trk_status(BYTE mgNo, BYTE trkNo, BYTE status)
{
    WORD    portIndex;
    char    tmpStr[128];
    
    if (mgcMgInfo[mgNo].created == 0)
    {
        sprintf(tmpStr, "mgc_8ecp_update_trk_status: MG not created, mgNo = %d\n\r", mgNo);
        mgc_log_err(tmpStr);
        return -1;
    }
    
    if (trkNo >= MGC_8ECP_MAX_TRK_PER_MG)
    {
        sprintf(tmpStr, "mgc_8ecp_update_trk_status: invalid trkNo, trkNo = %d\n\r", trkNo);
        mgc_log_err(tmpStr);
        return -1;
    }
    
    portIndex = mgcMgInfo[mgNo].portIndex[trkNo];
    if (portIndex >= MGC_MAX_NUM_OF_PHY_PORT)
        return -1;
    
    mgcPhyPort[portIndex].stLast = status;
    
    return 0;
}

int mgc_bind_8ecp()
{
    sprintf(mgc8ecpSap.name, "MGC");
    mgc8ecpSap.update_mg_status = mgc_8ecp_update_mg_status;
    mgc8ecpSap.update_trk_status = mgc_8ecp_update_trk_status;
    
    if ((mgc8ecpSapIndex = _8ecp_bind(&mgc8ecpSap)) < 0)
        return -1;
    
    return 0;
}

int mgc_find_mg_by_name(char *mgName, WORD localPort, DWORD ip)
{
    WORD    i;
    char    tmpStr[128];
    BYTE    usrType;
    
    if (MGC_MG_NETWORK_PORT == localPort)
    {
        usrType = MGC_USER_TYPE_MG;
    }
    else
    {
        usrType = MGC_USER_TYPE_MGC;
    }
    
    for (i = 0; i < MGC_MAX_NUM_OF_MG; i++)
    {
        if (mgcMgInfo[i].created == 0)
            continue;
        
        if ((strcmp(mgcMgInfo[i].mgAttr.domain, mgName) == 0) 
            && (mgcMgInfo[i].usrType == usrType))
            return i;
    }
    
    sprintf(tmpStr, "mgc_find_mg_by_name: invalid mgName: %s, ip: %ld\n\r", mgName, ip);
    mgc_log_err(tmpStr);
        
    return -1;
}

int mgc_codec_str_to_api(char *codec)
{
    if (strcmp(codec, "PCMA") == 0)
        return MGC_VCTYPE_PCMA;
    else if (strcmp(codec, "PCMU") == 0)
        return MGC_VCTYPE_PCMU;
    else if (strcmp(codec, "GSM") == 0)
        return MGC_VCTYPE_GSM;
    else if (strcmp(codec, "GSM-EFR") == 0)
        return MGC_VCTYPE_GSM_EFR;
    else if (strcmp(codec, "AMR") == 0)
        return MGC_VCTYPE_AMR_12_2;
    else if (strcmp(codec, "G729B") == 0)
        return MGC_VCTYPE_G729B;                
    else if (strcmp(codec, "AMR_12_2") == 0)
        return MGC_VCTYPE_AMR_12_2;    	
    else if (strcmp(codec, "AMR_10_2") == 0)
        return MGC_VCTYPE_AMR_10_2;    	
    else if (strcmp(codec, "AMR_7_95") == 0)
        return MGC_VCTYPE_AMR_7_95;    	
    else if (strcmp(codec, "AMR_7_4") == 0)
        return MGC_VCTYPE_AMR_7_4;    	
    else if (strcmp(codec, "AMR_6_7") == 0)
        return MGC_VCTYPE_AMR_6_7;    	
    else if (strcmp(codec, "AMR_5_15") == 0)
        return MGC_VCTYPE_AMR_5_15;    	
    else if (strcmp(codec, "AMR_5_9") == 0)
        return MGC_VCTYPE_AMR_5_9;    	
    else if (strcmp(codec, "AMR_4_75") == 0)
        return MGC_VCTYPE_AMR_4_75;    		
        
    return MGC_VCTYPE_PCMA;
}

void mgc_connect_init(WORD connectIndex)
{
    memset((BYTE *) &mgcConnectInfo[connectIndex], 0, sizeof(CONNECT_INFO));
    mgcConnectInfo[connectIndex].port = 0xFFFF;
    mgcConnectInfo[connectIndex].chlIndex = 0xFFFF;
    mgcConnectInfo[connectIndex].aasChnl.mgNo = 0xFFFF;
    mgcConnectInfo[connectIndex].aasChnl.portNo = 0xFF;
    mgcConnectInfo[connectIndex].aasChnl.chlNo = 0xFFFF;
    mgcConnectInfo[connectIndex].aasChnl.connectNo = 0xFFFF;
}

int mgc_assign_connect_to_chnl(CHNL chnl)
{
    WORD        portIndex;
    WORD        chnlIndex;
    WORD        connectIndex = mgc_select_connection;
    CHNL_INFO   *chnlInfo;    
    int         i;

    if (connectIndex >= MGC_MAX_NUM_OF_CON)
    {
        mgc_log_err("mgc_select_connection may be changed\n\r");

        connectIndex = 0;
    }

    for (i = 0; i < MGC_MAX_NUM_OF_CON; i++)
    {
        if (1 == mgcConnectInfo[connectIndex].assigned)
        {
            if (++connectIndex >= MGC_MAX_NUM_OF_CON)
            {
                connectIndex = 0;
            }

            continue;
        }
        else
        {
            mgc_connect_init(connectIndex);
            
            if ((MGC_MG_TYPE_ANN == mgcMgInfo[chnl.mgNo].mgAttr.mgType) 
                || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[chnl.mgNo].mgAttr.mgType))
            {
                chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
            }//add by Francis   
            else
            {       
                portIndex = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
                
                if (portIndex >= MGC_MAX_NUM_OF_PHY_PORT)
                {
                    mgc_log_err("mgc_assign_connect_to_chnl: phy portIndex out of range!\n\r");
                    return -1;                      
                }
                
                chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + chnl.chlNo;
            }
            
            if (chnlIndex >= MGC_MAX_NUM_OF_CHNL)
            {
                mgc_log_err("mgc_assign_connect_to_chnl: chnlIndex out of range!\n\r");
                return -1;              
            }
            
            chnlInfo = &mgcChnl[chnlIndex];
            
            if ((chnlInfo->connectIndex[chnl.connectNo] >= MGC_MAX_NUM_OF_CON)
                 || (mgcConnectInfo[chnlInfo->connectIndex[chnl.connectNo]].assigned != 1))
            {
                chnlInfo->connectIndex[chnl.connectNo] = connectIndex;
                
                mgcConnectInfo[connectIndex].assigned = 1;
                mgcConnectInfo[connectIndex].status = MGC_CONNECT_STATUS_IDLE;
                mgcConnectInfo[connectIndex].chlIndex = chnlIndex;            

                mgc_select_connection = connectIndex + 1;

                if (mgc_select_connection >= MGC_MAX_NUM_OF_CON)
                {
                    mgc_select_connection = 0;
                }

                return connectIndex;
            }
            else
            {
                if ((chnlInfo->connectIndex[chnl.connectNo] < MGC_MAX_NUM_OF_CON) 
                    && (mgcConnectInfo[chnlInfo->connectIndex[chnl.connectNo]].assigned == 1))
                {
                    mgc_log_err("mgc_assign_connect_to_chnl: one connect already created on chnl's connectNo\n\r");
                    return chnlInfo->connectIndex[chnl.connectNo];
                }
                
                return -1;            
            }          
        }
    }
    
    mgc_log_err("mgc_assign_connect_to_chnl: connect resource is not sufficient\n\r");
    return -1;    
}

int mgc_assign_connect(CHNL *chnl, WORD *chnlConnectIndex)
{
    WORD        portIndex;
    WORD        chnlIndex;
    CHNL_INFO   *chnlInfo;
    WORD        connectIndex = mgc_select_connection;
    int         i;
    int         j;

    if (connectIndex >= MGC_MAX_NUM_OF_CON)
    {
        mgc_log_err("mgc_select_connection may be changed\n\r");

        connectIndex = 0;
    }

    for (i = 0; i < MGC_MAX_NUM_OF_CON; i++)
    {
        if (1 == mgcConnectInfo[connectIndex].assigned)
        {
            if (++connectIndex >= MGC_MAX_NUM_OF_CON)
            {
                connectIndex = 0;
            }

            continue;
        }
        else
        {
            mgc_connect_init(connectIndex);
            
            if (MGC_MG_TYPE_ANN == mgcMgInfo[chnl->mgNo].mgAttr.mgType)
            {
                chnlIndex = mgcMgInfo[chnl->mgNo].chnlStartIndex + chnl->chlNo;
            }//add by Francis   
            else
            {       
                portIndex = mgcMgInfo[chnl->mgNo].portIndex[chnl->portNo];
                
                if (portIndex >= MGC_MAX_NUM_OF_PHY_PORT)
                {
                    mgc_log_err("mgc_assign_connect: phy portIndex out of range!\n\r");
                    return -1;                      
                }               
                
                chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + chnl->chlNo;
            }
            
            if (chnlIndex >= MGC_MAX_NUM_OF_CHNL)
            {
                mgc_log_err("mgc_assign_connect: chnlIndex out of range!\n\r");
                return -1;              
            }           
            
            chnlInfo = &mgcChnl[chnlIndex];
            
            for (j = 0; j < MGC_MAX_NUM_OF_CHNL_CON; j++)
            {
                if ((chnlInfo->connectIndex[j] < MGC_MAX_NUM_OF_CON)
                    && (mgcConnectInfo[chnlInfo->connectIndex[j]].assigned == 1))
                {
                    continue;
                }
                else
                {
                    chnlInfo->connectIndex[j] = connectIndex;
                    *chnlConnectIndex = j;
                    chnl->connectNo = j;

                    mgcConnectInfo[connectIndex].assigned = 1;
                    mgcConnectInfo[connectIndex].status = MGC_CONNECT_STATUS_IDLE;
                    mgcConnectInfo[connectIndex].chlIndex = chnlIndex;

                    mgc_select_connection = connectIndex + 1;

                    if (mgc_select_connection >= MGC_MAX_NUM_OF_CON)
                    {
                        mgc_select_connection = 0;
                    }

                    return connectIndex;
                }
            }
    
            mgc_log_err("mgc_assign_connect: chnl connect resource is not sufficient\n\r");
            return -1;            
        }
    }
    
    mgc_log_err("mgc_assign_connect: connect resource is not sufficient\n\r");
    return -1;
}

void mgc_remove_connect(WORD chnl)
{
    int    i;
    
    for (i = 0; i < MGC_MAX_NUM_OF_CON; i++)
    {
        if ((mgcConnectInfo[i].assigned != 1)
            || (mgcConnectInfo[i].chlIndex != chnl))
        {
            continue;
        }
        else
        {
            mgc_connect_init(i);
        }
    }
}

int mgc_release_connect(CHNL *chnl)
{
    WORD        portIndex;
    WORD        chnlIndex;
    WORD        connectIndex;
    CHNL_INFO   *chnlInfo; 
    
    if (MGC_MG_TYPE_ANN == mgcMgInfo[chnl->mgNo].mgAttr.mgType)
    {
        chnlIndex = mgcMgInfo[chnl->mgNo].chnlStartIndex + chnl->chlNo;
        chnlInfo = &mgcChnl[chnlIndex];
    }//add by Francis   
    else
    {       
        portIndex = mgcMgInfo[chnl->mgNo].portIndex[chnl->portNo];
        chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + chnl->chlNo;
        chnlInfo = &mgcChnl[chnlIndex];
    }
    

    if (((connectIndex = chnlInfo->connectIndex[chnl->connectNo]) >= MGC_MAX_NUM_OF_CON)
         || (mgcConnectInfo[connectIndex].chlIndex != chnlIndex))
    {
        mgc_log_err("mgc_release_connect: the chnl connectNo has no connection\n\r");       
        return -1;
    }
    else
    {
        mgc_connect_init(connectIndex);
        
        if (chnlInfo->connectNum > 0)
        {
            chnlInfo->connectNum--;
        }
        else
        {
            chnlInfo->connectNum = 0;
        }           
    }
    
    return 0;
}

int mgc_find_connect_by_con_id(CHNL *Chnl, char *conId)
{
    int         i;
    WORD        portIndex;
    WORD        chnlIndex;
    CHNL_INFO   *chnlInfo;    
    WORD      chnlConnectIndex;
    WORD        connectIndex;
    
    if (MGC_MG_TYPE_ANN == mgcMgInfo[Chnl->mgNo].mgAttr.mgType)
    {
        chnlIndex = mgcMgInfo[Chnl->mgNo].chnlStartIndex + Chnl->chlNo;
    }//add by Francis   
    else
    {       
        portIndex = mgcMgInfo[Chnl->mgNo].portIndex[Chnl->portNo];
      
        if (portIndex >= MGC_MAX_NUM_OF_PHY_PORT)
        {
            mgc_log_err("mgc_find_connect_by_con_id: portIndex out of range!\r\n");     
            return -1;
        }
        
        chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + Chnl->chlNo;
    }    
    
    if (chnlIndex >= MGC_MAX_NUM_OF_CHNL)
    {
        mgc_log_err("mgc_find_connect_by_con_id: chnlIndex out of range!\r\n");     
        return -1;      
    }
    
    chnlInfo = &mgcChnl[chnlIndex];

    if (mgcMgInfo[Chnl->mgNo].usrType == MGC_USER_TYPE_MG)
    {
        chnlConnectIndex = strtoll(conId, NULL, 16) >> 48;

        if ((chnlConnectIndex >= MGC_MAX_NUM_OF_CHNL_CON)
            || (chnlInfo->connectIndex[chnlConnectIndex] >= MGC_MAX_NUM_OF_CON) 
            || (strcmp(conId, mgcConnectInfo[chnlInfo->connectIndex[chnlConnectIndex]].mediaAttr.conId) != 0))
            return -1;
        else
            return chnlConnectIndex;
    }
    else if (mgcMgInfo[Chnl->mgNo].usrType == MGC_USER_TYPE_MGC)
    {
        for (i = 0; i < MGC_MAX_NUM_OF_CHNL_CON; i++)
        {
            if ((connectIndex = chnlInfo->connectIndex[i]) >= MGC_MAX_NUM_OF_CON)
            {
                continue;
            }
            else
            {
                if ((0 == strcmp(conId, mgcConnectInfo[connectIndex].mediaAttr.conId))
                     && (chnlIndex == mgcConnectInfo[connectIndex].chlIndex))
                {
                   return i;
                }
            }
        }
        
        return -1;
    }
    else
        return -1;
}


int mgc_extract_media_info(BYTE flag, BYTE cmd, MGCP_PARA *para, WORD port)//new replace
//int mgc_extract_media_info(BYTE flag, MGCP_PARA *para, CHNL *mgcfChnl)
{
    WORD        portIndex;
    WORD        chnlIndex;
    CHNL_INFO   *chnlInfo;
    CHNL      *mgcfChnl;
    int       connectIndex;
    int      chnlConnectIndex;//new replace
    PORT_INFO *portInfo;
    
    portInfo = &mgcPort[port];
    mgcfChnl = &portInfo->mgcfChnl;//new replace
    
    if (((MGC_MG_TYPE_ANN != mgcMgInfo[mgcfChnl->mgNo].mgAttr.mgType) && (mgcfChnl->portNo >= MGC_MAX_PHY_PORT_PER_MG)) 
        || (mgcfChnl->chlNo >= MGC_MAX_NUM_OF_CHNL))
        return 0;

    
    if ((MGC_MG_TYPE_ANN == mgcMgInfo[mgcfChnl->mgNo].mgAttr.mgType) 
        || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[mgcfChnl->mgNo].mgAttr.mgType))
    {
        chnlIndex = mgcMgInfo[mgcfChnl->mgNo].chnlStartIndex + mgcfChnl->chlNo;
    }//add by Francis   
    else
    {       
        portIndex = mgcMgInfo[mgcfChnl->mgNo].portIndex[mgcfChnl->portNo];
        
        if (portIndex >= MGC_MAX_NUM_OF_PHY_PORT)
        {
            mgc_log_err("mgc_extract_media_info: phy portIndex out of range!\n\r");
            return -1;                      
        }
        
        chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + mgcfChnl->chlNo;
    }

    if (chnlIndex >= MGC_MAX_NUM_OF_CHNL)
    {
        mgc_log_err("mgc_extract_media_info: chnlIndex out of range!\n\r");
        return -1;              
    } 
    
    chnlInfo = &mgcChnl[chnlIndex];

    if (flag == MGCP_RESPONSE)
    {
        if ((MGC_MG_TYPE_ANN != mgcMgInfo[mgcfChnl->mgNo].mgAttr.mgType) && (MGCP_CMD_CRCX == cmd) 
             && (((para->flag & MGCP_PARA_FLAG_I) != MGCP_PARA_FLAG_I) || ((para->flag & MGCP_PARA_FLAG_SDP) != MGCP_PARA_FLAG_SDP)))
        {
            mgc_log_err("mgc_extract_media_info: crcx response miss para!!\n\r");
            return -4;               
        }

        if (mgcfChnl->connectNo != mgcPort[port].mgcfOperSteps[mgcPort[port].mgcfOperStepIndex].chnlConnectIndex)
        {
            mgc_log_err("mgc_extract_media_info: connectNo is mismatch!\n\r");
            return -1;      
        }       
        
        if((MGCP_CMD_AUEP != cmd) && (MGCP_CMD_RQNT != cmd) && (MGCP_CMD_RSIP != cmd))
        {
            connectIndex = chnlInfo->connectIndex[mgcPort[port].mgcfOperSteps[mgcPort[port].mgcfOperStepIndex].chnlConnectIndex];
        }

        if (connectIndex >= MGC_MAX_NUM_OF_CON)
        {
            mgc_log_err("mgc_extract_media_info: chnl's connection released\n\r");
            return -1;          
        }
        
        if ((para->flag & MGCP_PARA_FLAG_I) == MGCP_PARA_FLAG_I)
        {
            strcpy(mgcConnectInfo[connectIndex].mediaAttr.conId, para->i.conId);
        }
        
        if ((para->flag & MGCP_PARA_FLAG_O) == MGCP_PARA_FLAG_O)
        {
            chnlInfo->comMediaAttr.pkgEvent = (para->o.package << 8) | para->o.event;
            
            if ((MGCP_CMD_AUEP != cmd) && (MGCP_CMD_RQNT != cmd))
                mgcConnectInfo[connectIndex].mediaAttr.pkgEvent = (para->o.package << 8) | para->o.event;
        }
    }
    else
    {
        if (MGCP_CMD_CRCX == cmd)
        {
            if ((MGC_MG_TYPE_ANN == mgcMgInfo[mgcfChnl->mgNo].mgAttr.mgType) && ((para->flag & MGCP_PARA_FLAG_SDP) != MGCP_PARA_FLAG_SDP))
            {
                mgc_log_err("mgc_extract_media_info: crcx command miss sdp!!\n\r");
                return -2;               
            }

            if ((connectIndex = mgc_assign_connect(mgcfChnl, &mgcPort[port].mgcfOperSteps[0].chnlConnectIndex)) < 0)
            {
                mgc_log_err("mgc_extract_media_info: assign connect failed\n\r");
                return -3;          
            }
            
            mgcPort[port].mgcfOperStepsNum = 1;
        }
        else if ((MGCP_CMD_MDCX == cmd) || (MGCP_CMD_DLCX == cmd))
        {
            if ((chnlConnectIndex = mgc_find_connect_by_con_id(mgcfChnl, para->i.conId)) < 0)
            {
                mgc_log_err("mgc_extract_media_info: find connect by id failed\n\r");
                return -1;              
            }
            
            mgcfChnl->connectNo = chnlConnectIndex;
            
            connectIndex = chnlInfo->connectIndex[chnlConnectIndex];
        }
		else if((MGCP_CMD_NTFY == cmd)&&((para->flag & MGCP_PARA_FLAG_O) == MGCP_PARA_FLAG_O))
		{
             chnlInfo->comMediaAttr.pkgEvent = (para->o.package << 8) | para->o.event;
			 return 0;
		}
/*      else
        {
            if (0xFFFF == (connectIndex = chnlInfo->connectIndex[0]))
            {
                mgc_log_err("mgc_extract_media_info: chnl's 0 connection released\n\r");
                return -1;
            }
        }
*/          
        if (connectIndex >= MGC_MAX_NUM_OF_CON)
        {
            mgc_log_err("mgc_extract_media_info: chnl's connection released\n\r");
            return -1;          
        } 
            
        if ((para->flag & MGCP_PARA_FLAG_L) == MGCP_PARA_FLAG_L)
        {
            mgcConnectInfo[connectIndex].mediaAttr.ecDisable = para->l.ecDisable;
            mgcConnectInfo[connectIndex].mediaAttr.ssDisable = para->l.ssDisable;
            mgcConnectInfo[connectIndex].mediaAttr.ptime = para->l.p;
            mgcConnectInfo[connectIndex].mediaAttr.vocoderType = mgc_codec_str_to_api(para->l.codec);
        }
        
        if ((para->flag & MGCP_PARA_FLAG_M) == MGCP_PARA_FLAG_M)
            mgcConnectInfo[connectIndex].mediaAttr.conMode = para->m.mode;
        
        if ((para->flag & MGCP_PARA_FLAG_C) == MGCP_PARA_FLAG_C)
            strcpy(mgcConnectInfo[connectIndex].mediaAttr.callId, para->c.callId);
        
        if ((para->flag & MGCP_PARA_FLAG_O) == MGCP_PARA_FLAG_O)
        {
            chnlInfo->comMediaAttr.pkgEvent = (para->o.package << 8) | para->o.event;
            mgcConnectInfo[connectIndex].mediaAttr.pkgEvent = (para->o.package << 8) | para->o.event;
        }
        
        if ((para->flag & MGCP_PARA_FLAG_S) == MGCP_PARA_FLAG_S)
        {
            chnlInfo->comMediaAttr.pkgSignal = (para->s.pkg << 8) | para->s.signal;
            mgcConnectInfo[connectIndex].mediaAttr.pkgSignal = (para->s.pkg << 8) | para->s.signal;
        }
    }           
    
    if ((para->flag & MGCP_PARA_FLAG_SDP) == MGCP_PARA_FLAG_SDP)
    {
        if (flag == MGCP_RESPONSE) 
        {
            if ((portInfo->mgcfOperSteps[portInfo->mgcfOperStepIndex].flag & MGCP_PARA_FLAG_TFO) == MGCP_PARA_FLAG_TFO)
            {
                mgcConnectInfo[connectIndex].flag |= MGCP_PARA_FLAG_TFO;
                memcpy(para->sdp.medias.medias, mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias, sizeof(PUB_SDP_MEDIA) * 8);
            }
            else
            {
                mgcConnectInfo[connectIndex].flag &= ~MGCP_PARA_FLAG_TFO;
            }
        }
/*
        if (mgcMgInfo[mgcfChnl->mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN)
        {
            num = para->sdp.medias.medias[0].m.plNum;
            for (i = 0; i < mgcMgInfo[mgcfChnl->mgNo].mgAttr.codecList.num; i++)
            {
                para->sdp.medias.medias[0].m.payloads[num + i] = mgc_codec_to_payload(mgcMgInfo[mgcfChnl->mgNo].mgAttr.codecList.codec[i]);
                para->sdp.medias.medias[0].m.plNum++;

                if (para->sdp.medias.medias[0].m.plNum >= 8)
                    break;
            }
        }*/

        //memcpy((BYTE *) &chnlInfo->mediaAttr.sdp, (BYTE *) &para->sdp, sizeof(PUB_SDP_MSG));
        memcpy((BYTE *) &mgcConnectInfo[connectIndex].mediaAttr.sdp, (BYTE *) &para->sdp, sizeof(PUB_SDP_MSG));
    }
    
    if ((MGCP_CMD_AUEP != cmd) && (MGCP_CMD_RQNT != cmd))
    {   
        if ((mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].flag & PUB_SDP_FLAG_C) != PUB_SDP_FLAG_C)
        //if ((chnlInfo->mediaAttr.sdp.medias.medias[0].flag & PUB_SDP_FLAG_C) != PUB_SDP_FLAG_C)
        {
            //memcpy(&chnlInfo->mediaAttr.sdp.medias.medias[0].c, &chnlInfo->mediaAttr.sdp.c, sizeof(PUB_SDP_C));
            //chnlInfo->mediaAttr.sdp.medias.medias[0].flag |= PUB_SDP_FLAG_C;
            memcpy(&mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].c, &mgcConnectInfo[connectIndex].mediaAttr.sdp.c, sizeof(PUB_SDP_C));
            mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].flag |= PUB_SDP_FLAG_C;
        }       
/*    
        num = mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].attrs.num;
        //num = chnlInfo->mediaAttr.sdp.medias.medias[0].attrs.num;
        if (num < PUB_SDP_MAX_ATTR_NUM)
        {
            //chnlInfo->mediaAttr.sdp.medias.medias[0].attrs.attrs[num].aType = PUB_SDP_ATTR_TYPE_PTIME;
            //sprintf(chnlInfo->mediaAttr.sdp.medias.medias[0].attrs.attrs[num].aValue, "%d", chnlInfo->mediaAttr.ptime);
            //chnlInfo->mediaAttr.sdp.medias.medias[0].attrs.num++;
            mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].attrs.attrs[num].aType = PUB_SDP_ATTR_TYPE_PTIME;
            sprintf(mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].attrs.attrs[num].aValue, "%d", mgcConnectInfo[connectIndex].mediaAttr.ptime);
            mgcConnectInfo[connectIndex].mediaAttr.sdp.medias.medias[0].attrs.num++;
        }*/
    }
    
    return 0;
}

void mgc_port_init(WORD port)
{
    memset((BYTE *) &mgcPort[port], 0, sizeof(PORT_INFO));
}

int mgc_get_port()
{
    WORD    i;
    WORD    port = mgcSelectPort;

    if (port >= MGC_MAX_NUM_OF_PORT)
    {
        mgc_log_err("mgcSelectPort may be changed\n\r");

        port = 0;
    }

    for (i = 0; i < MGC_MAX_NUM_OF_PORT; i++)
    {
        if (mgcPort[port].assigned != 0)
        {
            if (++port >= MGC_MAX_NUM_OF_PORT)
            {
                port = 0;
            }
            continue;
        }
        
        mgcPort[port].assigned = 1;

        mgcSelectPort = port + 1;
        if (mgcSelectPort >= MGC_MAX_NUM_OF_PORT)
        {
            mgcSelectPort = 0;
        }
        return port;
    }
    
    return -1;
}

int mgc_mgcp_ind(BYTE cmd, WORD *usrPort, WORD hdlPort, MGCP_PARA *para)
{
    int         ret;
    int         port;
    int         mgNo;
    PORT_INFO   *portInfo;
    MGCP_SL     *sl;
    WORD        portIndex = 0xFFFF, chnlIndex = 0xFFFF;
    char        tmpStr[128];
    MG_ATTR     *mgAttr;
    WORD        associPort;
    
    if (para == NULL)
    {
        mgc_log_err("mgc_mgcp_ind: para is NULL\n\r");
        return -1;
    }
    
    if ((para->flag & MGCP_PARA_FLAG_SL) != MGCP_PARA_FLAG_SL)
    {
        mgc_log_err("mgc_mgcp_ind: missing start line\n\r");
        return -1;
    }
    
    sl = &para->sl;
    if ((mgNo = mgc_find_mg_by_name(sl->mgName, para->localPort, para->ip)) < 0)
    {
        mgc_log_err("mgc_mgcp_ind: can't find the mgName\n\r");
        return -1;
    }
    
    if ((mgcMgInfo[mgNo].portIndex[sl->trkNum] >= MGC_MAX_NUM_OF_PHY_PORT)
        && (cmd == MGCP_CMD_RSIP))
    {
        mgcMgcpPara.ip = mgcMgInfo[mgNo].mgAttr.ip;
        
        if (mgcMgInfo[mgNo].usrType == MGC_USER_TYPE_MGC)
        {
            mgcMgcpPara.localPort = MGC_MGCP_MGC_PORT;
            mgcMgcpPara.peerPort = MGC_MGCP_MG_PORT;
        }
        else
        {
            mgcMgcpPara.localPort = MGC_MGCP_MG_PORT;
            mgcMgcpPara.peerPort = MGC_MGCP_MGC_PORT;
        }
        mgcMgcpPara.flag = 0;
    
        mgcMgcpPara.sl.cmdRes = MGCP_RESPONSE;
        
        mgcMgcpPara.flag |= MGCP_PARA_FLAG_SL;      
        
        MGCP_rsp(mgcMgcpSapIndex, cmd, 0xFFFF, hdlPort, 200, &mgcMgcpPara);
        return 0;       
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_mgcp_ind: can't allocate port\n\r");
        return -1;
    }
    
    mgAttr = &mgcMgInfo[mgNo].mgAttr;
    
    portInfo = &mgcPort[port];
    portInfo->mgcfState = MGC_MGCF_STATE_INDICATION;
    portInfo->llPort = hdlPort;
    portInfo->llCmd = cmd;
    
    if (mgcMgInfo[mgNo].usrType == MGC_USER_TYPE_MG)
        portInfo->ip = para->ip;
    
    portInfo->mgcfChnl.mgNo = mgNo;
    portInfo->mgcfChnl.portNo = sl->trkNum;
    portInfo->mgcfChnl.chlNo = sl->chlNum;
    
    if ((MGCP_CMD_CRCX == cmd) || (MGCP_CMD_MDCX == cmd) || (MGCP_CMD_DLCX == cmd)||(MGCP_CMD_NTFY == cmd))
    {       
        if ((ret = mgc_extract_media_info(MGCP_COMMAND, cmd, para, port)) < 0)
        {
            if (ret == -2)
            {
                mgc_log_err("mgc_mgcp_ind: crcx command to aas miss sdp!\n\r");
                mgc_port_init(port);
                return -1;
            }
            else if (ret == -3)
            {
                mgc_log_err("mgc_mgcp_ind: aas mg no connection resource!\n\r");
                mgc_port_init(port);
                return -1;
            }
            else
            {
                mgc_log_err("mgc_mgcp_ind: extract media info failed!\n\r");
                mgc_port_init(port);
                return -1;
            }
        }
    }
    
    *usrPort = port;
    
    if (sl->trkNum < MGC_MAX_PHY_PORT_PER_MG)
    {
        portIndex = mgcMgInfo[mgNo].portIndex[sl->trkNum];
        if ((portIndex < MGC_MAX_NUM_OF_PHY_PORT) && 
            (sl->chlNum < mgcPhyPort[portIndex].chnlNum))
            chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + sl->chlNum;
    }
    else
    {
        chnlIndex = mgcMgInfo[mgNo].chnlStartIndex + sl->chlNum;
    }
    
    sprintf(tmpStr, "mgc_mgcp_ind: succeed, cmd = %d, usrPort = %d, hdlPort = %d, mgNo: %d, portNo: %d, chlNo: %d\n\r",
                    cmd, port, hdlPort, portInfo->mgcfChnl.mgNo, portInfo->mgcfChnl.portNo, portInfo->mgcfChnl.chlNo);
    mgc_log_procedure(mgNo, portIndex, chnlIndex, tmpStr);      
    
    if ((mgcMgInfo[mgNo].usrType == MGC_USER_TYPE_MGC) 
        && (cmd != MGCP_CMD_RSIP) && (cmd != MGCP_CMD_NTFY))
    {
        if ((portInfo->mgcfChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON) 
            || (mgcChnl[chnlIndex].connectIndex[portInfo->mgcfChnl.connectNo] >= MGC_MAX_NUM_OF_CON))
        {
            mgc_log_err("mgc_mgcp_ind: connectNo >= MGC_MAX_NUM_OF_CHNL_CON\n\r");
            mgc_port_init(port);
            return -1;
        }
        
        associPort = mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[portInfo->mgcfChnl.connectNo]].port;

        if ((associPort < MGC_MAX_NUM_OF_PORT) 
            && (mgcPort[associPort].assigned != 0))
        {
            mgcPort[associPort].mngCmd = MGC_MNG_CMD_CLEAR_AFTER_OPER;
            mgc_log_err("mgc_mgcp_ind:  DLCX recved from MG, Chnl clear remain connection operation !\n\r");
            
            mgcMgcpPara.ip = mgcMgInfo[mgNo].mgAttr.ip;
        
            mgcMgcpPara.localPort = MGC_MGCP_MGC_PORT;
            mgcMgcpPara.peerPort = MGC_MGCP_MG_PORT;

            mgcMgcpPara.flag = 0;
    
            mgcMgcpPara.sl.cmdRes = MGCP_RESPONSE;
        
            mgcMgcpPara.flag |= MGCP_PARA_FLAG_SL;
            
            MGCP_rsp(mgcMgcpSapIndex, cmd, port, hdlPort, 250, &mgcMgcpPara);
            
//            mgc_connect_init(mgcChnl[chnlIndex].connectIndex[portInfo->mgcfChnl.connectNo]);
            mgc_port_init(port);
        }
    }
    
    return 0;
}

int mgc_mgcp_cnf(BYTE cmd, WORD usrPort, WORD hdlPort, WORD retCode, MGCP_PARA *para)
{
    char    tmpStr[128];
    
    if (usrPort >= MGC_MAX_NUM_OF_PORT)
    {
        sprintf(tmpStr, "mgc_mgcp_cnf, invalid usrPort = %d, hdlPort = %d, cmd = %d, retCode = %d\n\r", usrPort, hdlPort, cmd, retCode);
        mgc_log_err(tmpStr);
        return -1;
    }
    
    if (mgcPort[usrPort].llPort != hdlPort)
    {
        sprintf(tmpStr, "mgc_mgcp_cnf, mismatched llport = %d, hdlPort = %d, cmd = %d, retCode = %d\n\r", mgcPort[usrPort].llPort, hdlPort, cmd, retCode);
        mgc_log_err(tmpStr);
        return -1;
    }
    
    if (mgcPort[usrPort].mgcfOperSteps[mgcPort[usrPort].mgcfOperStepIndex].cmd != cmd)
    {
        sprintf(tmpStr, "mgc_mgcp_cnf, mismatched cmd = %d, hdlPort = %d, cmd = %d, retCode = %d\n\r", 
            mgcPort[usrPort].mgcfOperSteps[mgcPort[usrPort].mgcfOperStepIndex].cmd, hdlPort, cmd, retCode);
        mgc_log_err(tmpStr);
        return -1;
    }
    
    if (((MGCP_CMD_CRCX == cmd) && (retCode == 200)) || (MGCP_CMD_MDCX == cmd))
    {
	
//      mgc_extract_media_info(MGCP_RESPONSE, para, &mgcPort[usrPort].mgcfChnl);
         if (mgc_extract_media_info(MGCP_RESPONSE, cmd, para, usrPort) < 0)//new replace
         {
             sprintf(tmpStr, "mgc_mgcp_cnf: extract_media fail cmd = %d, hdlPort = %d, retCode = %d\n\r", cmd, hdlPort, retCode);
             mgc_log_err(tmpStr);
             return -1;
         }
    }

    mgcPort[usrPort].llCmd = retCode;
    
    return 0;
}

int mgc_bind_mgcp()
{
    sprintf(mgcMgcpSap.name, "MGC");
    mgcMgcpSap.MGCP_ind = mgc_mgcp_ind;
    mgcMgcpSap.MGCP_cnf = mgc_mgcp_cnf;
    
    if ((mgcMgcpSapIndex = mgcp_bind(&mgcMgcpSap)) < 0)
        return -1;
    
    return 0;
}

void mgc_chnl_init(WORD chnl)
{
    memset((BYTE *) &mgcChnl[chnl], 0, sizeof(CHNL_INFO));
    memset((BYTE *) mgcChnl[chnl].connectIndex, 0xFFFF, sizeof(WORD)*MGC_MAX_NUM_OF_CHNL_CON);//new replace
    mgcChnl[chnl].port = 0xFFFF;
    mgcChnl[chnl].sapIndex = 0xFF;
}

int mgc_vc_name_init()
{
    strcpy(vcName[MGC_VCTYPE_PCMA], "PCMA");
    strcpy(vcName[MGC_VCTYPE_PCMU], "PCMU");
    strcpy(vcName[MGC_VCTYPE_GSM], "GSM");
    strcpy(vcName[MGC_VCTYPE_GSM_EFR], "GSM-EFR");
    strcpy(vcName[MGC_VCTYPE_AMR_12_2], "AMR_12_2");
    strcpy(vcName[MGC_VCTYPE_G729B], "G729B");
    strcpy(vcName[MGC_VCTYPE_AMR_10_2], "AMR_10_2");
    strcpy(vcName[MGC_VCTYPE_AMR_7_95], "AMR_7_95");
    strcpy(vcName[MGC_VCTYPE_AMR_7_4],  "AMR_7_4");
    strcpy(vcName[MGC_VCTYPE_AMR_6_7],  "AMR_6_7");
    strcpy(vcName[MGC_VCTYPE_AMR_5_15], "AMR_5_15");	
    strcpy(vcName[MGC_VCTYPE_AMR_5_9], "AMR_5_9");
    strcpy(vcName[MGC_VCTYPE_AMR_4_75], "AMR_4_75");
    return 0;
}

int mgc_get_non_virtual_trk_status(WORD mgNo)
{
    struct snmp_pdu     mgcSnmpPdu;
    struct snmp_addr    mgcSnmpAddr;
    struct var_list     *mgcVarList;
    BYTE                i, j = 0;
    MG_INFO             *mgInfo;
    
    mgInfo = &mgcMgInfo[mgNo];
    mgcVarList = &mgcSnmpPdu.var[0];
    mgcSnmpPdu.var_num = 0;             //val list number
    
    if (MGC_MG_TYPE_AudioCoder == mgInfo->mgAttr.mgType)
    {
        for (i = 0; i < MGC_MAX_PHY_PORT_PER_MG; i++)
        {
            if (mgInfo->portIndex[i] != 0xFFFF)
            {
                mgcVarList[j].oidlen = MGC_AC_LINE_STATUS_IDLEN;
                MGC_AC_LINE_STATUS_OID[MGC_AC_LINE_STATUS_IDLEN - 1] = i;
                memcpy(&mgcVarList[mgcSnmpPdu.var_num].oid[0], MGC_AC_LINE_STATUS_OID, MGC_AC_LINE_STATUS_IDLEN*4);
                mgcVarList[mgcSnmpPdu.var_num].vartype = 0x04;//octet string
                mgcVarList[mgcSnmpPdu.var_num].msglen = 0;
                mgcSnmpPdu.var_num++;
                j++;
            }
        }
    }
    else if (MGC_MG_TYPE_LGC_MG == mgInfo->mgAttr.mgType)
    {
        mgcVarList[0].oidlen = MGC_LGC_MG_STATUS_IDLEN;
        memcpy(&mgcVarList[mgcSnmpPdu.var_num].oid[0], MGC_LGC_MG_STATUS_OID, MGC_LGC_MG_STATUS_IDLEN*4);
        mgcVarList[mgcSnmpPdu.var_num].vartype = 0x04;//octet string
        mgcVarList[mgcSnmpPdu.var_num].msglen = 0;
        mgcSnmpPdu.var_num++;       
    }//revise by Francis 0822
    
    mgInfo->requestId = (++mgInfo->requestId) & 0xFFFF;
    if (mgInfo->requestId == 0)
        mgInfo->requestId = 1;
    
    mgcSnmpPdu.pdu_type = 0x00; //get
    mgcSnmpPdu.request_id = (mgNo << 16) | mgInfo->requestId;
    
    mgcSnmpAddr.local_port = 4968;
    mgcSnmpAddr.remote_port = 161;
    mgcSnmpAddr.broadcast = 0;  //Not broadcast
    mgcSnmpAddr.remote_ip = mgInfo->mgAttr.ip;
    
    if (mgcSnmpPdu.var_num)
        snmp_send(&mgcSnmpPdu,&mgcSnmpAddr);
    
    return 1;
}

int mgc_get_snmp_msg()
{
    struct snmp_pdu     mgcSnmpPdu;
    struct snmp_addr    mgcSnmpAddr;
    struct var_list     *mgcVarList;
    BYTE                i, trkNo;
    WORD                mgNo, portIndex;
    MG_INFO             *mgInfo;
    
    mgcSnmpAddr.local_port = 4968;
    if (!snmp_receive(&mgcSnmpPdu, &mgcSnmpAddr))
        return 0;
    
    if (mgcSnmpPdu.error_index != 0)
        return -1;
    
    mgNo = mgcSnmpPdu.request_id >> 16;
    mgInfo = &mgcMgInfo[mgNo];
    if ((mgcSnmpPdu.request_id & 0xFFFF) != mgInfo->requestId)
        return -1;
    
    if (mgcSnmpPdu.var_num > MGC_MAX_PHY_PORT_PER_MG)
        return -1;
    
    mgcVarList = &mgcSnmpPdu.var[0];
    
    for (i = 0; i < mgcSnmpPdu.var_num; i++)
    {
        trkNo = mgcVarList[i].oid[MGC_AC_LINE_STATUS_IDLEN - 1];
        if (trkNo > (MGC_MAX_PHY_PORT_PER_MG - 1))
            return -1;
        if ((portIndex = mgInfo->portIndex[trkNo]) != 0xFFFF)
        {
            if (mgcVarList[i].msg[0] == 1)
            {   // No Alarm
                mgcPhyPort[portIndex].stLast = 1;//revise by Francis 0822
            }
            else
            {   // Alarm
                mgcPhyPort[portIndex].stLast = 0;//revise by Francis 0822
            }
        }
    }
    
    return 1;
}

void mgc_get_mg_trk_status(WORD mg, BYTE stage)
{
    BYTE    i;
    WORD    portIndex;
    CHNL    chnl = {0, 0, 0, 0};
//    static  BYTE    stage = 0;
    
//    stage++;
    
//    for (mg = 0; mg < MGC_MAX_NUM_OF_MG; mg++)
//    {
        if ((mgcMgInfo[mg].created == 0) ||
            ((!mgc_is_non_virtual_mg(mgcMgInfo[mg].mgAttr.mgType)) &&
            (mgcMgInfo[mg].mgAttr.mgType != MGC_MG_TYPE_ANN)))
            return;
        
        chnl.mgNo = mg;
        chnl.chlNo = 1;
        
        if ((mgcMgInfo[mg].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_MGCP)
            && (mgcMgInfo[mg].usrType == MGC_USER_TYPE_MGC))
        {
            if (mgcMgInfo[mg].mgAttr.mgType == MGC_MG_TYPE_ANN)//revise by Francis 0822
            {
                chnl.portNo = 0;
                mgc_auep_chnl(0xFFFF, chnl);
            }
            else if (mgcMgInfo[mg].portNum > 0)
            {
                for (i = 0; i < MGC_MAX_PHY_PORT_PER_MG; i++)
                {
                    if (mgcMgInfo[mg].portIndex[i] == 0xFFFF)
                        continue;
                    else
                    {
                        chnl.portNo = i;
                        mgc_auep_chnl(0xFFFF, chnl);
                        break;
                    }
                }
            }
        
            if ((mgc_is_non_virtual_mg(mgcMgInfo[mg].mgAttr.mgType))
                && (mgcMgInfo[mg].portNum > 0))
            {   
                if (MGC_MG_TYPE_SSW_CSS != mgcMgInfo[mg].mgAttr.mgType)
                {
                    mgc_get_non_virtual_trk_status(mg);
                }//revise by Francis 0822
            }
        }   
        
        if ((stage & 1) == 0)
        {
            mgcMgInfo[mg].status = mgcMgInfo[mg].stLast;
            mgcMgInfo[mg].stLast = 0;
            if (mgc_is_non_virtual_mg(mgcMgInfo[mg].mgAttr.mgType))//revise by Francis 0822
            {
                for (i = 0; i < MGC_MAX_PHY_PORT_PER_MG; i++)
                {
                    portIndex = mgcMgInfo[mg].portIndex[i];
                    if (portIndex != 0xFFFF)
                    {
                        mgcPhyPort[portIndex].phyStatus = mgcPhyPort[portIndex].stLast;
                        mgcPhyPort[portIndex].stLast = 0;
                    }
                }
            }
        }
//    }
}

void mgc_t10s()
{
//    static DWORD cntT10s = 0;
    static DWORD cntT50ms = 0;
    static BYTE  stage[MGC_MAX_NUM_OF_MG] = {0};
    WORD    i;
    
    if (++cntT50ms >= MGC_MGCF_TIMER_50MS)
    {   // 50 mini seconds period
        cntT50ms = 0;
        mgc_get_snmp_msg();
        mgc_mon();
    }

    for (i = 1; i < MGC_MAX_NUM_OF_MG; i++)
    {
        if (mgcMgInfo[i].created == 0)
            continue;
        
        if (++mgcMgInfo[i].auditTimer >= mgcMgInfo[i].mgAttr.auditTimer)
        {
            stage[i]++;
            mgcMgInfo[i].auditTimer = 0;
            mgc_get_mg_trk_status(i, stage[i]);
        }
    }

/*    if (++cntT10s >= MGC_MGCF_TIMER_10S)
    {   // 10 seconds period
        cntT10s = 0;
        mgc_get_mg_trk_status();
    }
*/
}

int mgc_mg_init(WORD mgNo)
{
    memset((BYTE *) &mgcMgInfo[mgNo], 0, sizeof(MG_INFO));
    memset((BYTE *) &mgcMgInfo[mgNo].portIndex, 0xFFFF, sizeof(WORD) * MGC_MAX_PHY_PORT_PER_MG);
    
    return 0;
}

void mgc_init(DWORD systemId, DWORD localIp, DWORD peerIp)
{
    WORD    i;
    MG_ATTR tmpMgAttr;
    MG_ATTR *mgAttr = &tmpMgAttr;
    
    printf("MGC module init start!\n");
    if (mgc_bind_8ecp() < 0)
        printf("MGC module binds 8ECP fail!\n");
    if (mgc_bind_mgcp() < 0)
        printf("MGC module binds MGCP fail!\n");
    
    memset((BYTE *) &mgcSap[0], 0, sizeof(MGC_SAP) * MGC_MAX_NUM_OF_SAP);
    memset((BYTE *) &mgcPhyPort[0], 0, sizeof(PHY_PORT_INFO) * MGC_MAX_NUM_OF_PHY_PORT);
    
    for (i = 0; i < MGC_MAX_NUM_OF_MG; i++)
        mgc_mg_init(i);
        
    for (i = 0; i < MGC_MAX_NUM_OF_PORT; i++)
        mgc_port_init(i);
    
    for (i = 0; i < MGC_MAX_NUM_OF_CHNL; i++)
        mgc_chnl_init(i);
        

    for (i = 0; i < MGC_MAX_NUM_OF_CON; i++)
        mgc_connect_init(i);//new replace
        
    mgc_sess_init();	
    mgc_vc_name_init();
    
    memset(mgc_aas_mgNo, 0xFFFF, sizeof(WORD)*MGC_MAX_NUM_OF_AAS_MGC);

    mgcSelectPort = 0;
    mgc_select_connection = 0;
    mgc_select_ass_mgc_mgNo = 0;
    
    mgcMaxMgNo      = MGC_MAX_NUM_OF_MG;
    mgcMaxChlNo     = MGC_MAX_NUM_OF_CHNL;
    mgcMgCreated    = 0;
    mgcChlAssigned  = 0;
    
    memset(mgAttr, 0, sizeof(MG_ATTR));
    mgAttr->mgType = MGC_MG_TYPE_INTERNAL;
    mgAttr->ctrlType = MGC_MG_CTRL_TYPE_MGCP;
    strcpy(mgAttr->domain, "InternalMG");
    mgAttr->ip = 1;
    
    mgc_create_MG(0, mgAttr);

    mgc_8k_tone_card_silent = 0;

    mgc_e1card0_mgNo = 0;
    mgc_e1card1_mgNo = 0;

    sysID = systemId;
    localIP = localIp;
    peerIP = peerIp;

    strcpy(mgcAsciInBuf, "\0");
    strcpy(mgcAsciOutBuf, "\0");
    mgcMonitorFg = MGC_MONITOR_NONE;
    mgc_debug_set();
    
    printf("MGC module init complete!\n");
}

void mgc_timer()
{
    WORD port;
    
    for (port = 0; port < MGC_MAX_NUM_OF_PORT; port++)
    {
        if (mgcPort[port].assigned == 0)
            continue;
        
        mgc_fsm(port);
    }
    
    mgc_t10s();
}

int mgc_bind(MGC_SAP *sap)
{
    BYTE sapIndex;
    
    if (wxc2_get_license(LIC_MGC) <= 0)
    {
        mgc_log_err("mgc_bind:  mgc module is not presented!\n\r");
        return -1;
    }
    
    if ((sap == NULL) ||
        (sap->mgc_cnf == NULL) ||
        (sap->usrType > MGC_USER_TYPE_MG))
        return -1;
    
    for (sapIndex = 0; sapIndex < MGC_MAX_NUM_OF_SAP; sapIndex++)
    {
        if (mgcSap[sapIndex].mgc_cnf != NULL)
            continue;
        
        memcpy((BYTE *) &mgcSap[sapIndex], sap, sizeof(MGC_SAP));
        return sapIndex;
    }
    
    return -1;
}

int mgc_unbind(MGC_SAP *sap, BYTE sapIndex)
{
    if ((sap == NULL) || (sapIndex >= MGC_MAX_NUM_OF_SAP))
        return -1;
    
    if ((strcmp(sap->usrName, mgcSap[sapIndex].usrName) != 0) ||
         (sap->usrType != mgcSap[sapIndex].usrType))
        return -1;
    
    memset((BYTE *) &mgcSap[sapIndex], 0, sizeof(MGC_SAP));
    
    return 0;
}

int mgc_store_aas_mgc_mg(WORD mgNo)
{
    int i;
    
    for (i = 0; i < MGC_MAX_NUM_OF_AAS_MGC; i++)
    {
        if ((mgc_aas_mgNo[i] < MGC_MAX_NUM_OF_MG) && (mgc_aas_mgNo[i] > 0))
        {
            continue;
        }
        else
        {
            mgc_aas_mgNo[i] = mgNo;
            return 0;
        }
    }
    
    return -1;  
}

int mgc_delet_aas_mgc_mg(WORD mgNo)
{
    int i;
    
    for (i = 0; i < MGC_MAX_NUM_OF_AAS_MGC; i++)
    {
        if ((mgc_aas_mgNo[i] > 0) && (mgc_aas_mgNo[i] != mgNo))
        {
            continue;
        }
        else
        {
            mgc_aas_mgNo[i] = 0;
            return 0;
        }
    }
    
    return -1;
}

int mgc_assign_chnl(BYTE sapIndex, WORD mgNo, BYTE portNo, BYTE chnlType)
{
    WORD    i, j;
    WORD    chnlStart, chnlEnd, chnlNum;
    
    if (mgNo >= MGC_MAX_NUM_OF_MG)
    {
        return -1;
    }
    
    if (chnlType == MGC_MG_TYPE_ANN)
    {
        chnlStart = MGC_CHNL_START_ANN;
        chnlEnd = MGC_CHNL_START_ANN + MGC_CHNL_NUM_ANN;
        chnlNum = MGC_CHNL_NUM_ANN_PER_TYPE;
    }
    else if (chnlType == MGC_PHY_PORT_TYPE_ANALOG)
    {
        chnlStart = MGC_CHNL_START_AALN;
        chnlEnd = MGC_CHNL_START_AALN + MGC_CHNL_NUM_AALN;
        chnlNum = MGC_CHNL_NUM_AALN_PER_PORT;
    }
    else if(chnlType == MGC_MG_TYPE_INTERNAL)
    {
        chnlStart = MGC_CHNL_START_INTERNAL;
        chnlEnd = MGC_CHNL_START_INTERNAL+ MGC_CHNL_NUM_INTERNAL;
        chnlNum = MGC_CHNL_NUM_INTERNAL_PER_PORT;   
    }   
    else
    {
        chnlStart = MGC_CHNL_START_DS;
        chnlEnd = MGC_CHNL_START_DS + MGC_CHNL_NUM_DS_TOTAL;
        chnlNum = MGC_CHNL_NUM_DS_PER_PORT;
    }
    
    if ((mgcChlAssigned + chnlNum) > mgcMaxChlNo)
        return -1;
    
    for (i = chnlStart; i < chnlEnd; i += chnlNum)
    {
        if (mgcChnl[i].assigned == 1)
            continue;
        
        for (j = 0; j < chnlNum; j++)
        {
            mgcChnl[i + j].assigned = 1;
            mgcChnl[i + j].mgNo = mgNo;
            mgcChnl[i + j].portNo = portNo;
            mgcChnl[i + j].port = 0xFFFF;
            
            if (chnlType == MGC_MG_TYPE_ANN)
            {
                mgcChnl[i + j].sapIndex = sapIndex;
            }
        }
        
        mgcChlAssigned += chnlNum;
        
        return i;
    }
    
    return -1;
}

int mgc_remove_chnl(WORD chnlIndex, WORD chnlNum)
{
    WORD    i, port;

    if ((chnlIndex>MGC_MAX_NUM_OF_CHNL) || ((chnlIndex+chnlNum)>MGC_MAX_NUM_OF_CHNL))
    {
        return -1;
    }
    
    for (i = 0; i < chnlNum; i++)
    {
        port = mgcChnl[chnlIndex + i].port;
        if (port < MGC_MAX_NUM_OF_CHNL)
            mgcPort[port].mngCmd = MGC_MNG_CMD_REMOVE_CHNL;
            
        mgc_chnl_init(chnlIndex + i);
        
        mgc_remove_connect(chnlIndex + i);
    }
    
    if (mgcChlAssigned > chnlNum)
        mgcChlAssigned -= chnlNum;
    else
        mgcChlAssigned = 0;
    
    return 0;
}

int mgc_assign_MG(BYTE sapIndex, WORD mgNo, MG_ATTR *mgAttr)
{
    int     chnlIndex;
    BYTE    cardNo;

    if ((mgNo >= MGC_MAX_NUM_OF_MG) || (mgAttr == NULL) || (0 == strcmp(mgAttr->domain, ""))
        || (0 == mgAttr->ip))
    {
        return -1;
    }
    
    if (mgAttr->mgType == MGC_MG_TYPE_ANN)
    {
        if ((chnlIndex = mgc_assign_chnl(sapIndex, mgNo, 0xFF, MGC_MG_TYPE_ANN)) < 0)
            return -1;
        mgcMgInfo[mgNo].chnlNum = MGC_CHNL_NUM_ANN_PER_TYPE;
        mgcMgInfo[mgNo].chnlStartIndex = chnlIndex;
    }
    
    if (mgAttr->mgType == MGC_MG_TYPE_INTERNAL)
    {
        if ((chnlIndex = mgc_assign_chnl(0xFF, mgNo, 0xFF, MGC_MG_TYPE_INTERNAL)) < 0)
            return -1;
        mgcMgInfo[mgNo].chnlNum = MGC_CHNL_NUM_INTERNAL_PER_PORT;
        mgcMgInfo[mgNo].chnlStartIndex = chnlIndex;
    }//add by Francis

    if (MGC_MG_CTRL_TYPE_8ECP == mgAttr->ctrlType)
    {
        if ((cardNo = atoi(mgAttr->domain)) > 31)
        {
            mgc_log_err("mgc_create_MG: 8ecp domain out of range!\n\r");
            return -1;
        }
            
        _8ecp_createMG(mgNo, mgAttr->ip, cardNo);
        
        if (0 == cardNo)
        {
            mgc_e1card0_mgNo = mgNo;
        }
        else if (1 == cardNo)
        {
            mgc_e1card1_mgNo = mgNo;
        }   
    }
    
    mgcMgInfo[mgNo].created = 1;
    memcpy((BYTE *) &mgcMgInfo[mgNo].mgAttr, (BYTE *) mgAttr, sizeof(MG_ATTR));

    if (mgcMgInfo[mgNo].mgAttr.auditTimer == 0)
    {
        mgcMgInfo[mgNo].mgAttr.auditTimer = MGC_MGCF_TIMER_10S;
    }
    else
    {
        mgcMgInfo[mgNo].mgAttr.auditTimer = mgcMgInfo[mgNo].mgAttr.auditTimer * MGC_MGCF_TIMER_1S;
    }

    mgcMgInfo[mgNo].mgAttr.e1cardNo = cardNo;
    mgcMgInfo[mgNo].portNum = 0;
    memset((BYTE *) mgcMgInfo[mgNo].portIndex, 0xFFFF, sizeof(WORD) * MGC_MAX_PHY_PORT_PER_MG);
    
    mgcMgCreated++;
    
    return mgNo;
}

int mgc_create_MG(BYTE sapIndex, MG_ATTR *mgAttr)
{
    WORD    i;
    int     mgNo;
    char    tmpStr[128];
    
    if ((mgAttr == NULL) || (sapIndex >= MGC_MAX_NUM_OF_SAP) || (0 == strcmp(mgAttr->domain, ""))
         || (0 == mgAttr->ip) || ((MGC_MG_CTRL_TYPE_8ECP != mgAttr->ctrlType) && (MGC_MG_CTRL_TYPE_MGCP != mgAttr->ctrlType)))
    {
        mgc_log_err("mgc_create_MG: invalid sapIndex or NULL mgAttr or No domain or No ip!\n\r");
        return -1;
    }
    
    if ((mgcMgCreated + 1) > mgcMaxMgNo)
    {
        mgc_log_err("mgc_create_MG: license not enough!\n\r");
        return -1;
    }

    for (i = 0; i < MGC_MAX_NUM_OF_MG; i++)
    {
        if (mgcMgInfo[i].created == 0)
        {
            continue;
        }
        
        if ((0 == strcmp(mgcMgInfo[i].mgAttr.domain, mgAttr->domain))
              && (mgcMgInfo[i].mgAttr.ip == mgAttr->ip) && (mgcMgInfo[i].usrType == mgcSap[sapIndex].usrType))
        {
            if (mgcMgInfo[i].sapIndex[sapIndex] == 0)
            {
                mgcMgInfo[i].sapIndex[sapIndex] = 1;
                return i;
            }
            else
            {
                mgc_log_err("mgc_create_MG: duplicated MG and sapIndex!\n\r");
                return -1;
            }
        }     
    }   
    
    if (mgAttr->mgType == MGC_MG_TYPE_INTERNAL)
    {
      if (0 == mgcMgInfo[0].created)
        return mgc_assign_MG(0xFF, MGC_INTERNAL_VIRTUAL_MG, mgAttr);
      else
        return -1;  
    }
    
    for (i = 1; i < MGC_MAX_NUM_OF_MG; i++)
    {
        if (mgcMgInfo[i].created == 1)
            continue;
        mgNo = mgc_assign_MG(sapIndex, i, mgAttr);
        if (mgNo >= 0)
        {
            if ((mgcMonitorFg & MGC_MONITOR_ALL) == MGC_MONITOR_ALL)
            {
                sprintf(tmpStr, "mgc_create_MG: succeed, sapIndex = %d, mgNo = %d, mgDomain: %s\n\r", sapIndex, mgNo, mgAttr->domain);
                mgc_asciout_proc(tmpStr);
                mgcMgInfo[mgNo].monFlag = 1;
            }
            mgcMgInfo[mgNo].usrType = mgcSap[sapIndex].usrType;
            
            if ((MGC_MG_TYPE_ANN == mgcMgInfo[mgNo].mgAttr.mgType)
                && (MGC_USER_TYPE_MGC == mgcMgInfo[mgNo].usrType))
            {
                if (mgc_store_aas_mgc_mg(mgNo) < 0)
                {
                    mgc_log_err("mgc_assign_MG: no resource store AAS MGC MG!\n\r");
                    mgc_mg_init(mgNo);
                    return -1;                  
                }
            }
    
            mgcMgInfo[mgNo].sapIndex[sapIndex] = 1;         
            
            return mgNo;
        }
        else
        {
            mgc_log_err("mgc_assign_MG: MG assign failed!\n\r");
    
            return -1;
        }   
    }
    
    mgc_log_err("mgc_create_MG: MG resource not available!\n\r");
    
    return -1;
}

int mgc_delete_MG(BYTE sapIndex, WORD mgNo)
{
    BYTE    i;
    char    tmpStr[128];
    BYTE    cardNo;
    BYTE    mgFlag = 0;
    
    if ((sapIndex >= MGC_MAX_NUM_OF_SAP) ||
        (mgNo >= MGC_MAX_NUM_OF_MG) || (0 == mgNo) 
        || (0 == mgcMgInfo[mgNo].created))//add by Francis
    {
        mgc_log_err("mgc_delete_MG: invalid sapIndex or mgNo!\n\r");
        return -1;
    }
    
    if (MGC_MG_CTRL_TYPE_8ECP == mgcMgInfo[mgNo].mgAttr.ctrlType)
    {
        cardNo = mgcMgInfo[mgNo].mgAttr.e1cardNo;
        
        if (cardNo > 31)
        {
            mgc_log_err("mgc_delete_MG: invalid 8ecp cardNo!\n\r");
            return -1;          
        }
        
        _8ecp_deleteMG(mgNo, mgcMgInfo[mgNo].mgAttr.ip, cardNo);
        
        if (0 == cardNo)
        {
            mgc_e1card0_mgNo = 0;
        }
        else if (1 == cardNo)
        {
            mgc_e1card1_mgNo = 0;
        }
    }
    else
    {
        if ((MGC_MG_TYPE_ANN == mgcMgInfo[mgNo].mgAttr.mgType) && (mgcMgInfo[mgNo].chnlNum > 0))
        {
            mgc_delet_aas_mgc_mg(mgNo);
            
            mgc_remove_chnl(mgcMgInfo[mgNo].chnlStartIndex, mgcMgInfo[mgNo].chnlNum);
        }//add by Francis
        else
        {       
            for (i = 0; i < MGC_MAX_PHY_PORT_PER_MG; i++)
            {
                if (mgcMgInfo[mgNo].portIndex[i] < MGC_MAX_NUM_OF_PHY_PORT)
                {   
                    mgc_delete_port(sapIndex, mgNo, i);
                }   
            }
        }
    }

    mgcMgInfo[mgNo].sapIndex[sapIndex] = 0;
            
    for (i = 0; i < MGC_MAX_NUM_OF_SAP; i++)
    {
        if (mgcMgInfo[mgNo].sapIndex[i] == 1)
        {
            mgFlag = 1; 
            break;
        }
    }
        
    if (mgFlag == 0)
    {   
        mgc_mg_init(mgNo);
            
        if (mgcMgCreated > 0)
            mgcMgCreated--;
                
        sprintf(tmpStr, "mgc_delete_MG: succeed, sapIndex = %d, mgNo = %d, mgDomain: %s\n\r", sapIndex, mgNo, mgcMgInfo[mgNo].mgAttr.domain);
        mgc_asciout_proc(tmpStr);
            
        return 0;
    }
    
    mgc_log_err("mgc_delete_MG: other users are using this mg!\n\r");
    
    return 0;
}

int mgc_modify_MG(BYTE sapIndex, WORD mgNo, MG_ATTR *mgAttr)
{
    char    tmpStr[128];
    BYTE    cardNo;
    
    if ((sapIndex >= MGC_MAX_NUM_OF_SAP) ||
        (mgNo >= MGC_MAX_NUM_OF_MG))
    {
        mgc_log_err("mgc_modify_MG: invalid sapIndex or mgNo!\n\r");
        return -1;
    }
    
    if (0 == mgcMgInfo[mgNo].created)
    {
        mgc_log_err("mgc_modify_MG: mg not create!\n\r");
        return -1;
    }           
        
    if (MGC_MG_CTRL_TYPE_8ECP == mgAttr->ctrlType)
    {
        if ((cardNo = atoi(mgAttr->domain)) > 31)
        {
            mgc_log_err("mgc_modify_MG: 8ecp domain out of range!\n\r");
            return -1;
        }
            
        _8ecp_createMG(mgNo, mgAttr->ip, cardNo);
    }       
        
    memcpy((BYTE *) &mgcMgInfo[mgNo].mgAttr, (BYTE *) mgAttr, sizeof(MG_ATTR)); 
    
    sprintf(tmpStr, "mgc_modify_MG: succeed, sapIndex = %d, mgNo = %d, mgDomain: %s\n\r", sapIndex, mgNo, mgAttr->domain);
    mgc_asciout_proc(tmpStr);
    
    return 0;
}

int mgc_add_port(BYTE sapIndex, WORD mgNo, BYTE portNo, BYTE portType)
{
    WORD        i;
    int         chnlIndex;
    MG_INFO     *mgInfo;
    BYTE        chnlNum;
    WORD        portIndex;
    char        tmpStr[128];
    
    if ((sapIndex >= MGC_MAX_NUM_OF_SAP) ||
        (mgNo >= MGC_MAX_NUM_OF_MG) ||
        (portNo >= MGC_MAX_PHY_PORT_PER_MG) ||
        (portType > MGC_PHY_PORT_TYPE_ANALOG))
    {
        mgc_log_err("mgc_add_port: invalid sapIndex, mgNo, portNo, or portType!\n\r");
        return -1;
    }
    
    mgInfo = &mgcMgInfo[mgNo];
    
    if (mgInfo->created != 1)
    {
        mgc_log_err("mgc_add_port: MG not created!\n\r");
        return -1;
    }
    
    if ((mgInfo->portNum + 1) > mgInfo->mgAttr.maxPorts)
    {
        mgc_log_err("mgc_add_port: reached maxPorts of that MG!\n\r");
        return -1;
    }
    
    portIndex = mgcMgInfo[mgNo].portIndex[portNo];
    
    if ((portIndex < MGC_MAX_NUM_OF_PHY_PORT) &&
        (mgcPhyPort[portIndex].created == 1))
    {
        mgc_log_err("mgc_add_port: port already created!\n\r");
        return -1;
    }
    
    for (i = 0; i < MGC_MAX_NUM_OF_PHY_PORT; i++)
    {
        if (mgcPhyPort[i].created == 1)
            continue;
        if (mgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_8ECP)
        {
            if (portType == MGC_PHY_PORT_TYPE_ANALOG)
                chnlNum = MGC_CHNL_NUM_AALN_PER_PORT;
            else
                chnlNum = MGC_CHNL_NUM_DS_PER_PORT;
            if ((chnlIndex = mgc_assign_chnl(sapIndex, mgNo, portNo, portType)) < 0)
            {
                mgc_log_err("mgc_add_port: insufficient channel resources!\n\r");
                return -1;
            }
            mgcPhyPort[i].chnlNum = chnlNum;
            mgcPhyPort[i].chnlStartIndex = chnlIndex;
        }
        
        mgcPhyPort[i].created = 1;
        mgcPhyPort[i].mgNo = mgNo;
        mgcPhyPort[i].portNo = portNo;
        mgcPhyPort[i].portType = portType;
        mgcPhyPort[i].sapIndex = sapIndex;
        
        mgInfo->portIndex[portNo] = i;
        mgInfo->portNum++;
        
        if ((mgcMonitorFg & MGC_MONITOR_ALL) == MGC_MONITOR_ALL)
            mgcPhyPort[i].monFlag = 1;
        
        sprintf(tmpStr, "mgc_add_port: succeed, sapIndex = %d, mgNo = %d, portNo = %d, portType = %d, allocated portNo = %d\n\r", sapIndex, mgNo, portNo, portType, i);
        mgc_log_procedure(mgNo, i, 0xFFFF, tmpStr);
    
        return i;
    }
    
    mgc_log_err("mgc_add_port: insufficient port resource!\n\r");
    
    return -1;
}

int mgc_delete_port(BYTE sapIndex, WORD mgNo, BYTE portNo)
{
    WORD        portIndex;
    MG_INFO     *mgInfo;
    char        tmpStr[128];
    
    if ((sapIndex >= MGC_MAX_NUM_OF_SAP) ||
        (mgNo >= MGC_MAX_NUM_OF_MG) ||
        (portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_delete_port: invalid sapIndex, mgNo, portNo!\n\r");
        return -1;
    }
    
    mgInfo = &mgcMgInfo[mgNo];
    portIndex = mgInfo->portIndex[portNo];
    
    if (mgcPhyPort[portIndex].sapIndex == sapIndex)
    {
        mgc_remove_chnl(mgcPhyPort[portIndex].chnlStartIndex, mgcPhyPort[portIndex].chnlNum);
        memset((BYTE *) &mgcPhyPort[portIndex], 0, sizeof(PHY_PORT_INFO));
    
        mgInfo->portIndex[portNo] = 0xFFFF;
        mgInfo->portNum--;
    
        sprintf(tmpStr, "mgc_delete_port: succeed, sapIndex = %d, mgNo = %d, portNo = %d\n\r", sapIndex, mgNo, portNo);
        mgc_asciout_proc(tmpStr);
        
        return 0;
    }
    else
    {
        mgc_log_err("mgc_delete_port: invalid sapIndex for the portNo!\n\r");
        return -1;      
    }
    
}

int mgc_modify_port(BYTE sapIndex, WORD mgNo, BYTE portNo, BYTE portType)
{
    WORD    phyPort;
    char    tmpStr[128];
    
    if ((sapIndex >= MGC_MAX_NUM_OF_SAP) ||
        (mgNo >= MGC_MAX_NUM_OF_MG) ||
        (!mgc_is_non_virtual_mg(mgcMgInfo[mgNo].mgAttr.mgType))||//add by Francis
        (portNo >= MGC_MAX_PHY_PORT_PER_MG) ||
        (portType > MGC_PHY_PORT_TYPE_ANALOG))
    {
        mgc_log_err("mgc_modify_port: invalid sapIndex, mgNo, portNo, or portType!\n\r");
        return -1;
    }
    
    phyPort = mgcMgInfo[mgNo].portIndex[portNo];
    
    if (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)
    {
        mgc_log_err("mgc_modify_port: invalid phyPort!\n\r");
        return -1;
    }
    
    mgcPhyPort[phyPort].portType = portType;
    
    sprintf(tmpStr, "mgc_modify_port: succeed, sapIndex = %d, mgNo = %d, portNo = %d, portType = %d\n\r", sapIndex, mgNo, portNo, portType);
    mgc_asciout_proc(tmpStr);
    
    return 0;
}

int mgc_apply_aas_tone(CHNL *aasChnl, BYTE toneNo)
{
    int    i;
    int    j;
    WORD    chnlIndex;
    WORD    connectIndex;
    
    for (i = 0; i < MGC_MAX_NUM_OF_AAS_MGC; i++)
    {
        if (mgc_select_ass_mgc_mgNo > 3)
        {
            mgc_select_ass_mgc_mgNo = 0;
        }   
                        
        if ((mgc_aas_mgNo[mgc_select_ass_mgc_mgNo] >= MGC_MAX_NUM_OF_MG) 
            || (mgc_aas_mgNo[mgc_select_ass_mgc_mgNo] == 0) 
            || (mgcMgInfo[mgc_aas_mgNo[mgc_select_ass_mgc_mgNo]].status != 1) 
            || (mgcMgInfo[mgc_aas_mgNo[mgc_select_ass_mgc_mgNo]].mgAttr.ip != localIP))
        {
           mgc_select_ass_mgc_mgNo++;
           continue;        
        }
        else
        {
            chnlIndex = mgcMgInfo[mgc_aas_mgNo[mgc_select_ass_mgc_mgNo]].chnlStartIndex + toneNo;
            
            for (j = 0; j < MGC_MAX_NUM_OF_CHNL_CON; j++)
            {
                if (((connectIndex = mgcChnl[chnlIndex].connectIndex[j]) < MGC_MAX_NUM_OF_CON)
                    && (mgcConnectInfo[connectIndex].assigned == 1)) 
                {
                    continue;
                }
                else
                {
                    aasChnl->mgNo = mgc_aas_mgNo[mgc_select_ass_mgc_mgNo];
                    aasChnl->portNo = 0xFF;
                    aasChnl->chlNo = toneNo;
                    aasChnl->connectNo = j;
            
                    if (mgc_assign_connect_to_chnl(*aasChnl) < 0)
                    {
                        mgc_log_err("mgc_apply_aas_tone: assigned connect to chnl failed!\n\r");
                        return -1; 
                    }

                    mgc_select_ass_mgc_mgNo++;  

                    return 0;
                }    
            } 
        }
    }
    
    return -1;
}

int mgc_match_codec_list(MGC_CODEC_LIST *dest, MGC_CODEC_LIST *aParty, MGC_CODEC_LIST *bParty)
{
    BYTE    i, j, num = 0;
    
    MGC_CODEC_LIST *base, *highPri;
    
    if (dest == NULL)
    {
        mgc_log_err("mgc_match_codec_list: dest == NULL!\n\r");
        return -1;
    }
    dest->num = 0;
    dest->priority = 0;
    
    if (aParty->priority >= bParty->priority)
    {
        base    = bParty;
        highPri = aParty;
    }
    else
    {
        base    = aParty;
        highPri = bParty;
    }

    if (aParty->codec[0] == MGC_VCTYPE_G729B)
    {
        base    = bParty;
        highPri = aParty;
    }
    else if (bParty->codec[0] == MGC_VCTYPE_G729B)
    {
        base    = aParty;
        highPri = bParty;
    }
    
    if (base->num == 0)
    {
        if (highPri->num == 0)
        {
            mgc_log_err("mgc_match_codec_list: base->num == 0!\n\r");
            return -1;
        }
        else
        {
            memcpy((BYTE *) dest, (BYTE *) highPri, sizeof(MGC_CODEC_LIST));
            return 0;
        }
    }
    
    if (highPri->num == 0)
    {
        memcpy((BYTE *) dest, (BYTE *) base, sizeof(MGC_CODEC_LIST));
        return 0;
    }
    
    for (i = 0; i < highPri->num; i++)
    {
        for (j = 0; j < base->num; j++)
        {
            if (highPri->codec[i] == base->codec[j])
            {
                dest->codec[num++] = highPri->codec[i];
                break;
            }
        }
    }
    
    if (num > 0)
    {
        dest->num = num;
        dest->priority = highPri->priority;
        return 0;
    }
    else
    {
        mgc_log_err("mgc_match_codec_list: can't match at all!\n\r");
        return -1;
    }
}

int mgc_crcx_chnl(WORD usrPort, CHNL chnl)
{
    int     port;
    WORD    chnlIndex, phyPort, associPort;
    char    tmpStr[256];
    BYTE    ptime;
    int      connectIndex;//new replace
    WORD     aasChnlIndex;
    WORD     aasConnectIndex;
    CHNL     aasChnl;
    
//  return 0;
    
    if (chnl.mgNo >= MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_crcx_chnl: invalid mgNo!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[chnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_INTERNAL)
    {
        mgc_log_err("mgc_crcx_chnl: MGC_MG_TYPE_INTERNAL!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[chnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
        return 1;
    
    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
        mgc_log_err("mgc_crcx_chnl: invalid portNo!\n\r");
        return -1;
    }
    
    if (chnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON)
    {
        mgc_log_err("mgc_crcx_chnl: invalid connectNo!\n\r");
        return -1;      
    }

    if (MGC_MG_TYPE_ANN == mgcMgInfo[chnl.mgNo].mgAttr.mgType)
    {
        chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    }
    else
    {   
        phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }
    
    if ((chnlIndex >= MGC_MAX_NUM_OF_CHNL) 
        || ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_crcx_chnl: invalid chnlIndex or phyPort!\n\r");
        return -1;
    }
    
    if ((mgcChnl[chnlIndex].connectIndex[chnl.connectNo] < MGC_MAX_NUM_OF_CON) 
         && (mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].assigned == 1)
         && ((mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].status == MGC_CONNECT_STATUS_CREATED)
             ||(mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].status == MGC_CONNECT_STATUS_TONE)))//new replace
    {
        mgc_log_err("mgc_crcx_chnl: connection already created on this channel!\n\r");
        return 0;
    }

    if ((mgcChnl[chnlIndex].connectIndex[chnl.connectNo] >= MGC_MAX_NUM_OF_CON) 
        || (mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].assigned != 1))
    {
        if ((connectIndex = mgc_assign_connect_to_chnl(chnl)) < 0)
        {
            mgc_log_err("mgc_crcx_chnl: connect resource not available!\n\r");
            return -1;    
        }//new replace
    }
    else
    {
        connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo];
    }

    associPort = mgcConnectInfo[connectIndex].port;
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_crcx_chnl: chnl connection operation overwritten!\n\r");
    }
    
    aasChnl = mgcConnectInfo[connectIndex].aasChnl;
    
    if ((aasChnl.mgNo < MGC_MAX_NUM_OF_MG) && (aasChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
        && (aasChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
    {
        aasChnlIndex = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
        
        if ((aasConnectIndex = mgcChnl[aasChnlIndex].connectIndex[aasChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
        {
            associPort = mgcConnectInfo[aasConnectIndex].port;
            if ((associPort < MGC_MAX_NUM_OF_PORT)
                && (mgcPort[associPort].assigned != 0))
            {
                mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                mgc_log_err("mgc_crcx_chnl: connection aasChnl operation overwritten!\n\r");
            }   
        }   
    }
    
    associPort = mgcChnl[chnlIndex].port;   
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_crcx_chnl: chnl operation overwritten!\n\r");
    }   

    if (mgcConnectInfo[connectIndex].codecList.num == 0)
//  if (mgcChnl[chnlIndex].codecList.num == 0)
    {
        if (mgc_match_codec_list(&mgcConnectInfo[connectIndex].codecList, &mgcConnectInfo[connectIndex].codecList, &mgcMgInfo[chnl.mgNo].mgAttr.codecList) < 0)
        //if (mgc_match_codec_list(&codecList, &mgcChnl[chnlIndex].codecList, &mgcMgInfo[chnl.mgNo].mgAttr.codecList) < 0)
        {
            mgc_log_err("mgc_crcx_chnl: mgcChnl[chnlIndex].codecList error!\n\n");
            return -1;
        }
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_crcx_chnl: port resource not available!\n\r");
        return -1;
    }
    
    ptime = mgcMgInfo[chnl.mgNo].mgAttr.ptime;
          
    mgcPort[port].usrPort = usrPort;
    mgcPort[port].mgcfOperStepsNum = 1;
    mgcPort[port].mgcfOperSteps[0].localChnl = chnl;
    mgcPort[port].mgcfOperSteps[0].media.ptime = ptime;
    mgcPort[port].mgcfOperSteps[0].media.conMode = MGCP_CON_MODE_RECVONLY;
    mgcPort[port].mgcfOperSteps[0].media.vocoderType = mgcConnectInfo[connectIndex].codecList;
    mgcPort[port].mgcfOperSteps[0].cmd = MGCP_CMD_CRCX;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_CRCX;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperSteps[0].chnlConnectIndex = chnl.connectNo;
    
    sprintf(tmpStr, "mgc_crcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, chnlConnectNo = %d, connectIndex = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, chnl.connectNo, connectIndex);//new replace
    mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
    
    return 0;
}

int mgc_mdcx_chnl(WORD usrPort, CHNL chnl, MEDIA_PARA *mediaPara, BYTE sdFlag)
{
    int     port;
    WORD    chnlIndex, phyPort;
    char    tmpStr[256];
    WORD      connectIndex;//new replace
    
//  return 0;
    
    if (chnl.mgNo >= MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_mdcx_chnl: invalid mgNo!\n\r");
        return -1;
    }
    
    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
        mgc_log_err("mgc_mdcx_chnl: invalid portNo!\n\r");
        return -1;
    }

    if ((MGC_MG_TYPE_ANN == mgcMgInfo[chnl.mgNo].mgAttr.mgType) 
        || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[chnl.mgNo].mgAttr.mgType))
    {
        chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    }
    else
    {   
        phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }

    if ((chnlIndex >= MGC_MAX_NUM_OF_CHNL) 
        || ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_mdcx_chnl: invalid chnlIndex or phyPort!\n\r");
        return -1;
    }


    if ((connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo]) >= MGC_MAX_NUM_OF_CON);//new replace
    {
        mgc_log_err("mgc_mdcx_chnl: invalid connectNo!\n\r");
        return -1;     
    }

    
    if ((mediaPara->flag & MGC_MEDIA_PARA_FLAG_EC) == MGC_MEDIA_PARA_FLAG_EC)
        //mgcChnl[chnlIndex].mediaAttr.ecDisable = mediaPara->ecDisable;
        mgcConnectInfo[connectIndex].mediaAttr.ecDisable = mediaPara->ecDisable;
    
    if ((mediaPara->flag & MGC_MEDIA_PARA_FLAG_SS) == MGC_MEDIA_PARA_FLAG_SS)
        //mgcChnl[chnlIndex].mediaAttr.ssDisable = mediaPara->ssDisable;
        mgcConnectInfo[connectIndex].mediaAttr.ssDisable = mediaPara->ssDisable;
        
    if ((mediaPara->flag & MGC_MEDIA_PARA_FLAG_CM) == MGC_MEDIA_PARA_FLAG_CM)
        //mgcChnl[chnlIndex].mediaAttr.conMode = mediaPara->conMode;
        mgcConnectInfo[connectIndex].mediaAttr.conMode = mediaPara->conMode;
    
    if ((mediaPara->flag & MGC_MEDIA_PARA_FLAG_PT) == MGC_MEDIA_PARA_FLAG_PT)
        //mgcChnl[chnlIndex].mediaAttr.ptime = mediaPara->ptime;
        mgcConnectInfo[connectIndex].mediaAttr.ptime = mediaPara->ptime;
    
    if ((mediaPara->flag & MGC_MEDIA_PARA_FLAG_VT) == MGC_MEDIA_PARA_FLAG_VT)
    {
        //mgc_match_codec_list(&mgcChnl[chnlIndex].codecList, &mediaPara->vocoderType, &mgcMgInfo[chnl.mgNo].mgAttr.codecList);
        mgc_match_codec_list(&mgcConnectInfo[connectIndex].codecList, &mediaPara->vocoderType, &mgcMgInfo[chnl.mgNo].mgAttr.codecList);
    }
    
    if (sdFlag == 0)
    {
//      sprintf(tmpStr, "mgc_mdcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, sdFlag = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, sdFlag);
        sprintf(tmpStr, "mgc_mdcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, sdFlag = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, chnl.connectNo, sdFlag);//new replace
        mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
        return 0;
    }

    if ((mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].assigned != 1)
         || ((mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].status != MGC_CONNECT_STATUS_CREATED)&&((mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].status != MGC_CONNECT_STATUS_TONE))))//new replace    
//  if (mgcChnl[chnlIndex].status != MGC_CHNL_STATUS_CREATED) 
    {
        mgc_log_err("mgc_mdcx_chnl: connection not created on this channel!\n\r");
        return -1;
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_mdcx_chnl: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    mgcPort[port].mgcfOperStepsNum = 1;
    mgcPort[port].mgcfOperSteps[0].localChnl = chnl;
    mgcPort[port].mgcfOperSteps[0].cmd = MGCP_CMD_MDCX;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_MDCX;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperSteps[0].chnlConnectIndex = chnl.connectNo;
    
//  sprintf(tmpStr, "mgc_mdcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, sdFlag = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, sdFlag);
  sprintf(tmpStr, "mgc_mdcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, sdFlag = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, chnl.connectNo, sdFlag);
    mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
    
    return 0;
}

int mgc_recvonly_chnl(WORD usrPort, CHNL orgChnl, CHNL destChnl)
{
    int     port;
    BYTE    ptime;
    WORD    chnlIndexOrg, chnlIndexDst, phyPortOrg, phyPortDst;
    char    tmpStr[256];
    int    orgConnectIndex;
    int    destConnectIndex;
    MGC_CODEC_LIST  codecList;
    
    if ((orgChnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (destChnl.mgNo >= MGC_MAX_NUM_OF_MG))
    {
        mgc_log_err("mgc_recvonly_chnl: invalid mgNo!\n\r");
        return -1;
    }   
    
    if ((orgChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG) ||
        (destChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_recvonly_chnl: invalid portNo!\n\r");
        return -1;
    }
    
    if ((orgChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON) ||
        (destChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON))
    {
        mgc_log_err("mgc_recvonly_chnl: invalid connectNo!\n\r");
        return -1;
    } 
    
    if ((MGC_MG_TYPE_ANN == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
        || (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_INTERNAL))
    {
        chnlIndexOrg = mgcMgInfo[orgChnl.mgNo].chnlStartIndex + orgChnl.chlNo;
    }
    else
    {       
        phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
        chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
    }   
    
    if ((chnlIndexOrg >= MGC_MAX_NUM_OF_CHNL) 
        || ((mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortOrg >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_recvonly_chnl: invalid chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }
    
    
    if (((orgConnectIndex = mgcChnl[chnlIndexOrg].connectIndex[orgChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[orgConnectIndex].assigned != 1)
        || ((mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_TONE)))//new replace
    {
        mgc_log_err("mgc_recvonly_chnl: orgChnl connectionIndex invaild or connection not create!\n\r");
        return -1;
   
    }

    if (mgcConnectInfo[orgConnectIndex].mediaAttr.conMode == MGCP_CON_MODE_RECVONLY)
    {
        sprintf(tmpStr, "mgc_recvonly_chnl: connection already in recvonly mode, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, Dest: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d\n\r",
            usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, orgChnl.connectNo, orgConnectIndex, destChnl.mgNo, destChnl.portNo, destChnl.chlNo, destChnl.connectNo);
        mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);

        return 0;
    }

    if ((MGC_MG_TYPE_ANN == mgcMgInfo[destChnl.mgNo].mgAttr.mgType)
        || (mgcMgInfo[destChnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_INTERNAL))
    {
        chnlIndexDst = mgcMgInfo[destChnl.mgNo].chnlStartIndex + destChnl.chlNo;
    }
    else
    {       
        phyPortDst = mgcMgInfo[destChnl.mgNo].portIndex[destChnl.portNo];
        chnlIndexDst = mgcPhyPort[phyPortDst].chnlStartIndex + destChnl.chlNo;
    }
    
    if (chnlIndexDst >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[destChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (phyPortDst >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_recvonly_chnl: invalid chnlIndex or phyPort of destChnl!\n\r");
        return -1;
    }

    
    if (((destConnectIndex = mgcChnl[chnlIndexDst].connectIndex[destChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[destConnectIndex].assigned != 1) 
        || ((mgcConnectInfo[destConnectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[destConnectIndex].status != MGC_CONNECT_STATUS_TONE)))//new replace
    {
        mgc_log_err("mgc_recvonly_chnl: destChnl connectionIndex invaild or connection not create!\n\r");
        return -1; 
    }

    if (mgcConnectInfo[orgConnectIndex].codecList.num == 0)
    {
        if (mgc_match_codec_list(&mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcMgInfo[orgChnl.mgNo].mgAttr.codecList) < 0)
        {
            mgc_log_err("mgc_crcx_chnl: mgcChnl[chnlIndex].codecList error!\n\n");
            return -1;
        }
    }

    codecList = mgcConnectInfo[orgConnectIndex].codecList;

    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_mdcx_chnl: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    mgcPort[port].mgcfOperStepsNum = 1;    
    
    ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
    mgcPort[port].mgcfOperSteps[0].media.ptime = ptime;
    mgcPort[port].mgcfOperSteps[0].media.conMode = MGCP_CON_MODE_RECVONLY;
    mgcPort[port].mgcfOperSteps[0].localChnl = orgChnl;
    mgcPort[port].mgcfOperSteps[0].remChnl = destChnl;
    mgcPort[port].mgcfOperSteps[0].cmd = MGCP_CMD_MDCX;
    mgcPort[port].mgcfOperSteps[0].media.vocoderType = codecList;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_MDCX;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;

    sprintf(tmpStr, "mgc_recvonly_chnl: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, Dest: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d\n\r",
            usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, orgChnl.connectNo, orgConnectIndex, destChnl.mgNo, destChnl.portNo, destChnl.chlNo, destChnl.connectNo, destConnectIndex);
    mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
        
    return 0;   
}

int mgc_dlcx_chnl(WORD usrPort, CHNL chnl)
{
    int     port;
    WORD    chnlIndex, phyPort, associPort;
    char    tmpStr[256];
    WORD    orgChl, dstChl;
    WORD    connectIndex;
    WORD    aasChnlIndex;   
    WORD    aasConnectIndex;
    CHNL    aasChnl;
    
//  return 0;
    
    if (chnl.mgNo >= MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_dlcx_chnl: invalid mgNo!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[chnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
    {
        orgChl = (mgcMgInfo[chnl.mgNo].mgAttr.e1cardNo * 8 + chnl.portNo) * 32 + chnl.chlNo;
        dstChl = (mgc_8k_tone_card_silent * 8 + 7) * 32 + 31;
        _8ecp_connect_chnl(orgChl, dstChl, 0); //ecDisable:0/1=enable/disable echo canceller
        
        phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
        
        sprintf(tmpStr, "mgc_dlcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo);
        mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
        
        return 0;
    }
    
    if ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) 
        && (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_dlcx_chnl: invalid portNo!\n\r");
        return -1;
    }
    
    if (chnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON)
    {
        mgc_log_err("mgc_dlcx_chnl: invalid connectNo!\n\r");
        return -1;
    }   
    
    if (chnl.chlNo >= MGC_MAX_NUM_OF_CHNL)
    {
        if (chnl.chlNo != MGCP_EP_NAME_CHNL_WILDCAST)
        {
            mgc_log_err("mgc_dlcx_chnl: invalid chnlIndex!\n\r");
            return -1;
        }
    }
    
    if (chnl.chlNo < MGC_MAX_NUM_OF_CHNL)
    {
        if (MGC_MG_TYPE_ANN == mgcMgInfo[chnl.mgNo].mgAttr.mgType)
        {
            chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
        }
        else
        {
            phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
            chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
        }
        
        if ((chnlIndex >= MGC_MAX_NUM_OF_CHNL) 
            || ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)))
        {
            mgc_log_err("mgc_dlcx_chnl: invalid chnlIndex or phyPort!\n\r");
            return -1;
        }
        
        
        if ((connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo]) >= MGC_MAX_NUM_OF_CON)//new replace
        {
            mgc_log_err("mgc_dlcx_chnl: invalid connectIndex!\n\r");
            return -1;     
        }
        
        
        associPort = mgcConnectInfo[connectIndex].port;
        if ((associPort < MGC_MAX_NUM_OF_PORT) 
             && (mgcPort[associPort].assigned != 0))
        {
            mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
            mgc_log_err("mgc_dlcx_chnl: chnl connection operation overwritten!\n\r");
        }
        
        aasChnl = mgcConnectInfo[connectIndex].aasChnl;
    
        if ((aasChnl.mgNo < MGC_MAX_NUM_OF_MG) && (aasChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
            && (aasChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
        {
            aasChnlIndex = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
        
            if ((aasConnectIndex = mgcChnl[aasChnlIndex].connectIndex[aasChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
            {
                associPort = mgcConnectInfo[aasConnectIndex].port;
                if ((associPort < MGC_MAX_NUM_OF_PORT)
                    && (mgcPort[associPort].assigned != 0))
                {
                    mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                    mgc_log_err("mgc_dlcx_chnl: connection aasChnl operation overwritten!\n\r");
                }   
            }   
        }       
        
        associPort = mgcChnl[chnlIndex].port;   
        if ((associPort < MGC_MAX_NUM_OF_PORT) 
             && (mgcPort[associPort].assigned != 0))
        {
            mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
            mgc_log_err("mgc_dlcx_chnl: chnl operation overwritten!\n\r");
        }       

        if ((mgcConnectInfo[connectIndex].assigned != 1)
             || ((mgcConnectInfo[connectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[connectIndex].status != MGC_CONNECT_STATUS_TONE)))  //new replace     
        {
            mgc_log_err("mgc_dlcx_chnl: connection not created on this channel!\n\r");
            return 0;
        }
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_dlcx_chnl: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    mgcPort[port].mgcfOperStepsNum = 1;
    mgcPort[port].mgcfOperSteps[0].localChnl = chnl;
    mgcPort[port].mgcfOperSteps[0].cmd = MGCP_CMD_DLCX;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_DLCX;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperSteps[0].chnlConnectIndex = chnl.connectNo;
    
    sprintf(tmpStr, "mgc_dlcx_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, chnl.connectNo);
    mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
    
	MGC_SESS_REC *pSess;

    pSess = mgc_sess_is_already_rec(chnl);
    if(pSess != NULL)
        mgc_sess_rec_init(pSess, pSess->id);
	
    return 0;
}

int mgc_rqnt_chnl(WORD usrPort, CHNL chnl, EVENT *event, SIGNAL *signal)
{
    int     port;
    WORD    chnlIndex, phyPort;
    char    tmpStr[256];
    
    if (chnl.mgNo >= MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_rqnt_chnl: invalid mgNo!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[chnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
        return 1;
    
    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
        mgc_log_err("mgc_rqnt_chnl: invalid portNo!\n\r");
        return -1;
    }

    if (MGC_MG_TYPE_ANN == mgcMgInfo[chnl.mgNo].mgAttr.mgType)
    {
        chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    }
    else
    {   
        phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }
    
    if ((chnlIndex >= MGC_MAX_NUM_OF_CHNL) || 
        ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_rqnt_chnl: invalid chnlIndex or phyPort!\n\r");
        return -1;
    }  

    if ((mgcChnl[chnlIndex].port < MGC_MAX_NUM_OF_PORT) 
          && (mgcPort[mgcChnl[chnlIndex].port].assigned != 0))
    {
        mgc_log_err("mgc_rqnt_chnl: channel already engaged!\n\r");
        return 0;
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_rqnt_chnl: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    mgcPort[port].mgcfOperStepsNum = 1;
    mgcPort[port].mgcfOperSteps[0].localChnl = chnl;
    mgcPort[port].mgcfOperSteps[0].cmd = MGCP_CMD_RQNT;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_RQNT;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperSteps[0].chnlConnectIndex = 0xFFFF;
    
    if (event != NULL)
        //mgcChnl[chnlIndex].mediaAttr.pkgEvent = (event->pkg << 8) | event->event;
        mgcChnl[chnlIndex].comMediaAttr.pkgEvent = (event->pkg << 8) | event->event;
        
    if (signal != NULL)
        //mgcChnl[chnlIndex].mediaAttr.pkgSignal = (signal->pkg << 8) | signal->signal;
        mgcChnl[chnlIndex].comMediaAttr.pkgSignal = (signal->pkg << 8) | signal->signal;
    
//  sprintf(tmpStr, "mgc_rqnt_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo);
  sprintf(tmpStr, "mgc_rqnt_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, chnl.connectNo);    
    mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
    
    return 0;
}

int mgc_auep_chnl(WORD usrPort, CHNL chnl)
{
    int     port;
    WORD    chnlIndex, phyPort;
    char    tmpStr[256];
    
//  return 0;
    
    if (chnl.mgNo >= MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_auep_chnl: invalid mgNo!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[chnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
        return 1;
    
    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
        mgc_log_err("mgc_auep_chnl: invalid portNo!\n\r");
        return -1;
    }

    if (MGC_MG_TYPE_ANN == mgcMgInfo[chnl.mgNo].mgAttr.mgType)
    {
        chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    }
    else
    {   
        phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }
    
    if ((chnlIndex >= MGC_MAX_NUM_OF_CHNL) 
        || ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_auep_chnl: invalid chnlIndex or phyPort!\n\r");
        return -1;
    }
    
    if (mgcChnl[chnlIndex].auepSt != MGC_CHNL_AUEP_IDLE)
    {
        mgc_log_err("mgc_auep_chnl: auep already in progress!\n\r");
        return -1;
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_auep_chnl: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    mgcPort[port].mgcfOperStepsNum = 1;
    mgcPort[port].mgcfOperSteps[0].localChnl = chnl;
    mgcPort[port].mgcfOperSteps[0].cmd = MGCP_CMD_AUEP;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_AUEP;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperSteps[0].chnlConnectIndex = 0xFFFF;
    
    mgcChnl[chnlIndex].auepSt = MGC_CHNL_AUEP_IN_PROGRESS;
    
//  sprintf(tmpStr, "mgc_auep_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo);
  sprintf(tmpStr, "mgc_auep_chnl: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d\n\r", usrPort, chnl.mgNo, chnl.portNo, chnl.chlNo, chnl.connectNo);
    mgc_log_procedure(chnl.mgNo, phyPort, chnlIndex, tmpStr);
    
    return 0;
}

int mgc_connect_chnl(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE flag)
{
    int     port;
    BYTE    step = 0, ptime;
    WORD    orgChl, dstChl;
    WORD    chnlIndexOrg, chnlIndexDst, phyPortOrg, phyPortDst, associPort;
    char    tmpStr[256];
    MGC_CODEC_LIST  codecList;
    int    orgConnectIndex;
    int    destConnectIndex;
    WORD    aasChnlIndex;   
    WORD    aasConnectIndex;
    CHNL    aasChnl;    
    CONNECT_INFO *pConnect;
    
    if ((orgChnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (destChnl.mgNo >= MGC_MAX_NUM_OF_MG))
    {
        mgc_log_err("mgc_connect_chnl: invalid mgNo!\n\r");
        return -1;
    }

    if ((mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType != mgcMgInfo[destChnl.mgNo].mgAttr.ctrlType) 
        && ((mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP) || (mgcMgInfo[destChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)))
    {
        mgc_log_err("mgc_connect_chnl: mg ctrlType error!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
    {
        orgChl = (mgcMgInfo[orgChnl.mgNo].mgAttr.e1cardNo * 8 + orgChnl.portNo) * 32 + orgChnl.chlNo;
        if ((flag & MGC_CONNECT_SILENT_TONE) == MGC_CONNECT_SILENT_TONE)
            dstChl = (mgc_8k_tone_card_silent * 8 + 7) * 32 + 31;
        else    
            dstChl = (mgcMgInfo[destChnl.mgNo].mgAttr.e1cardNo * 8 + destChnl.portNo) * 32 + destChnl.chlNo;
        
        phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
        chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
        _8ecp_connect_chnl(orgChl, dstChl, mgcChnl[chnlIndexOrg].comMediaAttr.ecDisable); //ecDisable:0/1=enable/disable echo canceller     
        
        phyPortDst = mgcMgInfo[destChnl.mgNo].portIndex[destChnl.portNo];
        chnlIndexDst = mgcPhyPort[phyPortDst].chnlStartIndex + destChnl.chlNo;
        
        sprintf(tmpStr, "mgc_connect_chnl: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d, Dest: mgNo = %d, portNo = %d, chnlNo = %d\n\r",
                    usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, destChnl.mgNo, destChnl.portNo, destChnl.chlNo);
        
        if (mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr) < 0)
            mgc_log_procedure(destChnl.mgNo, phyPortDst, chnlIndexDst, tmpStr);
        
        return 0;
    }
    
    if ((orgChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG) ||
        (destChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_connect_chnl: invalid portNo!\n\r");
        return -1;
    }
    
    if ((orgChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON) ||
        (destChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON))
    {
        mgc_log_err("mgc_connect_chnl: invalid connectNo!\n\r");
        return -1;
    } 
    
    if (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_INTERNAL)
    {
        phyPortOrg = 0;
        chnlIndexOrg = mgcMgInfo[orgChnl.mgNo].chnlStartIndex + orgChnl.chlNo;
    }
    else
    {
        if (MGC_MG_TYPE_ANN == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
        {
            chnlIndexOrg = mgcMgInfo[orgChnl.mgNo].chnlStartIndex + orgChnl.chlNo;
        }
        else
        {       
            phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
            chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
        }
    }
    
    if ((chnlIndexOrg >= MGC_MAX_NUM_OF_CHNL) 
        || ((mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortOrg >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_chnl: invalid chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }
    
    
    if (((orgConnectIndex = mgcChnl[chnlIndexOrg].connectIndex[orgChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[orgConnectIndex].assigned != 1))//new replace
    {
        if ((orgConnectIndex = mgc_assign_connect_to_chnl(orgChnl)) < 0)
        {
            mgc_log_err("mgc_connect_chnl: assigned connect on orgChnl failed!\n\r");
            return -1;
        }
   
    }   
    
    associPort = mgcConnectInfo[orgConnectIndex].port;
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_chnl: orgChnl operation overwritten!\n\r");
    }
    
    aasChnl = mgcConnectInfo[orgConnectIndex].aasChnl;
    
    if ((aasChnl.mgNo < MGC_MAX_NUM_OF_MG) && (aasChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
        && (aasChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
    {
        aasChnlIndex = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
        
        if ((aasConnectIndex = mgcChnl[aasChnlIndex].connectIndex[aasChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
        {
            associPort = mgcConnectInfo[aasConnectIndex].port;
            if ((associPort < MGC_MAX_NUM_OF_PORT)
                && (mgcPort[associPort].assigned != 0))
            {
                mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                mgc_log_err("mgc_connect_chnl: connection aasChnl operation overwritten!\n\r");
            }   
        }   
    }   
    
    associPort = mgcChnl[chnlIndexOrg].port;    
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_chnl: orgChnl chnl operation overwritten!\n\r");
    }       
    
    if (mgcMgInfo[destChnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_INTERNAL)
    {
        phyPortDst = 0;
        chnlIndexDst = mgcMgInfo[destChnl.mgNo].chnlStartIndex + destChnl.chlNo;
    }
    else
    {
        if (MGC_MG_TYPE_ANN == mgcMgInfo[destChnl.mgNo].mgAttr.mgType)
        {
            chnlIndexDst = mgcMgInfo[destChnl.mgNo].chnlStartIndex + destChnl.chlNo;
        }
        else
        {       
            phyPortDst = mgcMgInfo[destChnl.mgNo].portIndex[destChnl.portNo];
            chnlIndexDst = mgcPhyPort[phyPortDst].chnlStartIndex + destChnl.chlNo;
        }
    }
    
    if (chnlIndexDst >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[destChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortDst >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_chnl: invalid chnlIndex or phyPort of destChnl!\n\r");
        return -1;
    }

    
    if (((destConnectIndex = mgcChnl[chnlIndexDst].connectIndex[destChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[destConnectIndex].assigned != 1))//new replace
    {
        if ((destConnectIndex = mgc_assign_connect_to_chnl(destChnl)) < 0)
        {
            mgc_log_err("mgc_connect_chnl: assigned connect on destChnl failed!\n\r");
            return -1;
        }   
    }

    if (mgcMgInfo[destChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)
    {
        associPort = mgcConnectInfo[destConnectIndex].port;
        
        if ((associPort < MGC_MAX_NUM_OF_PORT) 
            && (mgcPort[associPort].assigned != 0))
        {
            mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
            mgc_log_err("mgc_connect_chnl: destChnl operation overwritten!\n\r");
        }

        associPort = mgcChnl[chnlIndexDst].port;    
        if ((associPort < MGC_MAX_NUM_OF_PORT) 
             && (mgcPort[associPort].assigned != 0))
        {
            mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
            mgc_log_err("mgc_connect_chnl: destChnl chnl operation overwritten!\n\r");
        }
        
    }

    if ((mgcConnectInfo[orgConnectIndex].codecList.num == 0)
        && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)) 
    {
        if (mgc_match_codec_list(&mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcMgInfo[orgChnl.mgNo].mgAttr.codecList) < 0)
        {
            mgc_log_err("mgc_connect_chnl: mgcConnectInfo[orgConnectIndex].codecList error!\n\n");
            return -1;
        }
    }
    
    if ((mgcConnectInfo[destConnectIndex].codecList.num == 0)
        && (mgcMgInfo[destChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL))
    {
        if (mgc_match_codec_list(&mgcConnectInfo[destConnectIndex].codecList, &mgcConnectInfo[destConnectIndex].codecList, &mgcMgInfo[destChnl.mgNo].mgAttr.codecList) < 0) 
        {
            mgc_log_err("mgc_connect_chnl: mgcConnectInfo[destConnectIndex].codecList error!\n\n");
            return -1;
        }
    }

    if (mgc_match_codec_list(&codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[destConnectIndex].codecList) < 0)
    {
        mgc_log_err("mgc_connect_chnl: can't match codec!\n\n");
        return -1;
    }
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_connect_chnl: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    if (mgcMgInfo[orgChnl.mgNo].mgAttr.ptime >= mgcMgInfo[destChnl.mgNo].mgAttr.ptime)
        ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
    else
        ptime = mgcMgInfo[destChnl.mgNo].mgAttr.ptime;

    if ((mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_TONE))
    {
        if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
        {
          mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
          mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
          mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
          mgcPort[port].mgcfOperSteps[step].media.vocoderType = codecList;
          mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;         
          mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_CRCX;
        }
    }
    
    if ((mgcConnectInfo[destConnectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[destConnectIndex].status != MGC_CONNECT_STATUS_TONE))  
    {
        if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[destChnl.mgNo].mgAttr.mgType)
        {
          mgcPort[port].mgcfOperSteps[step].localChnl = destChnl;
          mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
          mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
          mgcPort[port].mgcfOperSteps[step].media.vocoderType = codecList;
          mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = destChnl.connectNo;        
          mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_CRCX;
        }
    }
    
    if ((MGC_MG_TYPE_IPBSS != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType) && (orgChnl.mgNo == destChnl.mgNo) 
        && ((mgcConnectInfo[orgConnectIndex].flag & MGCP_PARA_FLAG_TFO) != MGCP_PARA_FLAG_TFO))
    {
        if ((mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_IPBSS) 
            && (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType))
        {
            mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
            mgcPort[port].mgcfOperSteps[step].remChnl = destChnl;
            mgcPort[port].mgcfOperSteps[step].pkgSignal = 0;
            mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
            mgcPort[port].mgcfOperSteps[step].media.conMode = mgcConnectInfo[orgConnectIndex].mediaAttr.conMode;

            mgcPort[port].mgcfOperSteps[step].flag |= MGCP_PARA_FLAG_TFO;

            mgcPort[port].mgcfOperSteps[step].media.vocoderType = codecList;
            mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;        
            mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
        }
    }
    else if ((orgChnl.mgNo != destChnl.mgNo) 
             && ((mgcConnectInfo[orgConnectIndex].flag & MGCP_PARA_FLAG_TFO) == MGCP_PARA_FLAG_TFO))
    {
        if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
        {
            mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
            mgcPort[port].mgcfOperSteps[step].remChnl = destChnl;
            mgcPort[port].mgcfOperSteps[step].pkgSignal = 0;
            mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
            mgcPort[port].mgcfOperSteps[step].media.conMode = mgcConnectInfo[orgConnectIndex].mediaAttr.conMode;
            mgcPort[port].mgcfOperSteps[step].media.vocoderType = codecList;
            mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;        
            mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
        }
    }

    if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
    {
        mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
        mgcPort[port].mgcfOperSteps[step].remChnl = destChnl;
        mgcPort[port].mgcfOperSteps[step].pkgSignal = 0;
        mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;

        mgcPort[port].mgcfOperSteps[step].media.conMode = mgcConnectInfo[orgConnectIndex].mediaAttr.conMode;

        if ((MGC_MG_TYPE_IPBSS != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType) && (orgChnl.mgNo == destChnl.mgNo))
        {
            mgcPort[port].mgcfOperSteps[step].flag |= MGCP_PARA_FLAG_TFO;
        }

        mgcPort[port].mgcfOperSteps[step].media.vocoderType = codecList;
        mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;        
        mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
    }

    if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[destChnl.mgNo].mgAttr.mgType)
    {
        mgcPort[port].mgcfOperSteps[step].localChnl = destChnl;
        mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;
        mgcPort[port].mgcfOperSteps[step].pkgSignal = 0;
        mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
        
        if ((flag & MGC_CONNECT_SILENT_TONE) == MGC_CONNECT_SILENT_TONE)
        {   
            mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
        }
        else    
            mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_SENDRECV;

        if ((MGC_MG_TYPE_IPBSS != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType) && (orgChnl.mgNo == destChnl.mgNo))
        {
            mgcPort[port].mgcfOperSteps[step].flag |= MGCP_PARA_FLAG_TFO;
        }

        mgcPort[port].mgcfOperSteps[step].media.vocoderType = codecList;
        mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = destChnl.connectNo;        
        mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
    }
    


    if(mgcMgInfo[destChnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_AudioCoder)
    {
        mgcPort[port].mgcfOperSteps[step].localChnl = destChnl;
	    mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_RQNT;	
		mgcChnl[chnlIndexDst].comMediaAttr.pkgReq = (MGCP_PKG_D << 8)|(MGCP_D_SIG_WILD);
	}

    pConnect = &mgcConnectInfo[orgConnectIndex];
    memset(&(pConnect->operRec) , 0 , sizeof(OPER_REC));
	pConnect->operRec.operaId = MGC_OPER_ID_CONNECT_CHNL;
	
    if (step == 0)
        mgc_port_init(port);
    else
    {
        mgcPort[port].mgcfOperId = MGC_OPER_ID_CONNECT_CHNL;
        mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
        mgcPort[port].mgcfOperStepsNum = step;
    }
    
    sprintf(tmpStr, "mgc_connect_chnl: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, Dest: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, step = %d\n\r",
                    usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, orgChnl.connectNo, orgConnectIndex, destChnl.mgNo, destChnl.portNo, destChnl.chlNo, destChnl.connectNo, destConnectIndex, step);
    if (mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr) < 0)
        mgc_log_procedure(destChnl.mgNo, phyPortDst, chnlIndexDst, tmpStr);
    

    if(mgc_sess_rec_org_and_dst_chnl(orgChnl , destChnl) == FALSE)
	    return -1;
	
    return 0;
}

int mgc_connect_dtmf(WORD usrPort, CHNL orgChnl, CHNL dstChnl, BYTE dtmfNo)
{
    int     port;
    BYTE    step = 0, ptime;
    WORD    orgChl, dstChl;
    WORD    chnlIndexOrg, phyPortOrg, associPort;
    char    tmpStr[256];
    BYTE    digit = 0;
    int     orgConnectIndex;
    WORD    aasChnlIndex;   
    WORD    aasConnectIndex;
    CHNL    aasChnl;    
    
//  return 0;
    
    if ((orgChnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (dstChnl.mgNo >= MGC_MAX_NUM_OF_MG))
    {
        mgc_log_err("mgc_connect_dtmf: invalid mgNo!\n\r");
        return -1;
    }
    
    if (0 == dtmfNo)
    {
        digit = 10;
    }
    else
    {
        digit = dtmfNo;
    }   
    
    if (mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
    {
        orgChl = (mgcMgInfo[orgChnl.mgNo].mgAttr.e1cardNo * 8 + orgChnl.portNo) * 32 + orgChnl.chlNo;
        dstChl = (mgcMgInfo[dstChnl.mgNo].mgAttr.e1cardNo * 8 + dstChnl.portNo) * 32 + dstChnl.chlNo;
        _8ecp_connect_dtmf(orgChl, dstChl, digit);
        
        phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
        chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
        
        sprintf(tmpStr, "mgc_connect_dtmf: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, dtmfNo = %d\n\r", usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, dtmfNo);
        mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
        
        return 0;
    }
    
    if (orgChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
        mgc_log_err("mgc_connect_dtmf: invalid portNo!\n\r");
        return -1;
    }
    
    if (orgChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON)
    {
        mgc_log_err("mgc_connect_dtmf: invalid connectNo!\n\r");
        return -1;      
    }

    if (MGC_MG_TYPE_ANN == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
    {
        chnlIndexOrg = mgcMgInfo[orgChnl.mgNo].chnlStartIndex + orgChnl.chlNo;
    }
    else
    {   
        phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
        chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
    }
    
    if (chnlIndexOrg >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortOrg >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_dtmf: invalid chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }

    if (((orgConnectIndex = mgcChnl[chnlIndexOrg].connectIndex[orgChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[orgConnectIndex].assigned != 1))//new replace
    {
        if ((orgConnectIndex = mgc_assign_connect_to_chnl(orgChnl)) < 0)
        {
            mgc_log_err("mgc_connect_dtmf: assigned connect on orgChnl failed!\n\r");
            return -1;
        }   
    }
    
    associPort = mgcConnectInfo[orgConnectIndex].port;  
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_dtmf: orgChnl connection operation overwritten!\n\r");
    }
    
    aasChnl = mgcConnectInfo[orgConnectIndex].aasChnl;
    
    if ((aasChnl.mgNo < MGC_MAX_NUM_OF_MG) && (aasChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
        && (aasChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
    {
        aasChnlIndex = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
        
        if ((aasConnectIndex = mgcChnl[aasChnlIndex].connectIndex[aasChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
        {
            associPort = mgcConnectInfo[aasConnectIndex].port;
            if ((associPort < MGC_MAX_NUM_OF_PORT)
                && (mgcPort[associPort].assigned != 0))
            {
                mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                mgc_log_err("mgc_connect_dtmf: connection aasChnl operation overwritten!\n\r");
            }   
        }   
    }   
    
    associPort = mgcChnl[chnlIndexOrg].port;    
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_dtmf: orgChnl chnl operation overwritten!\n\r");
    }   
    
    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_connect_dtmf: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;
    
  if ((mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_TONE)) 
    {
        ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
        mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
        mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
        mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
        mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;     
        mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_CRCX;
    }
    mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
    mgcPort[port].mgcfOperSteps[step].pkgSignal = (MGCP_PKG_D << 8) | digit;
    if(mgcMgInfo[orgChnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_AudioCoder)
    {
		mgcChnl[orgConnectIndex].comMediaAttr.pkgReq = (MGCP_PKG_D << 8)|(MGCP_D_SIG_WILD);
	}
    mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
    mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_RQNT;
    mgcPort[port].mgcfOperStepsNum = step;
    mgcPort[port].mgcfOperId = MGC_OPER_ID_CONNECT_DTMF;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    sprintf(tmpStr, "mgc_connect_dtmf: succeed, usrPort = %d, mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, dtmfNo = %d\n\r", usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, orgChnl.connectNo, dtmfNo);
    mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
    
    return 0;
}

int mgc_connect_AAS(WORD usrPort, CHNL orgChnl, CHNL dstChnl, BYTE toneNo, WORD duration, WORD times)
{
    int     port;
    BYTE    step = 0, ptime;
    WORD    orgChl, dstChl;
    WORD    chnlIndexOrg, chnlIndexDst, phyPortOrg, phyPortDst, associPort;
    char    tmpStr[256];
    CHNL    aasChnl = {0xFFFF, 0, 0xFFFF, 0xFFFF};
    int     orgConnectIndex;
    int     destConnectIndex;
    WORD    aasConnectIndex;
    WORD    chnlIndexAAS;
    MGC_CODEC_LIST  codecList;
    WORD    orgAASChnlIndex;    
    WORD    orgAASConnectIndex;
    CHNL    orgAASChnl; 
    CONNECT_INFO *pConnect;
	BYTE tone;
    
    if ((orgChnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (dstChnl.mgNo >= MGC_MAX_NUM_OF_MG))
    {
        mgc_log_err("mgc_connect_AAS: invalid mgNo!\n\r");
        return -1;
    }

    if ((mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType != mgcMgInfo[dstChnl.mgNo].mgAttr.ctrlType) 
        && ((mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP) || (mgcMgInfo[dstChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)))
    {
        mgc_log_err("mgc_connect_chnl: mg ctrlType error!\n\r");
        return -1;
    }
    
    if (toneNo >= MGC_MAX_TONE_NO)
    {
        mgc_log_err("mgc_connect_AAS: invalid toneNo!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
    {
        orgChl = (mgcMgInfo[orgChnl.mgNo].mgAttr.e1cardNo * 8 + orgChnl.portNo) * 32 + orgChnl.chlNo;
        
        if ((0 == dstChnl.mgNo) && (0 == dstChnl.portNo) && (0 == dstChnl.chlNo))
        {
            dstChl = (mgc_8k_tone_card_silent * 8 + 7) * 32 + 31;
        }
        else if ((1 == mgcMgInfo[dstChnl.mgNo].created) 
                  && (1 == mgcPhyPort[mgcMgInfo[dstChnl.mgNo].portIndex[dstChnl.portNo]].created))
        {
            dstChl = (mgcMgInfo[dstChnl.mgNo].mgAttr.e1cardNo * 8 + dstChnl.portNo) * 32 + dstChnl.chlNo;//need revise
        }
        else
        {
            mgc_log_err("mgc_connect_AAS: invalid 8ecp mgNo or portNo!\n\r");
            return -1;
        }
        
        _8ecp_connect_tone(orgChl, dstChl, toneNo, duration);
        
        sprintf(tmpStr, "mgc_connect_AAS: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d\n\r",
                    usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo);
        mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
        
        return 0;
    }
    
    if ((orgChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG) ||
        (dstChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_connect_AAS: invalid portNo!\n\r");
        return -1;
    }
    
    if ((orgChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON) ||
        (dstChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON))
    {
        mgc_log_err("mgc_connect_AAS: invalid connectNo!\n\r");
        return -1;      
    }

    if ((MGC_MG_TYPE_ANN == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType) 
        || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType))
    {
        chnlIndexOrg = mgcMgInfo[orgChnl.mgNo].chnlStartIndex + orgChnl.chlNo;
    }
    else
    {   
        phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
        chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
    }
    
    if (chnlIndexOrg >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortOrg >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_AAS: invalid chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }

    if (((orgConnectIndex = mgcChnl[chnlIndexOrg].connectIndex[orgChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[orgConnectIndex].assigned != 1))//new replace
    {
        if ((orgConnectIndex = mgc_assign_connect_to_chnl(orgChnl)) < 0)
        {
            mgc_log_err("mgc_connect_AAS: assigned connect on orgChnl failed!\n\r");
            return -1;
        }   
    }

    associPort = mgcConnectInfo[orgConnectIndex].port;  
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_AAS: orgChnl connection operation overwritten!\n\r");
    }
    
    orgAASChnl = mgcConnectInfo[orgConnectIndex].aasChnl;
    
    if ((orgAASChnl.mgNo < MGC_MAX_NUM_OF_MG) && (orgAASChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
        && (orgAASChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
    {
        orgAASChnlIndex = mgcMgInfo[orgAASChnl.mgNo].chnlStartIndex + orgAASChnl.chlNo;
        
        if ((orgAASConnectIndex = mgcChnl[orgAASChnlIndex].connectIndex[orgAASChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
        {
            associPort = mgcConnectInfo[orgAASConnectIndex].port;
            if ((associPort < MGC_MAX_NUM_OF_PORT)
                && (mgcPort[associPort].assigned != 0))
            {
                mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                mgc_log_err("mgc_connect_AAS: connection aasChnl operation overwritten!\n\r");
            }   
        }   
    }       
    
    associPort = mgcChnl[chnlIndexOrg].port;    
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_AAS: orgChnl chnl operation overwritten!\n\r");
    }   

    if ((MGC_MG_TYPE_ANN == mgcMgInfo[dstChnl.mgNo].mgAttr.mgType) 
        || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[dstChnl.mgNo].mgAttr.mgType))
    {
        chnlIndexDst = mgcMgInfo[dstChnl.mgNo].chnlStartIndex + dstChnl.chlNo;
    }
    else
    {       
        phyPortDst = mgcMgInfo[dstChnl.mgNo].portIndex[dstChnl.portNo];
        chnlIndexDst = mgcPhyPort[phyPortDst].chnlStartIndex + dstChnl.chlNo;
    }
    
    if (chnlIndexDst >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortDst >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_AAS: invalid destChnl chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }   
    
    destConnectIndex = mgcChnl[chnlIndexDst].connectIndex[dstChnl.connectNo];

    if ((mgcConnectInfo[orgConnectIndex].codecList.num == 0)
        && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)) 
    {
        if (mgc_match_codec_list(&mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcMgInfo[orgChnl.mgNo].mgAttr.codecList) < 0)
        {
            mgc_log_err("mgc_connect_AAS: mgcConnectInfo[orgConnectIndex].codecList error!\n\n");
            return -1;
        }
    }

    if ((destConnectIndex < MGC_MAX_NUM_OF_CON) && (mgcConnectInfo[destConnectIndex].codecList.num == 0)
        && (mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)) 
    {
        if (mgc_match_codec_list(&mgcConnectInfo[destConnectIndex].codecList, &mgcConnectInfo[destConnectIndex].codecList, &mgcMgInfo[dstChnl.mgNo].mgAttr.codecList) < 0)
        {
            mgc_log_err("mgc_connect_AAS: mgcConnectInfo[dstConnectIndex].codecList error!\n\n");
            return -1;
        }
    }

    if (destConnectIndex < MGC_MAX_NUM_OF_CON)
    {
        if (mgc_match_codec_list(&codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[destConnectIndex].codecList) < 0)
        {
            mgc_log_err("mgc_connect_AAS: orgConnect and dstConnect code negotiation fail!\n\n");
            return -1;
        }
    }

    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_connect_AAS: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;

    if (toneNo == MGC_HOLD_MUSIC)
    {
        if (mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_CREATED)
        {
            if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
            {
                ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
                mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
                mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
                mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_CRCX;
            }
        }
        else
        {
            if (mgcConnectInfo[orgConnectIndex].mediaAttr.conMode >= MGCP_CON_MODE_SENDONLY)
            {
                ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
                mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
                mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].remChnl = dstChnl;

                if (destConnectIndex < MGC_MAX_NUM_OF_CON)
                {
                    mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[destConnectIndex].codecList;//orgConnectIndex
                }
                else
                {
                    mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                }

                mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
            }
        }
    }

    if (mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)
    {
        if ((destConnectIndex < MGC_MAX_NUM_OF_CON)
            && (mgcConnectInfo[destConnectIndex].status == MGC_CONNECT_STATUS_CREATED))
        {
            if (mgcConnectInfo[destConnectIndex].mediaAttr.conMode >= MGCP_CON_MODE_SENDONLY)        
            {
                ptime = mgcMgInfo[dstChnl.mgNo].mgAttr.ptime;

                if ((mgcConnectInfo[destConnectIndex].flag & MGCP_PARA_FLAG_TFO) == MGCP_PARA_FLAG_TFO)
                {
                    mgcPort[port].mgcfOperSteps[step].flag |= MGCP_PARA_FLAG_TFO;
                }

                mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
                mgcPort[port].mgcfOperSteps[step].localChnl = dstChnl;
                mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = dstChnl.connectNo;
                mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;//destConnectIndex
                mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
            }       
        }
    }

    toneNo = times * 10 + (toneNo - 7);
        
    if (mgc_apply_aas_tone(&aasChnl, toneNo) < 0)
    {
        mgc_log_err("mgc_connect_AAS: apply aas tone fail!\n\r");
        mgc_port_init(port);
        return -1;          
    }
    else
    {
        if ((aasChnl.mgNo >= MGC_MAX_NUM_OF_MG) || (aasChnl.portNo != 0xFF) 
            || (aasChnl.chlNo != toneNo) || (aasChnl.connectNo > MGC_MAX_NUM_OF_CON))
        {
            mgc_log_err("mgc_connect_AAS: apply aas mg fail!\n\r");
            mgc_port_init(port);
            return -1;                
        }
        else
        {
            if ((mgcConnectInfo[orgConnectIndex].flag & MGCP_PARA_FLAG_TFO) == MGCP_PARA_FLAG_TFO)
            {
                ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
                mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;

                if (toneNo == 0)
                {
                    mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
                }
                else
                {
                    mgcPort[port].mgcfOperSteps[step].media.conMode = mgcConnectInfo[orgConnectIndex].mediaAttr.conMode;;
                }

                mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].remChnl = dstChnl;

                if (destConnectIndex < MGC_MAX_NUM_OF_CON)
                {
                    mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[destConnectIndex].codecList;//orgConnectIndex
                }
                else
                {
                    mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                }

                mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;                    
            }

            chnlIndexAAS = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
            aasConnectIndex = mgcChnl[chnlIndexAAS].connectIndex[aasChnl.connectNo];

            ptime = mgcConnectInfo[orgConnectIndex].mediaAttr.ptime;
            mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
            mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_SENDONLY;        
            mgcPort[port].mgcfOperSteps[step].localChnl = aasChnl;
			mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;			
            mgcPort[port].mgcfOperSteps[step].cmd = MGCP_CMD_CRCX;
//            mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcMgInfo[orgChnl.mgNo].mgAttr.codecList;
            mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;

            mgcConnectInfo[orgConnectIndex].aasChnl = aasChnl;
                
            memcpy((BYTE *) &mgcConnectInfo[aasConnectIndex].mediaAttr.sdp, (BYTE *) &mgcConnectInfo[orgConnectIndex].mediaAttr.sdp, sizeof(PUB_SDP_MSG));                

            if (MGC_MG_TYPE_INTERNAL == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
            {
                if (duration == 0)
                {
                    mgcPort[port].mgcfOperSteps[step].delay = MGC_MGCF_TIMER_1H;
                }
                else
                {
                    mgcPort[port].mgcfOperSteps[step].delay = duration * MGC_MGCF_TIMER_1S;
                }
            }
            
            mgcPort[port].mgcfOperSteps[step++].chnlConnectIndex = aasChnl.connectNo;

            if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
            {
                ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
                mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
                mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].remChnl = aasChnl;
                mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
                mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                mgcPort[port].mgcfOperSteps[step].cmd = MGCP_CMD_MDCX;

                if (duration == 0)
                {
                    mgcPort[port].mgcfOperSteps[step++].delay = MGC_MGCF_TIMER_1H;
                }
                else
                {
                    mgcPort[port].mgcfOperSteps[step++].delay = duration * MGC_MGCF_TIMER_1S;
                }
            }

            mgcPort[port].mgcfOperSteps[step].localChnl = aasChnl;
			mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;
            mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = aasChnl.connectNo;
            mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_DLCX;
        }              
    }
    
    mgcPort[port].mgcfOperId = MGC_OPER_ID_CONNECT_AAS;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperStepsNum = step;
    
    pConnect = &mgcConnectInfo[orgConnectIndex];
    memset(&(pConnect->operRec) , 0 , sizeof(OPER_REC));
	pConnect->operRec.operaId = MGC_OPER_ID_CONNECT_AAS;	
	pConnect->operRec.tone = tone;
	pConnect->operRec.duration = duration;
    pConnect->operRec.times = times;
	
    sprintf(tmpStr, "mgc_connect_AAS: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, Dest: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, step = %d\n\r",
                    usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, orgChnl.connectNo, orgConnectIndex, dstChnl.mgNo, dstChnl.portNo, dstChnl.chlNo, dstChnl.connectNo, destConnectIndex, step);
    mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
    
    return 0;
}

int mgc_connect_tone(WORD usrPort, CHNL orgChnl, CHNL dstChnl, BYTE toneNo, WORD duration)
{
    int     port;
    BYTE    step = 0, ptime;
    WORD    orgChl, dstChl;
    WORD    chnlIndexOrg, chnlIndexDst, phyPortOrg, phyPortDst, associPort;
    char    tmpStr[256];
    CHNL    aasChnl = {0xFFFF, 0, 0xFFFF, 0xFFFF};
    int     orgConnectIndex;
    int     destConnectIndex;
    WORD    aasConnectIndex;
    WORD    chnlIndexAAS;
    MGC_CODEC_LIST  codecList;
    WORD    orgAASChnlIndex;    
    WORD    orgAASConnectIndex;
    CHNL    orgAASChnl; 
    CONNECT_INFO *pConnect;
	BYTE tone;
    if ((orgChnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (dstChnl.mgNo >= MGC_MAX_NUM_OF_MG))
    {
        mgc_log_err("mgc_connect_tone: invalid mgNo!\n\r");
        return -1;
    }
    
    if ((mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType != mgcMgInfo[dstChnl.mgNo].mgAttr.ctrlType) 
        && ((mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP) || (mgcMgInfo[dstChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)))
    {
        mgc_log_err("mgc_connect_chnl: mg ctrlType error!\n\r");
        return -1;
    }
    
    if (toneNo >= MGC_MAX_TONE_NO)
    {
        mgc_log_err("mgc_connect_tone: invalid toneNo!\n\r");
        return -1;
    }
    
    tone = toneNo;
    
    if (mgcMgInfo[orgChnl.mgNo].mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
    {
        orgChl = (mgcMgInfo[orgChnl.mgNo].mgAttr.e1cardNo * 8 + orgChnl.portNo) * 32 + orgChnl.chlNo;
        
        if ((0 == dstChnl.mgNo) && (0 == dstChnl.portNo) && (0 == dstChnl.chlNo))
        {
            dstChl = (mgc_8k_tone_card_silent * 8 + 7) * 32 + 31;
        }
        else if ((1 == mgcMgInfo[dstChnl.mgNo].created) 
                  && (1 == mgcPhyPort[mgcMgInfo[dstChnl.mgNo].portIndex[dstChnl.portNo]].created))
        {
            dstChl = (mgcMgInfo[dstChnl.mgNo].mgAttr.e1cardNo * 8 + dstChnl.portNo) * 32 + dstChnl.chlNo;//need revise
        }
        else
        {
            mgc_log_err("mgc_connect_tone: invalid 8ecp mgNo or portNo!\n\r");
            return -1;
        }
        
        _8ecp_connect_tone(orgChl, dstChl, toneNo, duration);
        
        sprintf(tmpStr, "mgc_connect_tone: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d\n\r",
                    usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo);
        mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
        
        return 0;
    }
    
    if ((orgChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG) ||
        (dstChnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_connect_tone: invalid portNo!\n\r");
        return -1;
    }
    
    if ((orgChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON) ||
        (dstChnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON))
    {
        mgc_log_err("mgc_connect_tone: invalid connectNo!\n\r");
        return -1;      
    }

    if ((MGC_MG_TYPE_ANN == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType) 
        || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType))
    {
        chnlIndexOrg = mgcMgInfo[orgChnl.mgNo].chnlStartIndex + orgChnl.chlNo;
    }
    else
    {   
        phyPortOrg = mgcMgInfo[orgChnl.mgNo].portIndex[orgChnl.portNo];
        chnlIndexOrg = mgcPhyPort[phyPortOrg].chnlStartIndex + orgChnl.chlNo;
    }
    
    if (chnlIndexOrg >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortOrg >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_tone: invalid chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }

    if (((orgConnectIndex = mgcChnl[chnlIndexOrg].connectIndex[orgChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        || (mgcConnectInfo[orgConnectIndex].assigned != 1))//new replace
    {
        if ((orgConnectIndex = mgc_assign_connect_to_chnl(orgChnl)) < 0)
        {
            mgc_log_err("mgc_connect_tone: assigned connect on orgChnl failed!\n\r");
            return -1;
        }   
    }

    associPort = mgcConnectInfo[orgConnectIndex].port;  
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_tone: orgChnl connection operation overwritten!\n\r");
    }
    
    orgAASChnl = mgcConnectInfo[orgConnectIndex].aasChnl;
    
    if ((orgAASChnl.mgNo < MGC_MAX_NUM_OF_MG) && (orgAASChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
        && (orgAASChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
    {
        orgAASChnlIndex = mgcMgInfo[orgAASChnl.mgNo].chnlStartIndex + orgAASChnl.chlNo;
        
        if ((orgAASConnectIndex = mgcChnl[orgAASChnlIndex].connectIndex[orgAASChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
        {
            associPort = mgcConnectInfo[orgAASConnectIndex].port;
            if ((associPort < MGC_MAX_NUM_OF_PORT)
                && (mgcPort[associPort].assigned != 0))
            {
                mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                mgc_log_err("mgc_connect_tone: connection aasChnl operation overwritten!\n\r");
            }   
        }   
    }       
    
    associPort = mgcChnl[chnlIndexOrg].port;    
    if ((associPort < MGC_MAX_NUM_OF_PORT) 
         && (mgcPort[associPort].assigned != 0))
    {
        mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
        mgc_log_err("mgc_connect_tone: orgChnl chnl operation overwritten!\n\r");
    }   

    if ((MGC_MG_TYPE_ANN == mgcMgInfo[dstChnl.mgNo].mgAttr.mgType) 
        || (MGC_MG_TYPE_INTERNAL == mgcMgInfo[dstChnl.mgNo].mgAttr.mgType))
    {
        chnlIndexDst = mgcMgInfo[dstChnl.mgNo].chnlStartIndex + dstChnl.chlNo;
    }
    else
    {       
        phyPortDst = mgcMgInfo[dstChnl.mgNo].portIndex[dstChnl.portNo];
        chnlIndexDst = mgcPhyPort[phyPortDst].chnlStartIndex + dstChnl.chlNo;
    }
    
    if (chnlIndexDst >= MGC_MAX_NUM_OF_CHNL 
        || ((mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL) && (mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPortDst >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
        mgc_log_err("mgc_connect_tone: invalid destChnl chnlIndex or phyPort of orgChnl!\n\r");
        return -1;
    }   
    
    destConnectIndex = mgcChnl[chnlIndexDst].connectIndex[dstChnl.connectNo];

    if ((mgcConnectInfo[orgConnectIndex].codecList.num == 0)
        && (mgcMgInfo[orgChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)) 
    {
        if (mgc_match_codec_list(&mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcMgInfo[orgChnl.mgNo].mgAttr.codecList) < 0)
        {
            mgc_log_err("mgc_connect_tone: mgcConnectInfo[orgConnectIndex].codecList error!\n\n");
            return -1;
        }
    }

    if (destConnectIndex < MGC_MAX_NUM_OF_CON)
    {
        if ((mgcConnectInfo[destConnectIndex].codecList.num == 0)
            && (mgcMgInfo[dstChnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_INTERNAL)) 
        {
            if (mgc_match_codec_list(&mgcConnectInfo[destConnectIndex].codecList, &mgcConnectInfo[destConnectIndex].codecList, &mgcMgInfo[dstChnl.mgNo].mgAttr.codecList) < 0)
            {
                mgc_log_err("mgc_connect_tone: mgcConnectInfo[dstConnectIndex].codecList error!\n\n");
                return -1;
            }
        }

        if (mgc_match_codec_list(&codecList, &mgcConnectInfo[orgConnectIndex].codecList, &mgcConnectInfo[destConnectIndex].codecList) < 0)
        {
            mgc_log_err("mgc_connect_AAS: orgConnect and dstConnect code negotiation fail!\n\n");
            return -1;
        }
    }
    else
        codecList = mgcConnectInfo[orgConnectIndex].codecList;

    if ((port = mgc_get_port()) < 0)
    {
        mgc_log_err("mgc_connect_tone: port resource not available!\n\r");
        return -1;
    }
    
    mgcPort[port].usrPort = usrPort;

    if (mgcConnectInfo[orgConnectIndex].status != MGC_CONNECT_STATUS_CREATED)
    {
        if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
        {
            ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
            mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
            mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
            mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
            mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
            mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
            mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_CRCX;
        }
    }
    else
    {
        if (mgcConnectInfo[orgConnectIndex].mediaAttr.conMode >= MGCP_CON_MODE_SENDONLY)
        {
            ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
            mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
            mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
            mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
            mgcPort[port].mgcfOperSteps[step].remChnl = dstChnl;
            mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
            mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
        }
    }

    if ((destConnectIndex < MGC_MAX_NUM_OF_CON)
        && (mgcConnectInfo[destConnectIndex].status == MGC_CONNECT_STATUS_CREATED))
    {
        if (mgcConnectInfo[destConnectIndex].mediaAttr.conMode >= MGCP_CON_MODE_SENDONLY)        
        {
            ptime = mgcMgInfo[dstChnl.mgNo].mgAttr.ptime;
            mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
            mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
            mgcPort[port].mgcfOperSteps[step].localChnl = dstChnl;
            mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;
            mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = dstChnl.connectNo;
            mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;       
            mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;
        }       
    }

    if (mgcMgInfo[orgChnl.mgNo].mgAttr.toneCap == 1)
    {
        mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
        mgcPort[port].mgcfOperSteps[step].cmd = MGCP_CMD_RQNT;
        mgcPort[port].mgcfOperSteps[step].pkgSignal = MGC_TONE_NO_TO_PKG_SIG[toneNo];
        mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
        if (duration == 0)
        {
            mgcPort[port].mgcfOperSteps[step++].delay = MGC_MGCF_TIMER_1H;
        }
        else
        {
            mgcPort[port].mgcfOperSteps[step++].delay = duration * MGC_MGCF_TIMER_1S;
        }
        
        mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
        mgcPort[port].mgcfOperSteps[step].pkgSignal = 0;
        mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
        mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_RQNT;
    }
    else
    {
        toneNo = toneNo - 7;
        
        if (mgc_apply_aas_tone(&aasChnl, toneNo) < 0)
        {
            mgc_log_err("mgc_connect_tone: mg no toneCap and no AAS MG!\n\r");
            mgc_port_init(port);
            return -1;          
        }
        else
        {
            if ((aasChnl.mgNo >= MGC_MAX_NUM_OF_MG) || (aasChnl.portNo != 0xFF) 
                || (aasChnl.chlNo != toneNo) || (aasChnl.connectNo > MGC_MAX_NUM_OF_CON))
            {
                mgc_log_err("mgc_connect_tone: mg no toneCap and apply aas mg fault!\n\r");
                mgc_port_init(port);
                return -1;                
            }
            else
            {
                if ((mgcConnectInfo[orgConnectIndex].flag & MGCP_PARA_FLAG_TFO) == MGCP_PARA_FLAG_TFO)
                {
                    ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
                    mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                    mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_RECVONLY;
                    mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
                    mgcPort[port].mgcfOperSteps[step].remChnl = dstChnl;
                    mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                    mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_MDCX;                    
                }

                chnlIndexAAS = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
                aasConnectIndex = mgcChnl[chnlIndexAAS].connectIndex[aasChnl.connectNo];

                ptime = mgcConnectInfo[orgConnectIndex].mediaAttr.ptime;                
                mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                mgcPort[port].mgcfOperSteps[step].media.conMode = MGCP_CON_MODE_SENDONLY;        
                mgcPort[port].mgcfOperSteps[step].localChnl = aasChnl;
                mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].cmd = MGCP_CMD_CRCX;
                mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                
                mgcConnectInfo[orgConnectIndex].aasChnl = aasChnl;
                
                memcpy((BYTE *) &mgcConnectInfo[aasConnectIndex].mediaAttr.sdp, (BYTE *) &mgcConnectInfo[orgConnectIndex].mediaAttr.sdp, sizeof(PUB_SDP_MSG));
                if (MGC_MG_TYPE_INTERNAL == mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
                {
                    if (duration == 0)
                    {
                        mgcPort[port].mgcfOperSteps[step].delay = MGC_MGCF_TIMER_1H;
                    }
                    else
                    {
                        mgcPort[port].mgcfOperSteps[step].delay = duration * MGC_MGCF_TIMER_1S;
                    }
                }
                mgcPort[port].mgcfOperSteps[step++].chnlConnectIndex = aasChnl.connectNo;
               
                if (MGC_MG_TYPE_INTERNAL != mgcMgInfo[orgChnl.mgNo].mgAttr.mgType)
                {
                    ptime = mgcMgInfo[orgChnl.mgNo].mgAttr.ptime;
                    mgcPort[port].mgcfOperSteps[step].media.ptime = ptime;
                    mgcPort[port].mgcfOperSteps[step].media.conMode = mgcConnectInfo[orgConnectIndex].mediaAttr.conMode;
                    mgcPort[port].mgcfOperSteps[step].localChnl = orgChnl;
                    mgcPort[port].mgcfOperSteps[step].remChnl = aasChnl;
                    mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = orgChnl.connectNo;
                    mgcPort[port].mgcfOperSteps[step].media.vocoderType = mgcConnectInfo[orgConnectIndex].codecList;
                    mgcPort[port].mgcfOperSteps[step].cmd = MGCP_CMD_MDCX;

                    if (duration == 0)
                    {
                        mgcPort[port].mgcfOperSteps[step++].delay = MGC_MGCF_TIMER_1H;
                    }
                    else
                    {
                        mgcPort[port].mgcfOperSteps[step++].delay = duration * MGC_MGCF_TIMER_1S;
                    }
                }
            

                mgcPort[port].mgcfOperSteps[step].localChnl = aasChnl;
				mgcPort[port].mgcfOperSteps[step].remChnl = orgChnl;
                mgcPort[port].mgcfOperSteps[step].chnlConnectIndex = aasChnl.connectNo;
                mgcPort[port].mgcfOperSteps[step++].cmd = MGCP_CMD_DLCX;
            }              
        }
    }
    
    mgcPort[port].mgcfOperId = MGC_OPER_ID_CONNECT_TONE;
    mgcPort[port].mgcfState = MGC_MGCF_STATE_REQUEST;
    
    mgcPort[port].mgcfOperStepsNum = step;
    
    pConnect = &mgcConnectInfo[orgConnectIndex];
    memset(&(pConnect->operRec) , 0 , sizeof(OPER_REC));
	pConnect->operRec.operaId = MGC_OPER_ID_CONNECT_TONE;	
	pConnect->operRec.tone = tone;
	pConnect->operRec.duration = duration;
    
    sprintf(tmpStr, "mgc_connect_tone: succeed, usrPort = %d, Org: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, Dest: mgNo = %d, portNo = %d, chnlNo = %d, connectNo = %d, connectIndex = %d, step = %d\n\r",
                    usrPort, orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo, orgChnl.connectNo, orgConnectIndex, dstChnl.mgNo, dstChnl.portNo, dstChnl.chlNo, dstChnl.connectNo, destConnectIndex, step);
    mgc_log_procedure(orgChnl.mgNo, phyPortOrg, chnlIndexOrg, tmpStr);
    
    return 0;
}

int mgc_query_mg_status(WORD mgNo)
{
    if (mgNo >= MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_query_mg_status: invalid mgNo!\n\r");
        return -1;
    }
    
    return mgcMgInfo[mgNo].status;
}

int mgc_query_port_status(WORD mgNo, BYTE portNo)
{
    if ((mgNo >= MGC_MAX_NUM_OF_MG) ||
        (portNo >= MGC_MAX_PHY_PORT_PER_MG) || (0 == mgcPhyPort[mgcMgInfo[mgNo].portIndex[portNo]].created))
    {
        mgc_log_err("mgc_query_port_status: invalid mgNo or portNo!\n\r");
        return 0;
    }
    
    return mgcPhyPort[mgcMgInfo[mgNo].portIndex[portNo]].phyStatus;
}

int mgc_query_channel_status(CHNL chnl)
{
    if ((chnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_query_channel_status: invalid mgNo or portNo!\n\r");
        return -1;
    }
    
    return mgcChnl[mgcPhyPort[mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo]].chnlStartIndex + chnl.chlNo].status;
}

int mgc_create_virtual_chnl(WORD port, CHNL *chnl)
{
    int     chnlIndex;
    char    tmpStr[128];
    
    chnl->mgNo      = MGC_INTERNAL_VIRTUAL_MG;
    chnl->portNo    = 0;
    if ((chnlIndex = mgc_assign_chnl(0xFF, MGC_INTERNAL_VIRTUAL_MG, 0xFF, MGC_MG_TYPE_INTERNAL)) < 0)
    {
        mgc_log_err("mgc_create_virtual_chnl: can't allocate virtual channel!\n\r");
        return -1;
    }
    
    chnl->chlNo     = chnlIndex - mgcMgInfo[chnl->mgNo].chnlStartIndex;
    
    if (mgc_assign_connect_to_chnl(*chnl) < 0)
    {
        mgc_log_err("mgc_create_virtual_chnl: can't allocate connect!\n\r");
        return -1;
    }
    
    sprintf(tmpStr, "mgc_create_virtual_chnl: succeed, usrPort = %d, assigned chnlIndex = %d\n\r", port, chnlIndex);
    mgc_log_procedure(chnl->mgNo, 0xFFFF, chnlIndex, tmpStr);
//  mgc_asciout_proc(tmpStr);
    
    return 0;
}

int mgc_release_virtual_chnl(WORD port, CHNL chnl)
{
    WORD    chnlIndex;
    char    tmpStr[128];    
    int     connectIndex;
    WORD    associPort;
    WORD    aasChnlIndex;   
    WORD    aasConnectIndex;
    CHNL    aasChnl;    
    
    if ((chnl.mgNo != MGC_INTERNAL_VIRTUAL_MG) ||
        (chnl.portNo != 0))
    {
        mgc_log_err("mgc_release_virtual_chnl: invalid mgNo or portNo!\n\r");
        return -1;
    }
        
    chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    
    if ((connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo]) < MGC_MAX_NUM_OF_CON)
    {
    
        aasChnl = mgcConnectInfo[connectIndex].aasChnl;
        
        if ((aasChnl.mgNo < MGC_MAX_NUM_OF_MG) && (aasChnl.chlNo < MGC_MAX_NUM_OF_CHNL)
            && (aasChnl.connectNo < MGC_MAX_NUM_OF_CHNL_CON))
        {
            aasChnlIndex = mgcMgInfo[aasChnl.mgNo].chnlStartIndex + aasChnl.chlNo;
            
            if ((aasConnectIndex = mgcChnl[aasChnlIndex].connectIndex[aasChnl.connectNo]) < MGC_MAX_NUM_OF_CON)
            {
                associPort = mgcConnectInfo[aasConnectIndex].port;
                if ((associPort < MGC_MAX_NUM_OF_PORT)
                    && (mgcPort[associPort].assigned != 0))
                {
                    mgcPort[associPort].mngCmd = MGC_MNG_CMD_OVERWRITE;
                    mgc_log_err("mgc_release_virtual_chnl: connection aasChnl operation overwritten!\n\r");
                }   
            }   
        }
    }
    else
    {
        mgc_log_err("mgc_release_virtual_chnl: invalid connectIndex!\n\r");
    }       
    
    mgc_remove_chnl(chnlIndex, MGC_CHNL_NUM_INTERNAL_PER_PORT);
    
    sprintf(tmpStr, "mgc_release_virtual_chnl: succeed, usrPort = %d, chnlIndex = %d\n\r", port, chnlIndex);
    mgc_log_procedure(chnl.mgNo, 0xFFFF, chnlIndex, tmpStr);
//  mgc_asciout_proc(tmpStr);
    
    return 0;
}

int mgc_query_chnl_media(WORD port, CHNL chnl, PUB_SDP_MSG **mediaInfo, BYTE *mgPayloads, BYTE *mgPlNum)
{
    WORD    phyPort, chnlIndex;
    WORD    connectIndex;
    int     i;
    char    tmpStr[128];
    
    if ((chnl.mgNo >= MGC_MAX_NUM_OF_MG) ||
        (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG))
    {
        mgc_log_err("mgc_query_chnl_media: invalid mgNo or portNo!\n\r");
        return -1;
    }
    
    if (mgcMgInfo[chnl.mgNo].mgAttr.mgType == MGC_MG_TYPE_INTERNAL)
        chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    else
    {
        phyPort = mgcMgInfo[chnl.mgNo].portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }
    
    if ((connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
    {
        return -1;
    }

    if ((mgcConnectInfo[connectIndex].status != MGC_CONNECT_STATUS_CREATED)&&(mgcConnectInfo[connectIndex].status != MGC_CONNECT_STATUS_TONE))  
//  if (mgcChnl[chnlIndex].status != MGC_CHNL_STATUS_CREATED)
        return -1;
    
    *mediaInfo = &mgcConnectInfo[connectIndex].mediaAttr.sdp;

    for (i = 0; i < mgcConnectInfo[connectIndex].codecList.num; i++)
    {
        mgPayloads[i] = mgc_codec_to_payload(mgcConnectInfo[connectIndex].codecList.codec[i]);
    }

    *mgPlNum = mgcConnectInfo[connectIndex].codecList.num;
//  *mediaInfo = &mgcChnl[chnlIndex].mediaAttr.sdp;

    sprintf(tmpStr, "mgc_query_chnl: rtpmap=%s\n\r", (*mediaInfo)->medias.medias[0].attrs.attrs[0].aValue);
    mgc_asciout_proc(tmpStr);

    return 0;
}

int mgc_payload_to_codec(WORD payload, PUB_SDP_ATTRS attrs)
{
    BYTE    i = 0;

    if (attrs.num > 0)
    {
        for (i = 0; i < attrs.num; i++)
        {
            if (attrs.attrs[i].aType != PUB_SDP_ATTR_TYPE_RTPMAP)
            {
                continue;
            }

            if (strtol(attrs.attrs[i].aValue, NULL, 10) == payload)
            {
                if (strstr(attrs.attrs[i].aValue, " GSM/") != NULL)
                    return MGC_VCTYPE_GSM;
                else if (strstr(attrs.attrs[i].aValue, "GSM-EFR") != NULL)
                    return MGC_VCTYPE_GSM_EFR;
                else if (strstr(attrs.attrs[i].aValue, "AMR") != NULL)
                    return MGC_VCTYPE_AMR_12_2;
                else if (strstr(attrs.attrs[i].aValue, "G729B") != NULL)
                    return MGC_VCTYPE_G729B;
                else if (strstr(attrs.attrs[i].aValue, "PCMU") != NULL)
                    return MGC_VCTYPE_PCMU;
				else if (strstr(attrs.attrs[i].aValue, "AMR_12_2") != NULL)
					return MGC_VCTYPE_AMR_12_2;
				else if (strstr(attrs.attrs[i].aValue, "AMR_10_2") != NULL)
					return MGC_VCTYPE_AMR_10_2;
				else if (strstr(attrs.attrs[i].aValue, "AMR_7_95") != NULL)
					return MGC_VCTYPE_AMR_7_95;
				else if (strstr(attrs.attrs[i].aValue, "AMR_7_4") != NULL)
					return MGC_VCTYPE_AMR_7_4;
				else if (strstr(attrs.attrs[i].aValue, "AMR_6_7") != NULL)
					return MGC_VCTYPE_AMR_6_7;
				else if (strstr(attrs.attrs[i].aValue, "AMR_5_15") != NULL)
					return MGC_VCTYPE_AMR_5_15;
				else if (strstr(attrs.attrs[i].aValue, "AMR_5_9") != NULL)
					return MGC_VCTYPE_AMR_5_9;
				else if (strstr(attrs.attrs[i].aValue, "AMR_4_75") != NULL)
					return MGC_VCTYPE_AMR_4_75;				
                else
                    return MGC_VCTYPE_PCMA;
            }
        }
    }
    
    if (i == attrs.num)
    {
        if (payload == 3)
            return MGC_VCTYPE_GSM;
        else if (payload == 84)
            return MGC_VCTYPE_GSM_EFR;
        else if (payload == 118)
            return MGC_VCTYPE_G729B;
        else if (payload == 0)
            return MGC_VCTYPE_PCMU;
        else if (payload == 71)
            return MGC_VCTYPE_AMR_12_2;
        else if (payload == 70)
            return MGC_VCTYPE_AMR_10_2;
        else if (payload == 69)
            return MGC_VCTYPE_AMR_7_95;
        else if (payload == 68)
            return MGC_VCTYPE_AMR_7_4;
        else if (payload == 67)
            return MGC_VCTYPE_AMR_6_7;
        else if (payload == 65)
            return MGC_VCTYPE_AMR_5_15;
        else if (payload == 66)
            return MGC_VCTYPE_AMR_5_9;
        else if (payload == 64)
            return MGC_VCTYPE_AMR_4_75;		
    }
    
    return MGC_VCTYPE_PCMA;
}

int mgc_update_chnl_media(WORD port, CHNL chnl, PUB_SDP_MSG *mediaInfo)
{
    WORD    chnlIndex;
    BYTE    i;
    WORD    connectIndex;   
    BYTE    ptime;
    char    tmpStr[128];
    
    if ((chnl.mgNo != MGC_INTERNAL_VIRTUAL_MG) ||
        (chnl.portNo != 0))
    {
        mgc_log_err("mgc_update_chnl_media: invalid mgNo or portNo!\n\r");
        return -1;
    }
    
    chnlIndex = mgcMgInfo[chnl.mgNo].chnlStartIndex + chnl.chlNo;
    
    connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo];
    
    if (connectIndex > MGC_MAX_NUM_OF_CON)
    {
        mgc_log_err("mgc_update_chnl_media: invalid chnl connectNo!\n\r");
        return -1;      
    }   
    
    memcpy((BYTE *) &mgcConnectInfo[connectIndex].mediaAttr.sdp, mediaInfo, sizeof(PUB_SDP_MSG));
//  memcpy((BYTE *) &mgcChnl[chnlIndex].mediaAttr.sdp, mediaInfo, sizeof(PUB_SDP_MSG));

    mgcConnectInfo[connectIndex].codecList.num = mediaInfo->medias.medias[0].m.plNum;   
    for (i = 0; i < mgcConnectInfo[connectIndex].codecList.num; i++)
    {
        mgcConnectInfo[connectIndex].codecList.codec[i] = mgc_payload_to_codec(mediaInfo->medias.medias[0].m.payloads[i], mediaInfo->medias.medias[0].attrs);
    }
    mgcConnectInfo[connectIndex].codecList.priority = 256;

    if (chnl.mgNo == MGC_MG_TYPE_INTERNAL)
    {
        mgcMgInfo[chnl.mgNo].mgAttr.codecList.num = mediaInfo->medias.medias[0].m.plNum;

        for (i = 0; i < mgcConnectInfo[connectIndex].codecList.num; i++)
        {
            mgcMgInfo[chnl.mgNo].mgAttr.codecList.codec[i] = mgcConnectInfo[connectIndex].codecList.codec[i];
        }
    }

    for (i = 0; i < mediaInfo->medias.medias[0].attrs.num; i++)
    {
        if (mediaInfo->medias.medias[0].attrs.attrs[i].aType == PUB_SDP_ATTR_TYPE_PTIME)
        {
            ptime = atoi(mediaInfo->medias.medias[0].attrs.attrs[0].aValue);
            break;
        }
    }

    if (i == mediaInfo->medias.medias[0].attrs.num)
        ptime = 20;   

    mgcConnectInfo[connectIndex].mediaAttr.ptime = ptime;
    
    if (MGC_MG_TYPE_INTERNAL == mgcMgInfo[chnl.mgNo].mgAttr.mgType)
    {
//      mgcChnl[chnl.chlNo].status = MGC_CHNL_STATUS_CREATED;
        mgcConnectInfo[connectIndex].status = MGC_CONNECT_STATUS_CREATED;
    }    
    
//  mgcChnl[chnlIndex].codecList.num = mediaInfo->medias.medias[0].m.plNum;
//  for (i = 0; i < mgcChnl[chnlIndex].codecList.num; i++)
//      mgcChnl[chnlIndex].codecList.codec[i] = mgc_payload_to_codec(mediaInfo->medias.medias[0].m.payloads[i]);
//  mgcChnl[chnlIndex].codecList.priority = 1;
    sprintf(tmpStr, "mgc_update_chnl_media: codec=%d, connectIndex=%d\n\r", mgcConnectInfo[connectIndex].codecList.codec[0], connectIndex);
    mgc_asciout_proc(tmpStr);

    return 0;
}

int mgc_license_ctrl(WORD maxMgNum, WORD maxChnlNum)
{
    char    tmpStr[128];
    
    if ((maxMgNum > MGC_MAX_NUM_OF_MG) ||
        (maxChnlNum > MGC_MAX_NUM_OF_CHNL))
    {
        mgc_log_err("mgc_license_ctrl: invalid maxMgNum or maxChnlNum!\n\r");
        return -1;
    }
    
    mgcMaxMgNo  = maxMgNum;
    mgcMaxChlNo = maxChnlNum;
    
    sprintf(tmpStr, "mgc_license_ctrl: succeed, mgcMaxMgNo = %d, mgcMaxChlNo = %d\n\r", mgcMaxMgNo, mgcMaxChlNo);
    mgc_asciout_proc(tmpStr);
    
    return 0;
}

int mgc_rsp(BYTE cmd, WORD usrPort, WORD port, WORD retCode, MEDIA_ATTR *mediaAttr)
{
    WORD        portIndex;
    WORD        chnlIndex;
    PORT_INFO   *portInfo;
    char        tmpStr[128];
    int         connectIndex;   
    
    if ((port >= MGC_MAX_NUM_OF_PORT) ||
        ((cmd != MGCP_CMD_CRCX) && (mgcPort[port].usrPort != usrPort)) ||
        (mgcPort[port].llCmd != cmd))
    {
        mgc_log_err("mgc_rsp: invalid port or cmd!\n\r");
        return -1;
    }
    
    portInfo = &mgcPort[port];
    
    if (MGC_MG_TYPE_ANN == mgcMgInfo[portInfo->mgcfChnl.mgNo].mgAttr.mgType)
    {
        chnlIndex = mgcMgInfo[portInfo->mgcfChnl.mgNo].chnlStartIndex + portInfo->mgcfChnl.chlNo;
    }
    else
    {
        portIndex = mgcMgInfo[portInfo->mgcfChnl.mgNo].portIndex[portInfo->mgcfChnl.portNo];
        chnlIndex = mgcPhyPort[portIndex].chnlStartIndex + portInfo->mgcfChnl.chlNo;
    }
    
    
    if ((cmd == MGCP_CMD_CRCX) && (retCode == 200))
    {
        if ((connectIndex = mgcChnl[chnlIndex].connectIndex[portInfo->mgcfChnl.connectNo]) >= MGC_MAX_NUM_OF_CON)
        {
            mgc_log_err("mgc_rsp: CRCX invalid connectIndex!\n\r");
            return -1;      
        }        

        sprintf(mgcConnectInfo[connectIndex].mediaAttr.conId, "%X%04X%lX", portInfo->mgcfChnl.connectNo, usrPort, time(NULL));      
        
//      memcpy((BYTE *) &mgcChnl[chnlIndex].mediaAttr.sdp, (BYTE *) mediaAttr, sizeof(PUB_SDP_MSG));
        memcpy((BYTE *) &mgcConnectInfo[connectIndex].mediaAttr.sdp, (BYTE *) &mediaAttr->sdp, sizeof(PUB_SDP_MSG));
    }
    
    mgcPort[port].usrCmd = retCode;
    
    sprintf(tmpStr, "mgc_rsp: succeed, usrPort = %d, port = %d, retCode = %d, cmd = %d\n\r", usrPort, port, retCode, cmd);
    mgc_log_procedure(portInfo->mgcfChnl.mgNo, portIndex, chnlIndex, tmpStr);
    
    return 0;
}

/*
Parameter
  chnl: the chnl need to update codec
  codecList: the codec up layer support
Result
  failure: return -1
  sucess : return 0~6 which is represent following codec

#define MGC_VCTYPE_PCMA             0
#define MGC_VCTYPE_PCMU             1
#define MGC_VCTYPE_GSM              2
#define MGC_VCTYPE_GSM_EFR          3
#define MGC_VCTYPE_AMR              4
#define MGC_VCTYPE_G729B            5
#define MGC_VCTYPE_AMR_7_4           6
*/
int mgc_chnl_codec_update(CHNL chnl , MGC_CODEC_LIST codecList)
{
    MG_INFO *pMgInfo;
    WORD    chnlIndex, phyPort;
	int connectIndex;
	MGC_CODEC_LIST codecListMg;	
	MGC_CODEC_LIST codecListResult;
	BYTE codec;
    CONNECT_INFO *pConn = NULL;
	int i,j;
	
    if(chnl.mgNo > MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_chnl_codec_update: invalid mgNo!\n\r");
		return -1;
    }        
	
	pMgInfo = &mgcMgInfo[chnl.mgNo];
	if(pMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)
	    return -1;

    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
	    mgc_log_err("mgc_chnl_codec_update: invalid portNo!\n\r");
	    return -1;
    }

    if (chnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON)
    {
	    mgc_log_err("mgc_chnl_codec_update: invalid connectNo!\n\r");
	    return -1;		
    }


    if ((MGC_MG_TYPE_ANN == pMgInfo->mgAttr.mgType)||(MGC_MG_TYPE_INTERNAL == pMgInfo->mgAttr.mgType))
    {
        chnlIndex = pMgInfo->chnlStartIndex + chnl.chlNo;
    }
    else
    {   
        phyPort = pMgInfo->portIndex[chnl.portNo];
        chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }	

    if ((chnlIndex >= MGC_MAX_NUM_OF_CHNL) 
	    || ((mgcMgInfo[chnl.mgNo].mgAttr.mgType != MGC_MG_TYPE_ANN) && (phyPort >= MGC_MAX_NUM_OF_PHY_PORT)))
    {
	    mgc_log_err("mgc_chnl_codec_update: invalid chnlIndex or phyPort!\n\r");
	    return -1;
    }

    if((mgcChnl[chnlIndex].connectIndex[chnl.connectNo] >= MGC_MAX_NUM_OF_CON)||
		((mgcConnectInfo[mgcChnl[chnlIndex].connectIndex[chnl.connectNo]].assigned != 1)))
    {
        connectIndex = mgc_assign_connect_to_chnl(chnl);
		if(connectIndex < 0)
		    return -1;	
	}
	else
	{
        connectIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo];
	}

	pConn = &mgcConnectInfo[connectIndex];

    memset(&codecListResult , 0 , sizeof(MGC_CODEC_LIST));
    memcpy(&codecListMg , &pMgInfo->mgAttr.codecList , sizeof(MGC_CODEC_LIST));
    codecListMg.priority = codecList.priority + 1;	

        for(i=0 ; i<codecListMg.num ; i++)
            {
            codec = codecListMg.codec[i];	
			for(j=0 ; j<codecList.num ; j++)
                {
			    switch(codec)
                    {
						case MGC_VCTYPE_AMR_12_2: 
						case MGC_VCTYPE_AMR_10_2:
				   	    if(codecList.codec[j] == MGC_VCTYPE_AMR_12_2)
				   	    {
				   	        codecListResult.codec[codecListResult.num] = codec;
							codecListResult.num++;
				   	    }
				        break; 	
						case MGC_VCTYPE_AMR_7_95:
						case MGC_VCTYPE_AMR_7_4:
						case MGC_VCTYPE_AMR_6_7:
						case MGC_VCTYPE_AMR_5_15:
						case MGC_VCTYPE_AMR_5_9:
						case MGC_VCTYPE_AMR_4_75:	
				   	    if((codecList.codec[j] == MGC_VCTYPE_AMR_12_2)||(codecList.codec[j] == MGC_VCTYPE_AMR_7_95))
				   	    {
				   	        codecListResult.codec[codecListResult.num] = codec;
							codecListResult.num++;
				   	    }				   	
							break;
						default:
						if(codecList.codec[j] == codec)
						{
				   	        codecListResult.codec[codecListResult.num] = codec;
							codecListResult.num++;						    
						}
							break;
                    }
                }
            }

		if(codecListResult.num == 0)
		    return -1;

    if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_IPBSS)		
	    memcpy(&pConn->codecList , &codecListResult , sizeof(MGC_CODEC_LIST));

		switch(codecListResult.codec[0])
         	{
		    case MGC_VCTYPE_AMR_12_2: 
		    case MGC_VCTYPE_AMR_10_2:
		           return MGC_VCTYPE_AMR_12_2;
		    case MGC_VCTYPE_AMR_7_95:
	            case MGC_VCTYPE_AMR_7_4:
		    case MGC_VCTYPE_AMR_6_7:
		    case MGC_VCTYPE_AMR_5_15:
		    case MGC_VCTYPE_AMR_5_9:
		    case MGC_VCTYPE_AMR_4_75:	
        		    return MGC_VCTYPE_AMR_7_95;
		    default:
			 return codecListResult.codec[0];
               }        

	return -1;
}


/*
Parameter
    chnl: the chnl need to be queried
Result:
    failure:  return -1
    success: return 0~3 which represent following status

#define MGC_CONNECT_STATUS_IDLE		   0
#define MGC_CONNECT_STATUS_CREATING	   1
#define MGC_CONNECT_STATUS_CREATED     2
#define MGC_CONNECT_STATUS_TONE 3
*/
int mgc_query_chnl_status(CHNL chnl)
{
    MG_INFO *pMgInfo;
    WORD    chnlIndex, phyPort , connIndex;

    if(chnl.mgNo > MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_query_chnl_status: invalid mgNo!\n\r");
		return -1;
    }    

    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
	    mgc_log_err("mgc_query_chnl_status: invalid portNo!\n\r");
	    return -1;
    }

    if (chnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON)
    {
	    mgc_log_err("mgc_query_chnl_status: invalid connectNo!\n\r");
	    return -1;		
    }


    pMgInfo = &mgcMgInfo[chnl.mgNo];

    if ((MGC_MG_TYPE_ANN == pMgInfo->mgAttr.mgType)||(MGC_MG_TYPE_INTERNAL == pMgInfo->mgAttr.mgType))
    {
	    chnlIndex = pMgInfo->chnlStartIndex + chnl.chlNo;
    }
    else
    {	
	    phyPort = pMgInfo->portIndex[chnl.portNo];
	    chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }	

    connIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo];

    if(connIndex > MGC_MAX_NUM_OF_CON)	
	    return -1;	

    return(mgcConnectInfo[connIndex].status);	
}


OPER_REC *mgc_query_chnl_oper_rec(CHNL chnl)
{
    MG_INFO *pMgInfo;
    WORD    chnlIndex, phyPort , connIndex;

    if(chnl.mgNo > MGC_MAX_NUM_OF_MG)
    {
        mgc_log_err("mgc_query_chnl_status: invalid mgNo!\n\r");
		return NULL;
    }    

    if (chnl.portNo >= MGC_MAX_PHY_PORT_PER_MG)
    {
	    mgc_log_err("mgc_query_chnl_status: invalid portNo!\n\r");
	    return NULL;
    }

    if (chnl.connectNo >= MGC_MAX_NUM_OF_CHNL_CON)
    {
	    mgc_log_err("mgc_query_chnl_status: invalid connectNo!\n\r");
	    return NULL;		
    }


    pMgInfo = &mgcMgInfo[chnl.mgNo];

    if ((MGC_MG_TYPE_ANN == pMgInfo->mgAttr.mgType)||(MGC_MG_TYPE_INTERNAL == pMgInfo->mgAttr.mgType))
    {
	    chnlIndex = pMgInfo->chnlStartIndex + chnl.chlNo;
    }
    else
    {	
	    phyPort = pMgInfo->portIndex[chnl.portNo];
	    chnlIndex = mgcPhyPort[phyPort].chnlStartIndex + chnl.chlNo;
    }	

    connIndex = mgcChnl[chnlIndex].connectIndex[chnl.connectNo];

    if(connIndex > MGC_MAX_NUM_OF_CON)	
	    return NULL;	

    return &(mgcConnectInfo[connIndex].operRec); 	    
}
