/* ********************************************************************************* * * * NOTICE: * * * ********************************************************************************* * mgcPhyPort <---------- mgcChnls <-----------mgcConnections */ /********************************************************************************* * * This file should provide CHNL_INFO APIs used in MGC module. Every chnl should be attached to *a phyport if used, and could contain servral connections * * Author Date * ------ ------ * Sam Yao Aug 2008 *********************************************************************************/ /*-----------------------------------------------------------------------*/ /* INCLUDE HEADER FILES */ /*-----------------------------------------------------------------------*/ #include "./include/mgc_chnl_info.h" #include "./include/mgc_debug.h" #include "./include/mgc_conn_info.h" #include "./include/mgc_phy_port.h" #include "./include/mgc_mg_info.h" #include "./include/mgc_mgcp.h" static CHNL_INFO mgcChnl[MGC_MAX_NUM_OF_CHNL]; /*----------------------------------------------------------------------- CHNL_INFO M A N A G E R ------------------------------------------------------------------------*/ /*************************************************************************** * mgc_chnl_info_init * ------------------------------------------------------------------------ * General: init CHNL_INFO structure objcet * Return Value: void. * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo- the pointer of the CHNL_INFO object which should be init * id - the id of the CHNL_INFO object ***************************************************************************/ void mgc_chnl_info_init(CHNL_INFO *pChnlInfo , int id) { int i; if((pChnlInfo == NULL)||(id < 0)) return; pChnlInfo->id = id; pChnlInfo->status = MGC_CHNL_INFO_STATUS_UNDEF; pChnlInfo->pPhyPort = NULL; pChnlInfo->connectNum = 0; pChnlInfo->monFlag = 0; pChnlInfo->maxConnectNum = 0; for(i=0 ; ipConnection[i] = NULL; } return; } void mgc_chnl_info_setup(void) { int i; CHNL_INFO *pChnlInfo = NULL; for(i=0 ; ipConnection[i]; if(pConnect == NULL) continue; if((mgc_connect_get_status(pConnect) == MGC_CONNECT_STATUS_CREATED)||(mgc_connect_get_status(pConnect) == MGC_CONNECT_STATUS_CREATE)) { if(mgc_connect_dlcx_para_create(pConnect , &mgcpPara) == TRUE) MGCP_req(mgc_mgcp_get_sap_index(), MGCP_CMD_DLCX , 0xFFFF , &mgcpPara); } mgc_connect_init(pConnect , pConnect->id); } mgc_chnl_info_init(pChnlInfo , pChnlInfo->id); return; } /*************************************************************************** * mgc_chnl_info_get_unused_chnl * ------------------------------------------------------------------------ * General: get a unused CHNL_INFO structure * Return Value: if failure return NULL , else return a pointer * ------------------------------------------------------------------------ * Arguments: * Input: void ***************************************************************************/ CHNL_INFO *mgc_chnl_info_get_unused_chnl(void) { int i; CHNL_INFO *pChnlInfo = NULL; for(i=0 ; ipPhyPort != NULL) continue; return pChnlInfo; } return NULL; } /*************************************************************************** * mgc_chnl_info_attach_to_phy_port * ------------------------------------------------------------------------ * General: record the owner phyPort of the chnl * Return Value: if failure return FALSE , else return TRUE * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to record it's own phyPort * pPhyPort - the pointer of the PHY_PORT_INFO object which is the owner of the chnl ***************************************************************************/ BOOL mgc_chnl_info_attach_to_phy_port(CHNL_INFO *pChnlInfo , PHY_PORT_INFO *pPhyPort) { if((pChnlInfo == NULL) || (pPhyPort == NULL)) return FALSE; if(pChnlInfo->status != MGC_CHNL_INFO_STATUS_UNDEF) return FALSE; switch(pPhyPort->portType) { case MGC_PHY_PORT_TYPE_E1: case MGC_PHY_PORT_TYPE_T1: case MGC_PHY_PORT_TYPE_ANALOG: case MGC_PHY_VIRTUAL_TYPE_INTERNAL: pChnlInfo->maxConnectNum = 1; break; case MGC_PHY_VIRTUAL_TYPE_TANDEM: pChnlInfo->maxConnectNum = 2; break; case MGC_PHY_VIRTUAL_TYPE_SURVEILLANCE: pChnlInfo->maxConnectNum = 1; break; case MGC_PHY_VIRTUAL_TYPE_ANN: pChnlInfo->maxConnectNum = MGC_MAX_NUM_OF_CHNL_CON; break; default: pChnlInfo->maxConnectNum = 0; break; } pChnlInfo->pPhyPort = pPhyPort; return TRUE; } /*************************************************************************** * mgc_chnl_info_status_set * ------------------------------------------------------------------------ * General: set the status of the CHNL_INFO object * Return Value: void * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to be set * status - the status of the CHNL_INFO object ***************************************************************************/ void mgc_chnl_info_status_set(CHNL_INFO *pChnlInfo , MGC_CHNL_INFO_STATUS status) { if(pChnlInfo == NULL) return; pChnlInfo->status = status; return; } /*************************************************************************** * mgc_chnl_info_find_chnl_of_phy * ------------------------------------------------------------------------ * General: get the CHNL_INFO object in the phyPort according to the chnl id * Return Value: if failure return NULL , else return the pointor of the object * ------------------------------------------------------------------------ * Arguments: * Input: pPhyPort - the pointer of the phyPort which contain the CHNL_INFO objects pointers * chnlNo - the CHNL_INFO object id ***************************************************************************/ CHNL_INFO *mgc_chnl_info_find_chnl_of_phy(PHY_PORT_INFO *pPhyPort , int chnlNo) { if(pPhyPort == NULL) return NULL; if(chnlNo > MGC_MAX_CHNL_NUM_PER_PHY) return NULL; if(chnlNo >= pPhyPort->chnlNum) { MGC_WARN("chnlNo is out of suppose to be "); } return pPhyPort->pChnlInfo[chnlNo]; } /*************************************************************************** * mgc_chnl_info_get_chnl * ------------------------------------------------------------------------ * General: get the CHNL_INFO object according to the CHNL parameters * Return Value: if failure return NULL , else return the pointor of the object * ------------------------------------------------------------------------ * Arguments: * Input: chnl - CHNL object which contain mgNo , chnlNo, connectNo and phyPort No ***************************************************************************/ CHNL_INFO *mgc_chnl_info_get_chnl(CHNL chnl) { MG_INFO *pMgInfo = NULL; PHY_PORT_INFO *pPhyPort = NULL; CHNL_INFO *pChnlInfo = NULL; pMgInfo = mgc_mg_info_get_index_mg(chnl.mgNo); if(pMgInfo == NULL) return NULL; pPhyPort = mgc_phy_port_find_port_of_mg(pMgInfo , chnl.portNo); if(pPhyPort == NULL) return NULL; pChnlInfo = mgc_chnl_info_find_chnl_of_phy(pPhyPort , chnl.chlNo); if(pChnlInfo == NULL) return NULL; return pChnlInfo; } /*************************************************************************** * mgc_chnl_info_attach_connect * ------------------------------------------------------------------------ * General: record a connection in the assgined place * Return Value: if failure return FALSE , else return TRUE * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to record the connect * pConnect - the pointer of the CONNECT_INFO object * connNo - the place where the CONNECT_INFO should be record in ***************************************************************************/ BOOL mgc_chnl_info_attach_connect(CHNL_INFO *pChnlInfo , CONNECT_INFO *pConnect , int connNo) { if((pChnlInfo == NULL)||(pConnect == NULL)) return FALSE; if(connNo >= MGC_MAX_NUM_OF_CHNL_CON) return FALSE; if(mgc_connect_get_status(pConnect)!= MGC_CONNECT_STATUS_UNDEF) return FALSE; if(pChnlInfo->pConnection[connNo] != NULL) return FALSE; if(pChnlInfo->connectNum >= pChnlInfo->maxConnectNum) return FALSE; if(mgc_connect_attach_connect_to_chnl(pConnect , pChnlInfo) == FALSE) return FALSE; pChnlInfo->pConnection[connNo] = pConnect; pChnlInfo->connectNum++; mgc_connect_set_status(pConnect , MGC_CONNECT_STATUS_IDLE); mgc_chnl_info_status_set(pChnlInfo , MGC_CHNL_INFO_STATUS_USED); return TRUE; } /*************************************************************************** * mgc_chnl_info_detach_connect * ------------------------------------------------------------------------ * General: remove a connect info from the CHNL_INFO object * Return Value: if failure return FALSE , else return TRUE * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to remove connect info * pConnect - the pointer of the CONNECT_INFO object which need to be remove ***************************************************************************/ BOOL mgc_chnl_info_detach_connect(CHNL_INFO *pChnlInfo , CONNECT_INFO *pConnect) { int i; if((pChnlInfo == NULL)||(pConnect == NULL)) return FALSE; for(i=0 ; ipConnection[i]) continue; pChnlInfo->pConnection[i] = NULL; pChnlInfo->connectNum--; mgc_connect_init(pConnect, pConnect->id); // MGC_DEBUG("conn[%d] detach from chnlInfo[%d], as connNo %d" , pConnect->id , pChnlInfo->id , i); return TRUE; } return FALSE; } /*************************************************************************** * mgc_chnl_info_get_chnl_no_of_phy * ------------------------------------------------------------------------ * General: find the record place of the CHNL_INFO object in it's owner phyPort * Return Value: if failure return -1 , else return the place number * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to be find * pPhyPort - the pointer of the PHY_PORT_INFO object which contain the CHNL_INFO ***************************************************************************/ int mgc_chnl_info_get_chnl_no_of_phy(CHNL_INFO *pChnlInfo , PHY_PORT_INFO *pPhyPort) { int i; if((pChnlInfo == NULL)||(pPhyPort == NULL)) return -1; for(i=0 ; ipChnlInfo[i]) continue; return i; } return -1; } /*************************************************************************** * mgc_chnl_info_assign_connect * ------------------------------------------------------------------------ * General: assgin a connection on the assigned place * Return Value: if failure return NULL, else return the pointer of the connect * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to assign * connNo - the assgined place NO ***************************************************************************/ CONNECT_INFO *mgc_chnl_info_assign_connect(CHNL_INFO *pChnlInfo , int connNo) { CONNECT_INFO *pConnect = NULL; if(pChnlInfo == NULL) return NULL; pConnect = mgc_connect_find_connect_of_chnl(pChnlInfo, connNo); if(pConnect != NULL) { //MGC_DEBUG("chnlInfo[%d] already have conn[%d], as connNo %d" , pChnlInfo->id , pConnect->id , connNo); return pConnect; } if(pChnlInfo->connectNum >= pChnlInfo->maxConnectNum) return FALSE; pConnect = mgc_connect_get_unused(); if(pConnect == NULL) return NULL; if(mgc_chnl_info_attach_connect(pChnlInfo , pConnect , connNo) == FALSE) return NULL; //MGC_DEBUG("assign unused conn[%d] to chnlInfo[%d]connNo[%d]" , pConnect->id , pChnlInfo->id, connNo); return pConnect; } /*************************************************************************** * mgc_chnl_info_assign_idle_connect * ------------------------------------------------------------------------ * General: assgin a connection on the CHNL_INFO object * Return Value: if failure return NULL, else return the pointer of the connect * ------------------------------------------------------------------------ * Arguments: * Input: pChnlInfo - the pointer of the CHNL_INFO object which need to assign ***************************************************************************/ CONNECT_INFO *mgc_chnl_info_assign_idle_connect(CHNL_INFO *pChnlInfo) { int i; CONNECT_INFO *pConnect = NULL; CONNECT_INFO *pConnectTmp = NULL; if(pChnlInfo == NULL) return NULL; //MGC_DEBUG("func %s " , __FUNCTION__); for(i=0 ; ipConnection[i]; if(pConnect != NULL) { if(mgc_connect_get_status(pConnect) != MGC_CONNECT_STATUS_IDLE) continue; return pConnect; } pConnectTmp = mgc_chnl_info_assign_connect(pChnlInfo , i); if(pConnectTmp == NULL) continue; return pConnectTmp; } return NULL; } void mgc_chnl_info_set_mon(int id, BOOL enable) { if((id < 0) || (id > MGC_MAX_NUM_OF_CHNL)) return; mgcChnl[id].monFlag = enable; } BYTE *mgc_chnl_info_get_res_addr(void) { return (BYTE *)mgcChnl; } char *mgc_chnl_info_print_codec(CHNL_INFO *pChnlInfo) { int i; CONNECT_INFO *pConnect = NULL; if(pChnlInfo == NULL) return "UNKNOWN"; if(pChnlInfo->maxConnectNum > 1) return "UNKNOWN"; for(i=0 ; imaxConnectNum ; i++) { pConnect = pChnlInfo->pConnection[i]; if(pConnect != NULL) break; } if(pConnect == NULL) return "UNKNOWN"; return mgc_mgcp_print_vc_codec(pConnect->mediaAttr.vocoderType); } char *mgc_chnl_info_print_remote(CHNL_INFO *pChnlInfo) { int i; CONNECT_INFO *pConnect = NULL; PUB_SDP_MEDIA *pMedia = NULL; PUB_SDP_MSG *pSdp = NULL; static char buf[32]; sprintf(buf , "0.0.0.0:0"); if(pChnlInfo == NULL) return buf; if(pChnlInfo->maxConnectNum > 1) return buf; for(i=0 ; imaxConnectNum ; i++) { pConnect = pChnlInfo->pConnection[i]; if(pConnect != NULL) break; } if(pConnect == NULL) return buf; pSdp = &pConnect->mediaAttr.sdp; pMedia = &pSdp->medias.medias[0]; if((pMedia->m.port != 0)||(strlen(pSdp->c.addr) != 0)) sprintf(buf , "%s:%d" , pSdp->c.addr, pMedia->m.port); return buf; } char *mgc_chnl_info_print_mode(CHNL_INFO *pChnlInfo) { int i; CONNECT_INFO *pConnect = NULL; if(pChnlInfo == NULL) return "INACTIVE"; if(pChnlInfo->maxConnectNum > 1) return "INACTIVE"; for(i=0 ; imaxConnectNum ; i++) { pConnect = pChnlInfo->pConnection[i]; if(pConnect != NULL) break; } if(pConnect == NULL) return "INACTIVE"; switch(mgc_connect_get_conn_mode(pConnect)) { case MGC_CON_MODE_INACTIVE: return "INACTIVE"; case MGC_CON_MODE_RECVONLY: return "RECVONLY"; case MGC_CON_MODE_SENDONLY: return "SENDONLY"; case MGC_CON_MODE_SENDRECV: return "SENDRECV"; default: break; } return "INACTIVE"; } char *mgc_chnl_info_print_status(CHNL_INFO *pChnlInfo) { int i; CONNECT_INFO *pConnect = NULL; if(pChnlInfo == NULL) return "UNDEF"; if(pChnlInfo->maxConnectNum > 1) return "UNDEF"; for(i=0 ; imaxConnectNum ; i++) { pConnect = pChnlInfo->pConnection[i]; if(pConnect != NULL) break; } if(pConnect == NULL) return "IDLE"; switch(mgc_connect_get_status(pConnect)) { case MGC_CONNECT_STATUS_IDLE: return "IDLE"; case MGC_CONNECT_STATUS_CREATE: return "CREATE"; case MGC_CONNECT_STATUS_CREATED: return "CONNECT"; case MGC_CONNECT_STATUS_CREATING: return "CREATING"; default: break; } return "UNDEF"; } #ifdef MGC_TEST_ENABLE int mgc_chnl_info_assigned_num(void) { int i , num; CHNL_INFO *pChnlInfo = NULL; num = 0; for(i=0 ; ipPhyPort != NULL) num++; } return num; } #endif