diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway.c b/src/mod/endpoints/mod_media_gateway/media_gateway.c index 0c43adab6b..769bdc5465 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway.c @@ -46,6 +46,63 @@ void megaco_peer_profile_release(mg_peer_profile_t *profile) switch_thread_rwlock_unlock(profile->rwlock); } +megaco_profile_t* megaco_get_profile_by_suId(SuId suId) +{ + megaco_profile_t* profile = NULL; + void *val = NULL; + switch_hash_index_t *hi = NULL; + int found = 0x00; + const void *var; + + /*iterate through profile list to get requested suID profile */ + for (hi = switch_hash_first(NULL, megaco_globals.profile_hash); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + profile = (megaco_profile_t *) val; + if (profile->idx == suId) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Got profile[%s] associated with suId[%d]\n",profile->name, suId); + found = 0x01; + break; + } + } + + if(!found){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, " Not able to find profile associated with suId[%d]\n",suId); + return NULL; + } + + return profile; +} + +mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id) +{ + mg_context_t *result = NULL; + megaco_profile_t* profile = NULL; + + if(NULL == (profile = megaco_get_profile_by_suId(suId))){ + return NULL; + } + + + if (context_id > MG_MAX_CONTEXTS) { + return NULL; + } + + switch_thread_rwlock_rdlock(profile->contexts_rwlock); + + /* Context exists */ + if (profile->contexts_bitmap[context_id % 8] & (1 << (context_id / 8))) { + for (result = profile->contexts[context_id % MG_CONTEXT_MODULO]; result; result = result->next) { + if (result->context_id == context_id) { + break; + } + } + } + + switch_thread_rwlock_unlock(profile->contexts_rwlock); + + return result; +} + mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id) { mg_context_t *result = NULL; 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 7855bcd9d9..b19d799a9d 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 @@ -29,16 +29,65 @@ const char *mg_service_change_reason[] = { * * */ -switch_status_t handle_mg_add_cmd(MgMgcoAmmReq *addReq) +switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *inc_cmd) { - int descId; - for (descId = 0; descId < addReq->dl.num.val; descId++) { - switch (addReq->dl.descs[descId]->type.val) { + MgMgcoContextId *ctxtId; + int descId; + MgStr errTxt; + MgMgcoInd *mgErr; + MgMgcoTermId *termId; + MgMgcoTermIdLst* termLst; + int err_code; + MgMgcoAmmReq *cmd = &inc_cmd->u.mgCmdInd[0]->cmd.u.add; + U32 txn_id = inc_cmd->transId.val; + + /********************************************************************/ + ctxtId = &inc_cmd->contextId; + termLst = mg_get_term_id_list(inc_cmd); + termId = termLst->terms[0]; + + /********************************************************************/ + /* Validating ADD request *******************************************/ + + /*-- NULL Context & ALL Context not applicable for ADD request --*/ + if ((NOTPRSNT != ctxtId->type.pres) && + ((MGT_CXTID_ALL == ctxtId->type.val) || + (MGT_CXTID_NULL == ctxtId->type.val))) { + + switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_ERROR," ADD Request processing failed, Context ALL/NULL not allowed\n"); + + mg_util_set_ctxt_string(&errTxt, ctxtId); + err_code = MGT_MGCO_RSP_CODE_PROT_ERROR; + goto error; + } + + /********************************************************************/ + /* Allocate context - if context type is CHOOSE */ + if ((NOTPRSNT != ctxtId->type.pres) && + (MGT_CXTID_CHOOSE == ctxtId->type.val)){ + + /* TODO - Matt */ + } + + /********************************************************************/ + /* Allocate new RTP termination - If term type is CHOOSE */ + if ((NOTPRSNT != termId->type.pres) && + (MGT_TERMID_CHOOSE == termId->type.val)){ + + /* TODO - Matt */ + /* allocate rtp term and associated the same to context */ + } + + /********************************************************************/ + + + for (descId = 0; descId < cmd->dl.num.val; descId++) { + switch (cmd->dl.descs[descId]->type.val) { case MGT_MEDIADESC: { int mediaId; - for (mediaId = 0; mediaId < addReq->dl.descs[descId]->u.media.num.val; mediaId++) { - MgMgcoMediaPar *mediaPar = addReq->dl.descs[descId]->u.media.parms[mediaId]; + for (mediaId = 0; mediaId < cmd->dl.descs[descId]->u.media.num.val; mediaId++) { + MgMgcoMediaPar *mediaPar = cmd->dl.descs[descId]->u.media.parms[mediaId]; switch (mediaPar->type.val) { case MGT_MEDIAPAR_LOCAL: { @@ -94,6 +143,13 @@ switch_status_t handle_mg_add_cmd(MgMgcoAmmReq *addReq) return SWITCH_STATUS_SUCCESS; +error: + if (SWITCH_STATUS_SUCCESS == + mg_build_mgco_err_request(&mgErr, txn_id, ctxtId, err_code, &errTxt)) { + sng_mgco_send_err(mg_profile->idx, mgErr); + } + mg_free_cmd(cmd); + return SWITCH_STATUS_FALSE; } /*****************************************************************************************************************************/ 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 cdbde20c13..8225ee9570 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h @@ -133,7 +133,7 @@ int sng_mgco_mg_get_status(int elemId, MgMngmt* cfm, megaco_profile_t* mg_cfg, m switch_status_t mg_send_end_of_axn(SuId suId, MgMgcoTransId* transId, MgMgcoContextId* ctxtId, TknU32* peerId); void mgco_print_sdp(CmSdpInfoSet *sdp); void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId); -switch_status_t handle_mg_add_cmd(MgMgcoAmmReq *addReq); +switch_status_t handle_mg_add_cmd(megaco_profile_t* mg_profile, MgMgcoCommand *addReq); switch_status_t mg_stack_free_mem(void* msg); switch_status_t mg_stack_alloc_mem( Ptr* _memPtr, Size _memSize ); MgMgcoMediaDesc* get_default_media_desc(void); @@ -144,6 +144,8 @@ void mg_util_set_txn_string(MgStr *errTxt, U32 *txnId); switch_status_t mg_build_mgco_err_request(MgMgcoInd **errcmd,U32 trans_id, MgMgcoContextId *ctxt_id, U32 err, MgStr *errTxt); switch_status_t mg_send_audit_rsp(SuId suId, MgMgcoCommand *req); switch_status_t handle_mg_audit_cmd(SuId suId, MgMgcoCommand *auditReq); +switch_status_t mg_stack_termination_is_in_service(char* term_str, int len); +void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd); switch_status_t mg_send_modify_rsp(SuId suId, MgMgcoCommand *req); switch_status_t mg_send_subtract_rsp(SuId suId, MgMgcoCommand *req); 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 ed70b74173..e536fd83bf 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_utils.c @@ -78,6 +78,14 @@ switch_status_t mg_stack_free_mem(void* msg) } +/*****************************************************************************************************************************/ + +/* TODO - Matt - to see if term is in service or not */ +switch_status_t mg_stack_termination_is_in_service(char* term_str,int len) +{ + return SWITCH_STATUS_SUCCESS; +} + /*****************************************************************************************************************************/ S16 mg_fill_mgco_termid ( MgMgcoTermId *termId, char* term_str, int term_len, CmMemListCp *memCp) @@ -351,6 +359,55 @@ void mg_util_set_ctxt_string ( MgStr *errTxt, MgMgcoContextId *ctxtId) "info, error-text is: %s\n", __PRETTY_FUNCTION__,errTxt->val); } +/*****************************************************************************************************************************/ + +void mg_util_set_cmd_name_string (MgStr *errTxt, MgMgcoCommand *cmd) +{ + MG_ZERO((errTxt->val), sizeof(errTxt->val)); + errTxt->len = 0; + + if ((!cmd) && (!cmd->u.mgCmdInd[0])) { + switch(cmd->u.mgCmdInd[0]->cmd.type.val) + { + case MGT_AUDITCAP: + errTxt->val[0]='\"'; + errTxt->val[1]='A'; + errTxt->val[2]='u'; + errTxt->val[3]='d'; + errTxt->val[4]='i'; + errTxt->val[5]='t'; + errTxt->val[6]='C'; + errTxt->val[7]='a'; + errTxt->val[8]='p'; + errTxt->val[9]='a'; + errTxt->val[10]='b'; + errTxt->val[11]='i'; + errTxt->val[12]='l'; + errTxt->val[13]='i'; + errTxt->val[14]='t'; + errTxt->val[15]='y'; + errTxt->val[16]='\"'; + errTxt->len = 17; + break; + + case MGT_MOVE: + errTxt->val[0]='\"'; + errTxt->val[1]='M'; + errTxt->val[2]='o'; + errTxt->val[3]='v'; + errTxt->val[4]='e'; + errTxt->val[5]='\"'; + errTxt->len = 6; + break; + + default: + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s: Not expected command Type[%d]\n", + __PRETTY_FUNCTION__,cmd->u.mgCmdInd[0]->cmd.type.val); + + break; + } + } +} /*****************************************************************************************************************************/ void mgco_print_sdp(CmSdpInfoSet *sdp) diff --git a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c index 7e4be231ca..a6202295fd 100644 --- a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c @@ -233,6 +233,9 @@ static switch_status_t mgco_parse_local_sdp(mg_termination_t *term, CmSdpInfoSet } #endif +/* KAPIL- NOTE : We are using Command mode operation of MEGACO stack, so we will always get command indication instead of transaction */ +/* Below API is not useful ... just leaving as it is...*/ + void handle_mgco_txn_ind(Pst *pst, SuId suId, MgMgcoMsg* msg) { size_t txnIter; @@ -425,8 +428,12 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) MgMgcoInd *mgErr; MgStr errTxt; MgMgcoContextId ctxtId; + MgMgcoContextId *inc_context; MgMgcoTermIdLst* termLst; - + MgMgcoTermId *termId; + int count; + int err_code; + megaco_profile_t* mg_profile; switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s: Received Command Type[%s] \n", __PRETTY_FUNCTION__, PRNT_MG_CMD_TYPE(cmd->cmdType.val)); @@ -442,15 +449,8 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) ctxtId.val.pres = NOTPRSNT; mg_util_set_txn_string(&errTxt, &txn_id); - - if (SWITCH_STATUS_SUCCESS == mg_build_mgco_err_request(&mgErr, txn_id, &ctxtId, - MGT_MGCO_RSP_CODE_INVLD_IDENTIFIER, &errTxt)) { - sng_mgco_send_err(suId, mgErr); - } - - /* deallocate the msg */ - mg_free_cmd(cmd); - return ; + err_code = MGT_MGCO_RSP_CODE_INVLD_IDENTIFIER; + goto error; } /* Get the termination Id list from the command(Note: GCP_2_1 has termination list , else it will be termination Id) */ @@ -458,12 +458,80 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) if ((NULL == termLst) || (NOTPRSNT == termLst->num.pres)) { /* termination-id not present , error */ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Termination-Id Not received..rejecting command \n"); - mg_free_cmd(cmd); - return ; + + /*-- Send Error to MG Stack --*/ + MG_ZERO(&ctxtId, sizeof(MgMgcoContextId)); + ctxtId.type.pres = NOTPRSNT; + ctxtId.val.pres = NOTPRSNT; + mg_util_set_txn_string(&errTxt, &txn_id); + err_code = MGT_MGCO_RSP_CODE_INVLD_IDENTIFIER; + goto error; } + termId = termLst->terms[0]; + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Termination-Id received..value[%s] type[%d] \n", termId->name.lcl.val, termId->type.val); + + /* Not sure - IF Stack fills term type properly..but adding code just to be sure ...*/ + if ((PRSNT_NODEF == termId->type.pres) && + (MGT_TERMID_OTHER == termId->type.val)) { + /* Checking the $ in the pathname */ + if ((PRSNT_NODEF == termId->name.pres.pres) && + (PRSNT_NODEF == termId->name.lcl.pres)) { + for (count = 0; count < termId->name.lcl.len; count++) { + if (termId->name.lcl.val[count] == '$') { + termId->type.val = MGT_TERMID_CHOOSE; + break; + } + + if (termId->name.lcl.val[count] == '*') { + termId->type.val = MGT_TERMID_ALL; + break; + } + } + } + } + + /*If term type is other then check if that term is configured with us..for term type CHOOSE/ALL , no need to check */ + if (MGT_TERMID_OTHER == termId->type.val){ + if(SWITCH_STATUS_FALSE != mg_stack_termination_is_in_service((char*)termId->name.lcl.val, termId->name.lcl.len)){ + mg_util_set_term_string(&errTxt, termId); + err_code = MGT_MGCO_RSP_CODE_UNKNOWN_TERM_ID; + goto error; + } + } + + + /* Validate Context - if context is specified then check if its present with us */ + inc_context = &cmd->contextId; + MG_ZERO(&ctxtId, sizeof(MgMgcoContextId)); + memcpy(&ctxtId, inc_context, sizeof(MgMgcoContextId)); + + if(NOTPRSNT == inc_context->type.pres){ + goto ctxt_error; + + }else if(MGT_CXTID_OTHER == inc_context->type.pres){ + + if(NOTPRSNT != inc_context->val.pres){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Context specific request for contextId[%d]\n",inc_context->val.val); + /* check if context present with us */ + if(NULL == megaco_find_context_by_suid(suId, inc_context->val.val)){ + goto ctxt_error; + } + }else{ + /* context id value not present - in case of type OTHER we should have context value */ + goto ctxt_error; + } + } + + /*mgAccEvntPrntMgMgcoCommand(cmd, stdout);*/ + /*get mg profile associated with SuId */ + if(NULL == (mg_profile = megaco_get_profile_by_suId(suId))){ + goto error1; + } + switch(cmd->cmdType.val) { case CH_CMD_TYPE_IND: @@ -475,7 +543,7 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) { case MGT_ADD: { - handle_mg_add_cmd(&cmd->u.mgCmdInd[0]->cmd.u.add); + handle_mg_add_cmd(mg_profile, cmd); mg_send_add_rsp(suId, cmd); break; } @@ -488,9 +556,10 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) } case MGT_MOVE: { - /*MgMgcoAmmReq *addReq = &cmdReq->cmd.u.move;*/ - break; - + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "MOVE Method Not Yet Supported\n"); + err_code = MGT_MGCO_RSP_CODE_UNSUPPORTED_CMD; + mg_util_set_cmd_name_string(&errTxt, cmd); + goto error; } case MGT_SUB: { @@ -511,7 +580,9 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) case MGT_AUDITCAP: { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Audit-Capability Method Not Yet Supported\n"); - break; + err_code = MGT_MGCO_RSP_CODE_UNSUPPORTED_CMD; + mg_util_set_cmd_name_string(&errTxt, cmd); + goto error; } case MGT_AUDITVAL: { @@ -542,6 +613,18 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) } return; + +ctxt_error: + err_code = MGT_MGCO_RSP_CODE_UNKNOWN_CTXT; + +error: + if (SWITCH_STATUS_SUCCESS == + mg_build_mgco_err_request(&mgErr, txn_id, &ctxtId, err_code, &errTxt)) { + sng_mgco_send_err(suId, mgErr); + } +error1: + mg_free_cmd(cmd); + return; } /*****************************************************************************************************************************/ diff --git a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h index 91dc74210c..f1da14a4f2 100644 --- a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h +++ b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h @@ -139,6 +139,9 @@ mg_context_t *megaco_get_context(megaco_profile_t *profile, uint32_t context_id) mg_context_t *megaco_choose_context(megaco_profile_t *profile); void megaco_release_context(mg_context_t *ctx); +megaco_profile_t* megaco_get_profile_by_suId(SuId suId); +mg_context_t *megaco_find_context_by_suid(SuId suId, uint32_t context_id); + switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload); switch_status_t sng_mgco_start(megaco_profile_t* profile); switch_status_t sng_mgco_stop(megaco_profile_t* profile);