diff --git a/libs/freetdm/mod_freetdm/tdm.c b/libs/freetdm/mod_freetdm/tdm.c index c5850e6f51..790f7c17d3 100644 --- a/libs/freetdm/mod_freetdm/tdm.c +++ b/libs/freetdm/mod_freetdm/tdm.c @@ -84,7 +84,7 @@ switch_io_routines_t ctdm_io_routines = { .receive_message = channel_receive_message }; -static void ctdm_report_alarms(ftdm_channel_t *channel) +static void ctdm_report_alarms(ftdm_channel_t *channel, const char* mg_profile_name) { switch_event_t *event = NULL; ftdm_alarm_flag_t alarmflag = 0; @@ -109,6 +109,8 @@ static void ctdm_report_alarms(ftdm_channel_t *channel) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "ftdm-alarm-trap"); } + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "mg-profile-name", mg_profile_name); + if (alarmflag & FTDM_ALARM_RED) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "red"); } @@ -128,6 +130,7 @@ static void ctdm_report_alarms(ftdm_channel_t *channel) switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general"); } + switch_event_fire(&event); return; } @@ -146,6 +149,7 @@ static void ctdm_event_handler(switch_event_t *event) const char *chan_number = NULL; uint32_t chan_id = 0; const char *cond = switch_event_get_header(event, "condition"); + const char *mg_profile_name = switch_event_get_header(event, "mg-profile-name"); if (zstr(cond)) { return; @@ -183,7 +187,7 @@ static void ctdm_event_handler(switch_event_t *event) return; } - ctdm_report_alarms(channel); + ctdm_report_alarms(channel, mg_profile_name); } } break; diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway.c b/src/mod/endpoints/mod_media_gateway/media_gateway.c index 9056ee1bdc..7e13fbaebe 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway.c @@ -175,6 +175,9 @@ switch_status_t megaco_prepare_tdm_termination(mg_termination_t *term) switch_status_t megaco_check_tdm_termination(mg_termination_t *term) { switch_event_t *event = NULL; + + if(!term || !term->profile) return SWITCH_STATUS_FALSE; + if (switch_event_create(&event, SWITCH_EVENT_TRAP) != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Failed to create NOTIFY event\n"); return SWITCH_STATUS_FALSE; @@ -183,6 +186,7 @@ switch_status_t megaco_check_tdm_termination(mg_termination_t *term) switch_event_add_header(event, SWITCH_STACK_BOTTOM, "span-name", "%s", term->u.tdm.span_name); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "chan-number", "%d", term->u.tdm.channel); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "condition", "mg-tdm-check"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "mg-profile-name", term->profile->name); switch_event_fire(&event); return SWITCH_STATUS_SUCCESS; @@ -237,6 +241,42 @@ mg_termination_t *megaco_choose_termination(megaco_profile_t *profile, const cha return term; } +mg_termination_t* megaco_find_termination_by_span_chan(megaco_profile_t *profile, char *span_name, char *chan_number) +{ + void *val = NULL; + switch_hash_index_t *hi = NULL; + mg_termination_t *term = NULL; + int found = 0x00; + const void *var; + + if(!span_name || !chan_number){ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO,"Invalid span_name/chan_number \n"); + return NULL; + } + + for (hi = switch_hash_first(NULL, profile->terminations); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &var, NULL, &val); + term = (mg_termination_t *) val; + if(!term) continue; + if(MG_TERM_TDM != term->type) continue; + + if ((!strcasecmp(span_name, term->u.tdm.span_name))&& (atoi(chan_number) == term->u.tdm.channel)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "Got term[%s] associated with span[%s], channel[%s]\n",term->name, span_name, chan_number); + found = 0x01; + break; + } + } + + if(!found){ + term = NULL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + " Not able to find termination associated with span[%s], channel[%s]\n", span_name, chan_number); + } + + return term; +} + mg_termination_t *megaco_find_termination(megaco_profile_t *profile, const char *name) { mg_termination_t *term = switch_core_hash_find_rdlock(profile->terminations, name, profile->terminations_rwlock); @@ -568,6 +608,35 @@ switch_status_t megaco_profile_destroy(megaco_profile_t **profile) return SWITCH_STATUS_SUCCESS; } + +switch_status_t mgco_init_ins_service_change(SuId suId) +{ + megaco_profile_t* profile = NULL; + void *val = NULL; + const void *key = NULL; + switch_ssize_t keylen; + switch_hash_index_t *hi = NULL; + mg_termination_t *term = NULL; + + + if(NULL == (profile = megaco_get_profile_by_suId(suId))){ + return SWITCH_STATUS_FALSE; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "mgco_init_ins_service_change : Initiating terminations service change for profile: %s\n", profile->name); + + /* loop through all termination and post get status Event */ + for (hi = switch_hash_first(NULL, profile->terminations); hi; hi = switch_hash_next(hi)) { + switch_hash_this(hi, &key, &keylen, &val); + term = (mg_termination_t *) val; + if(!term) continue; + megaco_check_tdm_termination(term); + } + + return SWITCH_STATUS_SUCCESS; +} + switch_status_t megaco_peer_profile_destroy(mg_peer_profile_t **profile) { 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 f9ae4fe90a..ca2209b087 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 @@ -2288,6 +2288,45 @@ U32 get_txn_id(){ return outgoing_txn_id; } /*****************************************************************************************************************************/ +switch_status_t mg_send_term_service_change(char* mg_profile_name,char *span_name, char *chan_number, mg_term_states_e term_state) +{ + mg_termination_t* term = NULL; + switch_status_t ret = SWITCH_STATUS_SUCCESS; + megaco_profile_t *profile = NULL; + + switch_assert(span_name); + switch_assert(chan_number); + + profile = megaco_profile_locate(mg_profile_name); + + term = megaco_find_termination_by_span_chan(profile, span_name, chan_number); + + if(!term || !term->profile){ + return SWITCH_STATUS_FALSE; + } + + switch(term_state) + { + case MG_TERM_SERVICE_STATE_IN_SERVICE: + { + ret = mg_send_ins_service_change(term->profile, term->name, 0x00 ); + break; + } + case MG_TERM_SERVICE_STATE_OUT_OF_SERVICE: + { + ret = mg_send_oos_service_change(term->profile, term->name, 0x00 ); + break; + } + default: + { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR," Invalid term_state[%d]\n", term_state); + return SWITCH_STATUS_FALSE; + } + } + + return ret; +} +/*****************************************************************************************************************************/ /* Note : API to send Service Change when termination is coming up(in-service) */ /* INPUT : MG Profile structure and termination name */ /* wild flag will tell if service change request needs to be in W-SC format as we can have W-SC=A01* or SC=A01* */ 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 20354b0ccb..3e2ec81bdb 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack.h @@ -52,6 +52,13 @@ typedef enum{ SNG_MG_ENCODING_TEXT, }sng_mg_encoding_types_e; +typedef enum{ + MG_TERM_SERVICE_STATE_UNKNOWN, + MG_TERM_SERVICE_STATE_IN_SERVICE, + MG_TERM_SERVICE_STATE_OUT_OF_SERVICE, + MG_TERM_SERVICE_STATE_INVALID, +}mg_term_states_e; + #define PRNT_ENCODING_TYPE(_val)\ ((_val == SNG_MG_ENCODING_TEXT)?"SNG_MG_ENCODING_TEXT":\ (_val == SNG_MG_ENCODING_BINARY)?"SNG_MG_ENCODING_BINARY":\ @@ -157,6 +164,8 @@ void mg_util_set_err_string ( MgStr *errTxt, char* str); switch_status_t mg_build_sdp(MgMgcoMediaDesc* out, MgMgcoMediaDesc* inc, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp); switch_status_t mg_add_local_descriptor(MgMgcoMediaDesc* media, megaco_profile_t* mg_profile, mg_termination_t* term, CmMemListCp *memCp); +switch_status_t mg_send_term_service_change(char* mg_profile_name, char *span_name, char *chan_number, mg_term_states_e term_state); +mg_termination_t* megaco_find_termination_by_span_chan(megaco_profile_t *profile , char *span_name, char *chan_number); switch_status_t sng_mgco_cfg(megaco_profile_t* profile); @@ -183,6 +192,7 @@ 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 mgco_init_ins_service_change(SuId suId); 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_stack_alarms.c b/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c index 4564468e96..f392203db1 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c @@ -25,8 +25,8 @@ void handle_mg_alarm(Pst *pst, MgMngmt *usta) memset(&prBuf[0], 0, sizeof(prBuf)); - len = len + sprintf(prBuf+len,"MG Status Indication: received with Category = %d, Event = %d, Cause = %d \n", - usta->t.usta.alarm.category, usta->t.usta.alarm.event, + len = len + sprintf(prBuf+len,"MG Status Indication: received for sapId[%d] with Category = %d, Event = %d, Cause = %d \n", + usta->t.usta.alarmInfo.sapId, usta->t.usta.alarm.category, usta->t.usta.alarm.event, usta->t.usta.alarm.cause); len = len + sprintf(prBuf+len, "Category ( "); @@ -218,9 +218,8 @@ void handle_mg_alarm(Pst *pst, MgMngmt *usta) case LMG_EVENT_PEER_ENABLED: { len = len + sprintf(prBuf+len, "gateway enabled"); - /* gateway enabled now we can send termination service change */ - /*TODO - probably we cannt immediate send Service change - we have to find proper place */ - /*mg_send_service_change(0x01, "A01", MGT_SVCCHGMETH_RESTART,MG_SVC_REASON_900_RESTORED );*/ + /* gateway enabled now we can send termination service change for all terminations */ + mgco_init_ins_service_change( usta->t.usta.alarmInfo.sapId ); break; } case LMG_EVENT_PEER_DISCOVERED: diff --git a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c index 1b8173aa1e..6c87afa780 100644 --- a/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c +++ b/src/mod/endpoints/mod_media_gateway/media_gateway_xml.c @@ -84,7 +84,7 @@ switch_status_t config_profile(megaco_profile_t *profile, switch_bool_t reload) char *channel_map_dup = strdup(channel_map); char *chanmap[24]; int chanmap_count, i; - chanmap_count = switch_split(channel_map_dup, ' ', chanmap); + chanmap_count = switch_split(channel_map_dup, ',', chanmap); for (i = 0; i < chanmap_count; i++) { char *p = strchr(chanmap[i], '-'); if (p) { 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 00f5e9760f..97158fdcea 100644 --- a/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c +++ b/src/mod/endpoints/mod_media_gateway/mod_media_gateway.c @@ -64,9 +64,18 @@ static void mg_event_handler(switch_event_t *event) const char *span_name = NULL; const char *chan_number = NULL; const char *cond = NULL; + const char *mg_profile_name = NULL; + cond = switch_event_get_header(event, "condition"); if (zstr(cond)) { + printf("Condition NULL, returning \n"); + return; + } + + mg_profile_name = switch_event_get_header(event, "mg-profile-name"); + if (zstr(mg_profile_name)) { + printf("mg_profile_name NULL, returning \n"); return; } @@ -74,9 +83,19 @@ static void mg_event_handler(switch_event_t *event) chan_number = switch_event_get_header(event, "chan-number"); if (!strcmp(cond, "ftdm-alarm-trap")) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "ftdm-alarm-trap for span_name[%s] chan_number[%s] associated with MG profile[%s]\n", + span_name,chan_number, mg_profile_name); /* @KAPIL: TDM is in alarm, notify MGC */ + mg_send_term_service_change( + (char*)mg_profile_name, (char*)span_name, (char*)chan_number, MG_TERM_SERVICE_STATE_OUT_OF_SERVICE); } else if (!strcmp(cond, "ftdm-alarm-clear")) { - /* @KAPIL: TDM alarm cleared, notify MGC */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, + "ftdm-alarm-clear for span_name[%s] chan_number[%s] associated with MG profile[%s] \n", + span_name,chan_number, mg_profile_name); + /* TDM alarm cleared, notify MGC */ + mg_send_term_service_change( + (char*)mg_profile_name, (char*)span_name, (char*)chan_number, MG_TERM_SERVICE_STATE_IN_SERVICE); } } break;