.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;
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");
}
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "alarm", "general");
}
+
switch_event_fire(&event);
return;
}
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;
return;
}
- ctdm_report_alarms(channel);
+ ctdm_report_alarms(channel, mg_profile_name);
}
}
break;
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;
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;
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);
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)
{
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* */
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":\
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);
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);
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 ( ");
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:
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) {
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;
}
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;