/* ********************************************************************************* * * * NOTICE: * * * ********************************************************************************* * * * * mgcSap <---------mgcPhyPorts --------> mgcMgInfo * | * | * | * mgcChnls <-----------mgcConnections */ /********************************************************************************* * * 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)) 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 ; iusrType == 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 ; imgType == 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 ; ipPhyPort[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 ; imgAttr.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 ; icodecList.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; }