]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
adding m2ua stack config/control code
authorkapil <kgupta@sangoma.com>
Fri, 18 May 2012 06:35:25 +0000 (12:05 +0530)
committerkapil <kgupta@sangoma.com>
Fri, 18 May 2012 06:35:25 +0000 (12:05 +0530)
libs/freetdm/Makefile.am
libs/freetdm/mod_freetdm/mod_freetdm.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c [new file with mode: 0644]
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.h [new file with mode: 0644]
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c [new file with mode: 0644]
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h
libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c

index 35f1cecd1e61714a85c55a9f9f13ddb45b96d8fb..2038871de4b1198c158f87490c5afaa48de5a819 100644 (file)
@@ -213,6 +213,8 @@ ftmod_sangoma_ss7_la_SOURCES = \
        $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c \
        $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sts.c \
        $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c \
+       $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c \
+       $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c \
        $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c
 
 ftmod_sangoma_ss7_la_CFLAGS  = $(FTDM_CFLAGS) $(AM_CFLAGS) -D_GNU_SOURCE
index b6a6f49ca1c02c41b1a37f006e82fb5e944b5345..2e4f7e1e5f816b8ed1f8017fa33d7febf3e5774e 100755 (executable)
@@ -55,6 +55,8 @@
 /* How many consecutive IO errors before giving up */
 #define FTDM_MAX_READ_WRITE_ERRORS 10
 
+#define get_ss7_config_node(_cfg, _confname) _get_ss7_config_node(cfg, confname, "ISUP")
+
 SWITCH_MODULE_LOAD_FUNCTION(mod_freetdm_load);
 SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_freetdm_shutdown);
 SWITCH_MODULE_DEFINITION(mod_freetdm, mod_freetdm_load, mod_freetdm_shutdown, NULL);
@@ -2865,11 +2867,12 @@ static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode
        return 0;
 }
 
-static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confname)
+static ftdm_conf_node_t *_get_ss7_config_node(switch_xml_t cfg, const char *confname, const char *operatingMode)
 {
        switch_xml_t signode, ss7configs, isup, gen, param;
        ftdm_conf_node_t *rootnode, *list;
        char *var, *val;
+       int is_isup = 0x00;
 
        /* try to find the conf in the hash first */
        rootnode = switch_core_hash_find(globals.ss7_configs, confname);
@@ -2913,6 +2916,23 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn
                return NULL;
        }
 
+       /* operating mode , M2UA or ISUP */
+       if(operatingMode && ('\0' != operatingMode[0])) {
+               if(!strcasecmp(operatingMode, "ISUP")) {
+                       is_isup = 0x01;
+               }
+               else if(!strcasecmp(operatingMode, "M2UA_SG")) {
+                       is_isup = 0x00;
+               } else {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid operating Mode[%s] \n", operatingMode);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
+       } else {
+               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Operating mode not specified, default to ISUP \n");
+               is_isup = 0x01;
+       }
+
        /* add sng_gen */
        gen = switch_xml_child(isup, "sng_gen");
        if (gen == NULL) {
@@ -2954,11 +2974,14 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn
                return NULL;
        }
 
-       /* add mtp3 links */
-       if (add_config_list_nodes(isup, rootnode, "mtp3_links", "mtp3_link", NULL, NULL)) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp3_links for sng_isup config %s\n", confname);
-               ftdm_conf_node_destroy(rootnode);
-               return NULL;
+       /* If ISUP is operating mode then only include mtp3_links/isup links */
+       if(is_isup) {
+               /* add mtp3 links */
+               if (add_config_list_nodes(isup, rootnode, "mtp3_links", "mtp3_link", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp3_links for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
        }
 
        /* add mtp linksets */
@@ -2975,18 +2998,53 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn
                return NULL;
        }
 
-       /* add isup interfaces */
-       if (add_config_list_nodes(isup, rootnode, "isup_interfaces", "isup_interface", NULL, NULL)) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process isup_interfaces for sng_isup config %s\n", confname);
-               ftdm_conf_node_destroy(rootnode);
-               return NULL;
+       if(is_isup) {
+               /* add isup interfaces */
+               if (add_config_list_nodes(isup, rootnode, "isup_interfaces", "isup_interface", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process isup_interfaces for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
+
+               /* add cc spans */
+               if (add_config_list_nodes(isup, rootnode, "cc_spans", "cc_span", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process cc_spans for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
        }
+       else {
+               /* add sctp links */
+               if (add_config_list_nodes(isup, rootnode, "sng_sctp_interfaces", "sng_sctp_interface", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_sctp_interface for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
+
+               if (add_config_list_nodes(isup, rootnode, "sng_nif_interfaces", "sng_nif_interface", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_nif_interfaces for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
+
+               if (add_config_list_nodes(isup, rootnode, "sng_m2ua_interfaces", "sng_m2ua_interface", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_interfaces for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
+
+               if (add_config_list_nodes(isup, rootnode, "sng_m2ua_peer_interfaces", "sng_m2ua_peer_interface", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_peer_interfaces for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
+
+               if (add_config_list_nodes(isup, rootnode, "sng_m2ua_cluster_interfaces", "sng_m2ua_cluster_interface", NULL, NULL)) {
+                       switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_m2ua_cluster_interfaces for sng_isup config %s\n", confname);
+                       ftdm_conf_node_destroy(rootnode);
+                       return NULL;
+               }
 
-       /* add cc spans */
-       if (add_config_list_nodes(isup, rootnode, "cc_spans", "cc_span", NULL, NULL)) {
-               switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process cc_spans for sng_isup config %s\n", confname);
-               ftdm_conf_node_destroy(rootnode);
-               return NULL;
        }
 
        switch_core_hash_insert(globals.ss7_configs, confname, rootnode);
@@ -3223,6 +3281,7 @@ static switch_status_t load_config(void)
                        char *id = (char *) switch_xml_attr(myspan, "id");
                        char *name = (char *) switch_xml_attr(myspan, "name");
                        char *configname = (char *) switch_xml_attr(myspan, "cfgprofile");
+                       char *operatingMode = (char *) switch_xml_attr(myspan, "operating_mode");
                        ftdm_span_t *span = NULL;
                        uint32_t span_id = 0;
                        unsigned paramindex = 0;
@@ -3256,7 +3315,7 @@ static switch_status_t load_config(void)
                                span_id = ftdm_span_get_id(span);
                        }
 
-                       ss7confnode = get_ss7_config_node(cfg, configname);
+                       ss7confnode = _get_ss7_config_node(cfg, configname, operatingMode);
                        if (!ss7confnode) {
                                CONFIG_ERROR("Error finding ss7config '%s' for FreeTDM span id: %s\n", configname, switch_str_nil(id));
                                continue;
@@ -3264,6 +3323,11 @@ static switch_status_t load_config(void)
 
                        memset(spanparameters, 0, sizeof(spanparameters));
                        paramindex = 0;
+                       if(operatingMode){
+                               spanparameters[paramindex].var = "operatingMode";
+                               spanparameters[paramindex].val = operatingMode;
+                               paramindex++;
+                       }
                        spanparameters[paramindex].var = "confnode";
                        spanparameters[paramindex].ptr = ss7confnode;
                        paramindex++;
index 327ca40f0571105f44ea87d9aa7661d72568bef0..170f03f8f39f28eac1b6800ae08d5145574ff74b 100644 (file)
@@ -262,94 +262,103 @@ int  ft_to_sngss7_cfg_all(void)
        /* no configs above mtp2 for relay */
        if (g_ftdm_sngss7_data.cfg.procId == 1) {
                x = 1;
-               while (x < (MAX_MTP_LINKS)) {
-                       /* check if this link has been configured already */
-                       if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
-                               (!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
+                       while (x < (MAX_MTP_LINKS)) {
+                               /* check if this link has been configured already */
+                               if ((g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) &&
+                                               (!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED))) {
 
-                               /* configure mtp3 */
-                               if (ftmod_ss7_mtp3_dlsap_config(x)) {
-                                       SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
-                                       return 1;;
-                               } else {
-                                       SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
+                                       /* configure mtp3 */
+                                       if (ftmod_ss7_mtp3_dlsap_config(x)) {
+                                               SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x);
+                                               return 1;;
+                                       } else {
+                                               SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x);
+                                       }
+
+                                       /* set the SNGSS7_CONFIGURED flag */
+                                       g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED;
                                }
 
-                               /* set the SNGSS7_CONFIGURED flag */
-                               g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED;
+                               x++;
+                       } /* while (x < (MAX_MTP_LINKS+1)) */
+
+               /* in M2UA_SG mode there will not be any MTP3 layer */
+                       if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
+                               x = 1;
+                               while (x < (MAX_NSAPS)) {
+                                       /* check if this link has been configured already */
+                                       if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
+                                                       (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
+
+                                               ret = ftmod_ss7_mtp3_nsap_config(x);
+                                               if (ret) {
+                                                       SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
+                                                       return 1;
+                                               } else {
+                                                       SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
+                                               }
+
+                                               ret = ftmod_ss7_isup_nsap_config(x);
+                                               if (ret) {
+                                                       SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
+                                                       return 1;
+                                               } else {
+                                                       SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
+                                               }
+
+                                               /* set the SNGSS7_CONFIGURED flag */
+                                               g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED;
+                                       } /* if !SNGSS7_CONFIGURED */
+
+                                       x++;
+                               } /* while (x < (MAX_NSAPS)) */
                        }
-                       
-                       x++;
-               } /* while (x < (MAX_MTP_LINKS+1)) */
-
-               x = 1;
-               while (x < (MAX_NSAPS)) {
-                       /* check if this link has been configured already */
-                       if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
-                               (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED))) {
-
-                               ret = ftmod_ss7_mtp3_nsap_config(x);
-                               if (ret) {
-                                       SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
-                                       return 1;
-                               } else {
-                                       SS7_INFO("MTP3 NSAP %d configuration DONE!\n", x);
-                               }
 
-                               ret = ftmod_ss7_isup_nsap_config(x);
-                               if (ret) {
-                                       SS7_CRITICAL("ISUP NSAP %d configuration FAILED!(%s)\n", x, DECODE_LCM_REASON(ret));
-                                       return 1;
-                               } else {
-                                       SS7_INFO("ISUP NSAP %d configuration DONE!\n", x);
-                               }
+               /* in M2UA_SG mode there will not be any MTP3 layer */
+               if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
+                       x = 1;
+                       while (x < (MAX_MTP_LINKSETS+1)) {
+                               /* check if this link has been configured already */
+                               if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
+                                               (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
 
-                               /* set the SNGSS7_CONFIGURED flag */
-                               g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED;
-                       } /* if !SNGSS7_CONFIGURED */
-                       
-                       x++;
-               } /* while (x < (MAX_NSAPS)) */
+                                       if (ftmod_ss7_mtp3_linkset_config(x)) {
+                                               SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
+                                               return 1;
+                                       } else {
+                                               SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
+                                       }
 
-               x = 1;
-               while (x < (MAX_MTP_LINKSETS+1)) {
-                       /* check if this link has been configured already */
-                       if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
-                               (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED))) {
+                                       /* set the SNGSS7_CONFIGURED flag */
+                                       g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED;
+                               } /* if !SNGSS7_CONFIGURED */
 
-                               if (ftmod_ss7_mtp3_linkset_config(x)) {
-                                       SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x);
-                                       return 1;
-                               } else {
-                                       SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x);
-                               }
+                               x++;
+                       } /* while (x < (MAX_MTP_LINKSETS+1)) */
+               }
 
-                               /* set the SNGSS7_CONFIGURED flag */
-                               g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED;
-                       } /* if !SNGSS7_CONFIGURED */
-                       
-                       x++;
-               } /* while (x < (MAX_MTP_LINKSETS+1)) */
+               /* in M2UA_SG mode there will not be any MTP3 layer */
+               if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
+                       x = 1;
+                       while (x < (MAX_MTP_ROUTES+1)) {
+                               /* check if this link has been configured already */
+                               if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
+                                               (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
 
-               x = 1;
-               while (x < (MAX_MTP_ROUTES+1)) {
-                       /* check if this link has been configured already */
-                       if ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) &&
-                               (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & SNGSS7_CONFIGURED))) {
+                                       if (ftmod_ss7_mtp3_route_config(x)) {
+                                               SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
+                                               return 1;
+                                       } else {
+                                               SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
+                                       }
 
-                               if (ftmod_ss7_mtp3_route_config(x)) {
-                                       SS7_CRITICAL("MTP3 ROUTE %d configuration FAILED!\n", x);
-                                       return 1;
-                               } else {
-                                       SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x);
-                               }
+                                       /* set the SNGSS7_CONFIGURED flag */
+                                       g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED;
+                               } /* if !SNGSS7_CONFIGURED */
 
-                               /* set the SNGSS7_CONFIGURED flag */
-                               g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED;
-                       } /* if !SNGSS7_CONFIGURED */
-                       
-                       x++;
-               } /* while (x < (MAX_MTP_ROUTES+1)) */
+                               x++;
+                       } /* while (x < (MAX_MTP_ROUTES+1)) */
+               }
 
                x = 1;
                while (x < (MAX_ISAPS)) {
@@ -441,6 +450,11 @@ int  ft_to_sngss7_cfg_all(void)
                } /* if !SNGSS7_CONFIGURED */
                x++;
        } /* while (x < (MAX_RELAY_CHANNELS)) */
+
+
+       if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
+               return ftmod_ss7_m2ua_cfg();
+       }
        
        return 0;
 }
index c5aca9aa73ae98aa7563029eea1acc5ebf34cce3..0fcef7d90b1f1028226faff59920a35e63b9a76b 100644 (file)
@@ -60,7 +60,7 @@ int ft_to_sngss7_activate_all(void)
        while (x < (MAX_ISAPS)) {
                /* check if this link has already been actived */
                if ((g_ftdm_sngss7_data.cfg.isap[x].id != 0) &&
-                       (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
+                               (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_ACTIVE))) {
 
                        if (ftmod_ss7_enable_isap(x)) { 
                                SS7_CRITICAL("ISAP %d Enable: NOT OK\n", x);
@@ -72,15 +72,16 @@ int ft_to_sngss7_activate_all(void)
                        /* set the SNGSS7_ACTIVE flag */
                        g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_ACTIVE;
                } /* if !SNGSS7_ACTIVE */
-               
+
                x++;
        } /* while (x < (MAX_ISAPS)) */
 
+       if(SNG_SS7_OPR_MODE_M2UA_SG != g_ftdm_operating_mode){
        x = 1;
        while (x < (MAX_NSAPS)) {
                /* check if this link has already been actived */
                if ((g_ftdm_sngss7_data.cfg.nsap[x].id != 0) &&
-                       (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
+                               (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_ACTIVE))) {
 
                        if (ftmod_ss7_enable_nsap(x)) { 
                                SS7_CRITICAL("NSAP %d Enable: NOT OK\n", x);
@@ -92,30 +93,35 @@ int ft_to_sngss7_activate_all(void)
                        /* set the SNGSS7_ACTIVE flag */
                        g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_ACTIVE;
                } /* if !SNGSS7_ACTIVE */
-               
+
                x++;
        } /* while (x < (MAX_NSAPS)) */
 
-       if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
-               x = 1;
-               while (x < (MAX_MTP_LINKSETS+1)) {
-                       /* check if this link has already been actived */
-               if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
-                       (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
-       
-                               if (ftmod_ss7_enable_mtpLinkSet(x)) {   
-                                       SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
-                                       return 1;
-                               } else {
-                                       SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
-                               }
-       
-                               /* set the SNGSS7_ACTIVE flag */
-                               g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE;
-                       } /* if !SNGSS7_ACTIVE */
-                       
-                       x++;
-               } /* while (x < (MAX_MTP_LINKSETS+1)) */
+               if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) {
+                       x = 1;
+                       while (x < (MAX_MTP_LINKSETS+1)) {
+                               /* check if this link has already been actived */
+                               if ((g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) &&
+                                               (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_ACTIVE))) {
+
+                                       if (ftmod_ss7_enable_mtpLinkSet(x)) {   
+                                               SS7_CRITICAL("LinkSet \"%s\" Enable: NOT OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
+                                               return 1;
+                                       } else {
+                                               SS7_INFO("LinkSet \"%s\" Enable: OK\n", g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name);
+                                       }
+
+                                       /* set the SNGSS7_ACTIVE flag */
+                                       g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_ACTIVE;
+                               } /* if !SNGSS7_ACTIVE */
+
+                               x++;
+                       } /* while (x < (MAX_MTP_LINKSETS+1)) */
+               }
+       }
+
+       if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
+               return ftmod_ss7_m2ua_start();
        }
 
        return 0;
index 176de9e62703cbfe3e6d259b890a1035109c25db..5d4e183b20bc364f4b713340f3162179d0d94748 100644 (file)
@@ -824,6 +824,36 @@ void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta)
        return;
 }
 
+/******************************************************************************/
+void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta)
+{
+       ftdm_log(FTDM_LOG_ERROR," handle_sng_m2ua_alarm Not Yet Implement \n");
+
+}   /* handle_sng_m2ua_alarm */
+
+/******************************************************************************/
+void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta)
+{
+       ftdm_log(FTDM_LOG_ERROR," handle_sng_nif_alarm Not Yet Implement \n");
+
+}   /* handle_sng_nif_alarm */
+
+/******************************************************************************/
+void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta)
+{
+       ftdm_log(FTDM_LOG_ERROR," handle_sng_tucl_alarm Not Yet Implement \n");
+
+}   /* handle_sng_tucl_alarm */
+
+/******************************************************************************/
+void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta)
+{
+       ftdm_log(FTDM_LOG_ERROR," handle_sng_sctp_alarm Not Yet Implement \n");
+
+}   /* handle_sng_sctp_alarm */
+/******************************************************************************/
+
+
 /******************************************************************************/
 /* For Emacs:
  * Local Variables:
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.c
new file mode 100644 (file)
index 0000000..375be9f
--- /dev/null
@@ -0,0 +1,1335 @@
+/*
+ * Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Contributors: 
+ *
+ *
+ */
+
+/* INCLUDE ********************************************************************/
+#include "ftmod_sangoma_ss7_main.h"
+/******************************************************************************/
+
+/* DEFINES ********************************************************************/
+/******************************************************************************/
+/* FUNCTION PROTOTYPES ********************************************************/
+static int ftmod_sigtran_tucl_gen_config(void);
+static int ftmod_sigtran_tucl_sap_config(void);
+
+static int ftmod_sigtran_sctp_gen_config(void);
+ftdm_status_t ftmod_sigtran_cfg_sctp(void);
+int ftmod_sigtran_sctp_config(int id);
+ftdm_status_t ftmod_sigtran_sctp_sap_config(int id);
+ftdm_status_t ftmod_sigtran_sctp_tsap_config(int id);
+static S16 ftmod_sigtran_m2ua_gen_config(void);
+static S16 ftmod_sigtran_m2ua_sctsap_config(void);
+static S16 ftmod_sigtran_m2ua_peer_config(void);
+static S16 ftmod_sigtran_m2ua_cluster_config(void);
+static S16 ftmod_sigtran_m2ua_dlsap_config(U32 idx);
+
+static S16 ftmod_sigtran_nif_gen_config(void);
+static S16 ftmod_sigtran_nif_dlsap_config(U32 idx);
+
+
+static U32 ftmod_parse_conv_ipaddr(S8 *ptr);
+
+ftdm_status_t sng_m2ua_init(void); 
+ftdm_status_t sng_m2ua_cfg(void);
+
+
+static S16 ftmod_sigtran_tsap_bnd(void);
+static S16 ftmod_sigtran_sctsap_bnd(void);
+static S16 ftmod_sigtran_dlsap_bnd(U32 id);
+static S16 ftmod_ss7_dlsap_bnd(U32 id);
+
+/******************************************************************************/
+/******************************************************************************/
+
+ftdm_status_t ftmod_ss7_m2ua_cfg(void)
+{
+
+       if(FTDM_SUCCESS != sng_m2ua_init()){
+               ftdm_log (FTDM_LOG_ERROR, " sng_m2ua_init FAILED \n");
+               return FTDM_FAIL;
+       }
+       
+       if(FTDM_SUCCESS != sng_m2ua_cfg()){
+               ftdm_log (FTDM_LOG_ERROR, " sng_m2ua_cfg FAILED \n");
+               return FTDM_FAIL;
+       }
+
+       return FTDM_SUCCESS;
+}
+               
+/******************************************************************************/
+
+ftdm_status_t sng_m2ua_init(void) 
+{
+       if (sng_isup_init_nif()) {
+               ftdm_log (FTDM_LOG_ERROR , "Failed to start NIF\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"Started NIF!\n");
+       }
+
+       if (sng_isup_init_m2ua()) {
+               ftdm_log (FTDM_LOG_ERROR ,"Failed to start M2UA\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"Started M2UA!\n");
+       }
+
+       if (sng_isup_init_sctp()) {
+               ftdm_log (FTDM_LOG_ERROR ,"Failed to start SCTP\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"Started SCTP!\n");
+       }
+
+       if (sng_isup_init_tucl()) {
+               ftdm_log (FTDM_LOG_ERROR ,"Failed to start TUCL\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"Started TUCL!\n");
+       }
+
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+
+ftdm_status_t sng_m2ua_cfg(void)
+{
+       S16 ret = ROK;
+
+       /* TUCL */
+       if(ftmod_sigtran_tucl_gen_config()){
+               ftdm_log (FTDM_LOG_ERROR ,"TUCL GEN configuration: NOT OK\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"TUCL GEN configuration: OK\n");
+       }
+
+       if(ftmod_sigtran_tucl_sap_config()){
+               ftdm_log (FTDM_LOG_ERROR ,"TUCL SAP configuration: NOT OK\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"TUCL SAP configuration: OK\n");
+       }
+       /*********************************************************************************************/
+
+       /* SCTP */
+       if(ftmod_sigtran_sctp_gen_config()){
+               ftdm_log (FTDM_LOG_ERROR ,"SCTP GEN configuration: NOT OK\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"SCTP GEN configuration: OK\n");
+       }
+
+       if(ftmod_sigtran_cfg_sctp()){
+               ftdm_log (FTDM_LOG_ERROR ,"ftmod_sigtran_cfg_sctp : NOT OK\n");
+               return FTDM_FAIL;
+       } else {
+               ftdm_log (FTDM_LOG_INFO ,"ftmod_sigtran_cfg_sctp : OK\n");
+       }
+       /*********************************************************************************************/
+
+       /* M2UA and NIF configurations */
+
+       /* Send the general configuration request for M2UA layer */ 
+       if((ret = ftmod_sigtran_m2ua_gen_config()) != ROK)
+       {
+               ftdm_log (FTDM_LOG_ERROR ,"M2UA General configuration: NOT OK\n");
+               return FTDM_FAIL;
+       }   
+       else
+       {
+               ftdm_log (FTDM_LOG_INFO ,"M2UA General configuration: OK\n");
+       }
+
+       /* Send the SCTSAP configuration request for M2UA layer */ 
+       if((ret = ftmod_sigtran_m2ua_sctsap_config()) != ROK)
+       {
+               ftdm_log (FTDM_LOG_ERROR ,"M2UA SCTSAP configuration: NOT OK\n");
+               return FTDM_FAIL;
+       }   
+       else
+       {
+               ftdm_log (FTDM_LOG_INFO ,"M2UA SCTSAP configuration: OK\n");
+       }
+
+       /* Send the peer configuration request for M2UA layer */ 
+       if((ret = ftmod_sigtran_m2ua_peer_config()) != ROK)
+       {
+               ftdm_log (FTDM_LOG_ERROR ,"M2UA PEER configuration: NOT OK\n");
+               return FTDM_FAIL;
+       }   
+       else
+       {
+               ftdm_log (FTDM_LOG_INFO ,"M2UA PEER configuration: OK\n");
+       }
+
+       /* Send the cluster configuration request for M2UA layer */ 
+       if((ret = ftmod_sigtran_m2ua_cluster_config()) != ROK)
+       {
+               ftdm_log (FTDM_LOG_ERROR ,"M2UA CLUSTER configuration: NOT OK\n");
+               return FTDM_FAIL;
+       }   
+       else
+       {
+               ftdm_log (FTDM_LOG_INFO ,"M2UA CLUSTER configuration: OK\n");
+       }
+
+
+       /* Send the USAP (DLSAP) configuration request for M2UA layer; fill the number
+        * of saps required to be configured. Max is 3 */ 
+       /*for( idx = 0; idx < 3; idx++)*/
+       {   
+               if((ret = ftmod_sigtran_m2ua_dlsap_config(1)) != ROK)
+               {
+                       ftdm_log (FTDM_LOG_ERROR ,"M2UA DLSAP configuration: NOT OK\n");
+                       return FTDM_FAIL;
+               }   
+               else
+               {
+                       ftdm_log (FTDM_LOG_INFO ,"M2UA DLSAP configuration: OK\n");
+               }
+       }
+
+       /* Send the general configuration request for NIF */ 
+       if((ret = ftmod_sigtran_nif_gen_config()) != ROK)
+       {
+               ftdm_log (FTDM_LOG_ERROR ,"NIF General configuration: NOT OK\n");
+               return FTDM_FAIL;
+       }   
+       else
+       {
+               ftdm_log (FTDM_LOG_INFO ,"NIF General configuration: OK\n");
+       }
+
+       /* Send the USAP (DLSAP) configuration request for NIF layer; fill the number
+        * of saps required to be configured. Max is 3
+       for( idx = 0; idx < 3; idx++) */
+       {
+               if( (ret = ftmod_sigtran_nif_dlsap_config(1)) != ROK)
+               {
+                       ftdm_log (FTDM_LOG_ERROR ,"NIF DLSAP configuration: NOT OK\n");
+                       return FTDM_FAIL;
+               }   
+               else
+               {
+                       ftdm_log (FTDM_LOG_INFO ,"NIF DLSAP configuration: OK\n");
+               }
+       }
+
+
+       /********************************************************************************************/
+
+       return 0;
+}
+
+/******************************************************************************/
+static int ftmod_sigtran_tucl_gen_config(void)
+{
+       HiMngmt cfg;
+       Pst             pst;
+
+       /* initalize the post structure */
+       smPstInit(&pst);
+
+       /* insert the destination Entity */
+       pst.dstEnt = ENTHI;
+
+       /* clear the configuration structure */
+       memset(&cfg, 0, sizeof(cfg));
+
+       /* fill in the post structure */
+       smPstInit(&cfg.t.cfg.s.hiGen.lmPst);
+       /*fill in the specific fields of the header */
+       cfg.hdr.msgType                                 = TCFG;
+       cfg.hdr.entId.ent                               = ENTHI;
+       cfg.hdr.entId.inst                              = S_INST;
+       cfg.hdr.elmId.elmnt                             = STGEN;
+
+       cfg.t.cfg.s.hiGen.numSaps                       = HI_MAX_SAPS;                          /* number of SAPs */
+       cfg.t.cfg.s.hiGen.numCons                       = HI_MAX_NUM_OF_CON;                    /* maximum num of connections */
+       cfg.t.cfg.s.hiGen.numFdsPerSet                  = HI_MAX_NUM_OF_FD_PER_SET;             /* maximum num of fds to use per set */
+       cfg.t.cfg.s.hiGen.numFdBins                     = HI_MAX_NUM_OF_FD_HASH_BINS;           /* for fd hash lists */
+       cfg.t.cfg.s.hiGen.numClToAccept                 = HI_MAX_NUM_OF_CLIENT_TO_ACCEPT;       /* clients to accept simultaneously */
+       cfg.t.cfg.s.hiGen.permTsk                       = TRUE;                                 /* schedule as perm task or timer */
+       cfg.t.cfg.s.hiGen.schdTmrVal                    = HI_MAX_SCHED_TMR_VALUE;               /* if !permTsk - probably ignored */
+       cfg.t.cfg.s.hiGen.selTimeout                    = HI_MAX_SELECT_TIMEOUT_VALUE;          /* select() timeout */
+
+       /* number of raw/UDP messages to read in one iteration */
+       cfg.t.cfg.s.hiGen.numRawMsgsToRead              = HI_MAX_RAW_MSG_TO_READ;
+       cfg.t.cfg.s.hiGen.numUdpMsgsToRead              = HI_MAX_UDP_MSG_TO_READ;
+
+       /* thresholds for congestion on the memory pool */
+       cfg.t.cfg.s.hiGen.poolStrtThr                   = HI_MEM_POOL_START_THRESHOLD;
+       cfg.t.cfg.s.hiGen.poolDropThr                   = HI_MEM_POOL_DROP_THRESHOLD;
+       cfg.t.cfg.s.hiGen.poolStopThr                   = HI_MEM_POOL_STOP_THRESHOLD;
+
+       cfg.t.cfg.s.hiGen.timeRes                       = SI_PERIOD;        /* time resolution */
+
+#ifdef HI_SPECIFY_GENSOCK_ADDR
+       cfg.t.cfg.s.hiGen.ipv4GenSockAddr.address = CM_INET_INADDR_ANY;
+       cfg.t.cfg.s.hiGen.ipv4GenSockAddr.port  = 0;                            /* DAVIDY - why 0? */
+#ifdef IPV6_SUPPORTED
+       cfg.t.cfg.s.hiGen.ipv6GenSockAddr.address = CM_INET_INADDR6_ANY;
+       cfg.t.cfg.s.hiGen.ipv4GenSockAddr.port  = 0;
+#endif
+#endif
+
+       return(sng_cfg_tucl(&pst, &cfg));
+}
+
+static int ftmod_sigtran_tucl_sap_config(void)
+{
+        HiMngmt cfg;
+        Pst     pst;
+        HiSapCfg  *pCfg;
+
+        /* initalize the post structure */
+        smPstInit(&pst);
+
+        /* insert the destination Entity */
+        pst.dstEnt = ENTHI;
+
+        /* clear the configuration structure */
+        memset(&cfg, 0, sizeof(cfg));
+
+       /*fill LM  post structure*/
+       cfg.t.cfg.s.hiGen.lmPst.dstProcId   = SFndProcId();
+       cfg.t.cfg.s.hiGen.lmPst.dstInst     = S_INST;
+
+       cfg.t.cfg.s.hiGen.lmPst.dstProcId   = SFndProcId();
+       cfg.t.cfg.s.hiGen.lmPst.dstEnt      = ENTSM;
+       cfg.t.cfg.s.hiGen.lmPst.dstInst     = S_INST;
+
+       cfg.t.cfg.s.hiGen.lmPst.prior       = PRIOR0;
+       cfg.t.cfg.s.hiGen.lmPst.route       = RTESPEC;
+       cfg.t.cfg.s.hiGen.lmPst.region      = S_REG;
+       cfg.t.cfg.s.hiGen.lmPst.pool        = S_POOL;
+       cfg.t.cfg.s.hiGen.lmPst.selector    = 0;
+
+
+        /*fill in the specific fields of the header */
+        cfg.hdr.msgType         = TCFG;
+        cfg.hdr.entId.ent       = ENTHI;
+        cfg.hdr.entId.inst      = 0;
+        cfg.hdr.elmId.elmnt     = STTSAP;
+
+        pCfg = &cfg.t.cfg.s.hiSap;
+
+        pCfg->spId = 0x01 ; /* KAPIL - TODO - should be from configured value.but hardcoding as of now */ 
+        pCfg->uiSel = 0x00;  /*loosley coupled */
+        pCfg->flcEnb = TRUE;
+        pCfg->txqCongStrtLim = HI_SAP_TXN_QUEUE_CONG_START_LIMIT;
+        pCfg->txqCongDropLim = HI_SAP_TXN_QUEUE_CONG_DROP_LIMIT;
+        pCfg->txqCongStopLim = HI_SAP_TXN_QUEUE_CONG_STOP_LIMIT;
+        pCfg->numBins = 10;
+
+        pCfg->uiMemId.region = S_REG;
+        pCfg->uiMemId.pool   = S_POOL;
+        pCfg->uiPrior        = PRIOR0;
+        pCfg->uiRoute        = RTESPEC;
+
+        return(sng_cfg_tucl(&pst, &cfg));
+}
+static int ftmod_sigtran_sctp_gen_config(void)
+{
+       SbMgmt  cfg;
+       Pst             pst;
+
+       /* initalize the post structure */
+       smPstInit(&pst);
+
+       /* insert the destination Entity */
+       pst.dstEnt = ENTSB;
+
+       /* clear the configuration structure */
+       memset(&cfg, 0, sizeof(cfg));
+
+       /* fill in the post structure */
+       smPstInit(&cfg.t.cfg.s.genCfg.smPst);
+       /*fill in the specific fields of the header */
+       cfg.hdr.msgType                                         = TCFG;
+       cfg.hdr.entId.ent                                       = ENTSB;
+       cfg.hdr.entId.inst                                      = S_INST;
+       cfg.hdr.elmId.elmnt                                     = STSBGEN;
+
+#ifdef SB_IPV6_SUPPORTED
+       /* U8          ipv6SrvcReqdFlg; */ /* IPV6 service required for sctp */
+#endif
+
+       cfg.t.cfg.s.genCfg.serviceType                          = HI_SRVC_RAW_SCTP;                     /* Usr packetized TCP Data */    /* TUCL transport protocol (IP/UDP) */
+       cfg.t.cfg.s.genCfg.maxNmbSctSaps                        = SB_MAX_SCT_SAPS;                      /* max no. SCT SAPS */
+       cfg.t.cfg.s.genCfg.maxNmbTSaps                          = SB_MAX_T_SAPS;                        /* max no. Transport SAPS */
+       cfg.t.cfg.s.genCfg.maxNmbEndp                           = SB_MAX_NUM_OF_ENDPOINTS;              /* max no. endpoints */
+       cfg.t.cfg.s.genCfg.maxNmbAssoc                          = SB_MAX_NUM_OF_ASSOC;                  /* max no. associations */
+       cfg.t.cfg.s.genCfg.maxNmbDstAddr                        = SB_MAX_NUM_OF_DST_ADDR;               /* max no. dest. addresses */
+       cfg.t.cfg.s.genCfg.maxNmbSrcAddr                        = SB_MAX_NUM_OF_SRC_ADDR;               /* max no. src. addresses */
+       cfg.t.cfg.s.genCfg.maxNmbTxChunks                       = SB_MAX_NUM_OF_TX_CHUNKS;
+       cfg.t.cfg.s.genCfg.maxNmbRxChunks                       = SB_MAX_NUM_OF_RX_CHUNKS;
+       cfg.t.cfg.s.genCfg.maxNmbInStrms                        = SB_MAX_INC_STREAMS;
+       cfg.t.cfg.s.genCfg.maxNmbOutStrms                       = SB_MAX_OUT_STREAMS;
+       cfg.t.cfg.s.genCfg.initARwnd                            = SB_MAX_RWND_SIZE;
+       cfg.t.cfg.s.genCfg.mtuInitial                           = SB_MTU_INITIAL;
+       cfg.t.cfg.s.genCfg.mtuMinInitial                        = SB_MTU_MIN_INITIAL;
+       cfg.t.cfg.s.genCfg.mtuMaxInitial                        = SB_MTU_MAX_INITIAL;
+       cfg.t.cfg.s.genCfg.performMtu                           = FALSE;
+       cfg.t.cfg.s.genCfg.timeRes                              = 1;
+       sprintf((char*)cfg.t.cfg.s.genCfg.hostname, "www.sangoma.com"); /* DAVIDY - Fix this later, probably ignored */
+       cfg.t.cfg.s.genCfg.useHstName                           = FALSE;      /* Flag whether hostname is to be used in INIT and INITACK msg */
+       cfg.t.cfg.s.genCfg.reConfig.maxInitReTx         = 8;
+       cfg.t.cfg.s.genCfg.reConfig.maxAssocReTx        = 10;
+       cfg.t.cfg.s.genCfg.reConfig.maxPathReTx         = 10;
+       cfg.t.cfg.s.genCfg.reConfig.altAcceptFlg        = TRUE;
+       cfg.t.cfg.s.genCfg.reConfig.keyTm                       = 600; /* initial value for MD5 Key expiry timer */
+       cfg.t.cfg.s.genCfg.reConfig.alpha                       = 12;
+       cfg.t.cfg.s.genCfg.reConfig.beta                        = 25;
+#ifdef SB_ECN
+       cfg.t.cfg.s.genCfg.reConfig.ecnFlg                      = TRUE;
+#endif
+
+       return(sng_cfg_sctp(&pst, &cfg));
+}
+
+ftdm_status_t ftmod_sigtran_cfg_sctp(void)
+{
+       int x=0;
+       for (x=1; g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[x].id !=0; x++)
+       {
+               if (!(g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[x].flags & SNGSS7_CONFIGURED)) {
+                       
+                       if (  ftmod_sigtran_sctp_config(x) == FTDM_FAIL) {
+                               SS7_CRITICAL("SCTP %d configuration FAILED!\n", x);
+                               return FTDM_FAIL;
+                       } else {
+                               SS7_INFO("SCTP %d configuration DONE!\n", x);
+                       }
+               }
+       }
+       return FTDM_SUCCESS;
+}
+
+
+int ftmod_sigtran_sctp_config(int id)
+{ 
+    if  (ftmod_sigtran_sctp_tsap_config(id) != FTDM_SUCCESS)
+        return FTDM_FAIL;
+    
+    if  (ftmod_sigtran_sctp_sap_config(id) != FTDM_SUCCESS)
+        return FTDM_FAIL;
+    
+    return FTDM_SUCCESS;
+}
+
+ftdm_status_t ftmod_sigtran_sctp_tsap_config(int id)
+{
+       Pst                     pst;
+       SbMgmt          cfg;
+       SbTSapCfg       *c;     
+
+       int                     i = 0;
+       int                     ret = -1;
+       
+       sng_sctp_link_t *k = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[id];
+
+       smPstInit(&pst);
+       pst.dstEnt = ENTSB;
+       
+       memset(&cfg, 0x0, sizeof(cfg));
+       smHdrInit(&cfg.hdr);
+
+       cfg.hdr.msgType         = TCFG;
+       cfg.hdr.entId.ent               = ENTSB;
+       cfg.hdr.entId.inst              = S_INST;
+       cfg.hdr.elmId.elmnt     = STSBTSAP;
+       cfg.hdr.elmId.elmntInst1= k->id;
+
+       c = &cfg.t.cfg.s.tSapCfg;
+       c->swtch                = LSB_SW_RFC_REL0;
+       c->suId         = 1;
+       c->sel          = 0;
+       c->ent          = ENTHI;
+       c->inst         = S_INST;
+       c->procId       = g_ftdm_sngss7_data.cfg.procId;
+       c->memId.region = S_REG;
+       c->memId.pool   = S_POOL;
+       c->prior                = PRIOR1;
+       c->route                = RTESPEC;
+       c->srcNAddrLst.nmb = k->numSrcAddr;
+       for (i=0; i <= (k->numSrcAddr-1); i++) {
+               c->srcNAddrLst.nAddr[i].type = CM_NETADDR_IPV4;         
+               c->srcNAddrLst.nAddr[i].u.ipv4NetAddr = k->srcAddrList[i+1];
+       }
+
+       c->reConfig.spId        = 1;
+       c->reConfig.maxBndRetry = 3; 
+       c->reConfig.tIntTmr = 200;
+       
+       ret = sng_cfg_sctp(&pst, &cfg);
+       if (ret==0) {
+               SS7_INFO("SCTP TSAP %d configuration DONE!\n", id);
+               return FTDM_SUCCESS;
+       } else {
+               SS7_CRITICAL("SCTP TSAP %d configuration FAILED!\n", id);
+               return FTDM_FAIL;
+       }
+}
+
+ftdm_status_t ftmod_sigtran_sctp_sap_config(int id)
+{
+       Pst                     pst;
+       SbMgmt          cfg;
+       SbSctSapCfg     *c;     
+       
+       int             ret = -1;
+       sng_sctp_link_t *k = &g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[id];
+
+       smPstInit(&pst);
+       pst.dstEnt = ENTSB;
+       
+       memset(&cfg, 0x0, sizeof(cfg));
+       smHdrInit(&cfg.hdr);
+
+       cfg.hdr.msgType         = TCFG;
+       cfg.hdr.entId.ent               = ENTSB;
+       cfg.hdr.entId.inst              = S_INST;
+       cfg.hdr.elmId.elmnt     = STSBSCTSAP;
+       cfg.hdr.elmId.elmntInst1= k->id;
+
+       c = &cfg.t.cfg.s.sctSapCfg;
+       c->swtch        = LSB_SW_RFC_REL0;
+       c->spId         = 1;    /* Service Provider SAP Id */
+       c->sel          = 0;
+       c->memId.region = S_REG;
+       c->memId.pool   = S_POOL;
+       c->prior                = PRIOR1;
+       c->route                = RTESPEC;
+
+       /* Maximum time to wait before the SCTP layer must send a Selective Acknowledgement (SACK) message. Valid range is 1 -165535. */
+       c->reConfig.maxAckDelayTm = 200; 
+       /* Maximum number of messages to receive before the SCTP layer must send a SACK message. Valid range is 1 - 165535. */
+       c->reConfig.maxAckDelayDg = 2;
+       /* Initial value of the retransmission timer (RTO). The SCTP layer retransmits data after waiting for feedback during this time period. Valid range is 1 - 65535. */
+       c->reConfig.rtoInitial = 3000;
+       /* Minimum value used for the RTO. If the computed value of RTO is less than rtoMin, the computed value is rounded up to this value. */
+       c->reConfig.rtoMin = 1000;
+       /* Maxiumum value used for RTO. If the computed value of RTO is greater than rtoMax, the computed value is rounded down to this value. */
+       c->reConfig.rtoMax = 10000;
+       /* Default Freeze timer value */
+       c->reConfig.freezeTm = 3000;
+       /* Base cookie lifetime for the cookie in the Initiation Acknowledgement (INIT ACK) message. */
+       c->reConfig.cookieLife = 60000;
+       /* Default heartbeat interval timer. Valid range is 1 - 65535. */
+       c->reConfig.intervalTm = 3000;
+       /* Maximum burst value. Valid range is 1 - 65535. */
+       c->reConfig.maxBurst = 4;
+       /*Maximum number of heartbeats sent at each retransmission timeout (RTO). Valid range is 1 - 65535. */
+       c->reConfig.maxHbBurst = 1;
+       /*Shutdown guard timer value for graceful shutdowns. */
+       c->reConfig.t5SdownGrdTm = 15000;
+       /*      Action to take when the receiver's number of incoming streams is less than the sender's number of outgoing streams. Valid values are:
+               TRUE = Accept incoming stream and continue association.
+               FALSE = Abort the association.
+       */
+       c->reConfig.negAbrtFlg = FALSE;
+       /*      Whether to enable or disable heartbeat by default. Valid values are:
+               TRUE = Enable heartbeat.
+               FALSE = Disable heartbeat.
+       */
+       c->reConfig.hBeatEnable = TRUE;
+       /* Flow control start threshold. When the number of messages in SCTP\92s message queue reaches this value, flow control starts. */
+       c->reConfig.flcUpThr = 8;
+       /* Flow control stop threshold. When the number of messages in SCTP\92s message queue reaches this value, flow control stops. */
+       c->reConfig.flcLowThr = 6;
+
+       c->reConfig.handleInitFlg = FALSE;
+
+       ret = sng_cfg_sctp(&pst, &cfg);
+       if (ret==0) {
+               SS7_INFO("SCTP SAP %d configuration DONE!\n", id);
+               return FTDM_SUCCESS;
+       } else {
+               SS7_CRITICAL("SCTP SAP %d configuration FAILED!\n", id);
+               return FTDM_FAIL;
+       }
+}
+
+/**********************************************************************************************/
+/* M2UA - General configuration */
+static S16 ftmod_sigtran_m2ua_gen_config(void)
+{
+       Pst    pst; 
+       MwMgmt cfg;
+
+       memset((U8 *)&cfg, 0, sizeof(MwMgmt));
+       memset((U8 *)&pst, 0, sizeof(Pst));
+
+       smPstInit(&pst);
+
+       pst.dstEnt = ENTMW;
+
+       /* prepare header */
+       cfg.hdr.msgType     = TCFG;           /* message type */
+       cfg.hdr.entId.ent   = ENTMW;          /* entity */
+       cfg.hdr.entId.inst  = 0;              /* instance */
+       cfg.hdr.elmId.elmnt = STMWGEN;        /* General */
+       cfg.hdr.transId     = 0;     /* transaction identifier */
+
+       cfg.hdr.response.selector    = 0;
+       cfg.hdr.response.prior       = PRIOR0;
+       cfg.hdr.response.route       = RTESPEC;
+       cfg.hdr.response.mem.region  = S_REG;
+       cfg.hdr.response.mem.pool    = S_POOL;
+
+
+
+       cfg.t.cfg.s.genCfg.nodeType          = LMW_TYPE_SGP; /* NodeType ==  SGP or ASP  */
+       cfg.t.cfg.s.genCfg.maxNmbIntf        = MW_MAX_NUM_OF_INTF;
+       cfg.t.cfg.s.genCfg.maxNmbCluster     = MW_MAX_NUM_OF_CLUSTER;
+       cfg.t.cfg.s.genCfg.maxNmbPeer        = MW_MAX_NUM_OF_PEER;
+       cfg.t.cfg.s.genCfg.maxNmbSctSap      = MW_MAX_NUM_OF_SCT_SAPS;
+       cfg.t.cfg.s.genCfg.timeRes           = 1;              /* timer resolution */
+       cfg.t.cfg.s.genCfg.maxClusterQSize   = MW_MAX_CLUSTER_Q_SIZE;
+       cfg.t.cfg.s.genCfg.maxIntfQSize      = MW_MAX_INTF_Q_SIZE;
+
+#ifdef LCMWMILMW  
+       cfg.t.cfg.s.genCfg.reConfig.smPst.selector  = 0;     /* selector */
+#else /* LCSBMILSB */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.selector  = 1;     /* selector */
+#endif /* LCSBMILSB */
+
+       cfg.t.cfg.s.genCfg.reConfig.smPst.region    = S_REG;   /* region */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.pool      = S_POOL;     /* pool */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.prior     = PRIOR0;        /* priority */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.route     = RTESPEC;       /* route */
+
+       cfg.t.cfg.s.genCfg.reConfig.smPst.dstEnt    = ENTSM;         /* dst entity */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.dstInst   = 0;             /* dst inst */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.dstProcId = SFndProcId();  /* src proc id */
+
+       cfg.t.cfg.s.genCfg.reConfig.smPst.srcEnt    = ENTMW;         /* src entity */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.srcInst   = 0;             /* src inst */
+       cfg.t.cfg.s.genCfg.reConfig.smPst.srcProcId = SFndProcId();  /* src proc id */
+
+       cfg.t.cfg.s.genCfg.reConfig.tmrFlcPoll.enb = TRUE;            /* SCTP Flc Poll timer */
+       cfg.t.cfg.s.genCfg.reConfig.tmrFlcPoll.val = 10;
+
+#ifdef MWASP
+       cfg.t.cfg.s.genCfg.reConfig.tmrAspm.enb    = TRUE;         /* ASPM  timer */
+       cfg.t.cfg.s.genCfg.reConfig.tmrAspm.val    = 10;
+       cfg.t.cfg.s.genCfg.reConfig.tmrHeartBeat.enb  = TRUE;       /* Heartbeat timer */
+       cfg.t.cfg.s.genCfg.reConfig.tmrHeartBeat.val  = 10;
+#endif
+
+#ifdef MWSG
+       cfg.t.cfg.s.genCfg.reConfig.tmrAsPend.enb  = TRUE;   /* AS-PENDING timer */
+       cfg.t.cfg.s.genCfg.reConfig.tmrAsPend.val  = 10;
+       cfg.t.cfg.s.genCfg.reConfig.tmrCongPoll.enb = TRUE;  /* SS7 Congestion poll timer */
+       cfg.t.cfg.s.genCfg.reConfig.tmrCongPoll.val = 10;
+       cfg.t.cfg.s.genCfg.reConfig.tmrHeartBeat.enb  = FALSE;       /* HBtimer only at ASP */
+#endif
+       cfg.t.cfg.s.genCfg.reConfig.aspmRetry = 5;
+
+       return (sng_cfg_m2ua (&pst, &cfg));
+}   
+
+/**********************************************************************************************/
+
+
+/* M2UA - SCTSAP configuration */
+static S16 ftmod_sigtran_m2ua_sctsap_config(void)
+{
+
+   Pst    pst; 
+   MwMgmt cfg;
+
+   memset((U8 *)&cfg, 0, sizeof(MwMgmt));
+   memset((U8 *)&pst, 0, sizeof(Pst));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTMW;
+
+   /* prepare header */
+   cfg.hdr.msgType     = TCFG;           /* message type */
+   cfg.hdr.entId.ent   = ENTMW;          /* entity */
+   cfg.hdr.entId.inst  = 0;              /* instance */
+   cfg.hdr.elmId.elmnt = STMWSCTSAP;     /* SCTSAP */
+   cfg.hdr.transId     = 0;     /* transaction identifier */
+
+   cfg.hdr.response.selector    = 0;
+   cfg.hdr.response.prior       = PRIOR0;
+   cfg.hdr.response.route       = RTESPEC;
+   cfg.hdr.response.mem.region  = S_REG;
+   cfg.hdr.response.mem.pool    = S_POOL;
+
+
+
+   cfg.t.cfg.s.sctSapCfg.reConfig.selector     = 0;
+
+   /* service user SAP ID */
+   cfg.t.cfg.s.sctSapCfg.suId                   = 0;
+   /* service provider ID   */
+   cfg.t.cfg.s.sctSapCfg.spId                   = 1; /* TUCL sct sap id is 1 */
+   /* source port number */
+   cfg.t.cfg.s.sctSapCfg.srcPort                = 0;
+   /* interface address */
+   /*For multiple IP address support */
+#ifdef SCT_ENDP_MULTI_IPADDR
+   cfg.t.cfg.s.sctSapCfg.srcAddrLst.nmb = 1;
+   cfg.t.cfg.s.sctSapCfg.srcAddrLst.nAddr[0].type = CM_NETADDR_IPV4;
+   cfg.t.cfg.s.sctSapCfg.srcAddrLst.nAddr[0].u.ipv4NetAddr = ftmod_parse_conv_ipaddr((S8*)"192.168.1.100");
+#else
+   cfg.t.cfg.s.sctSapCfg.intfAddr.type          = CM_NETADDR_IPV4;
+   cfg.t.cfg.s.sctSapCfg.intfAddr.u.ipv4NetAddr = ftmod_parse_conv_ipaddr((S8*)"192.168.1.100");
+#endif
+
+   /* lower SAP primitive timer */
+   cfg.t.cfg.s.sctSapCfg.reConfig.tmrPrim.enb   = TRUE;
+   cfg.t.cfg.s.sctSapCfg.reConfig.tmrPrim.val   = 10;
+   /* Association primitive timer */
+   cfg.t.cfg.s.sctSapCfg.reConfig.tmrAssoc.enb   = TRUE;
+   cfg.t.cfg.s.sctSapCfg.reConfig.tmrAssoc.val   = 10;
+   /* maxnumber of retries */
+   cfg.t.cfg.s.sctSapCfg.reConfig.nmbMaxPrimRetry  = 5;
+   /* Life Time of Packets  */
+   cfg.t.cfg.s.sctSapCfg.reConfig.lifeTime  = 200;
+   /* priority */
+   cfg.t.cfg.s.sctSapCfg.reConfig.prior       =  PRIOR0;
+   /* route */
+   cfg.t.cfg.s.sctSapCfg.reConfig.route       =  RTESPEC;
+   cfg.t.cfg.s.sctSapCfg.reConfig.ent         =  ENTSB;
+   cfg.t.cfg.s.sctSapCfg.reConfig.inst        =  0;
+   cfg.t.cfg.s.sctSapCfg.reConfig.procId      =  SFndProcId();
+   /* memory region and pool ID */
+   cfg.t.cfg.s.sctSapCfg.reConfig.mem.region    = S_REG;
+   cfg.t.cfg.s.sctSapCfg.reConfig.mem.pool      = S_POOL;
+
+     return (sng_cfg_m2ua (&pst, &cfg));
+
+}
+
+/**********************************************************************************************/
+
+
+/* M2UA - Peer configuration */
+static S16 ftmod_sigtran_m2ua_peer_config(void)
+{
+   Pst    pst;
+   MwMgmt cfg;
+
+   memset((U8 *)&cfg, 0, sizeof(MwMgmt));
+   memset((U8 *)&pst, 0, sizeof(Pst));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTMW;
+
+   /* prepare header */
+       cfg.hdr.msgType     = TCFG;           /* message type */
+   cfg.hdr.entId.ent   = ENTMW;          /* entity */
+   cfg.hdr.entId.inst  = 0;              /* instance */
+   cfg.hdr.elmId.elmnt = STMWPEER;       /* Peer */
+   cfg.hdr.transId     = 0;     /* transaction identifier */
+
+   cfg.hdr.response.selector    = 0;
+   cfg.hdr.response.prior       = PRIOR0;
+   cfg.hdr.response.route       = RTESPEC;
+   cfg.hdr.response.mem.region  = S_REG;
+   cfg.hdr.response.mem.pool    = S_POOL;
+
+
+
+   cfg.t.cfg.s.peerCfg.peerId = 1;               /* peer id */
+   cfg.t.cfg.s.peerCfg.aspIdFlag = FALSE;        /* aspId flag */
+#ifdef MWASP
+   cfg.t.cfg.s.peerCfg.selfAspId =  1;  /* aspId */
+#endif
+   cfg.t.cfg.s.peerCfg.assocCfg.suId = 0; /* SCTSAP ID */
+   cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nmb = 1; /* destination address list*/
+   cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[0].type = CM_NETADDR_IPV4;
+   cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[0].u.ipv4NetAddr = ftmod_parse_conv_ipaddr((S8*)"192.168.1.100");/* TODO */;
+#if 0   
+   cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[1].type = CM_NETADDR_IPV4;
+   cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[1].u.ipv4NetAddr = ftmod_parse_conv_ipaddr("172.25.0.93"); /* TODO */;
+#endif   
+#ifdef MW_CFG_DSTPORT
+   cfg.t.cfg.s.peerCfg.assocCfg.dstPort = /* TODO */ 2904; /* Port on which M2UA runs */
+#endif
+   cfg.t.cfg.s.peerCfg.assocCfg.srcAddrLst.nmb = 1; /* source address list */
+   cfg.t.cfg.s.peerCfg.assocCfg.srcAddrLst.nAddr[0].type =  CM_NETADDR_IPV4;
+   cfg.t.cfg.s.peerCfg.assocCfg.srcAddrLst.nAddr[0].u.ipv4NetAddr = ftmod_parse_conv_ipaddr((S8*)"192.168.1.100");/* TODO */;
+
+   cfg.t.cfg.s.peerCfg.assocCfg.priDstAddr.type = CM_NETADDR_IPV4;
+   cfg.t.cfg.s.peerCfg.assocCfg.priDstAddr.u.ipv4NetAddr = cfg.t.cfg.s.peerCfg.assocCfg.dstAddrLst.nAddr[0].u.ipv4NetAddr;
+
+   cfg.t.cfg.s.peerCfg.assocCfg.locOutStrms = 10;
+#ifdef SCT3
+   cfg.t.cfg.s.peerCfg.assocCfg.tos = 0;
+#endif
+
+     return (sng_cfg_m2ua (&pst, &cfg));
+}
+/**********************************************************************************************/
+
+
+/* M2UA - Cluster configuration */
+static S16 ftmod_sigtran_m2ua_cluster_config(void)
+{
+   Pst    pst; 
+   MwMgmt cfg;
+
+   memset((U8 *)&cfg, 0, sizeof(MwMgmt));
+   memset((U8 *)&pst, 0, sizeof(Pst));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTMW;
+
+   /* prepare header */
+       cfg.hdr.msgType     = TCFG;           /* message type */
+   cfg.hdr.entId.ent   = ENTMW;          /* entity */
+   cfg.hdr.entId.inst  = 0;              /* instance */
+   cfg.hdr.elmId.elmnt = STMWCLUSTER;    /* Cluster */
+   cfg.hdr.transId     = 0;     /* transaction identifier */
+
+   cfg.hdr.response.selector    = 0;
+   cfg.hdr.response.prior       = PRIOR0;
+   cfg.hdr.response.route       = RTESPEC;
+   cfg.hdr.response.mem.region  = S_REG;
+   cfg.hdr.response.mem.pool    = S_POOL;
+
+
+
+   cfg.t.cfg.s.clusterCfg.clusterId = 0;
+   cfg.t.cfg.s.clusterCfg.trfMode = LMW_TRF_MODE_LOADSHARE;
+   cfg.t.cfg.s.clusterCfg.loadshareMode = LMW_LOADSH_RR;
+   cfg.t.cfg.s.clusterCfg.reConfig.nmbPeer = 1;
+   cfg.t.cfg.s.clusterCfg.reConfig.peer[0] = 1;
+#if 0   
+   cfg.t.cfg.s.clusterCfg.reConfig.peer[1] = 2;
+#endif   
+
+     return (sng_cfg_m2ua (&pst, &cfg));
+
+}
+/**********************************************************************************************/
+
+/* M2UA - DLSAP configuration */
+static S16 ftmod_sigtran_m2ua_dlsap_config(U32 id)
+{
+   Pst    pst; 
+   MwMgmt cfg;
+
+   memset((U8 *)&cfg, 0, sizeof(MwMgmt));
+   memset((U8 *)&pst, 0, sizeof(Pst));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTMW;
+
+   /* prepare header */
+       cfg.hdr.msgType     = TCFG;           /* message type */
+   cfg.hdr.entId.ent   = ENTMW;          /* entity */
+   cfg.hdr.entId.inst  = 0;              /* instance */
+   cfg.hdr.elmId.elmnt = STMWDLSAP;      /* DLSAP */
+   cfg.hdr.transId     = 0;     /* transaction identifier */
+
+   cfg.hdr.response.selector    = 0;
+   cfg.hdr.response.prior       = PRIOR0;
+   cfg.hdr.response.route       = RTESPEC;
+   cfg.hdr.response.mem.region  = S_REG;
+   cfg.hdr.response.mem.pool    = S_POOL;
+
+
+   switch(id)
+   {
+      case 0:
+         {
+            cfg.t.cfg.s.dlSapCfg.lnkNmb = 0; /* SapId */
+            cfg.t.cfg.s.dlSapCfg.intfId.type = LMW_INTFID_INT;
+            cfg.t.cfg.s.dlSapCfg.intfId.id.intId = 0;
+            break;
+         }
+      case 1:
+         {
+            cfg.t.cfg.s.dlSapCfg.lnkNmb = 1; /* SapId */
+            cfg.t.cfg.s.dlSapCfg.intfId.type = LMW_INTFID_INT;
+            cfg.t.cfg.s.dlSapCfg.intfId.id.intId = 1;
+            break;
+         }   
+
+      case 2:
+         {
+            cfg.t.cfg.s.dlSapCfg.lnkNmb = 2; /* SapId */
+            cfg.t.cfg.s.dlSapCfg.intfId.type = LMW_INTFID_INT;
+            cfg.t.cfg.s.dlSapCfg.intfId.id.intId = 2;
+            break;
+         }
+      default:
+         break;
+   }   
+   
+   cfg.t.cfg.s.dlSapCfg.swtch = LMW_SAP_ITU;
+
+   
+
+   cfg.t.cfg.s.dlSapCfg.reConfig.clusterId =  0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.selector  =  0; /* Loosely couple mode */
+   /* memory region and pool id*/
+   cfg.t.cfg.s.dlSapCfg.reConfig.mem.region  =  S_REG;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mem.pool    =  S_POOL;
+   /* priority */
+   cfg.t.cfg.s.dlSapCfg.reConfig.prior       =  PRIOR0;
+   /* route */
+   cfg.t.cfg.s.dlSapCfg.reConfig.route       =  RTESPEC;
+
+     return (sng_cfg_m2ua (&pst, &cfg));
+
+}
+/*****************************************************************************/
+
+/* NIF configurations */
+/* NIF - General configuration */
+static S16 ftmod_sigtran_nif_gen_config(void)
+{
+   Pst    pst; 
+   NwMgmt cfg;
+
+   memset((U8 *)&cfg, 0, sizeof(NwMgmt));
+   memset((U8 *)&pst, 0, sizeof(Pst));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTNW;
+
+   /* prepare header */
+       cfg.hdr.msgType     = TCFG;           /* message type */
+   cfg.hdr.entId.ent   = ENTNW;          /* entity */
+   cfg.hdr.entId.inst  = 0;              /* instance */
+   cfg.hdr.elmId.elmnt = STNWGEN;      /* DLSAP */
+   cfg.hdr.transId     = 0;     /* transaction identifier */
+
+   cfg.hdr.response.selector    = 0;
+   cfg.hdr.response.prior       = PRIOR0;
+   cfg.hdr.response.route       = RTESPEC;
+   cfg.hdr.response.mem.region  = S_REG;
+   cfg.hdr.response.mem.pool    = S_POOL;
+
+   cfg.t.cfg.s.genCfg.maxNmbDlSap       = NW_MAX_NUM_OF_DLSAPS;
+   cfg.t.cfg.s.genCfg.timeRes           = 1;    /* timer resolution */
+
+   cfg.t.cfg.s.genCfg.reConfig.maxNmbRetry    = NW_MAX_NUM_OF_RETRY;
+   cfg.t.cfg.s.genCfg.reConfig.tmrRetry.enb =   TRUE;     /* SS7 Congestion poll timer */
+   cfg.t.cfg.s.genCfg.reConfig.tmrRetry.val =   NW_RETRY_TMR_VALUE;
+
+#ifdef LCNWMILNW  
+   cfg.t.cfg.s.genCfg.reConfig.smPst.selector  = 0;     /* selector */
+#else /* LCSBMILSB */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.selector  = 1;     /* selector */
+#endif /* LCSBMILSB */
+
+   cfg.t.cfg.s.genCfg.reConfig.smPst.region    = S_REG;   /* region */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.pool      = S_POOL;     /* pool */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.prior     = PRIOR0;        /* priority */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.route     = RTESPEC;       /* route */
+
+   cfg.t.cfg.s.genCfg.reConfig.smPst.dstEnt    = ENTSM;         /* dst entity */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.dstInst   = 0;             /* dst inst */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.dstProcId = SFndProcId();  /* src proc id */
+
+   cfg.t.cfg.s.genCfg.reConfig.smPst.srcEnt    = ENTNW;         /* src entity */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.srcInst   = 0;             /* src inst */
+   cfg.t.cfg.s.genCfg.reConfig.smPst.srcProcId = SFndProcId();  /* src proc id */
+
+     return (sng_cfg_nif (&pst, &cfg));
+
+}
+
+/* NIF - DLSAP configuration */
+static S16 ftmod_sigtran_nif_dlsap_config(U32 id)
+{
+   Pst    pst; 
+   NwMgmt cfg;
+
+   memset((U8 *)&cfg, 0, sizeof(NwMgmt));
+   memset((U8 *)&pst, 0, sizeof(Pst));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTNW;
+
+   /* prepare header */
+       cfg.hdr.msgType     = TCFG;           /* message type */
+   cfg.hdr.entId.ent   = ENTNW;          /* entity */
+   cfg.hdr.entId.inst  = 0;              /* instance */
+   cfg.hdr.elmId.elmnt = STNWDLSAP;      /* DLSAP */
+   cfg.hdr.transId     = 0;     /* transaction identifier */
+
+   cfg.hdr.response.selector    = 0;
+   cfg.hdr.response.prior       = PRIOR0;
+   cfg.hdr.response.route       = RTESPEC;
+   cfg.hdr.response.mem.region  = S_REG;
+   cfg.hdr.response.mem.pool    = S_POOL;
+
+#if 0
+   switch(id)
+   {
+     case 0:   
+        {   
+           cfg.t.cfg.s.dlSapCfg.suId = 0;           /*ACC_DLSAP_0 */
+           cfg.t.cfg.s.dlSapCfg.m2uaLnkNmb  = 0;    /*ACC_DLSAP_0 */
+           cfg.t.cfg.s.dlSapCfg.mtp2LnkNmb  = 0;   /* ACC_DLSAP_0 */
+           break;
+        }
+     case 1:
+        {
+           cfg.t.cfg.s.dlSapCfg.suId = 1;           /*ACC_DLSAP_0 */
+           cfg.t.cfg.s.dlSapCfg.m2uaLnkNmb  = 1;    /*ACC_DLSAP_0 */
+           cfg.t.cfg.s.dlSapCfg.mtp2LnkNmb  = /* TODO */1;   /* ACC_DLSAP_0 */
+           break;
+        }
+     case 2:
+       {
+          cfg.t.cfg.s.dlSapCfg.suId = 2;           /*ACC_DLSAP_0 */
+          cfg.t.cfg.s.dlSapCfg.m2uaLnkNmb  = 2;    /*ACC_DLSAP_0 */
+          cfg.t.cfg.s.dlSapCfg.mtp2LnkNmb  = /* TODO */ 2;   /* ACC_DLSAP_0 */
+          break;
+       }   
+
+     default:
+      break;
+
+   }   
+#endif
+
+   cfg.t.cfg.s.dlSapCfg.suId = 1;           /*ACC_DLSAP_0 */
+   cfg.t.cfg.s.dlSapCfg.m2uaLnkNmb  = 1;    /*ACC_DLSAP_0 */
+   cfg.t.cfg.s.dlSapCfg.mtp2LnkNmb  = 1; /* TODO */  /* ACC_DLSAP_0 */
+      
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.selector   = 0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.region     = S_REG;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.pool       = S_POOL;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.route      = RTESPEC;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.prior      = PRIOR0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.srcEnt     = ENTNW;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.srcInst    = 0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.srcProcId  = SFndProcId();
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.dstEnt     = ENTMW;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.dstInst    = 0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.m2uaPst.dstProcId  = SFndProcId();
+
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.selector   = 0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.region     = S_REG;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.pool       = S_POOL;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.route      = RTESPEC;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.prior      = PRIOR0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.srcEnt     = ENTNW;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.srcInst    = 0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.srcProcId  = SFndProcId();
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.dstEnt     = ENTSD;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.dstInst    = 0;
+   cfg.t.cfg.s.dlSapCfg.reConfig.mtp2Pst.dstProcId  = SFndProcId();
+
+     return (sng_cfg_nif (&pst, &cfg));
+}   
+
+static U32 ftmod_atoi(S8 *str)
+{
+   U32 idx = 0;
+   U32 value = 0;
+
+   while(str[idx] != '\0')
+   {
+      value = (10 * value)  + (str[idx] - '0');
+      idx++;
+   }   
+   return(value);
+}   
+
+static U32 ftmod_parse_conv_ipaddr(S8 *ptr)
+{
+
+  U32 ipAddr     = 0;
+  U32 idx        = 0; 
+  U32 tmpCnt     = 0; 
+  U32 len_ipAddr = 0;
+  S8  tmpStr[8] = { 0, 0, 0, 0, 0, 0, 0, 0};
+
+  len_ipAddr = strlen(ptr);
+
+  idx = 0;
+  tmpCnt = 0;
+  while(idx < len_ipAddr)
+  {
+     if( ptr[idx] != '.' )
+     {
+        tmpStr[tmpCnt++] = ptr[idx];
+     }
+     else
+     {
+       tmpStr[tmpCnt] = '\0';
+       ipAddr |= ftmod_atoi(tmpStr);
+       ipAddr <<= 8;   
+       tmpCnt = 0;
+     }   
+     idx++;
+  }
+  
+  tmpStr[tmpCnt] = '\0';  
+  ipAddr |= ftmod_atoi(tmpStr);
+
+  return(ipAddr); 
+}
+
+uint32_t iptoul(const char *ip)
+{
+        char i,*tmp;
+        int strl;
+        char strIp[16];
+        unsigned long val=0, cvt;
+        if (!ip)
+                return 0;
+
+        memset(strIp, 0, sizeof(char)*16);
+        strl = strlen(ip);
+        strncpy(strIp, ip, strl>=15?15:strl);
+
+
+        tmp=strtok(strIp, ".");
+        for (i=0;i<4;i++)
+        {
+                sscanf(tmp, "%lu", &cvt);
+                val <<= 8;
+                val |= (unsigned char)cvt;
+                tmp=strtok(NULL,".");
+        }
+        return (uint32_t)val;
+}
+
+/***********************************************************************************************************************/
+
+int ftmod_ss7_m2ua_start(void){
+
+
+   S16 ret = 0x00;
+  
+   /* Send a control request to bind the TSAP between SCTP and TUCL */
+   if( (ret = ftmod_sigtran_tsap_bnd()) != ROK)
+   {
+      ftdm_log (FTDM_LOG_ERROR ,"\nControl request to bind TSAP of SCTP and TUCL : NOT OK\n");
+      return 1;
+   }   
+   else
+   {
+      ftdm_log (FTDM_LOG_INFO ,"\nControl request to bind TSAP of SCTP and TUCL: OK\n");
+   }
+
+   /* Send a control request to bind the SCTSAP between SCTP and M2UA */
+   if( (ret = ftmod_sigtran_sctsap_bnd()) != ROK)
+   {
+      ftdm_log (FTDM_LOG_ERROR ,"Control request to bind SCTSAP of M2UA and SCTP : NOT OK\n");
+      return 1;
+   }   
+   else
+   {
+      ftdm_log (FTDM_LOG_INFO ,"Control request to bind SCTSAP of M2UA and SCTP: OK\n");
+   }
+
+   /* Send a control request to bind the DLSAP between NIF, M2UA and MTP-2
+   for(idx = 0; idx < 3; idx++) */
+   {
+      if( (ret = ftmod_sigtran_dlsap_bnd(1)) != ROK)
+      {
+         ftdm_log (FTDM_LOG_ERROR ,"Control request to bind DLSAP between NIF and M2UA: NOT OK\n");
+        return 1;
+      }   
+      else
+      {
+         ftdm_log (FTDM_LOG_INFO ,"Control request to bind DLSAP between NIF and M2UA : OK\n");
+      }
+
+      if( (ret = ftmod_ss7_dlsap_bnd(0x01)) != ROK)
+      {
+         ftdm_log (FTDM_LOG_ERROR ,"Control request to bind DLSAP between NIF and MTP2  : NOT OK\n");
+        return 1;
+      }   
+      else
+      {
+         ftdm_log (FTDM_LOG_INFO ,"Control request to bind DLSAP between NIF and MTP2 : OK\n");
+      }
+   }
+   return 0;
+}
+
+
+
+static S16 ftmod_sigtran_tsap_bnd(void)
+{
+
+  Pst pst;
+  SbMgmt cntrl;  
+
+  memset((U8 *)&pst, 0, sizeof(Pst));
+  memset((U8 *)&cntrl, 0, sizeof(SbMgmt));
+
+  smPstInit(&pst);
+
+  pst.dstEnt = ENTSB;
+
+  /* prepare header */
+   cntrl.hdr.msgType     = TCNTRL;         /* message type */
+   cntrl.hdr.entId.ent   = ENTSB;          /* entity */
+   cntrl.hdr.entId.inst  = 0;              /* instance */
+   cntrl.hdr.elmId.elmnt = STSBTSAP;       /* General */
+   cntrl.hdr.transId     = 1;     /* transaction identifier */
+
+   cntrl.hdr.response.selector    = 0;
+
+   cntrl.hdr.response.prior       = PRIOR0;
+   cntrl.hdr.response.route       = RTESPEC;
+   cntrl.hdr.response.mem.region  = S_REG;
+   cntrl.hdr.response.mem.pool    = S_POOL;
+
+   cntrl.t.cntrl.action = ABND_ENA;
+   cntrl.t.cntrl.sapId  = 1;  /* SCT sap id configured at SCTP layer */
+
+     return (sng_cntrl_sctp (&pst, &cntrl));
+
+}  
+
+static S16 ftmod_sigtran_sctsap_bnd(void)
+{
+  Pst pst;
+  MwMgmt cntrl;  
+
+  memset((U8 *)&pst, 0, sizeof(Pst));
+  memset((U8 *)&cntrl, 0, sizeof(MwMgmt));
+
+  smPstInit(&pst);
+
+  pst.dstEnt = ENTMW;
+
+  /* prepare header */
+  cntrl.hdr.msgType     = TCNTRL;         /* message type */
+   cntrl.hdr.entId.ent   = ENTMW;          /* entity */
+   cntrl.hdr.entId.inst  = 0;              /* instance */
+   cntrl.hdr.elmId.elmnt = STMWSCTSAP;       /* General */
+   cntrl.hdr.transId     = 1;     /* transaction identifier */
+
+   cntrl.hdr.response.selector    = 0;
+   cntrl.hdr.response.prior       = PRIOR0;
+   cntrl.hdr.response.route       = RTESPEC;
+   cntrl.hdr.response.mem.region  = S_REG;
+   cntrl.hdr.response.mem.pool    = S_POOL;
+
+
+   cntrl.t.cntrl.action = ABND;
+   cntrl.t.cntrl.s.suId = 0; /* M2UA sct sap Id */
+
+     return (sng_cntrl_m2ua (&pst, &cntrl));
+
+}   
+
+
+static S16 ftmod_sigtran_dlsap_bnd(U32 id)
+{
+  Pst pst;
+  NwMgmt cntrl;  
+
+  memset((U8 *)&pst, 0, sizeof(Pst));
+  memset((U8 *)&cntrl, 0, sizeof(NwMgmt));
+
+  smPstInit(&pst);
+
+  pst.dstEnt = ENTNW;
+
+  /* prepare header */
+       cntrl.hdr.msgType     = TCNTRL;         /* message type */
+   cntrl.hdr.entId.ent   = ENTNW;          /* entity */
+   cntrl.hdr.entId.inst  = 0;              /* instance */
+   cntrl.hdr.elmId.elmnt = STNWDLSAP;       /* General */
+   cntrl.hdr.transId     = 1;     /* transaction identifier */
+
+   cntrl.hdr.response.selector    = 0;
+   cntrl.hdr.response.prior       = PRIOR0;
+   cntrl.hdr.response.route       = RTESPEC;
+   cntrl.hdr.response.mem.region  = S_REG;
+   cntrl.hdr.response.mem.pool    = S_POOL;
+
+   cntrl.t.cntrl.action = ABND;
+   cntrl.t.cntrl.suId = id;      /* NIF DL sap Id */
+   cntrl.t.cntrl.entity = ENTMW; /* M2UA */
+
+     return (sng_cntrl_nif (&pst, &cntrl));
+
+}   
+
+static S16 ftmod_ss7_dlsap_bnd(U32 id)
+{
+   Pst pst;
+   NwMgmt cntrl;  
+
+   memset((U8 *)&pst, 0, sizeof(Pst));
+   memset((U8 *)&cntrl, 0, sizeof(NwMgmt));
+
+   smPstInit(&pst);
+
+   pst.dstEnt = ENTNW;
+
+   /* prepare header */
+   cntrl.hdr.msgType     = TCNTRL;         /* message type */
+   cntrl.hdr.entId.ent   = ENTNW;          /* entity */
+   cntrl.hdr.entId.inst  = 0;              /* instance */
+   cntrl.hdr.elmId.elmnt = STNWDLSAP;       /* General */
+   cntrl.hdr.transId     = 1;     /* transaction identifier */
+
+   cntrl.hdr.response.selector    = 0;
+   cntrl.hdr.response.prior       = PRIOR0;
+   cntrl.hdr.response.route       = RTESPEC;
+   cntrl.hdr.response.mem.region  = S_REG;
+   cntrl.hdr.response.mem.pool    = S_POOL;
+
+   cntrl.t.cntrl.action = ABND;
+   cntrl.t.cntrl.suId = id;      /* NIF DL sap Id */
+   cntrl.t.cntrl.entity = ENTSD; /* MTP2 */
+
+     return (sng_cntrl_nif (&pst, &cntrl));
+}
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua.h
new file mode 100644 (file)
index 0000000..1dc9a1f
--- /dev/null
@@ -0,0 +1,125 @@
+/*
+ * Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Contributors: 
+ *
+ */
+/******************************************************************************/
+#ifndef __FTMOD_SNG_SS7_M2UA_H__
+#define __FTMOD_SNG_SS7_M2UA_H__
+/******************************************************************************/
+#include "private/ftdm_core.h"
+
+#define MAX_NAME_LEN                   25
+
+typedef struct sng_nif_cfg{
+       char        name[MAX_NAME_LEN];
+       uint32_t    flags;
+       uint32_t    id;
+       uint32_t    m2uaLnkNmb;
+       uint32_t    mtp2LnkNmb;
+}sng_nif_cfg_t;
+
+typedef enum{
+       SNG_M2UA_NODE_TYPE_SGP  = 1,      /* type SG */
+       SNG_M2UA_NODE_TYPE_ASP  = 2,      /* type ASP */
+}sng_m2ua_node_types_e;
+
+typedef struct sng_m2ua_cfg{
+       char                     name[MAX_NAME_LEN];
+       uint32_t                 flags;
+       uint32_t                 id;            /* ID */
+       uint8_t                  nodeType;      /*Node Type SG/ASP */
+       uint16_t                 sctpId;        /* idx to sctp profile */
+       uint16_t                 peerdId;       /* idx to m2ua_peer profile */
+       uint16_t                 clusterId;     /* idx to m2ua_cluster profile */
+}sng_m2ua_cfg_t;
+
+typedef struct sng_m2ua_peer_cfg{
+       char                     name[MAX_NAME_LEN];
+       uint32_t                 flags;
+       uint32_t                 id;            /* ID */
+       uint8_t                  aspIdFlag;     /* Flag used to indicate whether include the ASP ID in the ASP UP message */
+       uint16_t                 selfAspId;     /* Self ASP ID. ASP identifier for this ASP node if the aspIdFlag is TRUE. */
+       uint32_t                 numDestAddr;   /* Number of destination address defined */
+       uint16_t                 sctpId;        /* idx to sctp profile */
+       uint32_t                 destAddrList[SCT_MAX_NET_ADDRS+1]; /* Destination adddress list */
+       uint16_t                 locOutStrms;   /*Number of outgoing streams supported by this association*/ 
+}sng_m2ua_peer_cfg_t;
+
+typedef enum{
+       SNG_M2UA_LOAD_SHARE_ALGO_RR    = 0x1,     /* Round Robin Mode*/
+       SNG_M2UA_LOAD_SHARE_ALGO_LS    = 0x2,     /* Link Specified */
+       SNG_M2UA_LOAD_SHARE_ALGO_CS    = 0x3,     /* Customer Specified */
+}sng_m2ua_load_share_algo_types_e;
+
+
+/* Possible values of Traffic mode */
+typedef enum{
+       SNG_M2UA_TRF_MODE_OVERRIDE   = 0x1,     /* Override Mode */
+       SNG_M2UA_TRF_MODE_LOADSHARE  = 0x2,     /* Loadshare Mode */
+       SNG_M2UA_TRF_MODE_BROADCAST  = 0x3,     /* Broadcast Mode */
+       SNG_M2UA_TRF_MODE_ANY        = 0x0,     /* ANY       Mode */
+}sng_m2ua_traffic_mode_types_e;
+
+typedef struct sng_m2ua_cluster_cfg{
+       char                     name[MAX_NAME_LEN];
+       uint32_t                 flags;
+       uint32_t                 id;            /* ID */
+       uint8_t                  trfMode;       /* Traffic mode. This parameter defines the mode in which this m2ua cluster is supposed to work */ 
+       uint8_t                  loadShareAlgo; /* This parameter defines the M2UA load share algorithm which is used to distribute the traffic */ 
+       uint16_t                 numOfPeers;    /* idx to m2ua_peer profile */
+       uint16_t                 peerIdLst[MW_MAX_NUM_OF_PEER]; /* idx to m2ua_peer profile */
+}sng_m2ua_cluster_cfg_t;
+
+typedef struct sng_m2ua_gbl_cfg{
+       sng_nif_cfg_t           nif[MW_MAX_NUM_OF_INTF];
+       sng_m2ua_cfg_t          m2ua[MW_MAX_NUM_OF_INTF];
+       sng_m2ua_peer_cfg_t     m2ua_peer[MW_MAX_NUM_OF_PEER];
+       sng_m2ua_cluster_cfg_t  m2ua_clus[MW_MAX_NUM_OF_CLUSTER];
+}sng_m2ua_gbl_cfg_t;
+
+/* m2ua xml parsing APIs */
+int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces);
+int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces);
+int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces);
+int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_clust_interfaces);
+ftdm_status_t ftmod_m3ua_parse_sctp_links(ftdm_conf_node_t *node);
+uint32_t iptoul(const char *ip);
+
+int ftmod_ss7_m2ua_start(void);
+
+ftdm_status_t ftmod_ss7_m2ua_cfg(void);
+
+
+#endif /*__FTMOD_SNG_SS7_M2UA_H__*/
diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_m2ua_xml.c
new file mode 100644 (file)
index 0000000..70af479
--- /dev/null
@@ -0,0 +1,671 @@
+/*
+ * Copyright (c) 2012, Kapil Gupta <kgupta@sangoma.com>
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ *
+ * * Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * * Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * * Neither the name of the original author; nor the names of any contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER
+ * OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+ * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+ * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+ * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ *
+ *
+ * Contributors: 
+ *
+ *
+ */
+
+/* INCLUDE ********************************************************************/
+#include "ftmod_sangoma_ss7_main.h"
+/******************************************************************************/
+
+/* DEFINES ********************************************************************/
+/******************************************************************************/
+
+static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface);
+static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface);
+static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface);
+static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_clust_interface);
+static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface);
+static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface);
+static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_face);
+static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_face);
+
+static ftdm_status_t ftmod_m3ua_parse_sctp_link(ftdm_conf_node_t *node);
+
+/******************************************************************************/
+int ftmod_ss7_parse_nif_interfaces(ftdm_conf_node_t *nif_interfaces)
+{
+       ftdm_conf_node_t        *nif_interface = NULL;
+
+       /* confirm that we are looking at sng_nif_interfaces */
+       if (strcasecmp(nif_interfaces->name, "sng_nif_interfaces")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_nif_interfaces\"!\n",nif_interfaces->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"nif_interfaces\"...\n");
+       }
+
+       /* extract the isup_interfaces */
+       nif_interface = nif_interfaces->child;
+
+       while (nif_interface != NULL) {
+               /* parse the found mtp_route */
+               if (ftmod_ss7_parse_nif_interface(nif_interface)) {
+                       SS7_ERROR("Failed to parse \"nif_interface\"\n");
+                       return FTDM_FAIL;
+               }
+
+               /* go to the next nif_interface */
+               nif_interface = nif_interface->next;
+       }
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+static int ftmod_ss7_parse_nif_interface(ftdm_conf_node_t *nif_interface)
+{
+       sng_nif_cfg_t                   sng_nif;
+       ftdm_conf_parameter_t           *parm = nif_interface->parameters;
+       int                             num_parms = nif_interface->n_parameters;
+       int                             i;
+
+       /* initalize the nif intf and isap structure */
+       memset(&sng_nif, 0x0, sizeof(sng_nif));
+
+       /* confirm that we are looking at an nif_interface */
+       if (strcasecmp(nif_interface->name, "sng_nif_interface")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"nif_interface\"!\n",nif_interface->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"nif_interface\"...\n");
+       }
+
+
+       for (i = 0; i < num_parms; i++) {
+       /**************************************************************************/
+
+               /* try to match the parameter to what we expect */
+               if (!strcasecmp(parm->var, "name")) {
+               /**********************************************************************/
+                       strcpy((char *)sng_nif.name, parm->val);
+                       SS7_DEBUG("Found an nif_interface named = %s\n", sng_nif.name);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "id")) {
+               /**********************************************************************/
+                       sng_nif.id = atoi(parm->val);
+                       SS7_DEBUG("Found an nif id = %d\n", sng_nif.id);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "m2uaLnkNmb")) {
+               /**********************************************************************/
+                       sng_nif.m2uaLnkNmb = atoi(parm->val);
+                       SS7_DEBUG("Found an nif m2uaLnkNmb = %d\n", sng_nif.m2uaLnkNmb);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "mtp2LnkNmb")) {
+               /**********************************************************************/
+                       sng_nif.mtp2LnkNmb=atoi(parm->val);
+
+                       SS7_DEBUG("Found an nif mtp2LnkNmb = %d\n", sng_nif.mtp2LnkNmb);
+               /**********************************************************************/
+               } else {
+               /**********************************************************************/
+                       SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
+                       return FTDM_FAIL;
+               /**********************************************************************/
+               }
+
+               /* move to the next parameter */
+               parm = parm + 1;
+       /**************************************************************************/
+       } /* for (i = 0; i < num_parms; i++) */
+
+       /* default the interface to paused state */
+       sngss7_set_flag(&sng_nif, SNGSS7_PAUSED);
+
+       /* fill in the nif interface */
+       ftmod_ss7_fill_in_nif_interface(&sng_nif);
+
+       return FTDM_SUCCESS;
+}
+/******************************************************************************/
+static int ftmod_ss7_fill_in_nif_interface(sng_nif_cfg_t *nif_iface)
+{
+       int     i = nif_iface->id;
+
+       strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].name, (char *)nif_iface->name, MAX_NAME_LEN-1);
+
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].id             = nif_iface->id;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].m2uaLnkNmb     = nif_iface->m2uaLnkNmb;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.nif[i].mtp2LnkNmb     = nif_iface->mtp2LnkNmb;
+
+       return 0;
+}
+
+/******************************************************************************/
+int ftmod_ss7_parse_m2ua_interfaces(ftdm_conf_node_t *m2ua_interfaces)
+{
+       ftdm_conf_node_t        *m2ua_interface = NULL;
+
+       /* confirm that we are looking at sng_m2ua_interfaces */
+       if (strcasecmp(m2ua_interfaces->name, "sng_m2ua_interfaces")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_nif_interfaces\"!\n",m2ua_interfaces->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"m2ua_interfaces\"...\n");
+       }
+
+       /* extract the isup_interfaces */
+       m2ua_interface = m2ua_interfaces->child;
+
+       while (m2ua_interface != NULL) {
+               /* parse the found mtp_route */
+               if (ftmod_ss7_parse_m2ua_interface(m2ua_interface)) {
+                       SS7_ERROR("Failed to parse \"m2ua_interface\"\n");
+                       return FTDM_FAIL;
+               }
+
+               /* go to the next m2ua_interface */
+               m2ua_interface = m2ua_interface->next;
+       }
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+static int ftmod_ss7_parse_m2ua_interface(ftdm_conf_node_t *m2ua_interface)
+{
+       sng_m2ua_cfg_t                  sng_m2ua;
+       ftdm_conf_parameter_t           *parm = m2ua_interface->parameters;
+       int                             num_parms = m2ua_interface->n_parameters;
+       int                             i;
+
+       /* initalize the m2ua intf */
+       memset(&sng_m2ua, 0x0, sizeof(sng_m2ua));
+
+       /* confirm that we are looking at an nif_interface */
+       if (strcasecmp(m2ua_interface->name, "sng_m2ua_interface")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_interface\"!\n",m2ua_interface->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"m2ua_interface\"...\n");
+       }
+
+
+       for (i = 0; i < num_parms; i++) {
+       /**************************************************************************/
+
+               /* try to match the parameter to what we expect */
+               if (!strcasecmp(parm->var, "name")) {
+               /**********************************************************************/
+                       strcpy((char *)sng_m2ua.name, parm->val);
+                       SS7_DEBUG("Found an m2ua_interface named = %s\n", sng_m2ua.name);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "id")) {
+               /**********************************************************************/
+                       sng_m2ua.id = atoi(parm->val);
+                       SS7_DEBUG("Found an m2ua id = %d\n", sng_m2ua.id);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "nodeType")) {
+                       /**********************************************************************/
+                       if(!strcasecmp(parm->val, "SGP")){
+                               sng_m2ua.nodeType = SNG_M2UA_NODE_TYPE_SGP;
+                       } else if(!strcasecmp(parm->val, "ASP")){
+                               SS7_ERROR(" NodeType = ASP Not Supported Yet \n");
+                               return FTDM_FAIL;
+                       } else {
+                               SS7_ERROR("Found an invalid NodeType Parameter Value[%s]\n", parm->val);
+                               return FTDM_FAIL;
+                       }
+                       SS7_DEBUG("Found an nif nodeType = %d\n", sng_m2ua.nodeType);
+                       /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "sctpId")) {
+               /**********************************************************************/
+                       sng_m2ua.sctpId=atoi(parm->val);
+
+                       SS7_DEBUG("Found an m2ua sctpId = %d\n", sng_m2ua.sctpId);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "peerdId")) {
+               /**********************************************************************/
+                       sng_m2ua.peerdId=atoi(parm->val);
+
+                       SS7_DEBUG("Found an m2ua peerdId = %d\n", sng_m2ua.peerdId);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "clusterId")) {
+               /**********************************************************************/
+                       sng_m2ua.clusterId=atoi(parm->val);
+
+                       SS7_DEBUG("Found an m2ua clusterId = %d\n", sng_m2ua.clusterId);
+               /**********************************************************************/
+               } else {
+               /**********************************************************************/
+                       SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
+                       return FTDM_FAIL;
+               /**********************************************************************/
+               }
+
+               /* move to the next parameter */
+               parm = parm + 1;
+       /**************************************************************************/
+       } /* for (i = 0; i < num_parms; i++) */
+
+       /* default the interface to paused state */
+       sngss7_set_flag(&sng_m2ua, SNGSS7_PAUSED);
+
+       /* fill in the nif interface */
+       ftmod_ss7_fill_in_m2ua_interface(&sng_m2ua);
+
+       return FTDM_SUCCESS;
+}
+/******************************************************************************/
+static int ftmod_ss7_fill_in_m2ua_interface(sng_m2ua_cfg_t *m2ua_iface)
+{
+       int     i = m2ua_iface->id;
+
+       strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].name, (char *)m2ua_iface->name, MAX_NAME_LEN-1);
+
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].id            = m2ua_iface->id;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].nodeType      = m2ua_iface->nodeType;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].sctpId        = m2ua_iface->sctpId;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].peerdId       = m2ua_iface->peerdId;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua[i].clusterId     = m2ua_iface->clusterId;
+
+       return 0;
+}
+
+/******************************************************************************/
+int ftmod_ss7_parse_m2ua_peer_interfaces(ftdm_conf_node_t *m2ua_peer_interfaces)
+{
+       ftdm_conf_node_t        *m2ua_peer_interface = NULL;
+
+       /* confirm that we are looking at m2ua_peer_interfaces */
+       if (strcasecmp(m2ua_peer_interfaces->name, "sng_m2ua_peer_interfaces")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interfaces\"!\n",m2ua_peer_interfaces->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"m2ua_peer_interfaces\"...\n");
+       }
+
+       /* extract the m2ua_peer_interfaces */
+       m2ua_peer_interface = m2ua_peer_interfaces->child;
+
+       while (m2ua_peer_interface != NULL) {
+               /* parse the found mtp_route */
+               if (ftmod_ss7_parse_m2ua_peer_interface(m2ua_peer_interface)) {
+                       SS7_ERROR("Failed to parse \"m2ua_peer_interface\"\n");
+                       return FTDM_FAIL;
+               }
+
+               /* go to the next m2ua_peer_interface */
+               m2ua_peer_interface = m2ua_peer_interface->next;
+       }
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+static int ftmod_ss7_parse_m2ua_peer_interface(ftdm_conf_node_t *m2ua_peer_interface)
+{
+       sng_m2ua_peer_cfg_t             sng_m2ua_peer;
+       ftdm_conf_parameter_t           *parm = m2ua_peer_interface->parameters;
+       int                             num_parms = m2ua_peer_interface->n_parameters;
+       int                             i;
+
+       /* initalize the m2ua intf */
+       memset(&sng_m2ua_peer, 0x0, sizeof(sng_m2ua_peer));
+
+       /* confirm that we are looking at an m2ua_peer_interface */
+       if (strcasecmp(m2ua_peer_interface->name, "sng_m2ua_peer_interface")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_peer_interface\"!\n",m2ua_peer_interface->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"m2ua_peer_interface\"...\n");
+       }
+
+
+       for (i = 0; i < num_parms; i++) {
+       /**************************************************************************/
+
+               /* try to match the parameter to what we expect */
+               if (!strcasecmp(parm->var, "name")) {
+               /**********************************************************************/
+                       strcpy((char *)sng_m2ua_peer.name, parm->val);
+                       SS7_DEBUG("Found an sng_m2ua_peer named = %s\n", sng_m2ua_peer.name);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "id")) {
+               /**********************************************************************/
+                       sng_m2ua_peer.id = atoi(parm->val);
+                       SS7_DEBUG("Found an sng_m2ua_peer id = %d\n", sng_m2ua_peer.id);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "aspIdFlag")) {
+                       /**********************************************************************/
+                       if(!strcasecmp(parm->val, "TRUE")){
+                               sng_m2ua_peer.aspIdFlag = 0x01;
+                       } else if(!strcasecmp(parm->val, "FALSE")){
+                               sng_m2ua_peer.aspIdFlag = 0x00;
+                       } else {
+                               SS7_ERROR("Found an invalid aspIdFlag Parameter Value[%s]\n", parm->val);
+                               return FTDM_FAIL;
+                       }
+                       SS7_DEBUG("Found an sng_m2ua_peer aspIdFlag = %d\n", sng_m2ua_peer.aspIdFlag);
+                       /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "selfAspId")) {
+               /**********************************************************************/
+                       sng_m2ua_peer.selfAspId=atoi(parm->val);
+
+                       SS7_DEBUG("Found an sng_m2ua_peer selfAspId = %d\n", sng_m2ua_peer.selfAspId);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "DestAddr")) {
+               /**********************************************************************/
+                       if (sng_m2ua_peer.numDestAddr < SCT_MAX_NET_ADDRS) {
+                                sng_m2ua_peer.destAddrList[sng_m2ua_peer.numDestAddr] = iptoul (parm->val);
+                                sng_m2ua_peer.numDestAddr++;
+                                SS7_DEBUG("sng_m2ua_peer - Parsing  with dest IP Address = %s\n", parm->val);
+                        } else {
+                                SS7_ERROR("sng_m2ua_peer - too many dest address configured. dropping %s \n", parm->val);
+                        }
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "locOutStrms")) {
+               /**********************************************************************/
+                       sng_m2ua_peer.locOutStrms=atoi(parm->val);
+
+                       SS7_DEBUG("Found an sng_m2ua_peer locOutStrms = %d\n", sng_m2ua_peer.locOutStrms);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "sctpId")) {
+               /**********************************************************************/
+                       sng_m2ua_peer.sctpId=atoi(parm->val);
+
+                       SS7_DEBUG("Found an sng_m2ua_peer sctpId = %d\n", sng_m2ua_peer.sctpId);
+               /**********************************************************************/
+               } else {
+               /**********************************************************************/
+                       SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
+                       return FTDM_FAIL;
+               /**********************************************************************/
+               }
+
+               /* move to the next parameter */
+               parm = parm + 1;
+       /**************************************************************************/
+       } /* for (i = 0; i < num_parms; i++) */
+
+       /* default the interface to paused state */
+       sngss7_set_flag(&sng_m2ua_peer, SNGSS7_PAUSED);
+
+       /* fill in the sng_m2ua_peer interface */
+       ftmod_ss7_fill_in_m2ua_peer_interface(&sng_m2ua_peer);
+
+       return FTDM_SUCCESS;
+}
+/******************************************************************************/
+static int ftmod_ss7_fill_in_m2ua_peer_interface(sng_m2ua_peer_cfg_t *m2ua_peer_iface)
+{
+       int     k = 0x00;
+       int     i = m2ua_peer_iface->id;
+
+       strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].name, (char *)m2ua_peer_iface->name, MAX_NAME_LEN-1);
+
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].id               = m2ua_peer_iface->id;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].aspIdFlag        = m2ua_peer_iface->aspIdFlag;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].selfAspId        = m2ua_peer_iface->selfAspId;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].locOutStrms      = m2ua_peer_iface->locOutStrms;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].numDestAddr      = m2ua_peer_iface->numDestAddr;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].sctpId           = m2ua_peer_iface->sctpId;
+       for (k=1; k<=m2ua_peer_iface->numDestAddr; k++) {
+               g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].destAddrList[k] = m2ua_peer_iface->destAddrList[k];      
+       }
+
+
+       return 0;
+}
+
+/******************************************************************************/
+int ftmod_ss7_parse_m2ua_clust_interfaces(ftdm_conf_node_t *m2ua_cluster_interfaces)
+{
+       ftdm_conf_node_t        *m2ua_cluster_interface = NULL;
+
+       /* confirm that we are looking at m2ua_cluster_interfaces */
+       if (strcasecmp(m2ua_cluster_interfaces->name, "sng_m2ua_cluster_interfaces")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interfaces\"!\n",m2ua_cluster_interfaces->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"m2ua_cluster_interfaces\"...\n");
+       }
+
+       /* extract the m2ua_cluster_interfaces */
+       m2ua_cluster_interface = m2ua_cluster_interfaces->child;
+
+       while (m2ua_cluster_interface != NULL) {
+               /* parse the found m2ua_cluster_interface */
+               if (ftmod_ss7_parse_m2ua_clust_interface(m2ua_cluster_interface)) {
+                       SS7_ERROR("Failed to parse \"m2ua_cluster_interface\"\n");
+                       return FTDM_FAIL;
+               }
+
+               /* go to the next m2ua_cluster_interface */
+               m2ua_cluster_interface = m2ua_cluster_interface->next;
+       }
+
+       return FTDM_SUCCESS;
+}
+
+/******************************************************************************/
+static int ftmod_ss7_parse_m2ua_clust_interface(ftdm_conf_node_t *m2ua_cluster_interface)
+{
+       sng_m2ua_cluster_cfg_t          sng_m2ua_cluster;
+       ftdm_conf_parameter_t           *parm = m2ua_cluster_interface->parameters;
+       int                             num_parms = m2ua_cluster_interface->n_parameters;
+       int                             i;
+
+       /* initalize the m2ua_cluster_interface */
+       memset(&sng_m2ua_cluster, 0x0, sizeof(sng_m2ua_cluster));
+
+       /* confirm that we are looking at an m2ua_cluster_interface */
+       if (strcasecmp(m2ua_cluster_interface->name, "sng_m2ua_cluster_interface")) {
+               SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"m2ua_cluster_interface\"!\n",m2ua_cluster_interface->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("Parsing \"m2ua_cluster_interface\"...\n");
+       }
+
+
+       for (i = 0; i < num_parms; i++) {
+       /**************************************************************************/
+
+               /* try to match the parameter to what we expect */
+               if (!strcasecmp(parm->var, "name")) {
+               /**********************************************************************/
+                       strcpy((char *)sng_m2ua_cluster.name, parm->val);
+                       SS7_DEBUG("Found an sng_m2ua_cluster named = %s\n", sng_m2ua_cluster.name);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "id")) {
+               /**********************************************************************/
+                       sng_m2ua_cluster.id = atoi(parm->val);
+                       SS7_DEBUG("Found an sng_m2ua_cluster id = %d\n", sng_m2ua_cluster.id);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "trfMode")) {
+                       /**********************************************************************/
+                       if(!strcasecmp(parm->val, "LOADSHARE")){
+                               sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_LOADSHARE;
+                       } else if(!strcasecmp(parm->val, "OVERRIDE")){
+                               sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_OVERRIDE;
+                       } else if(!strcasecmp(parm->val, "BROADCAST")){
+                               sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_BROADCAST;
+                       } else {
+                               SS7_ERROR("Found an invalid trfMode Parameter Value[%s]..adding default one[ANY]\n", parm->val);
+                               sng_m2ua_cluster.trfMode = SNG_M2UA_TRF_MODE_ANY;
+                       }
+                       SS7_DEBUG("Found an sng_m2ua_cluster.trfMode  = %d\n", sng_m2ua_cluster.trfMode);
+                       /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "loadShareAlgo")) {
+               /**********************************************************************/
+                       if(!strcasecmp(parm->val, "Round_Robin")){
+                               sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_RR;
+                       } else if(!strcasecmp(parm->val, "Link_Specified")){
+                               sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_LS;
+                       } else if(!strcasecmp(parm->val, "Customer_Specified")){
+                               sng_m2ua_cluster.loadShareAlgo = SNG_M2UA_LOAD_SHARE_ALGO_CS;
+                       } else {
+                               SS7_ERROR("Found an invalid loadShareAlgo Parameter Value[%s]\n", parm->val);
+                               return FTDM_FAIL;
+                       }
+
+                       SS7_DEBUG("Found an sng_m2ua_cluster.loadShareAlgo = %d\n", sng_m2ua_cluster.loadShareAlgo);
+               /**********************************************************************/
+               } else if (!strcasecmp(parm->var, "peerId")) {
+                       /**********************************************************************/
+                       if(sng_m2ua_cluster.numOfPeers < MW_MAX_NUM_OF_PEER) {
+                               sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers] = atoi(parm->val);
+                               sng_m2ua_cluster.numOfPeers++;
+                               SS7_DEBUG("Found an sng_m2ua_cluster peerId[%d], Total numOfPeers[%d] \n", 
+                                               sng_m2ua_cluster.peerIdLst[sng_m2ua_cluster.numOfPeers],
+                                               sng_m2ua_cluster.numOfPeers);
+                       }else{
+                               SS7_ERROR("Peer List excedding max[%d] limit \n", MW_MAX_NUM_OF_PEER);
+                               return FTDM_FAIL;
+                       }
+                       /**********************************************************************/
+               } else {
+               /**********************************************************************/
+                       SS7_ERROR("Found an invalid parameter %s!\n", parm->var);
+                       return FTDM_FAIL;
+               /**********************************************************************/
+               }
+
+               /* move to the next parameter */
+               parm = parm + 1;
+       /**************************************************************************/
+       } /* for (i = 0; i < num_parms; i++) */
+
+       /* default the interface to paused state */
+       sngss7_set_flag(&sng_m2ua_cluster, SNGSS7_PAUSED);
+
+       /* fill in the sng_m2ua_peer interface */
+       ftmod_ss7_fill_in_m2ua_clust_interface(&sng_m2ua_cluster);
+
+       return FTDM_SUCCESS;
+}
+/******************************************************************************/
+static int ftmod_ss7_fill_in_m2ua_clust_interface(sng_m2ua_cluster_cfg_t *m2ua_cluster_iface)
+{
+       int     k = 0x00;
+       int     i = m2ua_cluster_iface->id;
+
+       strncpy((char *)g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_peer[i].name, (char *)m2ua_cluster_iface->name, MAX_NAME_LEN-1);
+
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].id               = m2ua_cluster_iface->id;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].trfMode          = m2ua_cluster_iface->trfMode;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].loadShareAlgo    = m2ua_cluster_iface->loadShareAlgo;
+       g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].numOfPeers       = m2ua_cluster_iface->numOfPeers;
+       for(k=0;k<m2ua_cluster_iface->numOfPeers;k++){
+               g_ftdm_sngss7_data.cfg.g_m2ua_cfg.m2ua_clus[i].peerIdLst[k]     = m2ua_cluster_iface->peerIdLst[k];
+       }
+
+       return 0;
+}
+
+/******************************************************************************/
+ftdm_status_t ftmod_m3ua_parse_sctp_links(ftdm_conf_node_t *node)
+{
+       ftdm_conf_node_t        *node_sctp_link = NULL;
+
+       if (!node)
+               return FTDM_FAIL;
+
+       if (strcasecmp(node->name, "sng_sctp_interfaces")) {
+               SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at <sng_sctp_interfaces>!\n", node->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> configurations\n");
+       }
+
+       for (node_sctp_link = node->child; node_sctp_link != NULL; node_sctp_link = node_sctp_link->next) {
+               if (ftmod_m3ua_parse_sctp_link(node_sctp_link) != FTDM_SUCCESS) {
+                       SS7_ERROR("SCTP - Failed to parse <node_sctp_link>. \n");
+                       return FTDM_FAIL;
+               }
+       }
+
+       return FTDM_SUCCESS; 
+}
+
+/******************************************************************************/
+static ftdm_status_t ftmod_m3ua_parse_sctp_link(ftdm_conf_node_t *node)
+{
+       ftdm_conf_parameter_t   *param = NULL;
+       int                                     num_params = 0;
+       int                                     i=0;
+
+       if (!node)
+               return FTDM_FAIL;
+
+       param = node->parameters;
+       num_params = node->n_parameters;
+       
+       sng_sctp_link_t         t_link;
+       memset (&t_link, 0, sizeof(sng_sctp_link_t));
+       
+       if (strcasecmp(node->name, "sng_sctp_interface")) {
+               SS7_ERROR("SCTP - We're looking at <%s>...but we're supposed to be looking at <sng_sctp_interface>!\n", node->name);
+               return FTDM_FAIL;
+       } else {
+               SS7_DEBUG("SCTP - Parsing <sng_sctp_interface> configurations\n");
+       }
+
+       for (i=0; i<num_params; i++, param++) {
+               if (!strcasecmp(param->var, "name")) {
+                       int n_strlen = strlen(param->val);
+                       strncpy((char*)t_link.name, param->val, (n_strlen>MAX_NAME_LEN)?MAX_NAME_LEN:n_strlen);
+                       SS7_DEBUG("SCTP - Parsing <sctp_link> with name = %s\n", param->val);
+               }
+               else if (!strcasecmp(param->var, "id")) {
+                       t_link.id = atoi(param->val);
+                       SS7_DEBUG("SCTP - Parsing <sctp_link> with id = %s\n", param->val);
+               }
+               else if (!strcasecmp(param->var, "srcAddr")) {
+                       if (t_link.numSrcAddr < SCT_MAX_NET_ADDRS) {
+                               t_link.srcAddrList[t_link.numSrcAddr+1] = iptoul (param->val);
+                               t_link.numSrcAddr++;
+                               SS7_DEBUG("SCTP - Parsing <sctp_link> with source IP Address = %s\n", param->val);
+                       } else {
+                               SS7_ERROR("SCTP - too many source address configured. dropping %s \n", param->val);
+                       }
+               }
+               else {
+                       SS7_ERROR("SCTP - Found an unknown parameter <%s>. Skipping it.\n", param->var);
+               }
+       }
+       
+       g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].id            = t_link.id;
+       g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].tuclId        = t_link.id;
+       strncpy((char*)g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].name, t_link.name, strlen(t_link.name) );
+       g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].flags         = 0;
+       g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].numSrcAddr = t_link.numSrcAddr;
+       for (i=1; i<=t_link.numSrcAddr; i++) {
+               g_ftdm_sngss7_data.cfg.sctpCfg.linkCfg[t_link.id].srcAddrList[i] = t_link.srcAddrList[i];
+       }
+                       
+       return FTDM_SUCCESS;
+}
+/******************************************************************************/
index 10981268905afce795045b35d5f90348e8d5096a..3c71b6741132f5d59b44f1669d513f5d1600530d 100644 (file)
@@ -50,6 +50,7 @@
 static sng_isup_event_interface_t sng_event;
 static ftdm_io_interface_t g_ftdm_sngss7_interface;
 ftdm_sngss7_data_t g_ftdm_sngss7_data;
+ftdm_sngss7_opr_mode g_ftdm_operating_mode;
 
 /******************************************************************************/
 
@@ -355,6 +356,15 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
        /* set IN_THREAD flag so that we know this thread is running */
        ftdm_set_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 
+       if(SNG_SS7_OPR_MODE_M2UA_SG == g_ftdm_operating_mode){
+               ftdm_log (FTDM_LOG_INFO, "FreeTDM running as M2UA_SG mode, freetdm dont have to do anything \n"); 
+
+               while (ftdm_running () && !(ftdm_test_flag (ftdmspan, FTDM_SPAN_STOP_THREAD))) {
+                       continue;
+               }
+               goto ftdm_sangoma_ss7_stop;
+       }
+
        /* get an interrupt queue for this span for channel state changes */
        if (ftdm_queue_get_interrupt (ftdmspan->pendingchans, &ftdm_sangoma_ss7_int[0]) != FTDM_SUCCESS) {
                SS7_CRITICAL ("Failed to get a ftdm_interrupt for span = %d for channel state changes!\n", ftdmspan->span_id);
@@ -497,10 +507,12 @@ static void *ftdm_sangoma_ss7_run(ftdm_thread_t * me, void *obj)
                /**********************************************************************/
                }
        }
+ftdm_sangoma_ss7_stop:
 
        /* clear the IN_THREAD flag so that we know the thread is done */
        ftdm_clear_flag (ftdmspan, FTDM_SPAN_IN_THREAD);
 
+
        ftdm_log (FTDM_LOG_INFO,"ftmod_sangoma_ss7 monitor thread for span=%u stopping.\n",ftdmspan->span_id);
 
        return NULL;
@@ -2496,6 +2508,8 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
        /* set the flag to indicate that this span uses sig event queues */
        ftdm_set_flag (span, FTDM_SPAN_USE_SIGNALS_QUEUE);
 
+
+
        /* parse the configuration and apply to the global config structure */
        if (ftmod_ss7_parse_xml(ftdm_parameters, span)) {
                ftdm_log (FTDM_LOG_CRIT, "Failed to parse configuration!\n");
@@ -2503,8 +2517,7 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_sangoma_ss7_span_config)
                return FTDM_FAIL;
        }
 
-       /* configure libsngss7 */
-       if (ft_to_sngss7_cfg_all()) {
+       if (ft_to_sngss7_cfg_all()) {   /* configure libsngss7 */
                ftdm_log (FTDM_LOG_CRIT, "Failed to configure LibSngSS7!\n");
                ftdm_sleep (100);
                return FTDM_FAIL;
@@ -2566,6 +2579,10 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init)
        sng_event.sm.sng_isup_alarm = handle_sng_isup_alarm;
        sng_event.sm.sng_cc_alarm = handle_sng_cc_alarm;
        sng_event.sm.sng_relay_alarm = handle_sng_relay_alarm;
+       sng_event.sm.sng_m2ua_alarm = handle_sng_m2ua_alarm;
+       sng_event.sm.sng_nif_alarm  = handle_sng_nif_alarm;
+       sng_event.sm.sng_tucl_alarm = handle_sng_tucl_alarm;
+       sng_event.sm.sng_sctp_alarm = handle_sng_sctp_alarm;
 
        /* initalize sng_ss7 library */
        sng_isup_init_gen(&sng_event);
index 4ccf4efe0e7ce94b35790bc33025e797947643c1..fc6a6e61b5e252282ba3b861df69d02b7e3b8eab 100644 (file)
@@ -52,6 +52,7 @@
 #include "private/ftdm_core.h"
 
 #include "sng_ss7/sng_ss7.h"
+#include "ftmod_sangoma_ss7_m2ua.h"
 
 /******************************************************************************/
 
@@ -60,6 +61,7 @@
 
 #define MAX_CIC_LENGTH                 5
 #define MAX_CIC_MAP_LENGTH             1000 
+#define MAX_SCTP_LINK                  100
 
 #define SNGSS7_EVENT_QUEUE_SIZE        100
 #define SNGSS7_PEER_CHANS_QUEUE_SIZE 100
@@ -449,6 +451,29 @@ typedef struct sng_relay {
        uint32_t                procId;
 } sng_relay_t;
 
+/**********************************************
+sctp structures and data definitions
+**********************************************/
+
+typedef struct sng_sctp_gen_cfg {
+} sng_sctp_gen_cfg_t;
+
+typedef struct sng_sctp_link {
+       char            name[MAX_NAME_LEN];
+       uint32_t        flags;
+       uint32_t        id;
+       uint32_t        tuclId;
+       uint32_t        numSrcAddr;
+       uint32_t        srcAddrList[SCT_MAX_NET_ADDRS+1];       
+} sng_sctp_link_t;
+
+typedef struct sng_sctp_cfg {
+       sng_sctp_gen_cfg_t      genCfg;
+       sng_sctp_link_t         linkCfg[MAX_SCTP_LINK+1];
+} sng_sctp_cfg_t;
+
+
+
 typedef struct sng_ss7_cfg {
        uint32_t                        spc;
        uint32_t                        procId;
@@ -468,6 +493,8 @@ typedef struct sng_ss7_cfg {
        sng_isap_t                      isap[MAX_ISAPS+1];      
        sng_glare_resolution    glareResolution;
        uint32_t                                force_inr;
+       sng_m2ua_gbl_cfg_t      g_m2ua_cfg;
+       sng_sctp_cfg_t          sctpCfg;
 } sng_ss7_cfg_t;
 
 typedef struct ftdm_sngss7_data {
@@ -480,6 +507,14 @@ typedef struct ftdm_sngss7_data {
        fio_signal_cb_t         sig_cb;
 } ftdm_sngss7_data_t;
 
+typedef enum{
+       SNG_SS7_OPR_MODE_NONE,
+       SNG_SS7_OPR_MODE_M2UA_SG,
+       SNG_SS7_OPR_MODE_ISUP,
+}ftdm_sngss7_operating_modes_e;
+
+typedef ftdm_sngss7_operating_modes_e ftdm_sngss7_opr_mode;
+
 typedef struct sngss7_timer_data {
        ftdm_timer_id_t                 hb_timer_id;
        int                                             beat;
@@ -728,6 +763,7 @@ typedef enum {
 
 /* GLOBALS ********************************************************************/
 extern ftdm_sngss7_data_t              g_ftdm_sngss7_data;
+extern ftdm_sngss7_opr_mode            g_ftdm_operating_mode;
 extern sng_ssf_type_t                  sng_ssf_type_map[];
 extern sng_switch_type_t               sng_switch_type_map[];
 extern sng_link_type_t                 sng_link_type_map[];
@@ -750,6 +786,10 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta);
 void handle_sng_isup_alarm(Pst *pst, SiMngmt *sta);
 void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta);
 void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta);
+void handle_sng_m2ua_alarm(Pst *pst, MwMgmt *sta);
+void handle_sng_nif_alarm(Pst *pst, NwMgmt *sta);
+void handle_sng_tucl_alarm(Pst *pst, HiMngmt *sta);
+void handle_sng_sctp_alarm(Pst *pst, SbMgmt *sta);
 
 /* in ftmod_sangoma_ss7_relay.c */
 ftdm_status_t handle_relay_connect(RyMngmt *sta);
@@ -974,6 +1014,7 @@ void handle_isup_t35(void *userdata);
 void handle_isup_t10(void *userdata);
 void handle_isup_t39(void *userdata);
 
+
 /******************************************************************************/
 
 /* MACROS *********************************************************************/
index f64356dd1f262c8158f90b5c0da8d3cb501cd3e7..32ebdc52b93ed8f96013fe090b3103cd85770ee0 100644 (file)
@@ -220,11 +220,32 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
        /* clean out the self route */
        memset(&self_route, 0x0, sizeof(self_route));
 
+       var = ftdm_parameters[i].var;
+       val = ftdm_parameters[i].val;
+
+       printf("var[%s], val[%s]\n",var,val);
+       /* confirm that the first parameter is the "operatingMode" */
+       if(!strcasecmp(var, "operatingMode")){
+               /**********************************************************************/
+               if(!strcasecmp(val, "ISUP")) {
+                       g_ftdm_operating_mode = SNG_SS7_OPR_MODE_ISUP;
+               }
+               else if(!strcasecmp(val, "M2UA_SG")) {
+                       g_ftdm_operating_mode = SNG_SS7_OPR_MODE_M2UA_SG;
+               } else {
+                       SS7_ERROR("Invalid operating Mode[%s] \n", val);
+                       return FTDM_FAIL;
+               }
+               /**********************************************************************/
+       }
+
+       i++;
+
        var = ftdm_parameters[i].var;
        val = ftdm_parameters[i].val;
        ptr = (ftdm_conf_node_t *)ftdm_parameters[i].ptr;
 
-       /* confirm that the first parameter is the "confnode" */
+       /* confirm that the 2nd parameter is the "confnode" */
        if (!strcasecmp(var, "confnode")) {
                /* parse the confnode and fill in the global libsng_ss7 config structure */
                if (ftmod_ss7_parse_sng_isup(ptr)) {
@@ -239,6 +260,7 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
        }
 
        i++;
+
        while (ftdm_parameters[i].var != NULL) {
        /**************************************************************************/
 
@@ -269,10 +291,12 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa
        /* fill the pointer to span into isupCkt */
        sngSpan.span = span;
 
-       /* setup the circuits structure */
-       if(ftmod_ss7_fill_in_circuits(&sngSpan)) {
-               SS7_ERROR("Failed to fill in circuits structure!\n");
-               goto ftmod_ss7_parse_xml_error;
+       if(SNG_SS7_OPR_MODE_ISUP == g_ftdm_operating_mode){
+               /* setup the circuits structure */
+               if(ftmod_ss7_fill_in_circuits(&sngSpan)) {
+                       SS7_ERROR("Failed to fill in circuits structure!\n");
+                       goto ftmod_ss7_parse_xml_error;
+               }
        }
 
        return FTDM_SUCCESS;
@@ -294,6 +318,11 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
        ftdm_conf_node_t        *isup_interfaces = NULL;
        ftdm_conf_node_t        *cc_spans = NULL;
        ftdm_conf_node_t        *tmp_node = NULL;
+       ftdm_conf_node_t        *nif_ifaces = NULL;
+       ftdm_conf_node_t        *m2ua_ifaces = NULL;
+       ftdm_conf_node_t        *m2ua_peer_ifaces = NULL;
+       ftdm_conf_node_t        *m2ua_clust_ifaces = NULL;
+       ftdm_conf_node_t        *sctp_ifaces = NULL;
 
        /* confirm that we are looking at sng_isup */
        if (strcasecmp(sng_isup->name, "sng_isup")) {
@@ -399,12 +428,62 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
                                return FTDM_FAIL;
                        }
                /**********************************************************************/
+               } else if (!strcasecmp(tmp_node->name, "sng_nif_interfaces")) {
+               /**********************************************************************/
+                       if (nif_ifaces == NULL) {
+                               nif_ifaces = tmp_node;
+                               SS7_DEBUG("Found a \"sng_nif_interfaces\" section!\n");
+                       } else {
+                               SS7_ERROR("Found a second \"sng_nif_interfaces\" section\n!");
+                               return FTDM_FAIL;
+                       }
+               /**********************************************************************/
+               } else if (!strcasecmp(tmp_node->name, "sng_m2ua_interfaces")) {
+               /**********************************************************************/
+                       if (m2ua_ifaces == NULL) {
+                               m2ua_ifaces = tmp_node;
+                               SS7_DEBUG("Found a \"sng_m2ua_interfaces\" section!\n");
+                       } else {
+                               SS7_ERROR("Found a second \"sng_m2ua_interfaces\" section\n!");
+                               return FTDM_FAIL;
+                       }
+               /**********************************************************************/
+               } else if (!strcasecmp(tmp_node->name, "sng_m2ua_peer_interfaces")) {
+               /**********************************************************************/
+                       if (m2ua_peer_ifaces == NULL) {
+                               m2ua_peer_ifaces = tmp_node;
+                               SS7_DEBUG("Found a \"sng_m2ua_peer_interfaces\" section!\n");
+                       } else {
+                               SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!");
+                               return FTDM_FAIL;
+                       }
+               /**********************************************************************/
+               } else if (!strcasecmp(tmp_node->name, "sng_m2ua_cluster_interfaces")) {
+               /**********************************************************************/
+                       if (m2ua_clust_ifaces == NULL) {
+                               m2ua_clust_ifaces = tmp_node;
+                               SS7_DEBUG("Found a \"sng_m2ua_cluster_interfaces\" section!\n");
+                       } else {
+                               SS7_ERROR("Found a second \"sng_m2ua_peer_interfaces\" section\n!");
+                               return FTDM_FAIL;
+                       }
+               /**********************************************************************/
+               } else if (!strcasecmp(tmp_node->name, "sng_sctp_interfaces")) {
+               /**********************************************************************/
+                       if (sctp_ifaces == NULL) {
+                               sctp_ifaces = tmp_node;
+                               SS7_DEBUG("Found a <sng_sctp_interfaces> section!\n");
+                       } else {
+                               SS7_ERROR("Found a second <sng_sctp_interfaces> section!\n");
+                               return FTDM_FAIL;
+                       }
+               /**********************************************************************/
                } else {
                /**********************************************************************/
                        SS7_ERROR("\tFound an unknown section \"%s\"!\n", tmp_node->name);
                        return FTDM_FAIL;
                /**********************************************************************/
-               } 
+               }
 
                /* go to the next sibling */
                tmp_node = tmp_node->next;
@@ -431,11 +510,6 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
                return FTDM_FAIL;
        }
 
-       if (ftmod_ss7_parse_mtp3_links(mtp3_links)) {
-               SS7_ERROR("Failed to parse \"mtp3_links\"!\n");
-               return FTDM_FAIL;
-       }
-
        if (ftmod_ss7_parse_mtp_linksets(mtp_linksets)) {
                SS7_ERROR("Failed to parse \"mtp_linksets\"!\n");
                return FTDM_FAIL;
@@ -446,14 +520,57 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup)
                return FTDM_FAIL;
        }
 
-       if (ftmod_ss7_parse_isup_interfaces(isup_interfaces)) {
-               SS7_ERROR("Failed to parse \"isup_interfaces\"!\n");
-               return FTDM_FAIL;
-       }
+       switch(g_ftdm_operating_mode)
+       {
+               case SNG_SS7_OPR_MODE_ISUP:
+                       {
+                               if (mtp3_links && ftmod_ss7_parse_mtp3_links(mtp3_links)) {
+                                       SS7_ERROR("Failed to parse \"mtp3_links\"!\n");
+                                       return FTDM_FAIL;
+                               }
+
+                               if (isup_interfaces && ftmod_ss7_parse_isup_interfaces(isup_interfaces)) {
+                                       SS7_ERROR("Failed to parse \"isup_interfaces\"!\n");
+                                       return FTDM_FAIL;
+                               }
+
+                               if (cc_spans && ftmod_ss7_parse_cc_spans(cc_spans)) {
+                                       SS7_ERROR("Failed to parse \"cc_spans\"!\n");
+                                       return FTDM_FAIL;
+                               }
+                               break;
+                       }
+               case SNG_SS7_OPR_MODE_M2UA_SG: 
+                       {
+                               if (ftmod_m3ua_parse_sctp_links(sctp_ifaces) != FTDM_SUCCESS) {
+                                       SS7_ERROR("Failed to parse <sctp_links>!\n");
+                                       return FTDM_FAIL;
+                               }
+                               SS7_INFO("Finished ftmod_m3ua_parse_sctp_links!\n");
+
+                               if (nif_ifaces && ftmod_ss7_parse_nif_interfaces(nif_ifaces)) {
+                                       SS7_ERROR("Failed to parse \"nif_ifaces\"!\n");
+                                       return FTDM_FAIL;
+                               }
+
+                               if (m2ua_ifaces && ftmod_ss7_parse_m2ua_interfaces(m2ua_ifaces)) {
+                                       SS7_ERROR("Failed to parse \"m2ua_ifaces\"!\n");
+                                       return FTDM_FAIL;
+                               }
+                               if (m2ua_peer_ifaces && ftmod_ss7_parse_m2ua_peer_interfaces(m2ua_peer_ifaces)) {
+                                       SS7_ERROR("Failed to parse \"m2ua_peer_ifaces\"!\n");
+                                       return FTDM_FAIL;
+                               }
+                               if (m2ua_clust_ifaces && ftmod_ss7_parse_m2ua_clust_interfaces(m2ua_clust_ifaces)) {
+                                       SS7_ERROR("Failed to parse \"m2ua_clust_ifaces\"!\n");
+                                       return FTDM_FAIL;
+                               }
+                               break;
+                       }
+               default:
+                       SS7_ERROR("Invalid operating mode[%d]\n",g_ftdm_operating_mode);
+                       break;
 
-       if (ftmod_ss7_parse_cc_spans(cc_spans)) {
-               SS7_ERROR("Failed to parse \"cc_spans\"!\n");
-               return FTDM_FAIL;
        }
 
        return FTDM_SUCCESS;