diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway.c b/src/mod/endpoints/mod_media_gateway/media_gateway.c index 5d58674a0c..cc4351799b 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway.c @@ -456,6 +456,8 @@ switch_status_t megaco_profile_start(const char *profilename) profile->pool = pool; profile->name = switch_core_strdup(pool, profilename); profile->next_context_id++; + profile->inact_tmr = 0x00; + profile->inact_tmr_task_id = 0x00; switch_thread_rwlock_create(&profile->rwlock, pool); diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c b/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c index 9b575c5384..e8cb79097b 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_cli.c @@ -205,7 +205,8 @@ switch_status_t mg_process_cli_cmd(const char *cmd, switch_stream_handle_t *stre goto done; usage: - megaco_profile_release(profile); + if(profile) + megaco_profile_release(profile); stream->write_function(stream, "-ERR Usage: \n""\t"MEGACO_CLI_SYNTAX" \n \t"MEGACO_FUNCTION_SYNTAX"\n \t" MEGACO_LOGGING_CLI_SYNTAX "\n"); done: 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 9a15871ff8..b801e3fa67 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 @@ -20,28 +20,40 @@ const char *mg_service_change_reason[] = { }; +/*****************************************************************************************************************************/ +void mg_restart_inactivity_timer(megaco_profile_t* profile) +{ + /* NOTE - For Restart - we are deleting existing task and adding it again */ + if(profile->inact_tmr_task_id) + switch_scheduler_del_task_id(profile->inact_tmr_task_id); + + if(profile->inact_tmr) { + mg_activate_ito_timer(profile); + } +} + /*****************************************************************************************************************************/ static void mg_inactivity_timer_exp(switch_scheduler_task_t *task) { megaco_profile_t* profile = (megaco_profile_t*) task->cmd_arg; - /* TODO */ switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO," mg_inactivity_timer_exp for profile[%s]\n", profile->name); mg_print_time(); mg_send_ito_notify(profile); - /*task->runtime = switch_epoch_time_now(NULL)+100; */ /* interval in seconds */ + /* resetting task_id */ + profile->inact_tmr_task_id = 0x00; } /*****************************************************************************************************************************/ switch_status_t mg_activate_ito_timer(megaco_profile_t* profile) { - switch_log_printf(SWITCH_CHANNEL_LOG_CLEAN, SWITCH_LOG_INFO," Starting IT/ITO Timer \n"); mg_print_time(); - switch_scheduler_add_task(switch_epoch_time_now(NULL)+profile->inact_tmr, mg_inactivity_timer_exp,"","media_gateway",0,profile,0); + profile->inact_tmr_task_id = switch_scheduler_add_task(switch_epoch_time_now(NULL)+profile->inact_tmr, mg_inactivity_timer_exp,"","media_gateway",0,profile,0); + return SWITCH_STATUS_SUCCESS; } @@ -137,8 +149,7 @@ switch_status_t mg_is_ito_pkg_req(megaco_profile_t* mg_profile, MgMgcoCommand *c if(0 == mg_profile->inact_tmr){ /* value ZERO means MGC wantes to disable ito timer */ - - /* TODO - check and stop currently running ito timer */ + switch_scheduler_del_task_id(mg_profile->inact_tmr_task_id) ; } else { mg_activate_ito_timer(mg_profile); } 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 37c1c321eb..8c429ef620 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h @@ -191,6 +191,7 @@ switch_status_t mg_util_build_obs_evt_desc (MgMgcoObsEvt *obs_event, MgMgcoRequ void mg_print_time(); switch_status_t mg_activate_ito_timer(megaco_profile_t* profile); +void mg_restart_inactivity_timer(megaco_profile_t* profile); /****************************************************************************************************************/ 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 2cd68716be..1533ca7d15 100644 --- a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c @@ -102,35 +102,40 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_media_gateway_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_media_gateway_shutdown) { - void *val = NULL; - const void *key = NULL; - switch_ssize_t keylen; - switch_hash_index_t *hi = NULL; - megaco_profile_t* profile = NULL; - mg_peer_profile_t* peer_profile = NULL; + void *val = NULL; + const void *key = NULL; + switch_ssize_t keylen; + switch_hash_index_t *hi = NULL; + megaco_profile_t* profile = NULL; + mg_peer_profile_t* peer_profile = NULL; - /* destroy all the mg profiles */ - while ((hi = switch_hash_first(NULL, megaco_globals.profile_hash))) { - switch_hash_this(hi, &key, &keylen, &val); - profile = (megaco_profile_t *) val; - megaco_profile_destroy(&profile); - profile = NULL; - } + /* destroy all the mg profiles */ + while ((hi = switch_hash_first(NULL, megaco_globals.profile_hash))) { + switch_hash_this(hi, &key, &keylen, &val); + profile = (megaco_profile_t *) val; + if(profile->inact_tmr_task_id){ + switch_scheduler_del_task_id(profile->inact_tmr_task_id); + profile->inact_tmr_task_id = 0x00; + } + megaco_profile_destroy(&profile); + profile = NULL; + } - hi = NULL; - key = NULL; - val = NULL; - /* destroy all the mg peer profiles */ - while ((hi = switch_hash_first(NULL, megaco_globals.peer_profile_hash))) { - switch_hash_this(hi, &key, &keylen, &val); - peer_profile = (mg_peer_profile_t *) val; - megaco_peer_profile_destroy(&peer_profile); - peer_profile = NULL; - } + hi = NULL; + key = NULL; + val = NULL; + /* destroy all the mg peer profiles */ + while ((hi = switch_hash_first(NULL, megaco_globals.peer_profile_hash))) { + switch_hash_this(hi, &key, &keylen, &val); + peer_profile = (mg_peer_profile_t *) val; + megaco_peer_profile_destroy(&peer_profile); + peer_profile = NULL; + } - sng_mgco_stack_shutdown(); + sng_mgco_stack_shutdown(); - return SWITCH_STATUS_SUCCESS; + + return SWITCH_STATUS_SUCCESS; } /*****************************************************************************************************************************/ @@ -443,6 +448,14 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "%s: Received Command Type[%s] \n", __PRETTY_FUNCTION__, PRNT_MG_CMD_TYPE(cmd->cmdType.val)); + /*get mg profile associated with SuId */ + if(NULL == (mg_profile = megaco_get_profile_by_suId(suId))){ + goto error1; + } + + /* first thing - restart ito timer */ + mg_restart_inactivity_timer(mg_profile); + /* validate Transaction Id */ if (NOTPRSNT != cmd->transId.pres){ txn_id = cmd->transId.val; @@ -536,12 +549,7 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) /*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: @@ -618,11 +626,111 @@ void handle_mgco_cmd_ind(Pst *pst, SuId suId, MgMgcoCommand* cmd) case CH_CMD_TYPE_CFM: { #ifdef BIT_64 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Received Command txn[%d] Response/Confirmation \n",txn_id); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Received Command[%s] txn[%d] Response/Confirmation \n", + PRNT_MG_CMD(cmd->u.mgCmdCfm[0]->type.val), txn_id); #else - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Received Command txn[%ld] Response/Confirmation \n",txn_id); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, "Received Command[%s] txn[%ld] Response/Confirmation \n", + PRNT_MG_CMD(cmd->u.mgCmdCfm[0]->type.val), txn_id); #endif - break; + switch(cmd->u.mgCmdCfm[0]->type.val) + { + case MGT_NTFY: + { + MgMgcoNtfyReply* ntfy = &cmd->u.mgCmdCfm[0]->u.ntfy; + MgMgcoTermId* term = NULL; + char term_name[32]; + memset(&term_name[0], 32, 0x00); + + strcpy(&term_name[0], "Invalid"); + +#ifdef GCP_VER_2_1 + if((NOTPRSNT != ntfy->termIdLst.num.pres) && + (0 != ntfy->termIdLst.num.val)){ + term = ntfy->termIdLst.terms[0]; + } +#else + term = &ntfy->termId; + +#endif + if(NOTPRSNT != term->type.pres){ + if(MGT_TERMID_ROOT == term->type.val){ + strcpy(&term_name[0],"ROOT"); + } + else if(MGT_TERMID_OTHER == term->type.val){ + strcpy(&term_name[0], (char*)term->name.lcl.val); + }else if(MGT_TERMID_ALL == term->type.val){ + strcpy(&term_name[0],"ALL Termination"); + }else if(MGT_TERMID_CHOOSE == term->type.val){ + strcpy(&term_name[0],"CHOOSE Termination"); + } + } + + if(NOTPRSNT != ntfy->pres.pres){ + if((NOTPRSNT != ntfy->err.pres.pres) && + (NOTPRSNT != ntfy->err.code.pres)){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, + "Received NOTIFY command response with ErroCode[%d] for Termination[%s] \n", + ntfy->err.code.val, &term_name[0]); + } + else{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, + "Received Successful NOTIFY command response for Termination[%s] \n", &term_name[0]); + } + } + + break; + } + case MGT_SVCCHG: + { + MgMgcoSvcChgReply* svc = &cmd->u.mgCmdCfm[0]->u.svc; + MgMgcoTermId* term = NULL; + char term_name[32]; + memset(&term_name[0], 32, 0x00); + + strcpy(&term_name[0], "Invalid"); + +#ifdef GCP_VER_2_1 + if((NOTPRSNT != svc->termIdLst.num.pres) && + (0 != svc->termIdLst.num.val)){ + term = svc->termIdLst.terms[0]; + } +#else + term = &svc->termId; + +#endif + if(NOTPRSNT != term->type.pres){ + if(MGT_TERMID_ROOT == term->type.val){ + strcpy(&term_name[0],"ROOT"); + } + else if(MGT_TERMID_OTHER == term->type.val){ + strcpy(&term_name[0], (char*)term->name.lcl.val); + }else if(MGT_TERMID_ALL == term->type.val){ + strcpy(&term_name[0],"ALL Termination"); + }else if(MGT_TERMID_CHOOSE == term->type.val){ + strcpy(&term_name[0],"CHOOSE Termination"); + } + } + + if(NOTPRSNT != svc->pres.pres){ + + if((NOTPRSNT != svc->res.type.pres) && + (MGT_ERRDESC == svc->res.type.val)){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, + "Received Service-Change command response with ErroCode[%d] for Termination[%s] \n", + svc->res.u.err.code.val, &term_name[0]); + } + else{ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CONSOLE, + "Received Successful Service-Change command response for Termination[%s] \n", &term_name[0]); + } + } + + break; + } + default: + break; + } + break; } default: #ifdef BIT_64 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 050ffcbad3..03f03b5c2d 100644 --- a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h +++ b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.h @@ -151,6 +151,7 @@ struct megaco_profile_s { int rtp_termination_id_len; char* peer_list[MG_MAX_PEERS]; /* MGC Peer ID LIST */ int inact_tmr; /* inactivity timer value */ + uint32_t inact_tmr_task_id; /* FS timer scheduler task-id */ switch_thread_rwlock_t *contexts_rwlock; uint32_t next_context_id;