/* ********************************************************************************* * * * NOTICE: * * * ********************************************************************************* * ++++++++++++++++++++++++++++++++++ * + + * + + * target -------> + recv endpoint <-------------->send enpoint + <--------------associator * + | | + * + | | + * + | | + * + + * + tandem objec + * ++++++++++++++++++++++++++++++++++ * * * */ /********************************************************************************* * * This file should provide rtp_proxy related object APIs * * Author Date * ------ ------ * Sam Yao Aug 2008 *********************************************************************************/ #include "./include/mgc_tandem_info.h" #include "./include/mgc_debug.h" #include "./include/mgc_conn_info.h" #include "./include/mgc_chnl_info.h" #include "./include/mgc_phy_port.h" #include "./include/mgc_mgcp.h" #include "./include/mgc_mg_info.h" #include "./include/mgc_port_info.h" #include "./include/mgc_sur_info.h" static MGC_TANDEM_INFO mgcTandem[MGC_MAX_NUM_OF_TANDEM]; static CONNECT_INFO mgcTandConn[MGC_MAX_NUM_OF_TANDEM_CONN]; static CHNL_INFO mgcTandChnl[MGC_MAX_NUM_OF_TANDEM_CHNL]; static PHY_PORT_INFO mgcTandPort[MGC_MAX_NUM_OF_RTP_PROXY_NUM]; extern MGC_SAP *mgc_sap_get_index_sap(int index); MGC_TANDEM_STATUS mgc_tandem_info_get_status(MGC_TANDEM_INFO *pTandem) { if(pTandem == NULL) return MGC_TANDEM_STATUS_UNDEF; return pTandem->status; } void mgc_tandem_info_set_status(MGC_TANDEM_INFO *pTandem , MGC_TANDEM_STATUS status) { if((pTandem == NULL)||(status == MGC_TANDEM_STATUS_UNDEF)) return; pTandem->status = status; } CONNECT_INFO *mgc_tandem_info_get_unattached_conn(void) { CONNECT_INFO *pConnect = NULL; int i; for(i=0 ; ipTandem != NULL) continue; return pConnect; } return NULL; } BOOL mgc_tandem_info_conn_rec_tandem(CONNECT_INFO *pConnect , MGC_TANDEM_INFO *pTandem) { if((pConnect == NULL) || (pTandem == NULL)) return FALSE; if(pConnect->pTandem != NULL) { MGC_ERROR("conn[%d] already attached to tandem[%d]!" , pConnect->id, pConnect->pTandem->id); return FALSE; } pConnect->pTandem = pTandem; return TRUE; } BOOL mgc_tandem_info_unset_conn(MGC_TANDEM_INFO *pTandem , CONNECT_INFO *pConnect) { if((pTandem == NULL)||(pConnect == NULL)) return FALSE; if(pTandem->pAconn == pConnect) { pTandem->pAconn = NULL; MGC_DEBUG("tandem[%d] unset aor conn[%d]!" , pTandem->id, pConnect->id); } else if(pTandem->pTconn == pConnect) { pTandem->pTconn = NULL; MGC_DEBUG("tandem[%d] unset tar conn[%d]!" , pTandem->id, pConnect->id); } else if(pTandem->pTxconn == pConnect) { pTandem->pTxconn = NULL; MGC_WARN("tandem[%d] tx is removed!" , pTandem->id); } else if(pTandem->pRxconn == pConnect) { pTandem->pRxconn = NULL; MGC_WARN("tandem[%d] rx is removed!" , pTandem->id); } else if(mgc_sur_info_remove_conn_to_list(&pTandem->list, pConnect) != FALSE) { MGC_DEBUG("tandem[%d] remove sur conn[%d]" , pTandem->id , pConnect->id); } pConnect->pTandem = NULL; return TRUE; } BOOL mgc_tandem_info_set_conn(MGC_TANDEM_INFO *pTandem , CONNECT_INFO *pConnect, MGC_TANDEM_CONN_POS pos) { BOOL result = FALSE; if((pTandem == NULL)||(pConnect== NULL)||(pos == MGC_TANDEM_CONN_POS_UNDEF)) return FALSE; if(pConnect->pTandem != NULL) { MGC_ERROR("conn[%d] already attached to tandem[%d]!" , pConnect->id, pConnect->pTandem->id); return FALSE; } switch(pos) { case MGC_TANDEM_CONN_POS_TAR: if(pTandem->pTconn != NULL) { MGC_ERROR("tandem[%d] already have target conn[%d]!" , pTandem->id, pTandem->pTconn->id); break; } if(mgc_tandem_info_conn_rec_tandem(pConnect, pTandem) == TRUE) { pTandem->pTconn = pConnect; result = TRUE; MGC_DEBUG("tandem[%d] set tar conn[%d]", pTandem->id, pConnect->id); } mgc_tandem_info_set_status(pTandem, MGC_TANDEM_STATUS_USED); break; case MGC_TANDEM_CONN_POS_TX: if(pTandem->pTxconn != NULL) { MGC_ERROR("tandem[%d] already have tx conn[%d]!" , pTandem->id, pTandem->pTxconn->id); break; } if(mgc_tandem_info_conn_rec_tandem(pConnect, pTandem) == TRUE) { pTandem->pTxconn = pConnect; result = TRUE; // MGC_DEBUG("tandem[%d] set tx conn[%d]", pTandem->id, pConnect->id); } break; case MGC_TANDEM_CONN_POS_RX: if(pTandem->pRxconn != NULL) { MGC_ERROR("tandem[%d] already have rx conn[%d]!" , pTandem->id, pTandem->pRxconn->id); break; } if(mgc_tandem_info_conn_rec_tandem(pConnect, pTandem) == TRUE) { pTandem->pRxconn = pConnect; result = TRUE; // MGC_DEBUG("tandem[%d] set rx conn[%d]", pTandem->id, pConnect->id); } break; case MGC_TANDEM_CONN_POS_AOR: if(pTandem->pAconn != NULL) { MGC_ERROR("tandem[%d] already have associator conn[%d]!" , pTandem->id, pTandem->pAconn->id); break; } if(mgc_tandem_info_get_status(pTandem) == MGC_TANDEM_STATUS_IDLE) { MGC_ERROR("tandem[%d] should not set aorConn[%d] fisrt" , pTandem->id , pConnect->id); result = FALSE; break; } if(mgc_tandem_info_conn_rec_tandem(pConnect, pTandem) == TRUE) { pTandem->pAconn = pConnect; result = TRUE; MGC_DEBUG("tandem[%d] set aor conn[%d]", pTandem->id, pConnect->id); } break; case MGC_TANDEM_CONN_POS_SUR: MGC_DEBUG("try find conn[%d] in tandem[%d] list" , pConnect->id , pTandem->id); if(mgc_sur_info_find_conn_in_list(&pTandem->list, pConnect) != NULL) { result = TRUE; MGC_DEBUG("tandem[%d] already has sur conn[%d]" , pTandem->id , pConnect->id); break; } if(mgc_tandem_info_conn_rec_tandem(pConnect, pTandem) == FALSE) break; if(mgc_sur_info_add_conn_to_list(&pTandem->list, pConnect) == TRUE) { result = TRUE; MGC_DEBUG("tandem[%d] add sur conn[%d]" , pTandem->id , pConnect->id); break; } break; default: return result; } pConnect->pTandem = pTandem; return result; } MGC_TANDEM_CONN_POS mgc_tandem_info_get_conn_pos(MGC_TANDEM_INFO *pTandem , CONNECT_INFO *pConnect) { MGC_TANDEM_CONN_POS pos = MGC_TANDEM_CONN_POS_UNDEF; if((pTandem == NULL) || (pConnect == NULL)) return MGC_TANDEM_CONN_POS_UNDEF; if(pTandem->pTconn == pConnect) { pos = MGC_TANDEM_CONN_POS_TAR; } else if(pTandem->pTxconn == pConnect) { pos = MGC_TANDEM_CONN_POS_TX; } else if(pTandem->pRxconn == pConnect) { pos = MGC_TANDEM_CONN_POS_RX; } else if(pTandem->pAconn == pConnect) { pos = MGC_TANDEM_CONN_POS_AOR; } else if(mgc_sur_info_find_conn_in_list(&pTandem->list,pConnect) != NULL) { pos = MGC_TANDEM_CONN_POS_SUR; } if(pos != MGC_TANDEM_CONN_POS_UNDEF) { if(pTandem != pConnect->pTandem) { MGC_ERROR(" conn[%d] do not bleong to tandem[%d]" , pConnect->id , pTandem->id); pos = MGC_TANDEM_CONN_POS_UNDEF; } } return pos; } BOOL mgc_tandem_info_init(MGC_TANDEM_INFO *pTandem , int id) { CONNECT_INFO *pConn = NULL; MGCP_PARA mgcpPara; if(pTandem == NULL) return FALSE; pTandem->id = id; pTandem->pTconn = NULL; pTandem->pAconn = NULL; if(pTandem->pRxconn != NULL) { if((mgc_connect_get_status(pTandem->pRxconn) == MGC_CONNECT_STATUS_CREATED)||(mgc_connect_get_status(pTandem->pRxconn) == MGC_CONNECT_STATUS_CREATE)) { if(mgc_connect_dlcx_para_create(pTandem->pRxconn , &mgcpPara) == TRUE) MGCP_req(mgc_mgcp_get_sap_index(), MGCP_CMD_DLCX , 0xFFFF , &mgcpPara); } mgc_tandem_info_unset_conn(pTandem,pTandem->pRxconn); mgc_chnl_info_detach_connect(pTandem->pRxconn->pChnlInfo,pTandem->pRxconn); mgc_connect_init(pTandem->pRxconn , pTandem->pRxconn->id); } if(pTandem->pTxconn != NULL) { if((mgc_connect_get_status(pTandem->pTxconn) == MGC_CONNECT_STATUS_CREATED)||(mgc_connect_get_status(pTandem->pTxconn) == MGC_CONNECT_STATUS_CREATE)) { if(mgc_connect_dlcx_para_create(pTandem->pTxconn , &mgcpPara) == TRUE) MGCP_req(mgc_mgcp_get_sap_index(), MGCP_CMD_DLCX , 0xFFFF , &mgcpPara); } mgc_tandem_info_unset_conn(pTandem,pTandem->pTxconn); mgc_chnl_info_detach_connect(pTandem->pTxconn->pChnlInfo,pTandem->pTxconn); mgc_connect_init(pTandem->pTxconn , pTandem->pTxconn->id); } pTandem->status = MGC_TANDEM_STATUS_UNDEF; pConn = mgc_tandem_info_get_unattached_conn(); if(pConn == NULL) return FALSE; if(mgc_tandem_info_set_conn(pTandem, pConn,MGC_TANDEM_CONN_POS_RX) == FALSE) return FALSE; pConn = mgc_tandem_info_get_unattached_conn(); if(pConn == NULL) return FALSE; if(mgc_tandem_info_set_conn(pTandem, pConn,MGC_TANDEM_CONN_POS_TX) == FALSE) return FALSE; mgc_sur_info_clear_list(&pTandem->list); mgc_tandem_info_set_status(pTandem,MGC_TANDEM_STATUS_IDLE); sprintf(pTandem->escci , "%x%lx" , id , time(NULL)); return TRUE; } MGC_TANDEM_INFO *mgc_tandem_info_get_tandem_by_id(DWORD id) { if(id >= MGC_MAX_NUM_OF_TANDEM) return NULL; return &mgcTandem[id]; } MGC_TANDEM_INFO *mgc_tandem_info_get_idle_tandem(void) { int i; static int index = 0; MGC_TANDEM_INFO *pTandem = NULL; MGC_TANDEM_INFO *pTandemTmp = NULL; MG_INFO *pMgInfo = NULL; i = index; do { i++; if(i == MGC_MAX_NUM_OF_TANDEM) i = 0; pTandem = &mgcTandem[i]; if(mgc_tandem_info_get_status(pTandem) != MGC_TANDEM_STATUS_IDLE) continue; if(pTandem->pRxconn == NULL) { MGC_ERROR("tandem[%d] lost rxConn" , pTandem->id); continue; } if(pTandem->pTxconn == NULL) { MGC_ERROR("tandem[%d] lost txConn" , pTandem->id); continue; } pMgInfo = mgc_connect_get_own_mg_info(pTandem->pRxconn); if(pMgInfo == NULL) continue; if(pMgInfo != mgc_connect_get_own_mg_info(pTandem->pTxconn)) { MGC_WARN("tandem[%d] txConn and rxConn is not on the same rtpproxy" , pTandem->id); continue; } if(pMgInfo->enable == FALSE) continue; pTandemTmp = pTandem; index = i; break; }while(i != index); return pTandemTmp; } void mgc_tandem_info_setup(void) { int i; CONNECT_INFO *pConn = NULL; MGC_TANDEM_INFO *pTandem = NULL; CHNL_INFO *pChnl = NULL; PHY_PORT_INFO *pPhyPort = NULL; for(i=0; ichnlNum == 0)&&(pPhyPort->pMgInfo == NULL)) return pPhyPort; } return NULL; } static CONNECT_INFO *mgc_tandem_info_get_unsed_conn(void) { int i; CONNECT_INFO *pConnect = NULL; for(i=0 ; ipChnlInfo != NULL) continue; return pConnect; } return NULL; } static CHNL_INFO *mgc_tandem_info_get_unsed_chnl(void) { int i; CHNL_INFO *pChnlInfo = NULL; for(i=0 ; istatus != MGC_CHNL_INFO_STATUS_UNDEF) continue; return pChnlInfo; } return NULL; } static BOOL mgc_tandem_info_add_conn_to_chnl(CHNL_INFO *pChnlInfo) { int i; CONNECT_INFO *pConn = NULL; if(pChnlInfo == NULL) return FALSE; for(i=0 ; imaxConnectNum ; i++) { pConn = mgc_tandem_info_get_unsed_conn(); if(pConn == NULL) return FALSE; if(mgc_chnl_info_attach_connect(pChnlInfo, pConn, i) == FALSE) return FALSE; } return TRUE; } static BOOL mgc_tandem_info_check_tandem_chnl_conn(CHNL_INFO *pChnlInfo) { int i; BOOL result = FALSE; CONNECT_INFO *pConn = NULL; MGC_TANDEM_INFO *pTandem = NULL; if(pChnlInfo == NULL) return FALSE; /*get first attached connection's tandem*/ for(i=0; imaxConnectNum ; i++) { pConn = pChnlInfo->pConnection[i]; if(pConn == NULL) continue; result = TRUE; pTandem = pConn->pTandem; break; } for(i=0; imaxConnectNum ; i++) { pConn = pChnlInfo->pConnection[i]; if(pConn == NULL) continue; if(pTandem == pConn->pTandem) continue; result = FALSE; break; } return result; } static BOOL mgc_tandem_info_add_chnl_to_port(PHY_PORT_INFO *pPhyPort) { int i; CHNL_INFO *pChnlInfo = NULL; if(pPhyPort == NULL) return FALSE; for(i=0 ; ichnlNum ; i++) { pChnlInfo = mgc_tandem_info_get_unsed_chnl(); if(pChnlInfo == NULL) return FALSE; pPhyPort->pChnlInfo[i] = pChnlInfo; if(mgc_chnl_info_attach_to_phy_port(pChnlInfo , pPhyPort) == FALSE) return FALSE; if(mgc_tandem_info_add_conn_to_chnl(pChnlInfo) == FALSE) return FALSE; if(mgc_tandem_info_check_tandem_chnl_conn(pChnlInfo) == FALSE) return FALSE; mgc_chnl_info_status_set(pChnlInfo , MGC_CHNL_INFO_STATUS_IDLE); } return TRUE; } static BOOL mgc_tandem_info_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((pMgcSap == NULL)||(pMgInfo == NULL)) return FALSE; if(pMgInfo->created == FALSE) return FALSE; if(portType!= MGC_PHY_VIRTUAL_TYPE_TANDEM) return FALSE; if(pMgInfo->mgAttr.mgType != MGC_MG_TYPE_TANDEM) return FALSE; pPhyPort = mgc_tandem_info_get_unused_phy_port(); if(pPhyPort == NULL) return FALSE; pPhyPort->portType = portType; pPhyPort->portNo = portNo; pPhyPort->pMgcSap = pMgcSap; pPhyPort->pMgInfo = pMgInfo; switch(pMgInfo->mgAttr.ctrlType) { 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 FALSE; } if(mgc_tandem_info_add_chnl_to_port(pPhyPort) == FALSE) { mgc_phy_port_clear(pPhyPort); return FALSE; } if(mgc_mg_info_attach_phy_port(pMgInfo , pPhyPort, pMgcSap)== FALSE) { mgc_phy_port_clear(pPhyPort); return FALSE; } return TRUE; } BOOL mgc_tandem_info_add_tandem_res(BYTE sapIndex, WORD mgNo) { MG_INFO *pMgInfo = NULL; BOOL result = FALSE; PHY_PORT_INFO *pPhyPort = NULL; int i; pMgInfo = mgc_mg_info_get_index_mg(mgNo); if(pMgInfo == NULL) return FALSE; if(pMgInfo->mgAttr.mgType != MGC_MG_TYPE_TANDEM) return FALSE; pPhyPort = mgc_tandem_info_get_unused_phy_port(); if(pPhyPort == NULL) return FALSE; for(i=0 ; i< MGC_MAX_PHY_PORT_PER_MG ; i++) { if(pMgInfo->pPhyPort[i] != NULL) continue; result = TRUE; break; } if(result == FALSE) { MGC_DEBUG("mg[%d] is full of phyport" , pMgInfo->id); return FALSE; } if(mgc_tandem_info_add_port(sapIndex, mgNo, i , MGC_PHY_VIRTUAL_TYPE_TANDEM) == FALSE) return FALSE; return TRUE; } BOOL mgc_tandem_info_create_tandem(MGC_TANDEM_INFO *pTandem , PORT_INFO *pPortInfo) { if((pTandem == NULL) || (pPortInfo == NULL)) return FALSE; if(mgc_connect_get_status(pTandem->pTxconn) == MGC_CONNECT_STATUS_IDLE) mgc_connect_add_crcx_with_mode(pTandem->pTxconn, MGC_CON_MODE_SENDRECV ,pPortInfo); if(mgc_connect_get_status(pTandem->pRxconn) == MGC_CONNECT_STATUS_IDLE) mgc_connect_add_crcx_with_mode(pTandem->pRxconn, MGC_CON_MODE_RECVONLY,pPortInfo); mgc_connect_add_nop(pTandem->pTxconn, pPortInfo); mgc_tandem_info_set_status(pTandem, MGC_TANDEM_STATUS_USED); return TRUE; } BOOL mgc_tandem_info_updadte_media(MGC_TANDEM_INFO *pTandem , PORT_INFO *pPortInfo) { CONNECT_INFO *pTarConn = NULL; CONNECT_INFO *pSurConn = NULL; MG_INFO *pTarMgInfo = NULL; MGC_SUR_INFO_NODE *pNode = NULL; BYTE ptime; MGC_CODEC_LIST codeclist; int i; if((pTandem == NULL) ||(pPortInfo == NULL)) return FALSE; pTarConn = pTandem->pTconn; if(mgc_tandem_info_get_conn_pos(pTandem, pTarConn) != MGC_TANDEM_CONN_POS_TAR) return FALSE; pTarMgInfo = mgc_connect_get_own_mg_info(pTarConn); if(pTarMgInfo == NULL) return FALSE; mgc_connect_codec_list_init(&codeclist); ptime = 0; if((mgc_connect_get_status(pTarConn) == MGC_CONNECT_STATUS_CREATED)||(mgc_connect_get_status(pTarConn) == MGC_CONNECT_STATUS_CREATE)) { memcpy(&codeclist , &pTarConn->codecList , sizeof(MGC_CODEC_LIST)); ptime = pTarConn->mediaAttr.ptime; } else { memcpy(&codeclist , &pTarMgInfo->mgAttr.codecList , sizeof(MGC_CODEC_LIST)); ptime = pTarMgInfo->mgAttr.ptime; } if(pTandem->pRxconn == NULL) { MGC_ERROR("tandem[%d] lost RxConn" , pTandem->id); return FALSE; } memcpy(&pTandem->pRxconn->codecList , &codeclist, sizeof(MGC_CODEC_LIST)); pTandem->pRxconn->mediaAttr.ptime = ptime; if(pTandem->pTxconn == NULL) { MGC_ERROR("tandem[%d] lost TxConn" , pTandem->id); return FALSE; } memcpy(&pTandem->pTxconn->codecList , &codeclist,sizeof(MGC_CODEC_LIST)); pTandem->pTxconn->mediaAttr.ptime = ptime; for(i=0 ; ilist.len ; i++) { pNode = mgc_sur_info_get_list_node(&pTandem->list , i); if(pNode == NULL) { MGC_WARN("tandem[%d] sur_list lost node[%d]" , pTandem->id , i); continue; } pSurConn = pNode->pConn; if(pSurConn == NULL) { MGC_WARN("tandem[%d] sur_list node[%d] lost surConn " , pTandem->id , i); continue; } memcpy(&pSurConn->codecList , &codeclist , sizeof(MGC_CODEC_LIST)); pSurConn->mediaAttr.ptime = ptime; } return TRUE; } BOOL mgc_tandem_info_create_tar_tandem(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR) return FALSE; mgc_tandem_info_create_tandem(pTandem, pPortInfo); mgc_tandem_info_updadte_media(pTandem, pPortInfo); return TRUE; } BOOL mgc_tandem_info_stop_tar_send_to_tandem(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR) return FALSE; mgc_connect_add_mdcx(pConnect, pTandem->pTxconn, MGC_CON_MODE_RECVONLY, pPortInfo); MGC_DEBUG("tarConn[%d] stop send stream to tandem[%d]" , pConnect->id , pTandem->id); return TRUE; } BOOL mgc_tandem_info_stop_aor_send_to_tandem(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_AOR) return FALSE; mgc_connect_add_mdcx(pConnect, pTandem->pRxconn, MGC_CON_MODE_RECVONLY, pPortInfo); MGC_DEBUG("AorConn[%d] stop send stream to tandem[%d]" , pConnect->id , pTandem->id); return TRUE; } BOOL mgc_tandem_info_stop_tandem_send_to_tar(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR) return FALSE; mgc_connect_add_mdcx(pTandem->pTxconn, pConnect, MGC_CON_MODE_RECVONLY, pPortInfo); MGC_DEBUG("tandem[%d] stop send stream to TarConn[%d]" , pTandem->id , pConnect->id); return TRUE; } BOOL mgc_tandem_info_stop_tandem_send_to_aor(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_AOR) return FALSE; mgc_connect_add_mdcx(pTandem->pRxconn, pConnect, MGC_CON_MODE_RECVONLY, pPortInfo); MGC_DEBUG("tandem[%d] stop send stream to AorConn[%d]" , pTandem->id , pConnect->id); return TRUE; } BOOL mgc_tandem_info_start_tandem_send_to_tar(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR) return FALSE; mgc_connect_add_mdcx(pConnect, pTandem->pTxconn, MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pTandem->pTxconn, pConnect, MGC_CON_MODE_SENDRECV, pPortInfo); MGC_DEBUG("tandem[%d] start communication with tar conn[%d]" , pTandem->id , pConnect->id); return TRUE; } BOOL mgc_tandem_info_start_tandem_send_to_aor(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return FALSE; pTandem = pConnect->pTandem; if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_AOR) return FALSE; mgc_connect_add_mdcx(pConnect, pTandem->pRxconn, MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pTandem->pRxconn, pConnect, MGC_CON_MODE_SENDRECV, pPortInfo); MGC_DEBUG("tandem[%d] start communication with aor conn[%d]" , pTandem->id , pConnect->id); return TRUE; } BOOL mgc_tandem_info_dettach_aor_related_tandem(CONNECT_INFO *pConnect, CONNECT_INFO *pPeerConnect, PORT_INFO *pPortInfo) { if((pConnect == NULL)||(pPeerConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR) { if(mgc_tandem_info_stop_tandem_send_to_aor(pConnect, pPortInfo) == FALSE) return FALSE; mgc_tandem_info_unset_conn(pConnect->pTandem, pConnect); } if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_AOR) { if(mgc_tandem_info_stop_tandem_send_to_aor(pPeerConnect, pPortInfo) == FALSE) return FALSE; mgc_tandem_info_unset_conn(pPeerConnect->pTandem, pPeerConnect); } return TRUE; } BOOL mgc_tandem_info_connect_tandem_to_connection(CONNECT_INFO *pConnect, CONNECT_INFO *pPeerConnect, MGC_CON_MODE mode , PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPeerConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR) { MGC_ERROR("conn[%d] is not a target!!" , pConnect->id); return FALSE; } if(pPeerConnect->pTandem) { if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem,pPeerConnect) != MGC_TANDEM_CONN_POS_AOR) { MGC_ERROR("conn[%d] should not be related to any tandem!" , pPeerConnect->id); return FALSE; } if(pConnect->pTandem != pPeerConnect->pTandem) { MGC_ERROR("conn[%d] and peerConn[%d] should not be called by %s!" , pConnect->id, pPeerConnect->id, __FUNCTION__); return FALSE; } } MGC_DEBUG("enter %s" , __FUNCTION__); pTandem = pConnect->pTandem; mgc_connect_add_mdcx(pTandem->pTxconn, pConnect, MGC_CON_MODE_SENDRECV , pPortInfo); mgc_connect_add_mdcx(pTandem->pRxconn , pPeerConnect, MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pConnect,pTandem->pTxconn,mode, pPortInfo); if(pPeerConnect->pTandem == NULL) mgc_tandem_info_set_conn(pTandem, pPeerConnect, MGC_TANDEM_CONN_POS_AOR); MGC_DEBUG("tandem[%d] connect to conn[%d]" , pTandem->id , pPeerConnect->id); return TRUE; } BOOL mgc_tandem_info_connect_tandem_to_tandem(CONNECT_INFO *pConnect, CONNECT_INFO *pPeerConnect, MGC_CON_MODE mode , PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; MGC_TANDEM_INFO *pPeerTandem = NULL; if((pConnect == NULL)||(pPeerConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) != MGC_TANDEM_CONN_POS_TAR) { MGC_ERROR("conn[%d] is not a target!!" , pConnect->id); return FALSE; } if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) != MGC_TANDEM_CONN_POS_TAR) { MGC_ERROR("conn[%d] is not a target!!" , pPeerConnect->id); return FALSE; } MGC_DEBUG("enter %s" , __FUNCTION__); pTandem = pConnect->pTandem; pPeerTandem = pPeerConnect->pTandem; mgc_connect_add_mdcx(pTandem->pTxconn, pConnect, MGC_CON_MODE_SENDRECV , pPortInfo); mgc_connect_add_mdcx(pTandem->pRxconn , pPeerTandem->pRxconn , MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pPeerTandem->pRxconn , pTandem->pRxconn , MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pConnect,pTandem->pTxconn,mode, pPortInfo); MGC_DEBUG("tandem[%d] connect to tandem[%d]" , pTandem->id , pPeerTandem->id); return TRUE; } BOOL mgc_tandem_info_connect_connection_to_tandem(CONNECT_INFO *pConnect, CONNECT_INFO *pPeerConnect, MGC_CON_MODE mode , PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pPeerTandem = NULL; if((pConnect == NULL)||(pPeerConnect == NULL)||(pPortInfo == NULL)) return FALSE; MGC_DEBUG("enter %s" , __FUNCTION__); if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) != MGC_TANDEM_CONN_POS_TAR) { MGC_ERROR("conn[%d] is not a target!!" , pPeerConnect->id); return FALSE; } if(pConnect->pTandem != NULL) { if(mgc_tandem_info_get_conn_pos(pConnect->pTandem,pConnect) != MGC_TANDEM_CONN_POS_AOR) { MGC_ERROR("conn[%d] should not be related to tandem[%d]!" , pConnect->id , pConnect->pTandem->id); mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo); } if(pConnect->pTandem != pPeerConnect->pTandem) { MGC_ERROR("conn[%d] and peerConn[%d] should not be called by %s!" , pConnect->id, pPeerConnect->id, __FUNCTION__); return FALSE; } } pPeerTandem = pPeerConnect->pTandem; mgc_connect_add_mdcx(pPeerTandem->pRxconn, pConnect, MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pPeerTandem->pTxconn, pPeerConnect , MGC_CON_MODE_SENDRECV, pPortInfo); mgc_connect_add_mdcx(pConnect, pPeerTandem->pRxconn , mode, pPortInfo); if(pConnect->pTandem == NULL) mgc_tandem_info_set_conn(pPeerTandem, pConnect, MGC_TANDEM_CONN_POS_AOR); MGC_DEBUG("conn[%d] connect to tandem[%d]" , pConnect->id , pPeerTandem->id); return TRUE; } BOOL mgc_tandem_info_connect(CONNECT_INFO *pConnect, CONNECT_INFO *pPeerConnect, MGC_CON_MODE mode , PORT_INFO *pPortInfo) { MG_INFO *pPeerMgInfo = NULL; if((pConnect == NULL)||(pPeerConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_TAR) { if(pConnect->pTandem->pAconn != pPeerConnect) mgc_tandem_info_remove_connection_from_tandem(pConnect->pTandem->pAconn, pPortInfo); if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_TAR) { mgc_tandem_info_connect_tandem_to_tandem(pConnect, pPeerConnect, mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem,pPeerConnect) == MGC_TANDEM_CONN_POS_AOR) { mgc_tandem_info_connect_tandem_to_connection(pConnect, pPeerConnect,mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_UNDEF) { mgc_tandem_info_connect_tandem_to_connection(pConnect, pPeerConnect,mode, pPortInfo); } else { MGC_ERROR("peerConn[%d] is in illegal tandem[%d]!" , pPeerConnect->id, pPeerConnect->pTandem->id); return FALSE; } return TRUE; } 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) { if(pPeerConnect->pTandem != pConnect->pTandem) mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo); if(pPeerConnect->pTandem->pAconn != pConnect) mgc_tandem_info_remove_connection_from_tandem(pPeerConnect->pTandem->pAconn, pPortInfo); mgc_tandem_info_connect_connection_to_tandem(pConnect, pPeerConnect, mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_AOR) { mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo); mgc_tandem_info_remove_connection_from_tandem(pPeerConnect, pPortInfo); mgc_connect_add_mdcx(pConnect, pPeerConnect, mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_UNDEF) { mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo); mgc_connect_add_mdcx(pConnect, pPeerConnect, mode, pPortInfo); } else { MGC_WARN("AorConn[%d] is not rec correct" , pConnect->id); mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo); return FALSE; } return TRUE; } if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_SUR) { mode = MGC_CON_MODE_SENDONLY; if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) != MGC_TANDEM_CONN_POS_UNDEF) { MGC_ERROR("surConn[%d] can't connect conn[%d]" , pConnect->id , pPeerConnect->id); return FALSE; } mgc_connect_add_mdcx(pConnect, pPeerConnect, mode, pPortInfo); return TRUE; } if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_UNDEF) { if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_TAR) { mgc_tandem_info_remove_connection_from_tandem(pPeerConnect->pTandem->pAconn, pPortInfo); mgc_tandem_info_connect_connection_to_tandem(pConnect, pPeerConnect, mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_AOR) { mgc_tandem_info_remove_connection_from_tandem(pPeerConnect, pPortInfo); mgc_connect_add_mdcx(pConnect, pPeerConnect, mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_SUR) { mgc_connect_add_mdcx(pConnect, pPeerConnect, mode, pPortInfo); } else if(mgc_tandem_info_get_conn_pos(pPeerConnect->pTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_UNDEF) { pPeerMgInfo = mgc_connect_get_own_mg_info(pPeerConnect); if(pPeerMgInfo == NULL) return FALSE; if((pPeerMgInfo->mgAttr.mgType == MGC_MG_TYPE_INTERNAL)&&(pPeerConnect->mediaAttr.conMode == MGC_CON_MODE_SENDONLY)) mode = MGC_CON_MODE_RECVONLY; mgc_connect_add_mdcx(pConnect, pPeerConnect, mode, pPortInfo); } else { MGC_ERROR("conn[%d] can't connect conn[%d]" , pConnect->id , pPeerConnect->id); return FALSE; } return TRUE; } MGC_ERROR("Conn[%d] is in illegal tandem[%d]!" , pConnect->id, pConnect->pTandem->id); return FALSE; } BOOL mgc_tandem_info_add_crcx_aas(CONNECT_INFO *pAasConnect, CONNECT_INFO *pPeerConnect, PORT_INFO *pPortInfo) { CONNECT_INFO *pPeerConn = NULL; CONNECT_INFO *pConn = NULL; MGC_TANDEM_INFO *pPeerTandem = NULL; if((pAasConnect == NULL)||(pPeerConnect == NULL)||(pPortInfo == NULL)) return FALSE; pPeerConn = pPeerConnect; pConn = pAasConnect; pPeerTandem = pPeerConnect->pTandem; if(pConn->pTandem != NULL) { MGC_WARN("aasConn[%d] should not rec any tandem!" , pConn->id); mgc_tandem_info_remove_connection_from_tandem(pConn, pPortInfo); mgc_connect_add_dlcx(pConn, pPortInfo); } if(mgc_tandem_info_get_conn_pos(pPeerTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_TAR) { if(pPeerConnect->pTandem->pAconn != NULL) mgc_tandem_info_remove_connection_from_tandem(pPeerTandem->pAconn, pPortInfo); mgc_tandem_info_start_tandem_send_to_tar(pPeerConnect, pPortInfo); pPeerConn = pPeerTandem->pRxconn; } else if(mgc_tandem_info_get_conn_pos(pPeerTandem, pPeerConnect) == MGC_TANDEM_CONN_POS_AOR) { if(mgc_tandem_info_get_conn_pos(pPeerTandem, pPeerTandem->pTconn) == MGC_TANDEM_CONN_POS_TAR) { mgc_tandem_info_remove_connection_from_tandem(pPeerConnect, pPortInfo); } else { mgc_tandem_info_start_tandem_send_to_aor(pPeerConnect, pPortInfo); pPeerConn = pPeerTandem->pTxconn; } } else if(mgc_tandem_info_get_conn_pos(pPeerTandem, pPeerConnect) != MGC_TANDEM_CONN_POS_UNDEF) { MGC_ERROR("peerConn[%d] is in illegal tandem[%d]!" , pPeerConnect->id, pPeerTandem->id); return FALSE; } MGC_DEBUG("aasConn[%d] send tone to peerConn[%d]" , pConn->id , pPeerConn->id); mgc_connect_add_crcx_aas(pConn, pPeerConn, pPortInfo); return TRUE; } BOOL mgc_tandem_info_add_mdcx_aas(CONNECT_INFO *pConnect, CONNECT_INFO *pAasConnect, PORT_INFO *pPortInfo) { CONNECT_INFO *pPeerConn = NULL; CONNECT_INFO *pConn = NULL; MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pAasConnect == NULL)||(pPortInfo == NULL)) return FALSE; pPeerConn = pAasConnect; pConn = pConnect; pTandem = pConn->pTandem; if(pPeerConn->pTandem != NULL) { MGC_WARN("aasConn[%d] should not related to any tandem" , pAasConnect->id); mgc_tandem_info_remove_connection_from_tandem(pPeerConn, pPortInfo); mgc_connect_add_dlcx(pConnect, pPortInfo); return FALSE; } if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) == MGC_TANDEM_CONN_POS_TAR) { mgc_tandem_info_start_tandem_send_to_tar(pConnect, pPortInfo); pConn = pTandem->pRxconn; } else if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR) { if(mgc_tandem_info_get_conn_pos(pTandem, pTandem->pTconn) == MGC_TANDEM_CONN_POS_TAR) { mgc_tandem_info_remove_connection_from_tandem(pConnect, pPortInfo); } else { mgc_tandem_info_start_tandem_send_to_aor(pConnect, pPortInfo); pConn = pTandem->pTxconn; } } else if(mgc_tandem_info_get_conn_pos(pTandem, pConnect) != MGC_TANDEM_CONN_POS_UNDEF) { MGC_ERROR("Conn[%d] is in illegal tandem[%d]!" , pConnect->id, pTandem->id); return FALSE; } MGC_DEBUG("conn[%d] hear aasConn[%d] " , pConn->id , pPeerConn->id); mgc_connect_add_mdcx_aas(pConn, pPeerConn, pPortInfo); return TRUE; } BOOL mgc_tandem_info_mdcx(CONNECT_INFO *pConnect , PORT_INFO *pPortInfo) { if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_TAR) mgc_connect_add_mdcx(pConnect, pConnect->pTandem->pTxconn, pConnect->mediaAttr.conMode, pPortInfo); if(mgc_tandem_info_get_conn_pos(pConnect->pTandem, pConnect) == MGC_TANDEM_CONN_POS_AOR) mgc_connect_add_mdcx(pConnect, pConnect->pTandem->pRxconn, pConnect->mediaAttr.conMode, pPortInfo); return TRUE; } BOOL mgc_tandem_info_remove_connection_from_tandem(CONNECT_INFO *pConnect, PORT_INFO *pPortInfo) { MGC_TANDEM_INFO *pTandem = NULL; if((pConnect == NULL)||(pPortInfo == NULL)) return FALSE; if(pConnect->pTandem == NULL) return TRUE; pTandem = pConnect->pTandem; switch(mgc_tandem_info_get_conn_pos(pTandem, pConnect)) { case MGC_TANDEM_CONN_POS_TAR: mgc_tandem_info_stop_tandem_send_to_tar(pConnect, pPortInfo); mgc_tandem_info_stop_tar_send_to_tandem(pConnect, pPortInfo); mgc_tandem_info_unset_conn(pTandem, pConnect); break; case MGC_TANDEM_CONN_POS_AOR: mgc_tandem_info_stop_tandem_send_to_aor(pConnect, pPortInfo); mgc_tandem_info_stop_aor_send_to_tandem(pConnect, pPortInfo); mgc_tandem_info_unset_conn(pTandem, pConnect); break; case MGC_TANDEM_CONN_POS_TX: case MGC_TANDEM_CONN_POS_RX: MGC_ERROR("tandem[%d] is not allowed remove conn[%d]" , pTandem->id, pConnect->id); break; default: MGC_ERROR("conn[%d] in illegal tandem[%d]", pConnect->id , pConnect->pTandem->id); return FALSE; } return TRUE; } BOOL mgc_tandem_info_clear(MGC_TANDEM_INFO *pTandem, PORT_INFO *pPortInfo) { CONNECT_INFO *pConnect = NULL; MGC_SUR_INFO_NODE *pNode = NULL; if((pTandem == NULL)||(pPortInfo == NULL)) return FALSE; pNode = mgc_sur_info_get_list_tail(&pTandem->list); while(pNode != NULL) { pConnect = pNode->pConn; mgc_connect_add_dlcx(pConnect, pPortInfo); mgc_tandem_info_unset_conn(pTandem, pConnect); pNode = mgc_sur_info_get_list_tail(&pTandem->list); } mgc_connect_add_dlcx(pTandem->pRxconn, pPortInfo); mgc_connect_add_dlcx(pTandem->pTxconn, pPortInfo); mgc_tandem_info_unset_conn(pTandem, pTandem->pAconn); mgc_tandem_info_unset_conn(pTandem, pTandem->pTconn); mgc_tandem_info_set_status(pTandem, MGC_TANDEM_STATUS_IDLE); return TRUE; }