Files
svc.ems/plat/mgc_v2/src/mgc.c
2024-09-27 15:39:34 +08:00

2634 lines
90 KiB
C

/*
*********************************************************************************
* *
* NOTICE: *
* *
*********************************************************************************
*
*
*
* mgcSap <---------mgcPhyPorts --------> mgcMgInfo
* |
* |
* |
* mgcChnls <-----------mgcConnections
*/
/*********************************************************************************
* <mgc.c>
* This file contain APIs which is provided to uplayer to implement media control between sessions
* by using MGCP protocol
*
*
* Author Date
* ------ ------
* Sam Yao Aug 2008
*********************************************************************************/
#define MGC_AAS_ITL_PORT_NO 255
/*-----------------------------------------------------------------------*/
/* INCLUDE HEADER FILES */
/*-----------------------------------------------------------------------*/
#include "./include/mgc_struct.h"
#include "./include/mgc_debug.h"
#include "./include/mgc_chnl_info.h"
#include "./include/mgc_mg_info.h"
#include "./include/mgc_port_info.h"
#include "./include/mgc_conn_info.h"
#include "./include/mgc_ctl.h"
#include "./include/mgc_8ecp.h"
#include "./include/mgc_phy_port.h"
#include "./include/mgc_mgcp.h"
#include "./include/mgc_internal.h"
#include "./include/mgc_snmp.h"
#include "./include/mgc_tandem_info.h"
#include "./include/mgc_sur_info.h"
#ifdef MGC_PORT_LIST_EN
#include "./include/mgc_port_list.h"
#endif
static MGC_SAP mgcSap[MGC_MAX_NUM_OF_SAP];
/*-----------------------------------------------------------------------*/
/* MODULE FUNCTIONS */
/*-----------------------------------------------------------------------*/
static int mgc_get_snmp_msg(void);
/*-----------------------------------------------------------------------
MGC - SAP M A N A G E R
------------------------------------------------------------------------*/
char *mgc_print_failure_reason(int ret)
{
if(ret >= 0)
return "MGC_RESULT_OK";
switch(ret)
{
case MGC_RESULT_FAILURE:
return "MGC_RESULT_FAILURE";
case MGC_RESULT_INPUT_ILLEGAL:
return "MGC_RESULT_INPUT_ILLEGAL";
case MGC_RESULT_NO_RES:
return "MGC_RESULT_NO_RES";
case MGC_RESULT_LACK_PARA:
return "MGC_RESULT_LACK_PARA";
default:
break;
}
return "MGC_RESULT_UNKNOW_REASON";
}
/***************************************************************************
* mgc_sap_init
* ------------------------------------------------------------------------
* General: init MGC_SAP structure object , and set the id of this MGC_SAP object.
* Return Value: void.
* ------------------------------------------------------------------------
* Arguments:
* Input: pMgcSap - pointer of the MGC_SAP object which want to be init
* id - the id of this MGC_SAP object should be, this id can't be set out of MGC module
***************************************************************************/
static void mgc_sap_init(MGC_SAP *pMgcSap , int id)
{
if(pMgcSap == NULL)
return ;
pMgcSap->id = id;
memset(pMgcSap->usrName , 0 , MGC_MAX_USER_NAME_LEN);
pMgcSap->usrType = MGC_USER_TYPE_UNDEF;
pMgcSap->cnf_func = NULL;
pMgcSap->ind_func = NULL;
return;
}
static void mgc_sap_setup(void)
{
int i;
MGC_SAP *pMgcSap = NULL;
for(i=0 ; i<MGC_MAX_NUM_OF_SAP ; i++)
{
pMgcSap = &mgcSap[i];
mgc_sap_init(pMgcSap , i);
}
return;
}
/***************************************************************************
* mgc_sap_get_index_sap
* ------------------------------------------------------------------------
* General: get the pointer of the MGC_SAP object.
* Return Value: if failed return NULL , else return a pointer.
* ------------------------------------------------------------------------
* Arguments:
* Input: index - the index of MGC_SAP object
*
***************************************************************************/
MGC_SAP *mgc_sap_get_index_sap(int index)
{
if((index < 0)||(index>= MGC_MAX_NUM_OF_SAP))
return NULL;
return &(mgcSap[index]);
}
/***************************************************************************
* mgc_sap_get_idle_sap
* ------------------------------------------------------------------------
* General: get an pointer of the MGC_SAP object which is not used.
* Return Value: if failed return NULL , else return a pointer.
* ------------------------------------------------------------------------
* Arguments:
* Input: void
*
***************************************************************************/
static MGC_SAP *mgc_sap_get_idle_sap(void)
{
int i;
MGC_SAP *pSap = NULL;
for(i=0 ; i< MGC_MAX_NUM_OF_SAP ; i++)
{
pSap = &mgcSap[i];
if((pSap->usrType == MGC_USER_TYPE_UNDEF)&&(pSap->ind_func == NULL) && (pSap->cnf_func == NULL))
return pSap;
}
return NULL;
}
/***************************************************************************
* mgc_sap_is_already_bind
* ------------------------------------------------------------------------
* General: check if the MGC_SAP object is already exist.
* Return Value: if not exist return NULL , else return a pointer.
* ------------------------------------------------------------------------
* Arguments:
* Input: pSap- the pointer
*
***************************************************************************/
static MGC_SAP *mgc_sap_is_already_bind(MGC_SAP *pSap)
{
int i;
MGC_SAP *pSapTmp = NULL;
if(pSap == NULL)
return NULL;
for(i=0 ; i<MGC_MAX_NUM_OF_SAP ; i++)
{
pSapTmp = &mgcSap[i];
if(pSapTmp->usrType == MGC_USER_TYPE_UNDEF)
continue;
if(strcmp(pSapTmp->usrName , pSap->usrName) != 0)
continue;
return pSapTmp;
}
return NULL;
}
/*-----------------------------------------------------------------------
MGC - INTERFACE M A N A G E R
------------------------------------------------------------------------*/
/***************************************************************************
* mgc_init
* ------------------------------------------------------------------------
* General: init mgc module, which is used by up-layer
* Return Value: void.
* ------------------------------------------------------------------------
* Arguments:
* Input: systemId - the ID of the MGC
* localIp - the IP of the MGC
* peerIp - the IP of the peer object
*
* Notice : the input arguments is not actually useful, just for keep interface unchange
***************************************************************************/
void mgc_init(DWORD systemId, DWORD localIp, DWORD peerIp)
{
mgc_debug_set();
MGC_DEBUG("MGC %ld init start!!" , systemId);
if(mgc_bind_8ecp_setup() < 0)
return;
if(mgc_bind_mgcp_setup() < 0)
return;
mgc_sap_setup();
mgc_phy_port_setup();
mgc_mg_info_setup();
mgc_chnl_info_setup();
mgc_connect_setup();
mgc_port_info_setup();
mgc_tandem_info_setup();
mgc_sur_info_setup();
mgc_ctl_num_init(systemId , localIp , peerIp);
#ifdef MGC_PORT_LIST_EN
mgc_port_list_setup();
#endif
/*create internal mg, need to be done*/
if(mgc_internal_sap_bind() == FALSE)
{
MGC_ERROR("bind internal sap failed");
return;
}
if(mgc_internal_mg_create() == FALSE)
{
MGC_ERROR("create internal mg failed!");
return;
}
MGC_DEBUG("mgc module init over");
return;
}
/***************************************************************************
* mgc_bind
* ------------------------------------------------------------------------
* General: bind up-layer user info to MGC_SAP object
* Return Value: if failed return -1 , else return the id of the MGC_SAP object.
* ------------------------------------------------------------------------
* Arguments:
* Input: pSap - pointer to the up-layer info
*
***************************************************************************/
int mgc_bind(MGC_SAP *pSap)
{
MGC_SAP *pSapIdle = NULL;
#ifndef MGC_TEST_ENABLE
if (wxc2_get_license(LIC_MGC) <= 0)
{
MGC_ERROR("mgc_bind: mgc module is not presented!");
return MGC_RESULT_INPUT_ILLEGAL;
}
#endif
if(pSap == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
switch(pSap->usrType)
{
case MGC_USER_TYPE_MG:
if(pSap->ind_func == NULL)
return MGC_RESULT_LACK_PARA;
break;
case MGC_USER_TYPE_MGC:
if(pSap->cnf_func == NULL)
return MGC_RESULT_LACK_PARA;
break;
default:
return MGC_RESULT_INPUT_ILLEGAL;
}
pSapIdle = mgc_sap_is_already_bind(pSap);
if(pSapIdle != NULL)
{
MGC_WARN("mgcSap[%d] already bind" , pSap->id);
return pSapIdle->id;
}
pSapIdle = mgc_sap_get_idle_sap();
if(pSapIdle == NULL)
return MGC_RESULT_NO_RES;
sprintf(pSapIdle->usrName , "%s" , pSap->usrName);
pSapIdle->usrType = pSap->usrType;
pSapIdle->ind_func = pSap->ind_func;
pSapIdle->cnf_func = pSap->cnf_func;
MGC_DEBUG("mgcSap[%d] %s bind !" , pSapIdle->id , pSapIdle->usrName);
return pSapIdle->id;
}
/***************************************************************************
* mgc_unbind
* ------------------------------------------------------------------------
* General: remove the up-layer info from MGC_SAP objects
* Return Value: if failed return -1 , else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: pSap - pointer to the up-layer info which want to be remove
* sapIndex - the MGC_SAP object id which is returned when use mgc_bind
***************************************************************************/
int mgc_unbind(MGC_SAP *pSap, BYTE sapIndex)
{
MGC_SAP *pDestSap = NULL;
if(pSap == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pDestSap = mgc_sap_get_index_sap(sapIndex);
if(pDestSap == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if((pSap->usrType != pDestSap->usrType)||(strcmp(pSap->usrName , pDestSap->usrName)))
{
MGC_WARN("unbind mgc sap not matched!");
}
MGC_DEBUG("mgcSap[%d] %s unbind !" ,pDestSap->id,pDestSap->usrName);
mgc_sap_init(pDestSap , pDestSap->id);
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_misc_timer
* ------------------------------------------------------------------------
* General: handle snmp msg and debug msg reciving
* Return Value: void
* ------------------------------------------------------------------------
* Arguments:
* Input: void
***************************************************************************/
static void mgc_misc_timer(void)
{
static DWORD cntT50ms;
if(cntT50ms++ >= MGC_MGCF_TIMER_50MS)
{
cntT50ms = 0;
mgc_get_snmp_msg();
}
mgc_mon();
}
/***************************************************************************
* mgc_timer
* ------------------------------------------------------------------------
* General: mgc Module polling
* Return Value: void
* ------------------------------------------------------------------------
* Arguments:
* Input: void
***************************************************************************/
void mgc_timer(void)
{
#ifndef MGC_PORT_LIST_EN
PORT_INFO *pPortInfo = NULL;
#endif
MG_INFO *pMgInfo = NULL;
int i;
#ifndef MGC_PORT_LIST_EN
for(i=0 ; i<MGC_MAX_NUM_OF_PORT ; i++)
{
pPortInfo = mgc_port_info_find_port_by_id(i);
mgc_port_info_fsm(pPortInfo);
}
#else
mgc_port_active_list_proc();
#endif
for(i=0 ; i<MGC_MAX_NUM_OF_MG ; i++)
{
pMgInfo = mgc_mg_info_get_index_mg(i);
mgc_mg_info_state_check(pMgInfo);
}
mgc_misc_timer();
}
/***************************************************************************
* mgc_create_MG
* ------------------------------------------------------------------------
* General: inferace for up-layer create mg
* Return Value: if failure return -1, else return the id of the MG_INFO object
* ------------------------------------------------------------------------
* Arguments:
* Input: sapIndex - the id of the MGC_SAP object which is provided by mgc_bind
* pMgAttr - the pointer of the MG attribute
***************************************************************************/
int mgc_create_MG(BYTE sapIndex, MG_ATTR *pMgAttr)
{
MGC_SAP *pMgcSap = NULL;
MG_INFO *pMgInfo = NULL;
int i;
BOOL tag;
PHY_PORT_INFO *pPhyPort;
MGC_PHY_PORT_TYPE portType = MGC_PHY_PORT_TYPE_UNDEF;
if(pMgAttr == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(mgc_ctl_is_mg_full())
return MGC_RESULT_NO_RES;
pMgcSap = mgc_sap_get_index_sap(sapIndex);
if(pMgcSap == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgAttr->mgType == MGC_MG_TYPE_ANN)
{
portType = MGC_PHY_VIRTUAL_TYPE_ANN;
}
else if(pMgAttr->mgType == MGC_MG_TYPE_TANDEM)
{
portType = MGC_PHY_VIRTUAL_TYPE_TANDEM;
}
pMgInfo = mgc_mg_info_check_mg_is_exsit(pMgAttr);
if(pMgInfo != NULL)
{
/*check if the same sapIndex already create MGC_MG_TYPE_ANN*/
if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_ANN)
{
tag = FALSE;
for(i=0 ; i<MGC_MAX_PHY_PORT_PER_MG ; i++)
{
pPhyPort = pMgInfo->pPhyPort[i];
if(pPhyPort == NULL)
continue;
if(pPhyPort->pMgcSap != pMgcSap)
continue;
tag = TRUE; // the same user already create MGC_MG_TYPE_ANN
}
if(tag == FALSE) //new user create MGC_MG_TYPE_ANN
{
pPhyPort = mgc_phy_port_get_unused_phy();
/*only add one phyPort for rtp_proxy*/
if(mgc_add_port(sapIndex, pMgInfo->id, MGC_AAS_ITL_PORT_NO,portType) < 0)
{
mgc_delete_MG(sapIndex, pMgInfo->id);
return MGC_RESULT_FAILURE ;
}
}
}
return pMgInfo->id;
}
pMgInfo = mgc_mg_info_get_unused_mg();
if(pMgInfo == NULL)
return MGC_RESULT_NO_RES;
if(mgc_mg_info_assign_attr(pMgInfo ,pMgAttr) == FALSE)
{
mgc_mg_info_init(pMgInfo, pMgInfo->id);
return MGC_RESULT_FAILURE ;
}
mgc_ctl_mg_add_one();
if(pMgAttr->mgType == MGC_MG_TYPE_ANN)
{
pPhyPort = mgc_phy_port_get_unused_phy();
/*only add one phyPort for rtp_proxy*/
MGC_DEBUG("add phyPort[%d] to aas" , pPhyPort->id);
if(mgc_add_port(sapIndex, pMgInfo->id, MGC_AAS_ITL_PORT_NO,portType) < 0)
{
mgc_delete_MG(sapIndex, pMgInfo->id);
return MGC_RESULT_FAILURE ;
}
}
if(pMgAttr->mgType == MGC_MG_TYPE_TANDEM)
{
if(mgc_tandem_info_add_tandem_res(sapIndex , pMgInfo->id) == FALSE)
{
mgc_delete_MG(sapIndex, pMgInfo->id);
return MGC_RESULT_FAILURE ;
}
if(mgc_sur_info_add_survillance_res(sapIndex, pMgInfo->id) == FALSE)
{
MGC_ERROR("add survilliance res failed!");
mgc_delete_MG(sapIndex, pMgInfo->id);
return MGC_RESULT_FAILURE ;
}
}
MGC_DEBUG("create mg[%d] %s success" , pMgInfo->id , pMgInfo->mgAttr.domain);
return pMgInfo->id;
}
/***************************************************************************
* mgc_delete_MG
* ------------------------------------------------------------------------
* General: inferace for up-layer delete mg
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: sapIndex - the id of the MGC_SAP object which is provided by mgc_bind
* mgNo - the id of which MG_INFO need to be removed
***************************************************************************/
int mgc_delete_MG(BYTE sapIndex, WORD mgNo)
{
MG_INFO *pMgInfo = NULL;
MGC_SAP *pMgcSap = NULL;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
pMgcSap = mgc_sap_get_index_sap(sapIndex);
if((pMgInfo == NULL)||(pMgcSap) == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->created == FALSE)
{
MGC_WARN("mg[%d] is not created, could not delete" , pMgInfo->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
switch(pMgInfo->mgAttr.ctrlType)
{
case MGC_MG_CTRL_TYPE_8ECP:
mgc_8ecp_delete(pMgInfo);
break;
case MGC_MG_CTRL_TYPE_MGCP:
break;
default:
MGC_WARN("mg[%d] unsupport ctrlType %d" , pMgInfo->id , pMgInfo->mgAttr.ctrlType);
break;
}
mgc_mg_info_clear(pMgInfo);
MGC_DEBUG("remove mg[%d] success" , pMgInfo->id);
mgc_ctl_mg_remove_one();
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_modify_MG
* ------------------------------------------------------------------------
* General: inferace for up-layer to modify mg
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: sapIndex - the id of the MGC_SAP object which is provided by mgc_bind
* mgNo - the id of which MG_INFO need to be modified
* pMgAttr - pointer of the new mg attribute
***************************************************************************/
int mgc_modify_MG(BYTE sapIndex, WORD mgNo, MG_ATTR *pMgAttr)
{
MG_INFO *pMgInfo = NULL;
MGC_SAP *pMgcSap = NULL;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
pMgcSap = mgc_sap_get_index_sap(sapIndex);
if((pMgInfo == NULL)||(pMgcSap) == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->created == FALSE)
{
MGC_ERROR("mg[%d] is not created, could not modify" , pMgInfo->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
if(pMgInfo->mgAttr.ctrlType != pMgAttr->ctrlType)
{
MGC_ERROR("do not support different ctltype modify");
return MGC_RESULT_INPUT_ILLEGAL;
}
switch(pMgAttr->ctrlType)
{
case MGC_MG_CTRL_TYPE_8ECP:
mgc_8ecp_create(pMgInfo, pMgAttr);
break;
case MGC_MG_CTRL_TYPE_MGCP:
mgc_mg_info_assign_attr(pMgInfo , pMgAttr);
break;
default:
MGC_WARN("mg[%d] unsupport ctrlType %d" , pMgInfo->id , pMgInfo->mgAttr.ctrlType);
return MGC_RESULT_INPUT_ILLEGAL;
}
MGC_DEBUG("modify mg[%d] %s success" , pMgInfo->id , pMgInfo->mgAttr.domain);
return MGC_RESULT_OK;
}
static char *mgc_print_user_type(MGC_USER_TYPE userType)
{
switch(userType)
{
case MGC_USER_TYPE_MG:
return "MGC_USER_TYPE_MG";
case MGC_USER_TYPE_MGC:
return "MGC_USER_TYPE_MGC";
default:
return "MGC_USER_TYPE_UNDKNOWN";
}
return "MGC_USER_TYPE_UNDKNOWN";
}
/***************************************************************************
* mgc_add_port
* ------------------------------------------------------------------------
* General: inferace for up-layer to add phyPort
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: sapIndex - the id of the MGC_SAP object which is provided by mgc_bind
* mgNo - the id of which MG_INFO need to attach to
* portNo - the id of the phyPort in the up-layer, this is used for up-layer find phyPort in the MGC
* portType - the phyPort type to be created
***************************************************************************/
int mgc_add_port(BYTE sapIndex, WORD mgNo, BYTE portNo, MGC_PHY_PORT_TYPE portType)
{
MG_INFO *pMgInfo = NULL;
MGC_SAP *pMgcSap = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
pMgcSap = mgc_sap_get_index_sap(sapIndex);
if((pMgInfo == NULL)||(pMgcSap) == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->created == FALSE)
{
MGC_ERROR("mg[%d] is not created, could not add port" , pMgInfo->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
if((ITL_OPERA_PORT_NO == portNo)&&(sapIndex != mgc_internal_get_sap_index()))
{
MGC_ERROR("portNo %d is internal used! " , portNo);
return MGC_RESULT_INPUT_ILLEGAL;
}
if(mgc_mg_info_is_port_already_exist(pMgInfo , portNo , pMgcSap) == TRUE)
return MGC_RESULT_OK;
pPhyPort = mgc_phy_port_get_unused_phy();
if(pPhyPort == NULL)
return MGC_RESULT_NO_RES;
pPhyPort->portType = portType;
pPhyPort->portNo = portNo;
pPhyPort->pMgcSap = pMgcSap;
pPhyPort->pMgInfo = pMgInfo;
switch(pMgInfo->mgAttr.ctrlType)
{
case MGC_MG_CTRL_TYPE_8ECP:
/*do nothing ?*/
mgc_phy_port_set_chnl_num(pPhyPort , MGC_PHY_PORT_TYPE_E1);
return MGC_RESULT_8ECP_OK;
case MGC_MG_CTRL_TYPE_MGCP:
mgc_phy_port_set_chnl_num(pPhyPort , pPhyPort->portType);
break;
default:
mgc_phy_port_clear(pPhyPort);
MGC_ERROR("mgcMgInfo[%d] unsupport ctrl type %d" , pMgInfo->id , pMgInfo->mgAttr.ctrlType);
return MGC_RESULT_INPUT_ILLEGAL;
}
if(mgc_phy_port_attach_chnl(pPhyPort) == FALSE)
{
mgc_phy_port_clear(pPhyPort);
return MGC_RESULT_FAILURE;
}
if(mgc_mg_info_attach_phy_port(pMgInfo , pPhyPort , pMgcSap)== FALSE)
{
mgc_phy_port_clear(pPhyPort);
return MGC_RESULT_FAILURE;
}
if(sapIndex != mgc_internal_get_sap_index())
{
MGC_INFO("phyPort[%d] is add to mgInfo[%d] %s , as portNo %d, userType %s"
, pPhyPort->id , pMgInfo->id , pMgInfo->mgAttr.domain, pPhyPort->portNo , mgc_print_user_type(pPhyPort->pMgcSap->usrType));
}
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_delete_port
* ------------------------------------------------------------------------
* General: inferace for up-layer to delete phyPort
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: sapIndex - the id of the MGC_SAP object which is provided by mgc_bind
* mgNo - the id of which MG_INFO need to attach to
* portNo - the id of the phyPort in the up-layer, this is used for up-layer find phyPort in the MGC
***************************************************************************/
int mgc_delete_port(BYTE sapIndex, WORD mgNo, BYTE portNo)
{
MG_INFO *pMgInfo = NULL;
MGC_SAP *pMgcSap = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
pMgcSap = mgc_sap_get_index_sap(sapIndex);
if((pMgInfo == NULL)||(pMgcSap) == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pPhyPort = mgc_phy_port_find_port_of_mg(pMgInfo , portNo);
if(pPhyPort == NULL)
{
if(sapIndex != mgc_internal_get_sap_index())
{
MGC_ERROR("mg[%d] %s do not have port[%d]" , pMgInfo->id , pMgInfo->mgAttr.domain , portNo);
}
return MGC_RESULT_INPUT_ILLEGAL;
}
if(pPhyPort->pMgcSap != pMgcSap)
{
MGC_ERROR("Port[%d] is not belong to mgcSap[%d] %s" , pPhyPort->portNo, pMgcSap->id , pMgcSap->usrName);
return MGC_RESULT_INPUT_ILLEGAL;
}
if(sapIndex != mgc_internal_get_sap_index())
{
MGC_INFO("phyPort[%d] is remove from mgInfo[%d] %s , as portNo %d, userType %s"
, pPhyPort->id , pMgInfo->id , pMgInfo->mgAttr.domain, pPhyPort->portNo , mgc_print_user_type(pPhyPort->pMgcSap->usrType));
}
mgc_mg_info_dettach_phy_port(pMgInfo , pPhyPort);
mgc_phy_port_clear(pPhyPort);
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_auep_chnl
* ------------------------------------------------------------------------
* General: inferace for up-layer to send auep
* Return Value : if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* chnl - the chnl need to send auep
***************************************************************************/
int mgc_auep_chnl(WORD usrPort, CHNL chnl)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if((pMgInfo == NULL)||(pChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
return MGC_RESULT_8ECP_OK;
pConnect = mgc_chnl_info_assign_connect(pChnlInfo, chnl.connectNo);
pPortInfo = mgc_port_info_get_unused_port();
if((pPortInfo == NULL)||(pConnect == NULL))
{
return MGC_RESULT_NO_RES;
}
mgc_connect_add_auep(pConnect , pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_AUEP);
pPortInfo->usrPort = usrPort;
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_crcx_chnl
* ------------------------------------------------------------------------
* General: inferace for up-layer to send crcx, on the specific chnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* chnl - the chnl need to send crcx
***************************************************************************/
int mgc_crcx_chnl(WORD usrPort, CHNL chnl)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
CONNECT_INFO *pConnectTmp = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
pConnect = mgc_chnl_info_assign_connect(pChnlInfo, chnl.connectNo);
pPortInfo = mgc_port_info_get_unused_port();
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pPortInfo == NULL)||(pConnect == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
return MGC_RESULT_8ECP_OK;
if(pMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)
return MGC_RESULT_INPUT_ILLEGAL;
MGC_DEBUG("mg[%d]port[%d]chnl[%d]conNo[%d] ==> conn[%d]" , chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo , pConnect->id);
if(mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_IDLE)
{
MGC_WARN("conn[%d] should be idle" , pConnect->id);
pConnectTmp = mgc_connect_dup_attr(pConnect);
mgc_connect_add_dlcx(pConnectTmp, pPortInfo);
mgc_connect_set_status(pConnect,MGC_CONNECT_STATUS_IDLE);
mgc_connect_codec_list_init(&pConnect->codecList);
memset(&pConnect->mediaAttr , 0 , sizeof(MEDIA_ATTR));
}
mgc_connect_add_crcx(pConnect , pPortInfo);
mgc_connect_add_nop(pConnect,pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_CRCX);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
int mgc_rqnt_chnl(WORD usrPort, CHNL chnl, PKG_EVENT *pPkgEvent, PKG_SIGNAL *pPkgSig)
{
CHNL_INFO *pChnlInfo = NULL;
MG_INFO *pMgInfo = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo,chnl.connectNo);
pPortInfo = mgc_port_info_get_unused_port();
MGC_DEBUG("func %s " , __FUNCTION__);
if((pChnlInfo == NULL)||(pConnect== NULL)||(pPortInfo == NULL)||(pMgInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
return MGC_RESULT_8ECP_OK;
mgc_connect_add_rqnt(pConnect, pPkgEvent, pPkgSig, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_RQNT);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
int mgc_mdcx_chnl(WORD usrPort, CHNL chnl, MEDIA_PARA *pMediaPara)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pPortInfo = mgc_port_info_get_unused_port();
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)
return MGC_RESULT_INPUT_ILLEGAL;
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pMediaPara)
{
if((pMediaPara->flag & MGC_MEDIA_PARA_FLAG_EC) == MGC_MEDIA_PARA_FLAG_EC)
{
pConnect->mediaAttr.ecDisable = pMediaPara->ecDisable;
}
if((pMediaPara->flag & MGC_MEDIA_PARA_FLAG_SS) == MGC_MEDIA_PARA_FLAG_SS)
{
pConnect->mediaAttr.ssDisable = pMediaPara->ssDisable;
}
if((pMediaPara->flag & MGC_MEDIA_PARA_FLAG_CM) == MGC_MEDIA_PARA_FLAG_CM)
{
pConnect->mediaAttr.conMode = mgc_mgcp_convert_to_mgc_mode(pMediaPara->conMode);
}
if((pMediaPara->flag & MGC_MEDIA_PARA_FLAG_PT) == MGC_MEDIA_PARA_FLAG_PT)
{
pConnect->mediaAttr.ptime = pMediaPara->ptime;
}
if((pMediaPara->flag & MGC_MEDIA_PARA_FLAG_VT) == MGC_MEDIA_PARA_FLAG_VT)
{
mgc_mgcp_match_codec_list(&pConnect->codecList , &pMediaPara->vocoderType , &pConnect->codecList);
}
}
mgc_tandem_info_mdcx(pConnect, pPortInfo);
mgc_connect_add_nop(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_MDCX);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_connect_chnl
* ------------------------------------------------------------------------
* General: inferace for up-layer to connect orgChnl to the destChnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* orgChnl - the chnl need to send connect info
* destChnl - the peer chnl to be connected
* flag - reserved
*-------------------------------------------------------------------------
*Note: if connection of the chnl is not created send crcx first, then send mdcx
***************************************************************************/
int mgc_connect_chnl(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE flag)
{
MG_INFO *pOrgMgInfo = NULL;
MG_INFO *pDestMgInfo = NULL;
CHNL_INFO *pOrgChnlInfo = NULL;
CHNL_INFO *pDestChnlInfo = NULL;
CONNECT_INFO *pOrgConnect = NULL;
CONNECT_INFO *pDestConnect = NULL;
CONNECT_INFO *pPeerConnect = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
pOrgMgInfo = mgc_mg_info_get_index_mg(orgChnl.mgNo);
pOrgChnlInfo = mgc_chnl_info_get_chnl(orgChnl);
pDestMgInfo = mgc_mg_info_get_index_mg(destChnl.mgNo);
pDestChnlInfo = mgc_chnl_info_get_chnl(destChnl);
if((pOrgMgInfo == NULL)||(pOrgChnlInfo == NULL)||(pDestMgInfo == NULL) || (pDestChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if((pOrgMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)||(pDestMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP) )
return -MGC_RESULT_INPUT_ILLEGAL;
if(pOrgMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
{
mgc_8ecp_connect_chnl(orgChnl, destChnl, flag);
return MGC_RESULT_OK ;
}
MGC_DEBUG("func %s " , __FUNCTION__);
pOrgConnect = mgc_chnl_info_assign_connect(pOrgChnlInfo,orgChnl.connectNo);
pDestConnect= mgc_chnl_info_assign_connect(pDestChnlInfo, destChnl.connectNo);
pPortInfo = mgc_port_info_get_unused_port();
if((pPortInfo == NULL)||(pOrgConnect == NULL)||(pDestConnect == NULL))
{
return MGC_RESULT_NO_RES;
}
MGC_DEBUG("Org mg[%d]port[%d]chnl[%d]conNo[%d] ==> conn[%d]" ,
orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo,orgChnl.connectNo , pOrgConnect->id);
MGC_DEBUG("Dest mg[%d]port[%d]chnl[%d]conNo[%d] ==> conn[%d]" ,
destChnl.mgNo, destChnl.portNo, destChnl.chlNo,destChnl.connectNo , pDestConnect->id);
pConnect = pOrgConnect;
pPeerConnect = pDestConnect;
/*
if((pConnect->pOperStep != NULL)&&(pConnect->pOperStep->stepInfo.delay != 0))
{
pConnect->pOperStep->stepInfo.delay = 0;
MGC_DEBUG("conn[%d] set clear delay" , pConnect->id);
}
if(pPeerConnect->pOperStep != NULL)
{
pPeerConnect->pOperStep->stepInfo.delay = 0;
MGC_DEBUG("conn[%d] set clear delay" , pPeerConnect->id);
}
*/
if(pConnect->pOperStep != NULL)
mgc_port_info_mv_step_into_new_port(pPortInfo, pConnect->pOperStep);
if(pPeerConnect->pOperStep != NULL)
mgc_port_info_mv_step_into_new_port(pPortInfo, pPeerConnect->pOperStep);
//if any connection is a target, create the tandem if neccessary
mgc_connect_add_crcx(pConnect,pPortInfo);
mgc_connect_add_crcx(pPeerConnect,pPortInfo);
//if any connecion is aor, stop related tandem and dettach from the tandem
if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_AOR)
{
if((mgc_tandem_info_get_conn_pos(pConnect->pTandem , pConnect) == MGC_TANDEM_CONN_POS_TAR)
&&(pConnect->pTandem == pPeerConnect->pTandem))
{
MGC_DEBUG("PeerConn[%d] and Conn[%d] is in tandem[%d]" , pPeerConnect->id , pConnect->id , pConnect->pTandem->id);
}
else
{
mgc_tandem_info_dettach_aor_related_tandem(pConnect , pPeerConnect, pPortInfo);
}
}
if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR)
{
if((mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem , pPeerConnect) == MGC_TANDEM_CONN_POS_TAR)
&&(pPeerConnect->pTandem == pConnect->pTandem))
{
MGC_DEBUG("Conn[%d] and PeerConn[%d] is in tandem[%d]" , pConnect->id , pPeerConnect->id , pConnect->pTandem->id);
}
else
{
mgc_tandem_info_dettach_aor_related_tandem(pPeerConnect , pConnect, pPortInfo);
}
}
//connect to peer connection
if(mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_CREATED)
{
mgc_tandem_info_connect(pConnect,pPeerConnect, MGC_CON_MODE_OWN, pPortInfo);
}
mgc_tandem_info_connect(pPeerConnect, pConnect,MGC_CON_MODE_SENDRECV,pPortInfo);
if((pOrgMgInfo->mgAttr.mgType == MGC_MG_TYPE_INTERNAL)&&(pDestMgInfo->mgAttr.mgType != MGC_MG_TYPE_INTERNAL))
mgc_connect_add_nop(pPeerConnect, pPortInfo);
if((flag & MGCP_PARA_FLAG_TFO) == MGCP_PARA_FLAG_TFO)
{
pDestConnect->flag |= MGCP_PARA_FLAG_TFO;
pOrgConnect->flag |= MGCP_PARA_FLAG_TFO;
}
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_CONNECT_CHNL);
pPortInfo->usrPort = usrPort;
memset(&pOrgConnect->operRec , 0 , sizeof(OPER_REC));
pOrgConnect->operRec.operaId = MGC_OPER_ID_CONNECT_CHNL;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] and mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
orgChnl.mgNo,orgChnl.portNo,orgChnl.chlNo,orgChnl.connectNo,
destChnl.mgNo,destChnl.portNo,destChnl.chlNo,destChnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_dlcx_chnl
* ------------------------------------------------------------------------
* General: inferace for up-layer to send dlcx to the specific chnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* chnl - the chnl need to send dlcx
***************************************************************************/
int mgc_dlcx_chnl(WORD usrPort, CHNL chnl)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
pPortInfo = mgc_port_info_get_unused_port();
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
{
mgc_8ecp_dlcx_chnl(chnl);
return MGC_RESULT_OK;
}
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
{
MGC_ERROR("lost connect in dlcx");
return MGC_RESULT_INPUT_ILLEGAL;
}
/*
if((pConnect->pOperStep != NULL)&&(pConnect->pOperStep->stepInfo.delay != 0))
{
pConnect->pOperStep->stepInfo.delay = 0;
MGC_DEBUG("conn[%d] set clear delay" , pConnect->id);
}
*/
if(pConnect->pOperStep != NULL)
mgc_port_info_mv_step_into_new_port(pPortInfo, pConnect->pOperStep);
MGC_DEBUG("mg[%d]port[%d]chnl[%d]conNo[%d] ==> conn[%d]" , chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo , pConnect->id);
if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR)
mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo);
mgc_connect_add_dlcx(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_DLCX);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
int mgc_recvonly_chnl(WORD usrPort, CHNL orgChnl, CHNL destChnl)
{
MG_INFO *pOrgMgInfo = NULL;
MG_INFO *pDestMgInfo = NULL;
CHNL_INFO *pOrgChnlInfo = NULL;
CHNL_INFO *pDestChnlInfo = NULL;
CONNECT_INFO *pOrgConnect = NULL;
CONNECT_INFO *pDestConnect = NULL;
CONNECT_INFO *pPeerConnect = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pOrgMgInfo = mgc_mg_info_get_index_mg(orgChnl.mgNo);
pOrgChnlInfo = mgc_chnl_info_get_chnl(orgChnl);
pDestMgInfo = mgc_mg_info_get_index_mg(destChnl.mgNo);
pDestChnlInfo = mgc_chnl_info_get_chnl(destChnl);
if((pOrgMgInfo == NULL)||(pOrgChnlInfo == NULL)||(pDestMgInfo == NULL) || (pDestChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if((pOrgMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)||(pDestMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP))
return MGC_RESULT_INPUT_ILLEGAL;
pOrgConnect = mgc_connect_find_connect_of_chnl(pOrgChnlInfo,orgChnl.connectNo);
pDestConnect= mgc_connect_find_connect_of_chnl(pDestChnlInfo, destChnl.connectNo);
pPortInfo = mgc_port_info_get_unused_port();
if((pPortInfo == NULL)||(pOrgConnect == NULL)||(pDestConnect == NULL))
return MGC_RESULT_NO_RES;
pConnect = pOrgConnect;
pPeerConnect = pDestConnect;
//if any connecion is aor, stop related tandem and dettach from the tandem
mgc_tandem_info_dettach_aor_related_tandem(pConnect , pPeerConnect, pPortInfo);
mgc_tandem_info_connect(pConnect, pPeerConnect,MGC_CON_MODE_RECVONLY, pPortInfo);
memset(&pOrgConnect->operRec , 0 , sizeof(OPER_REC));
pOrgConnect->operRec.operaId = MGC_OPER_ID_MDCX;
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_MDCX);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] and mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
orgChnl.mgNo,orgChnl.portNo,orgChnl.chlNo,orgChnl.connectNo,
destChnl.mgNo,destChnl.portNo,destChnl.chlNo,destChnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_connect_dtmf
* ------------------------------------------------------------------------
* General: inferace for up-layer to send dtmf to the specific chnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* chnl - the chnl need to send dtmf
* dtmfNo - the dtmf need to be sent
***************************************************************************/
int mgc_connect_dtmf(WORD usrPort, CHNL chnl,CHNL dstChnl, BYTE dtmfNo)
{
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MG_INFO *pMgInfo = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
pPortInfo = mgc_port_info_get_unused_port();
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
{
mgc_8ecp_connect_dtmf(chnl, dstChnl, dtmfNo);
return MGC_RESULT_OK;
}
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
{
MGC_WARN("lost connect in dtmf");
return MGC_RESULT_INPUT_ILLEGAL;
}
mgc_connect_set_dtmf(pConnect, dtmfNo);
mgc_connect_add_rqnt(pConnect, NULL , &pConnect->mediaAttr.pkgSignal,pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_CONNECT_DTMF);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] and mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo,
dstChnl.mgNo,dstChnl.portNo,dstChnl.chlNo,dstChnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_connect_AAS
* ------------------------------------------------------------------------
* General: inferace for up-layer to make the specific orgChnl to connect to specific toneNo chnl on the AAS
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* orgChnl - the chnl need to send tone
* destChnl - the peer endpoint of the orgChnl
* toneNo - the tone identify on the AAS
* duration - the time need to be played
* times - reserved
***************************************************************************/
int mgc_connect_AAS(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE toneNo, WORD duration, WORD times)
{
MG_INFO *pOrgMgInfo = NULL;
MG_INFO *pDestMgInfo = NULL;
MG_INFO *pAasMgInfo = NULL;
CHNL_INFO *pOrgChnlInfo = NULL;
CHNL_INFO *pDestChnlInfo = NULL;
CONNECT_INFO *pOrgConnect = NULL;
CONNECT_INFO *pDestConnect = NULL;
CONNECT_INFO *pAasConnect = NULL;
CONNECT_INFO *pPeerConnect = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
PORT_INFO *pPortInfoTmp = NULL;
DWORD delay;
BYTE tone;
MGC_DEBUG("func %s toneNo[%d] times[%d] duration[%d]" , __FUNCTION__ , toneNo , times , duration);
pOrgMgInfo = mgc_mg_info_get_index_mg(orgChnl.mgNo);
pOrgChnlInfo = mgc_chnl_info_get_chnl(orgChnl);
pDestMgInfo = mgc_mg_info_get_index_mg(destChnl.mgNo);
pDestChnlInfo = mgc_chnl_info_get_chnl(destChnl);
tone = toneNo;
if((pOrgMgInfo == NULL)||(pOrgChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pOrgMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)
return MGC_RESULT_INPUT_ILLEGAL;
toneNo = times * 10 + (toneNo - 7);
pAasConnect = mgc_mg_info_assign_aas_tone_connection(toneNo);
pOrgConnect = mgc_connect_find_connect_of_chnl(pOrgChnlInfo,orgChnl.connectNo);
pDestConnect= mgc_connect_find_connect_of_chnl(pDestChnlInfo, destChnl.connectNo);
pPortInfoTmp = mgc_port_info_get_unused_port();
if((pPortInfoTmp == NULL)||(pOrgConnect == NULL)||(pAasConnect == NULL))
return MGC_RESULT_NO_RES;
MGC_DEBUG("Org mg[%d]port[%d]chnl[%d]conNo[%d] ==> conn[%d]" ,
orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo,orgChnl.connectNo , pOrgConnect->id);
pAasMgInfo = mgc_connect_get_own_mg_info(pAasConnect);
if((mgc_connect_get_status(pAasConnect) != MGC_CONNECT_STATUS_IDLE)||(pAasMgInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if((mgc_connect_get_status(pOrgConnect) == MGC_CONNECT_STATUS_IDLE)||
(mgc_connect_get_status(pDestConnect) == MGC_CONNECT_STATUS_IDLE))
{
MGC_ERROR("conn[%d] and conn[%d] is not created" , pOrgConnect->id , pDestConnect->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
pConnect = pOrgConnect;
pPeerConnect = pDestConnect;
//stop stream sending
if(mgc_connect_get_status(pPeerConnect) == MGC_CONNECT_STATUS_CREATED)
{
if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) != MGC_TANDEM_CONN_POS_UNDEF)
{
mgc_tandem_info_connect(pPeerConnect, pConnect,MGC_CON_MODE_RECVONLY, pPortInfoTmp);
}
else
{
mgc_connect_add_mdcx(pPeerConnect, pConnect, MGC_CON_MODE_RECVONLY, pPortInfoTmp);
}
mgc_connect_add_nop(pPeerConnect, pPortInfoTmp);
mgc_port_info_set_step_to_start(pPortInfoTmp);
mgc_port_info_set_oper_id(pPortInfoTmp , MGC_OPER_ID_MDCX);
pPortInfoTmp->usrPort = usrPort;
}
pPortInfo = mgc_port_info_get_unused_port();
if(pPortInfo == NULL)
return MGC_RESULT_NO_RES;
delay = duration * MGC_MGCF_TIMER_1S;
if(delay == 0)
delay = MGC_MGCF_TIMER_1H;
/*copy dest connection sdp and made codec negotiate*/
pConnect = pAasConnect;
pPeerConnect = pOrgConnect;
if(pPeerConnect->pOperStep != NULL)
mgc_port_info_mv_step_into_new_port(pPortInfo, pPeerConnect->pOperStep);
MGC_DEBUG("conn[%d] send crcx to aas with %ld delay" , pConnect->id , delay);
mgc_tandem_info_add_crcx_aas(pConnect, pPeerConnect, pPortInfo);
mgc_tandem_info_add_mdcx_aas(pPeerConnect, pConnect, pPortInfo);
mgc_connect_add_nop_with_delay(pPeerConnect, delay , pPortInfo);
/*remove aas connection*/
MGC_DEBUG("conn[%d] send dlcx to delete aas" , pConnect->id);
mgc_connect_add_dlcx(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_CONNECT_AAS);
pPortInfo->usrPort = usrPort;
pPortInfo->cause = tone;
memset(&pOrgConnect->operRec , 0 , sizeof(OPER_REC));
pOrgConnect->operRec.operaId = MGC_OPER_ID_CONNECT_AAS;
pOrgConnect->operRec.duration = duration;
pOrgConnect->operRec.times = times;
pOrgConnect->operRec.tone = tone;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
orgChnl.mgNo,orgChnl.portNo,orgChnl.chlNo,orgChnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_connect_tone
* ------------------------------------------------------------------------
* General: inferace for up-layer to make the specific orgChnl to connect to specific toneNo chnl on the AAS
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: usrPort - up-layer parameter to identify
* orgChnl - the chnl need to send tone
* destChnl - the peer endpoint of the orgChnl
* toneNo - the tone identify on the AAS
* duration - the time need to be played
***************************************************************************/
int mgc_connect_tone(WORD usrPort, CHNL orgChnl, CHNL destChnl, BYTE toneNo, WORD duration)
{
MG_INFO *pOrgMgInfo = NULL;
MG_INFO *pDestMgInfo = NULL;
MG_INFO *pAasMgInfo = NULL;
CHNL_INFO *pOrgChnlInfo = NULL;
CHNL_INFO *pDestChnlInfo = NULL;
CONNECT_INFO *pOrgConnect = NULL;
CONNECT_INFO *pDestConnect = NULL;
CONNECT_INFO *pAasConnect = NULL;
CONNECT_INFO *pPeerConnect = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
PORT_INFO *pPortInfoTmp = NULL;
DWORD delay;
BYTE tone , toneTmp;
MGC_DEBUG("func %s " , __FUNCTION__);
pOrgMgInfo = mgc_mg_info_get_index_mg(orgChnl.mgNo);
pOrgChnlInfo = mgc_chnl_info_get_chnl(orgChnl);
pDestMgInfo = mgc_mg_info_get_index_mg(destChnl.mgNo);
pDestChnlInfo = mgc_chnl_info_get_chnl(destChnl);
MGC_DEBUG("Org mg[%d]port[%d]chnl[%d]conNo[%d]" ,
orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo,orgChnl.connectNo);
MGC_DEBUG("Dest mg[%d]port[%d]chnl[%d]conNo[%d]" ,
destChnl.mgNo, destChnl.portNo, destChnl.chlNo,destChnl.connectNo);
if((pOrgMgInfo == NULL)||(pOrgChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pOrgMgInfo->mgAttr.ctrlType == MGC_MG_CTRL_TYPE_8ECP)
{
mgc_8ecp_connect_tone(orgChnl, destChnl, toneNo , duration);
return MGC_RESULT_OK;
}
if((pOrgMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP) )
return MGC_RESULT_INPUT_ILLEGAL;
tone = toneNo;
toneTmp = toneNo-7;
pAasConnect = mgc_mg_info_assign_aas_tone_connection(toneTmp);
pOrgConnect = mgc_connect_find_connect_of_chnl(pOrgChnlInfo,orgChnl.connectNo);
pDestConnect= mgc_connect_find_connect_of_chnl(pDestChnlInfo, destChnl.connectNo);
pPortInfoTmp = mgc_port_info_get_unused_port();
if((pPortInfoTmp == NULL)||(pOrgConnect == NULL)||(pAasConnect == NULL))
return MGC_RESULT_NO_RES;
MGC_DEBUG("Org mg[%d]port[%d]chnl[%d]conNo[%d] ==> conn[%d]" ,
orgChnl.mgNo, orgChnl.portNo, orgChnl.chlNo,orgChnl.connectNo , pOrgConnect->id);
pAasMgInfo = mgc_connect_get_own_mg_info(pAasConnect);
if((mgc_connect_get_status(pAasConnect) != MGC_CONNECT_STATUS_IDLE)||(pAasMgInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pConnect = pOrgConnect;
pPeerConnect = pDestConnect;
// stop dest send stream to org
if(mgc_connect_get_status(pPeerConnect) == MGC_CONNECT_STATUS_CREATED)
{
if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) != MGC_TANDEM_CONN_POS_UNDEF)
{
mgc_tandem_info_connect(pPeerConnect, pConnect,MGC_CON_MODE_RECVONLY, pPortInfoTmp);
}
else
{
mgc_connect_add_mdcx(pPeerConnect, pConnect, MGC_CON_MODE_RECVONLY, pPortInfoTmp);
}
mgc_connect_add_nop(pPeerConnect, pPortInfoTmp);
mgc_port_info_set_step_to_start(pPortInfoTmp);
mgc_port_info_set_oper_id(pPortInfoTmp , MGC_OPER_ID_MDCX);
pPortInfoTmp->usrPort = usrPort;
}
pPortInfo = mgc_port_info_get_unused_port();
if(pPortInfo == NULL)
return MGC_RESULT_NO_RES;
//if org is not created create first
if(mgc_connect_get_status(pOrgConnect) == MGC_CONNECT_STATUS_IDLE)
{
mgc_connect_add_crcx(pOrgConnect , pPortInfo);
}
if(pOrgConnect->pOperStep != NULL)
mgc_port_info_mv_step_into_new_port(pPortInfo, pOrgConnect->pOperStep);
delay = duration * MGC_MGCF_TIMER_1S;
if(delay == 0)
delay = MGC_MGCF_TIMER_1H;
if(pOrgMgInfo->mgAttr.toneCap == 1)
{
mgc_connect_set_tone(pConnect , toneNo);
mgc_connect_add_rqnt_with_delay(pConnect, delay, NULL ,&pOrgConnect->mediaAttr.pkgSignal,pPortInfo);
mgc_connect_clear_tone(pConnect);
mgc_connect_add_rqnt(pConnect,NULL,&pOrgConnect->mediaAttr.pkgSignal,pPortInfo);
}
else
{
pConnect = pAasConnect;
pPeerConnect = pOrgConnect;
mgc_tandem_info_add_crcx_aas(pConnect, pPeerConnect, pPortInfo);
mgc_tandem_info_add_mdcx_aas(pPeerConnect, pConnect, pPortInfo);
mgc_connect_add_nop_with_delay(pPeerConnect, delay, pPortInfo);
mgc_connect_add_dlcx(pConnect, pPortInfo);
}
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_CONNECT_TONE);
pPortInfo->usrPort = usrPort;
memset(&pOrgConnect->operRec , 0 , sizeof(OPER_REC));
pOrgConnect->operRec.operaId = MGC_OPER_ID_CONNECT_TONE;
pOrgConnect->operRec.duration = duration;
pOrgConnect->operRec.tone = tone;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] ==> %s",
__FUNCTION__ ,
orgChnl.mgNo,orgChnl.portNo,orgChnl.chlNo,orgChnl.connectNo,
mgc_port_info_print_opera_id(pPortInfo->mgcfOperId));
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_query_mg_status
* ------------------------------------------------------------------------
* General: inferace for up-layer to query the specific mg status
* Return Value: if mg not created return -1,
* else return the status of the mg, 1 stand for enable, 0 stand for disable
* ------------------------------------------------------------------------
* Arguments:
* Input: mgNo - the mg id, return by mgc_create_MG
***************************************************************************/
int mgc_query_mg_status(WORD mgNo)
{
MG_INFO *pMgInfo = NULL;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
if(pMgInfo == NULL)
return -1;
MGC_INFO("%s mg[%d] %s" , __FUNCTION__ , pMgInfo->id , pMgInfo->enable?"ENABLE":"DISABLE");
return pMgInfo->enable;
}
/***************************************************************************
* mgc_query_port_status
* ------------------------------------------------------------------------
* General: inferace for up-layer to query the specific port
* Return Value: if port not created return -1,
* else return the status of the port, 1 stand for enable, 0 stand for disable
* ------------------------------------------------------------------------
* Arguments:
* Input: mgNo - the mg id, return by mgc_create_MG
* portNo - used in the mgc_add_port
***************************************************************************/
int mgc_query_port_status(WORD mgNo, BYTE portNo)
{
MG_INFO *pMgInfo = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
if(pMgInfo == NULL)
return -1;
pPhyPort = mgc_phy_port_find_port_of_mg(pMgInfo, portNo);
if(pPhyPort == NULL)
return -1;
return pPhyPort->status;
}
/***************************************************************************
* mgc_query_channel_status
* ------------------------------------------------------------------------
* General: inferace for up-layer to query the specific chnl
* Return Value: if port not created return -1,
* else return the status of the chnl, 1 stand for enable, 0 stand for disable
* ------------------------------------------------------------------------
* Arguments:
* Input: chnl - the chnl need to query
***************************************************************************/
int mgc_query_channel_status(CHNL chnl)
{
CHNL_INFO *pChnlInfo = NULL;
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if(pChnlInfo == NULL)
return -1;
return pChnlInfo->status;
}
/***************************************************************************
* mgc_create_virtual_chnl
* ------------------------------------------------------------------------
* General: inferace for up-layer to create virtual chnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: pChnl - the address of the chnl to be filled
* usrPort - reserved
***************************************************************************/
int mgc_create_virtual_chnl(WORD usrPort, CHNL *pChnl)
{
MG_INFO *pMgInfo = NULL;
CONNECT_INFO *pConnect = NULL;
CHNL_INFO *pChnlInfo = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
PORT_INFO *pPortInfo = NULL;
pPortInfo = mgc_port_info_get_unused_port();
if((pChnl == NULL)||(pPortInfo == NULL))
return MGC_RESULT_NO_RES;
MGC_DEBUG("func %s " , __FUNCTION__);
pMgInfo = mgc_mg_info_find_available_mg(MGC_MG_TYPE_INTERNAL);
if(pMgInfo == NULL)
return MGC_RESULT_NO_RES;
pConnect = mgc_mg_info_assign_idle_connection(pMgInfo);
if(pConnect == NULL)
return MGC_RESULT_NO_RES;
pChnlInfo = mgc_connect_get_own_chnl_info(pConnect);
if(pChnlInfo == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pPhyPort = mgc_connect_get_own_phy_port_info(pConnect);
if(pPhyPort == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pChnl->mgNo = pMgInfo->id;
pChnl->portNo = pPhyPort->portNo;
pChnl->chlNo = mgc_chnl_info_get_chnl_no_of_phy(pChnlInfo, pPhyPort);
pChnl->connectNo = mgc_connect_get_connNo_of_chnl_info(pConnect, pChnlInfo);
mgc_connect_set_status(pConnect,MGC_CONNECT_STATUS_CREATING);
mgc_connect_add_nop(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_CREATE_VIRTUAL_CHNL);
pPortInfo->usrPort = usrPort;
MGC_INFO("create virtual mg[%d]port[%d]chnl[%d]connNo[%d]" , pChnl->mgNo , pChnl->portNo , pChnl->chlNo , pChnl->connectNo);
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_release_virtual_chnl
* ------------------------------------------------------------------------
* General: inferace for up-layer to release virtual chnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: pChnl - the address of the chnl to be filled
* usrPort - reserved
***************************************************************************/
int mgc_release_virtual_chnl(WORD usrPort, CHNL chnl)
{
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pPortInfo = mgc_port_info_get_unused_port();
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if((pChnlInfo == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR)
mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo);
mgc_connect_add_dlcx(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_RELEASE_VIRTUAL_CHNL);
pPortInfo->usrPort = usrPort;
MGC_INFO("release virtual mg[%d]port[%d]chnl[%d]connNo[%d]" , chnl.mgNo , chnl.portNo , chnl.chlNo , chnl.connectNo);
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_license_ctrl
* ------------------------------------------------------------------------
* General: inferace for up-layer to make license control
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: maxMgNum - the maxMgNum could be created
* maxChnlNum - the maxChnlNum could be created
***************************************************************************/
int mgc_license_ctrl(WORD maxMgNum, WORD maxChnlNum)
{
if(mgc_ctl_set_mg_max_num(maxMgNum) != maxMgNum)
return MGC_RESULT_FAILURE;
if(mgc_ctl_set_chnl_max_num(maxChnlNum) != maxChnlNum)
return MGC_RESULT_FAILURE;
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_rsp
* ------------------------------------------------------------------------
* General: interface for up-layer to send rsp msg to the incoming ind
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: cmd - mgcp ind command
* usrPort - up-layer parameter for identify
* port - the mgcPort id , get from ind callback function
* retCode - the respond code
* pMediaAttr - media info get from up-layer
***************************************************************************/
int mgc_rsp(BYTE cmd, WORD usrPort, WORD port, WORD retCode, MEDIA_ATTR *pMediaAttr)
{
PORT_INFO *pPortInfo = NULL;
MGCF_OPER_STEP *pCurrentStep = NULL;
CONNECT_INFO *pConnect = NULL;
MGC_DEBUG("mgc rsp to mgcPort[%d]" , port);
pPortInfo = mgc_port_info_find_port_by_id(port);
if(pPortInfo == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pCurrentStep = pPortInfo->pMgcOperCurrent;
if(pCurrentStep == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pCurrentStep->status != MGCP_OPER_STEP_IND_SENT)
{
MGC_WARN("mgcPort[%d]step[%d] error status" , port , pCurrentStep->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
pConnect = pCurrentStep->pConnect;
if(pConnect == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(pMediaAttr != NULL)
memcpy(&(pConnect->mediaAttr) , pMediaAttr, sizeof(MEDIA_ATTR));
pCurrentStep->llCmd = retCode;
pCurrentStep->stepInfo.pPeerConn = pConnect;
pCurrentStep->status = MGCP_OPER_STEP_RESPONSE;
return MGC_RESULT_OK;
}
/***************************************************************************
* mgc_chnl_codec_update
* ------------------------------------------------------------------------
* General: interface for up-layer to update codecList on the specific chnl
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: chnl - the chnl to be update
* codecList - the codecList from the up-layer
***************************************************************************/
int mgc_chnl_codec_update(CHNL chnl , MGC_CODEC_LIST codecList)
{
int i ,j;
BYTE codec;
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MGC_CODEC_LIST codecListResult, codecListMg;
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if(pChnlInfo == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
MGC_DEBUG("func %s " , __FUNCTION__);
pConnect = mgc_chnl_info_assign_connect(pChnlInfo , chnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_NO_RES;
pMgInfo = mgc_connect_get_own_mg_info(pConnect);
if(pMgInfo == NULL)
return MGC_RESULT_FAILURE;
mgc_connect_codec_list_init(&codecListResult);
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 MGC_RESULT_FAILURE;
if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_IPBSS)
memcpy(&pConnect->codecList , &codecListResult , sizeof(MGC_CODEC_LIST));
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] sucess",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo);
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 MGC_RESULT_FAILURE;
}
/***************************************************************************
* mgc_query_chnl_oper_rec
* ------------------------------------------------------------------------
* General: interface for up-layer to query last time operation
* Return Value: if failure return NULL, else return pointer of the record
* ------------------------------------------------------------------------
* Arguments:
* Input: chnl - the chnl to be query
***************************************************************************/
OPER_REC *mgc_query_chnl_oper_rec(CHNL chnl)
{
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if(pChnlInfo == NULL)
return NULL;
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
return NULL;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] sucess",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo);
return &(pConnect->operRec);
}
/***************************************************************************
* mgc_query_chnl_media
* ------------------------------------------------------------------------
* General: interface for up-layer to query chnl media info
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: chnl - the chnl to be query
***************************************************************************/
int mgc_query_chnl_media(WORD usrPort, CHNL chnl, PUB_SDP_MSG **ppMediaInfo, BYTE *pMgPayloads, BYTE *pMgPlNum)
{
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MGC_TANDEM_INFO *pTandem = NULL;
int i;
if((ppMediaInfo == NULL)||(pMgPayloads == NULL)||(pMgPlNum == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if(pChnlInfo == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pTandem = pConnect->pTandem;
if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) == MGC_TANDEM_CONN_POS_TAR)
{
pConnect= pTandem->pRxconn;
}
else if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR)
{
pConnect = pConnect;
}
else if((mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_UNDEF)&&
(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_SUR))
{
MGC_ERROR("conn[%d] in illegal tandem" , pConnect->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
if((mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_CREATED)&&(mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_CREATE))
return MGC_RESULT_INPUT_ILLEGAL;
*ppMediaInfo = &(pConnect->mediaAttr.sdp);
for(i=0 ; i< pConnect->codecList.num ; i++)
{
pMgPayloads[i] = mgc_mgcp_print_vc_num(pConnect->codecList.codec[i]);
}
*pMgPlNum = pConnect->codecList.num;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] sucess",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo);
return MGC_RESULT_OK;
}
static 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;
}
/***************************************************************************
* mgc_update_chnl_media
* ------------------------------------------------------------------------
* General: interface for up-layer to update chnl media info
* Return Value: if failure return -1, else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: chnl - the chnl to be update
***************************************************************************/
int mgc_update_chnl_media(WORD usrPort, CHNL chnl, PUB_SDP_MSG *pMediaInfo)
{
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MG_INFO *pMgInfo = NULL;
PUB_SDP_A *pSdpA = NULL;
PORT_INFO *pPortInfo = NULL;
BYTE ptime;
int i;
pPortInfo = mgc_port_info_get_unused_port();
if((pMediaInfo == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pChnlInfo = mgc_chnl_info_get_chnl(chnl);
if(pChnlInfo == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, chnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
pMgInfo = mgc_connect_get_own_mg_info(pConnect);
if(pMgInfo == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
memcpy(&pConnect->mediaAttr.sdp , pMediaInfo , sizeof(PUB_SDP_MSG));
pConnect->codecList.num = pMediaInfo->medias.medias[0].m.plNum;
for(i=0 ; i<pConnect->codecList.num ; i++)
{
pConnect->codecList.codec[i] = mgc_payload_to_codec(pMediaInfo->medias.medias[0].m.payloads[i], pMediaInfo->medias.medias[0].attrs);
}
pConnect->codecList.priority = 255;
for (i = 0; i < pMediaInfo->medias.medias[0].attrs.num; i++)
{
pSdpA = &pMediaInfo->medias.medias[0].attrs.attrs[i];
if (pSdpA->aType == PUB_SDP_ATTR_TYPE_PTIME)
{
ptime = atoi(pSdpA->aValue);
continue;
}
if(strcmp(pSdpA->aValue , "inactive") == 0)
{
mgc_connect_set_conn_mode(pConnect, MGC_CON_MODE_INACTIVE);
}
else if(strcmp(pSdpA->aValue , "sendonly") == 0)
{
mgc_connect_set_conn_mode(pConnect, MGC_CON_MODE_SENDONLY);
}
else if(strcmp(pSdpA->aValue , "recvonly") == 0)
{
mgc_connect_set_conn_mode(pConnect, MGC_CON_MODE_RECVONLY);
}
else if(strcmp(pSdpA->aValue , "sendrecv") == 0)
{
mgc_connect_set_conn_mode(pConnect, MGC_CON_MODE_SENDRECV);
}
}
if (i == pMediaInfo->medias.medias[0].attrs.num)
ptime = 20;
pConnect->mediaAttr.ptime = ptime;
MGC_DEBUG("conn[%d] , %s " , pConnect->id ,__FUNCTION__);
if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_INTERNAL)
{
mgc_connect_add_crcx(pConnect, pPortInfo);
}
mgc_connect_add_nop(pConnect, pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_UPDATE_CHNL_MEDIA);
mgc_port_info_set_step_to_start(pPortInfo);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] sucess",
__FUNCTION__ ,
chnl.mgNo,chnl.portNo,chnl.chlNo,chnl.connectNo);
return MGC_RESULT_OK;
}
/*-----------------------------------------------------------------------
SNMP M A N A G E R
------------------------------------------------------------------------*/
/***************************************************************************
* mgc_get_snmp_msg
* ------------------------------------------------------------------------
* General: check trunk state by snmp info msg
* Return Value: if failed return -1 , else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: void
***************************************************************************/
static int mgc_get_snmp_msg(void)
{
struct snmp_pdu mgcSnmpPdu;
struct snmp_addr mgcSnmpAddr;
struct var_list *mgcVarList;
BYTE i, trkNo;
WORD mgNo;
MG_INFO *pMgInfo = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
mgcSnmpAddr.local_port = 4968;
if (!snmp_receive(&mgcSnmpPdu, &mgcSnmpAddr))
return 0;
if (mgcSnmpPdu.error_index != 0)
return -1;
mgNo = mgcSnmpPdu.request_id >> 16;
pMgInfo = mgc_mg_info_get_index_mg(mgNo);
if(pMgInfo == NULL)
return -1;
if ((mgcSnmpPdu.request_id & 0xFFFF) != pMgInfo->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];
pPhyPort = mgc_phy_port_find_port_of_mg(pMgInfo, trkNo);
if(pPhyPort == NULL)
return -1;
if(mgcVarList[i].msg[0] == 1)
{
pPhyPort->status = MGC_PHY_PORT_STATUS_ON_LINE;
}
else
{
pPhyPort->status = MGC_PHY_PORT_STATUS_OFF_LINE;
}
}
return 1;
}
/***************************************************************************
* mgc_get_non_virtual_trk_status
* ------------------------------------------------------------------------
* General: send snmp msg to check mg status
* Return Value: if failed return -1 , else return 0
* ------------------------------------------------------------------------
* Arguments:
* Input: void
***************************************************************************/
int mgc_get_non_virtual_trk_status(MG_INFO *pMgInfo)
{
struct snmp_pdu mgcSnmpPdu;
struct snmp_addr mgcSnmpAddr;
struct var_list *mgcVarList;
BYTE i, j = 0;
PHY_PORT_INFO *pPhyPort;
if(pMgInfo == NULL)
return MGC_RESULT_FAILURE;
mgcVarList = &mgcSnmpPdu.var[0];
mgcSnmpPdu.var_num = 0; //val list number
if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_AudioCoder)
{
for(i=0 ; i< MGC_MAX_PHY_PORT_PER_MG ; i++)
{
pPhyPort = mgc_phy_port_find_port_of_mg_by_index(pMgInfo, i);
if(pPhyPort == NULL)
continue;
mgcVarList[j].oidlen = MGC_AC_LINE_STATUS_IDLEN;
MGC_AC_LINE_STATUS_OID[MGC_AC_LINE_STATUS_IDLEN - 1] = pPhyPort->portNo;
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++;
}
}
if(pMgInfo->mgAttr.mgType == MGC_MG_TYPE_LGC_MG)
{
for(i=0 ; i< MGC_MAX_PHY_PORT_PER_MG ; i++)
{
pPhyPort = mgc_phy_port_find_port_of_mg_by_index(pMgInfo, i);
if(pPhyPort == NULL)
continue;
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_LGC_MG_STATUS_IDLEN*4);
mgcVarList[mgcSnmpPdu.var_num].vartype = 0x04;//octet string
mgcVarList[mgcSnmpPdu.var_num].msglen = 0;
mgcSnmpPdu.var_num++;
j++;
}
}
pMgInfo->requestId = (++pMgInfo->requestId) & 0xFFFF;
if (pMgInfo->requestId == 0)
pMgInfo->requestId = 1;
mgcSnmpPdu.pdu_type = 0x00; //get
mgcSnmpPdu.request_id = (pMgInfo->id<< 16) | pMgInfo->requestId;
mgcSnmpAddr.local_port = 4968;
mgcSnmpAddr.remote_port = 161;
mgcSnmpAddr.broadcast = 0; //Not broadcast
mgcSnmpAddr.remote_ip = pMgInfo->mgAttr.ip;
if (mgcSnmpPdu.var_num)
snmp_send(&mgcSnmpPdu,&mgcSnmpAddr);
return MGC_RESULT_OK;
}
int mgc_get_idle_tandem_id(void)
{
MGC_TANDEM_INFO *pTandem = NULL;
pTandem = mgc_tandem_info_get_idle_tandem();
if(pTandem == NULL)
return MGC_RESULT_NO_RES;
MGC_INFO("%s tandem[%d]" , __FUNCTION__ , pTandem->id);
return pTandem->id;
}
int mgc_create_tandem(WORD usrPort , DWORD tandId)
{
MGC_TANDEM_INFO *pTandem = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pTandem = mgc_tandem_info_get_tandem_by_id(tandId);
pPortInfo = mgc_port_info_get_unused_port();
if((pTandem == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
mgc_tandem_info_create_tandem(pTandem, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_TANDEM_CREATE);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s tandem[%d]" , __FUNCTION__ , pTandem->id);
return MGC_RESULT_OK;
}
int mgc_bind_chnl_to_tandem(WORD usrPort , CHNL tarChnl , DWORD tandId)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MGC_TANDEM_INFO *pTandem = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pMgInfo = mgc_mg_info_get_index_mg(tarChnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(tarChnl);
pTandem = mgc_tandem_info_get_tandem_by_id(tandId);
pPortInfo = mgc_port_info_get_unused_port();
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pTandem == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)
return -MGC_RESULT_INPUT_ILLEGAL;
MGC_DEBUG("mg[%d]port[%d]chnl[%d]connNo[%d]" , tarChnl.mgNo,tarChnl.portNo,tarChnl.chlNo,tarChnl.connectNo);
pConnect = mgc_chnl_info_assign_connect(pChnlInfo, tarChnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_NO_RES;
if(mgc_tandem_info_get_conn_pos(pTandem , pTandem->pTconn) != MGC_TANDEM_CONN_POS_UNDEF)
{
MGC_ERROR("tandem[%d] is in use" ,pTandem->id);
return MGC_RESULT_FAILURE;
}
if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) != MGC_TANDEM_CONN_POS_UNDEF)
{
MGC_WARN("conn[%d] already bind to tandem[%d]" , pConnect->id , pConnect->pTandem->id);
mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo);
}
if(mgc_tandem_info_set_conn(pTandem,pConnect, MGC_TANDEM_CONN_POS_TAR) == FALSE)
return MGC_RESULT_FAILURE;
mgc_tandem_info_create_tar_tandem(pConnect, pPortInfo);
mgc_connect_add_nop(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_TANDEM_SET_TAR);
MGC_DEBUG("%s tandem[%ld] conn[%d]" , __FUNCTION__, tandId , pConnect->id);
MGC_DEBUG("tandem[%d] rxConn[%d] txConn[%d]" , pTandem->id , pTandem->pRxconn->id , pTandem->pTxconn->id);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] bind tandem[%d] success" , __FUNCTION__ ,
tarChnl.mgNo , tarChnl.portNo , tarChnl.chlNo , tarChnl.connectNo ,pTandem->id);
return MGC_RESULT_OK;
}
int mgc_unbind_chnl_from_tandem(WORD usrPort , CHNL tarChnl , DWORD tandId)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MGC_TANDEM_INFO *pTandem = NULL;
PORT_INFO *pPortInfo = NULL;
MGC_DEBUG("func %s " , __FUNCTION__);
pMgInfo = mgc_mg_info_get_index_mg(tarChnl.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(tarChnl);
pTandem = mgc_tandem_info_get_tandem_by_id(tandId);
pPortInfo = mgc_port_info_get_unused_port();
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pTandem == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.ctrlType != MGC_MG_CTRL_TYPE_MGCP)
return -MGC_RESULT_INPUT_ILLEGAL;
MGC_DEBUG("mg[%d]port[%d]chnl[%d]connNo[%d]" , tarChnl.mgNo,tarChnl.portNo,tarChnl.chlNo,tarChnl.connectNo);
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, tarChnl.connectNo);
if(pConnect == NULL)
return MGC_RESULT_NO_RES;
if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR)
return MGC_RESULT_FAILURE;
mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_TANDEM_UNSET_TAR);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s mg[%d]port[%d]chnl[%d]conNo[%d] unbind tandem[%d] success" , __FUNCTION__ ,
tarChnl.mgNo , tarChnl.portNo , tarChnl.chlNo , tarChnl.connectNo ,pTandem->id);
return MGC_RESULT_OK;
}
int mgc_get_tandem_near_end(DWORD tandem_id, CHNL *pChnl)
{
MGC_TANDEM_INFO *pTandem = NULL;
CONNECT_INFO *pConnect = NULL;
MG_INFO *pMgInfo = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
CHNL_INFO *pChnlInfo = NULL;
if(pChnl == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
MGC_DEBUG("func %s " , __FUNCTION__);
pTandem = mgc_tandem_info_get_tandem_by_id(tandem_id);
if(pTandem == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(mgc_tandem_info_get_conn_pos(pTandem, pTandem->pTxconn) != MGC_TANDEM_CONN_POS_TX)
{
MGC_ERROR("tandem[%d] lost TxConn" , pTandem->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
pConnect = pTandem->pTxconn;
pMgInfo = mgc_connect_get_own_mg_info(pConnect);
pPhyPort = mgc_connect_get_own_phy_port_info(pConnect);
pChnlInfo = mgc_connect_get_own_chnl_info(pConnect);
if((pConnect == NULL)||(pMgInfo == NULL)||(pPhyPort == NULL)||(pChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pChnl->mgNo = pMgInfo->id;
pChnl->portNo = pPhyPort->portNo;
pChnl->chlNo = mgc_chnl_info_get_chnl_no_of_phy(pChnlInfo, pPhyPort);
pChnl->connectNo = mgc_connect_get_connNo_of_chnl_info(pConnect, pChnlInfo);
MGC_INFO("%s success" , __FUNCTION__);
return MGC_RESULT_OK;
}
int mgc_get_tandem_far_end(DWORD tandem_id, CHNL *pChnl)
{
MGC_TANDEM_INFO *pTandem = NULL;
CONNECT_INFO *pConnect = NULL;
MG_INFO *pMgInfo = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
CHNL_INFO *pChnlInfo = NULL;
if(pChnl == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
MGC_DEBUG("func %s " , __FUNCTION__);
pTandem = mgc_tandem_info_get_tandem_by_id(tandem_id);
if(pTandem == NULL)
return MGC_RESULT_INPUT_ILLEGAL;
if(mgc_tandem_info_get_conn_pos(pTandem, pTandem->pRxconn) != MGC_TANDEM_CONN_POS_RX)
{
MGC_ERROR("tandem[%d] lost RxConn" , pTandem->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
pConnect = pTandem->pRxconn;
pMgInfo = mgc_connect_get_own_mg_info(pConnect);
pPhyPort = mgc_connect_get_own_phy_port_info(pConnect);
pChnlInfo = mgc_connect_get_own_chnl_info(pConnect);
if((pConnect == NULL)||(pMgInfo == NULL)||(pPhyPort == NULL)||(pChnlInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pChnl->mgNo = pMgInfo->id;
pChnl->portNo = pPhyPort->portNo;
pChnl->chlNo = mgc_chnl_info_get_chnl_no_of_phy(pChnlInfo, pPhyPort);
pChnl->connectNo = mgc_connect_get_connNo_of_chnl_info(pConnect, pChnlInfo);
MGC_INFO("%s success" , __FUNCTION__);
return MGC_RESULT_OK;
}
int mgc_fork_chnl(WORD usrPort , CHNL parent, CHNL *pChild)
{
MG_INFO *pMgInfo = NULL;
CHNL_INFO *pChnlInfo = NULL;
CONNECT_INFO *pConnect = NULL;
MGC_TANDEM_INFO *pTandem = NULL;
CONNECT_INFO *pSurConnect = NULL;
PHY_PORT_INFO *pSurPhyPort = NULL;
CHNL_INFO *pSurChnlInfo = NULL;
PORT_INFO *pPortInfo = NULL;
pMgInfo = mgc_mg_info_get_index_mg(parent.mgNo);
pChnlInfo = mgc_chnl_info_get_chnl(parent);
pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo,parent.connectNo);
pPortInfo = mgc_port_info_get_unused_port();
MGC_DEBUG("func %s " , __FUNCTION__);
if((pMgInfo == NULL)||(pChnlInfo == NULL)||(pConnect == NULL)||(pPortInfo == NULL)||(pChild == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
if(pMgInfo->mgAttr.mgType != MGC_MG_TYPE_TANDEM)
{
MGC_ERROR("mg[%d] is not tandem type!" , pMgInfo->id);
return MGC_RESULT_INPUT_ILLEGAL;
}
if((mgc_tandem_info_get_conn_pos(pConnect->pTandem,pConnect) != MGC_TANDEM_CONN_POS_RX)&&
(mgc_tandem_info_get_conn_pos(pConnect->pTandem,pConnect) != MGC_TANDEM_CONN_POS_TX))
{
MGC_ERROR("conn[%d] is not a connection on tandem" , pConnect->id);
return MGC_RESULT_FAILURE;
}
if((mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_CREATED)&&(mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_CREATE))
{
MGC_ERROR("conn[%d] of tandem[%d] is not created, can't fork!" , pConnect->id , pConnect->pTandem->id);
return MGC_RESULT_FAILURE;
}
pTandem = pConnect->pTandem;
pSurConnect = mgc_sur_info_find_sur_conn_in_mg(pMgInfo);
pSurPhyPort = mgc_connect_get_own_phy_port_info(pSurConnect);
pSurChnlInfo = mgc_connect_get_own_chnl_info(pSurConnect);
if((pSurConnect == NULL)||(pSurChnlInfo == NULL)||(pSurPhyPort == NULL))
return MGC_RESULT_NO_RES;
if(mgc_tandem_info_set_conn(pTandem, pSurConnect,MGC_TANDEM_CONN_POS_SUR) == FALSE)
return MGC_RESULT_FAILURE;
pChild->mgNo = pMgInfo->id;
pChild->portNo = pSurPhyPort->portNo;
pChild->chlNo = mgc_chnl_info_get_chnl_no_of_phy(pSurChnlInfo, pSurPhyPort);
pChild->connectNo = mgc_connect_get_connNo_of_chnl_info(pSurConnect, pSurChnlInfo);
sprintf(pSurConnect->mediaAttr.callId, "%s" , pConnect->mediaAttr.callId);
memcpy(&pSurConnect->codecList, &pConnect->codecList , sizeof(MGC_CODEC_LIST));
mgc_connect_add_crcx_with_mode(pSurConnect, MGC_CON_MODE_SENDONLY , pPortInfo);
mgc_connect_add_nop(pConnect, pPortInfo); //report to the parant chnl
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_TANDEM_FORK_CHNL);
pPortInfo->usrPort = usrPort;
MGC_DEBUG("conn[%d] fork conn[%d] callid :%s , on tandem[%d]" , pConnect->id , pSurConnect->id , pSurConnect->mediaAttr.callId, pTandem->id);
MGC_DEBUG("fork mg[%d]port[%d]chnl[%d]connNo[%d]" , pChild->mgNo , pChild->portNo , pChild->chlNo, pChild->connectNo);
MGC_INFO("%s success" , __FUNCTION__);
return MGC_RESULT_OK;
}
int mgc_delete_tandem(WORD usrPort , DWORD tandemId)
{
MGC_TANDEM_INFO *pTandem = NULL;
PORT_INFO *pPortInfo = NULL;
CONNECT_INFO *pConnect = NULL;
pTandem = mgc_tandem_info_get_tandem_by_id(tandemId);
pPortInfo = mgc_port_info_get_unused_port();
MGC_DEBUG("func %s " , __FUNCTION__);
if((pTandem == NULL)||(pPortInfo == NULL))
return MGC_RESULT_INPUT_ILLEGAL;
pConnect = pTandem->pTxconn;
mgc_tandem_info_unset_conn(pTandem, pTandem->pTconn);
mgc_tandem_info_unset_conn(pTandem, pTandem->pAconn);
mgc_tandem_info_clear(pTandem, pPortInfo);
mgc_port_info_set_step_to_start(pPortInfo);
mgc_port_info_set_oper_id(pPortInfo , MGC_OPER_ID_TANDEM_CLEAR);
pPortInfo->usrPort = usrPort;
MGC_INFO("%s tandem[%d] success" , __FUNCTION__ , pTandem->id);
return MGC_RESULT_OK;
}
int mgc_update_phy_port_status(CHNL chnl, BOOL status)
{
MG_INFO *pMgInfo = NULL;
PHY_PORT_INFO *pPhyPort = NULL;
pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo);
pPhyPort = mgc_phy_port_find_port_of_mg(pMgInfo, chnl.portNo);
MGC_DEBUG("func %s " , __FUNCTION__);
if((pMgInfo == NULL)||(pPhyPort == NULL))
{
MGC_ERROR("update phyport failed! ,lost phyport");
return MGC_RESULT_INPUT_ILLEGAL;
}
if(status == TRUE)
{
pPhyPort->status = MGC_PHY_PORT_STATUS_ON_LINE;
}
else
{
pPhyPort->status = MGC_PHY_PORT_STATUS_OFF_LINE;
}
return MGC_RESULT_OK;
}