]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
adding termination service-change code
authorroot <root@nsg-media-test.sangoma.local>
Sun, 29 Jul 2012 14:17:13 +0000 (10:17 -0400)
committerroot <root@nsg-media-test.sangoma.local>
Sun, 29 Jul 2012 14:17:13 +0000 (10:17 -0400)
libs/freetdm/mod_freetdm/tdm.c
src/mod/endpoints/mod_media_gateway/media_gateway.c
src/mod/endpoints/mod_media_gateway/media_gateway_cmd_handler.c
src/mod/endpoints/mod_media_gateway/media_gateway_stack.h
src/mod/endpoints/mod_media_gateway/media_gateway_stack_alarms.c
src/mod/endpoints/mod_media_gateway/media_gateway_xml.c
src/mod/endpoints/mod_media_gateway/mod_media_gateway.c

index c5850e6f5135a9e585c22d8ea2efa805acabc088..790f7c17d34fd8a03d7a94e8c95c2e321c5facb0 100644 (file)
@@ -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;
index 9056ee1bdc457f8a0a402af41360fba6e736c68e..7e13fbaebe01c7952ccced4ba27703aafe5566b8 100644 (file)
@@ -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) 
 {
 
index f9ae4fe90ab9f5e1e9d7c053f098707cd2a7d67c..ca2209b08758a1451286bcfc27c8bfcea50356af 100644 (file)
@@ -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* */
index 20354b0ccb73b56d416e64bda0b6433a408ca415..3e2ec81bdbc61ec3160d3b12d3c47eadb3ae1fcb 100644 (file)
@@ -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);
index 4564468e96f908bbd13ef9b3655c816f45df8eeb..f392203db127846707e9d540808f0be4cc7c73ba 100644 (file)
@@ -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:
index 1b8173aa1ed0f1895e084402cb539bba3ad52bbd..6c87afa780c4c9c8c00ec928c86f12c7bd0e35ce 100644 (file)
@@ -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) {
index 00f5e9760f9964873c423fe15539881655c8156e..97158fdcea249b4fb2ff372711f8cf344123811e 100644 (file)
@@ -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;