From ad5297cab71287bb48e6efe004104da34d756ace Mon Sep 17 00:00:00 2001 From: root Date: Fri, 27 Jul 2012 12:54:58 -0400 Subject: [PATCH] adding codec nogotiation code --- .../media_gateway_cmd_handler.c | 28 ++++++--- .../mod_media_gateway/media_gateway_stack.h | 4 +- .../mod_media_gateway/media_gateway_utils.c | 58 +++++++++++++++++-- 3 files changed, 75 insertions(+), 15 deletions(-) diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c b/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c index 8940d36e66..18129ff975 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c @@ -198,7 +198,7 @@ switch_status_t mg_is_ito_pkg_req(megaco_profile_t* mg_profile, MgMgcoCommand *c * * */ -switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *cmd, mg_termination_t* term) +switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *cmd, mg_termination_t* term, CmMemListCp *memCp) { CmSdpMedProtoFmts *format; TknU8 *fmt; @@ -301,7 +301,7 @@ switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand * } } - mgco_handle_sdp(&local->sdp, term, MG_SDP_LOCAL); + mgco_handle_incoming_sdp(&local->sdp, term, MG_SDP_LOCAL, mg_profile, memCp); break; } @@ -313,7 +313,7 @@ switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand * remote = &mediaPar->u.remote; sdp = remote->sdp.info[0]; /* for Matt - same like local descriptor */ - mgco_handle_sdp(&remote->sdp, term, MG_SDP_REMOTE); + mgco_handle_incoming_sdp(&remote->sdp, term, MG_SDP_REMOTE, mg_profile, memCp); break; } @@ -406,12 +406,12 @@ switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand * if (mgStream->sl.remote.pres.pres) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got remote stream media description:\n"); - mgco_handle_sdp(&mgStream->sl.remote.sdp, term, MG_SDP_LOCAL); + mgco_handle_incoming_sdp(&mgStream->sl.remote.sdp, term, MG_SDP_LOCAL, mg_profile, memCp); } if (mgStream->sl.local.pres.pres) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got local stream media description:\n"); - mgco_handle_sdp(&mgStream->sl.local.sdp, term, MG_SDP_REMOTE); + mgco_handle_incoming_sdp(&mgStream->sl.local.sdp, term, MG_SDP_REMOTE, mg_profile, memCp); } break; @@ -610,7 +610,14 @@ switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *i /********************************************************************/ - ret = mg_prc_descriptors(mg_profile, inc_cmd, term); + ret = mg_prc_descriptors(mg_profile, inc_cmd, term, &inc_cmd->u.mgCmdInd[0]->memCp); + + /* IF there is any error , return */ + if(term->mg_error_code && (*term->mg_error_code == MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT)){ + mg_util_set_err_string(&errTxt, " Unsupported Codec "); + err_code = MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT; + goto error; + } /* TODO - locally assigned SDP must be the part of termination...which we can use to fill responses*/ @@ -1067,7 +1074,14 @@ switch_status_t handle_mg_modify_cmd(megaco_profile_t* mg_profile, MgMgcoCommand /********************************************************************/ - ret = mg_prc_descriptors(mg_profile, inc_cmd, term); + ret = mg_prc_descriptors(mg_profile, inc_cmd, term, &inc_cmd->u.mgCmdInd[0]->memCp); + + /* IF there is any error , return */ + if(term->mg_error_code && (*term->mg_error_code == MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT)){ + mg_util_set_err_string(&errTxt, " Unsupported Codec "); + err_code = MGT_MGCP_RSP_CODE_INCONSISTENT_LCL_OPT; + goto error; + } /* SDP updated to termination */ megaco_activate_termination(term); diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h index f84bfbd5e4..20354b0ccb 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h @@ -141,7 +141,7 @@ typedef enum { (_reqId)->id.val = 0xFFFFFFFF; -switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, mg_termination_t* term); +switch_status_t mg_prc_descriptors(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, mg_termination_t* term, CmMemListCp *memCp); void handle_sng_log(uint8_t level, char *fmt, ...); void handle_mgco_sta_ind(Pst *pst, SuId suId, MgMgtSta* msg); void handle_mgco_txn_sta_ind(Pst *pst, SuId suId, MgMgcoInd* msg); @@ -166,7 +166,7 @@ int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, megaco_profile_t* mg_cfg, m switch_status_t mg_is_ito_pkg_req(megaco_profile_t* mg_profile, MgMgcoCommand *cmd); switch_status_t mg_send_end_of_axn(SuId suId, MgMgcoTransId* transId, MgMgcoContextId* ctxtId, TknU32* peerId); -void mgco_handle_sdp(CmSdpInfoSet *sdp,mg_termination_t* term, mgco_sdp_types_e sdp_type); +void mgco_handle_incoming_sdp(CmSdpInfoSet *sdp,mg_termination_t* term, mgco_sdp_types_e sdp_type, megaco_profile_t* mg_profile, CmMemListCp *memCp); void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId); switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd, MgMgcoContextId* new_ctxtId); switch_status_t handle_mg_subtract_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd); diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c b/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c index ae4ec24b04..019725208f 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c @@ -421,7 +421,7 @@ void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd) } /*****************************************************************************************************************************/ -void mgco_print_sdp_attr_set(CmSdpAttrSet *s) +void mgco_handle_sdp_attr_set(CmSdpAttrSet *s, mg_termination_t* term) { int i=0x00; if (s->numComp.pres) { @@ -461,6 +461,9 @@ void mgco_print_sdp_attr_set(CmSdpAttrSet *s) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "\t PTIME = %ld \n", (NOTPRSNT != a->u.ptime.pres)?a->u.ptime.val:-1); #endif + if(MG_TERM_RTP == term->type){ + term->u.rtp.ptime = a->u.ptime.val; + } break; } case CM_SDP_ATTR_RECVONLY: @@ -786,7 +789,30 @@ void mgco_print_CmSdpU8OrNil(CmSdpU8OrNil* p) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE,"CmSdpU8OrNil: Value = %d \n", (NOTPRSNT != p->val.pres)?p->val.val:-1); } -void mgco_print_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp_types_e sdp_type) +const char* mg_get_codec_name(megaco_profile_t* mg_profile, int iana_code) +{ + int i = 0x00; + const switch_codec_implementation_t *codecs[16]; + char *codec_prefs[16] = { 0 }; + char *szcodec_prefs; + int codec_count; + + szcodec_prefs = strdup(mg_profile->codec_prefs); + codec_count = switch_split(szcodec_prefs, ',', codec_prefs); + + /* Get the list of codecs, by preference */ + switch_loadable_module_get_codecs_sorted(codecs, switch_arraylen(codecs), codec_prefs, switch_arraylen(codec_prefs)); + /* see if received codec is present in our codec supported list */ + for (i = 0; codecs[i] && i < codec_count; i++) { + if(iana_code == codecs[i]->ianacode){ + return codecs[i]->iananame; + } + } + + return NULL; +} + +void mgco_handle_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp_types_e sdp_type, megaco_profile_t* mg_profile, CmSdpAttrSet *attrSet, CmMemListCp *memCp) { int i=0x00; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "***** Media Parameter *********** \n"); @@ -837,6 +863,26 @@ void mgco_print_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp } } } + + /* Ideally remote descriptor should have supported codec..but just in case calling remove un-supported codecs api */ + mg_rem_unsupported_codecs(mg_profile, term , r, attrSet, memCp); + + + /* now whatever we have , that will be suported one */ + if((NOTPRSNT != r->num.pres) && (0 != r->num.val) && (NULL != r->fmts[0])){ + const char* name = mg_get_codec_name(mg_profile, r->fmts[0]->val.val); + if(name){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, " Updating codec to[%d], name[%s] \n", + r->fmts[0]->val.val, name); + if(MG_TERM_RTP == term->type){ + term->u.rtp.codec = name; + } + }else{ + /* ERROR */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " NO Codec Name found against iana[%d] \n", r->fmts[0]->val.val); + } + } + break; } @@ -854,7 +900,7 @@ void mgco_print_sdp_media_param(CmSdpMedPar *s, mg_termination_t* term, mgco_sdp switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "**************** \n"); } -void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e sdp_type) +void mgco_handle_incoming_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e sdp_type, megaco_profile_t* mg_profile, CmMemListCp *memCp) { int i; @@ -1021,7 +1067,7 @@ void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e /************************************************************************************************************************/ /* Attribute Set */ - mgco_print_sdp_attr_set(&s->attrSet); + mgco_handle_sdp_attr_set(&s->attrSet, term); /************************************************************************************************************************/ /* Media Descriptor Set */ @@ -1077,7 +1123,7 @@ void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e break; } } - mgco_print_sdp_media_param(&f->par, term, sdp_type); + mgco_handle_sdp_media_param(&f->par, term, sdp_type, mg_profile, &desc->attrSet, memCp); } /*info */ @@ -1097,7 +1143,7 @@ void mgco_handle_sdp(CmSdpInfoSet *sdp, mg_termination_t* term, mgco_sdp_types_e } /* attribute set */ - mgco_print_sdp_attr_set(&desc->attrSet); + mgco_handle_sdp_attr_set(&desc->attrSet, term); if (desc->field.mediaType.val == CM_SDP_MEDIA_AUDIO &&