diff --git a/.gitignore b/.gitignore index 304b42c1f9..c53d07d8a9 100644 --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,12 @@ *.ilk *.bsc *.pch +*.tar +*.gz +*.tgz +*.xz +*.bz2 +*.tbz2 core.* /Path /w32/Library/lastversion @@ -79,7 +85,6 @@ configure.lineno /scripts/fsxs /scripts/gentls_cert /a.out.dSYM -/freeswitch-sounds-* src/mod/applications/mod_easyroute/Makefile src/mod/applications/mod_lcr/Makefile src/mod/applications/mod_nibblebill/Makefile diff --git a/Makefile.am b/Makefile.am index 8d35068c35..37a01d27fb 100644 --- a/Makefile.am +++ b/Makefile.am @@ -349,7 +349,7 @@ scripts/fsxs: scripts/fsxs.in -e "s|@INCLUDES\@|-I$(prefix)/include|" \ -e "s|@SOLINK\@|$(SOLINK)|" \ -e "s|@LDFLAGS\@|-L$(prefix)/lib|" \ - -e "s|@LIBS\@|`./libs/apr/apr-1-config --libs` `./libs/apr-util/apu-1-config --libs`|" \ + -e "s|@LIBS\@||" \ $(top_srcdir)/scripts/fsxs.in > scripts/fsxs ## diff --git a/build/modules.conf.in b/build/modules.conf.in index 2be000f6b3..84a9e9a74d 100644 --- a/build/modules.conf.in +++ b/build/modules.conf.in @@ -78,6 +78,7 @@ event_handlers/mod_cdr_sqlite #event_handlers/mod_cdr_pg_csv #event_handlers/mod_radius_cdr #event_handlers/mod_erlang_event +#event_handlers/mod_snmp formats/mod_native_file formats/mod_sndfile #formats/mod_shout diff --git a/conf/autoload_configs/easyroute.conf.xml b/conf/autoload_configs/easyroute.conf.xml index 7cd490942f..350a50989b 100644 --- a/conf/autoload_configs/easyroute.conf.xml +++ b/conf/autoload_configs/easyroute.conf.xml @@ -11,6 +11,9 @@ + + + + diff --git a/libs/freetdm/Makefile.am b/libs/freetdm/Makefile.am index 96f1c9a10f..b3353f32de 100644 --- a/libs/freetdm/Makefile.am +++ b/libs/freetdm/Makefile.am @@ -240,7 +240,8 @@ ftmod_sangoma_ss7_la_SOURCES = \ $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c \ $(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_logger.c \ + $(SRC)/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c ftmod_sangoma_ss7_la_CFLAGS = $(AM_CFLAGS) $(FTDM_CFLAGS) -D_GNU_SOURCE ftmod_sangoma_ss7_la_LDFLAGS = -shared -module -avoid-version -lsng_ss7 diff --git a/libs/freetdm/TODO b/libs/freetdm/TODO index 6b8ef8f826..6b4cf71f5f 100644 --- a/libs/freetdm/TODO +++ b/libs/freetdm/TODO @@ -11,3 +11,12 @@ cannot be shown to end users, we already provide extensive logging for problem troubleshooting. +- Implement threaded IO. + Currently IO modules only work on-demand, where the user (ie, FreeSWITCH) drives the read/write + of media. If the user stops reading, some functions are not possible + (DTMF detection or Hangup tone detection). It would be useful to implement a FreeTDM mode + where the media is driven by a group of threads that are always reading (and possibly writing) + then when the user does ftdm_channel_read(), the media would be read from the buffers filled + by the media thread and not from the underlying IO device, this gives a chance to FreeTDM to + still perform hangup detection or other media services even if the application is not reading. + diff --git a/libs/freetdm/configure.ac b/libs/freetdm/configure.ac index a070e994a3..1f4fc9c6ac 100644 --- a/libs/freetdm/configure.ac +++ b/libs/freetdm/configure.ac @@ -267,7 +267,7 @@ fi # HAVE_SNG_SS7="no" AC_MSG_RESULT([${as_nl}<<>> Sangoma SS7 stack]) -AC_CHECK_LIB([sng_ss7], [sng_isup_init], [HAVE_SNG_SS7="yes"]) +AC_CHECK_LIB([sng_ss7], [sng_isup_init_gen], [HAVE_SNG_SS7="yes"]) AC_MSG_RESULT([checking whether to build ftmod_sangoma_ss7... ${HAVE_SNG_SS7}]) AM_CONDITIONAL([HAVE_SNG_SS7], [test "${HAVE_SNG_SS7}" = "yes"]) diff --git a/libs/freetdm/mod_freetdm/mod_freetdm.c b/libs/freetdm/mod_freetdm/mod_freetdm.c index 970cb5b993..92cf9e54b9 100755 --- a/libs/freetdm/mod_freetdm/mod_freetdm.c +++ b/libs/freetdm/mod_freetdm/mod_freetdm.c @@ -2360,8 +2360,9 @@ static int add_config_list_nodes(switch_xml_t swnode, ftdm_conf_node_t *rootnode static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confname) { - switch_xml_t signode, ss7configs, isup; - ftdm_conf_node_t *rootnode; + switch_xml_t signode, ss7configs, isup, gen, param; + ftdm_conf_node_t *rootnode, *list; + char *var, *val; /* try to find the conf in the hash first */ rootnode = switch_core_hash_find(globals.ss7_configs, confname); @@ -2405,15 +2406,63 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn return NULL; } + /* add sng_gen */ + gen = switch_xml_child(isup, "sng_gen"); + if (gen == NULL) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_gen for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + if ((FTDM_SUCCESS != ftdm_conf_node_create("sng_gen", &list, rootnode))) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to create %s node for %s\n", "sng_gen", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + for (param = switch_xml_child(gen, "param"); param; param = param->next) { + var = (char *) switch_xml_attr_soft(param, "name"); + val = (char *) switch_xml_attr_soft(param, "value"); + ftdm_conf_node_add_param(list, var, val); + } + + /* add relay channels */ + if (add_config_list_nodes(isup, rootnode, "sng_relay", "relay_channel", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process sng_relay for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + /* add mtp1 links */ + if (add_config_list_nodes(isup, rootnode, "mtp1_links", "mtp1_link", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp1_links for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + return NULL; + } + + /* add mtp2 links */ + if (add_config_list_nodes(isup, rootnode, "mtp2_links", "mtp2_link", NULL, NULL)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp2_links for sng_isup config %s\n", confname); + ftdm_conf_node_destroy(rootnode); + 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; + } + /* add mtp linksets */ - if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", "mtp_links", "mtp_link")) { + if (add_config_list_nodes(isup, rootnode, "mtp_linksets", "mtp_linkset", NULL, NULL)) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_linksets for sng_isup config %s\n", confname); ftdm_conf_node_destroy(rootnode); return NULL; } /* add mtp routes */ - if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", NULL, NULL)) { + if (add_config_list_nodes(isup, rootnode, "mtp_routes", "mtp_route", "linksets", "linkset")) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "failed to process mtp_routes for sng_isup config %s\n", confname); ftdm_conf_node_destroy(rootnode); return NULL; @@ -2426,6 +2475,13 @@ static ftdm_conf_node_t *get_ss7_config_node(switch_xml_t cfg, const char *confn 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); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Added SS7 node configuration %s\n", confname); diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj b/libs/freetdm/msvc/freetdm.2010.vcxproj index 71eb6dbf22..aecb9ef79c 100644 --- a/libs/freetdm/msvc/freetdm.2010.vcxproj +++ b/libs/freetdm/msvc/freetdm.2010.vcxproj @@ -188,6 +188,7 @@ + @@ -209,6 +210,7 @@ + diff --git a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters index ed642baf3d..e6dc40d372 100644 --- a/libs/freetdm/msvc/freetdm.2010.vcxproj.filters +++ b/libs/freetdm/msvc/freetdm.2010.vcxproj.filters @@ -71,6 +71,9 @@ Header Files + + Header Files + @@ -124,5 +127,8 @@ Source Files + + Source Files + \ No newline at end of file diff --git a/libs/freetdm/src/ftdm_io.c b/libs/freetdm/src/ftdm_io.c index 529a30f120..0f92f59053 100644 --- a/libs/freetdm/src/ftdm_io.c +++ b/libs/freetdm/src/ftdm_io.c @@ -37,6 +37,9 @@ * */ +#ifdef MOYTEST +crap +#endif #define _GNU_SOURCE #include "private/ftdm_core.h" #include diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c index e7053c1d43..df528ae9c1 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.c @@ -676,6 +676,9 @@ static ftdm_status_t ftdm_sangoma_isdn_process_state_change(ftdm_channel_t *ftdm /*OUTBOUND...so we were told by the line of this so noifiy the user*/ sigev.event_id = FTDM_SIGEVENT_PROCEED; ftdm_span_send_signal(ftdmchan->span, &sigev); + if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { + ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); + } } else { if (!sngisdn_test_flag(sngisdn_info, FLAG_SENT_PROCEED)) { /* By default, we do not send a progress indicator in the proceed */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h index 58fcc07040..80dc73f0fa 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn.h @@ -112,6 +112,11 @@ typedef enum { SNGISDN_OPT_FALSE = 2, } sngisdn_opt_t; +typedef enum { + SNGISDN_EARLY_MEDIA_ON_PROCEED = (1 << 0), + SNGISDN_EARLY_MEDIA_ON_PROGRESS = (1 << 1), + SNGISDN_EARLY_MEDIA_ON_ALERT= (1 << 2), +} sngisdn_early_media_opt_t; typedef enum { SNGISDN_AVAIL_DOWN = 1, @@ -188,7 +193,8 @@ typedef struct sngisdn_span_data { uint8_t span_id; uint8_t tei; uint8_t min_digits; - uint8_t trace_flags; /* TODO: change to flags, so we can use ftdm_test_flag etc.. */ + uint8_t trace_flags; /* TODO change to bit map of sngisdn_tracetype_t */ + uint8_t early_media_flags; /* bit map of ftdm_sngisdn_early_media_opt_t */ uint8_t overlap_dial; uint8_t setup_arb; uint8_t facility_ie_decode; @@ -196,10 +202,10 @@ typedef struct sngisdn_span_data { int8_t facility_timeout; uint8_t num_local_numbers; uint8_t ignore_cause_value; - uint8_t raw_trace_q931; - uint8_t raw_trace_q921; + uint8_t raw_trace_q931; /* TODO: combine with trace_flags */ + uint8_t raw_trace_q921; /* TODO: combine with trace_flags */ uint8_t timer_t3; - uint8_t restart_opt; + uint8_t restart_opt; char* local_numbers[SNGISDN_NUM_LOCAL_NUMBERS]; ftdm_sched_t *sched; ftdm_queue_t *event_queue; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c index aad68e15d1..bd5b13bfec 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_cfg.c @@ -192,6 +192,24 @@ static ftdm_status_t parse_signalling(const char* signalling, ftdm_span_t *span) return FTDM_SUCCESS; } +static ftdm_status_t parse_early_media(const char* opt, ftdm_span_t *span) +{ + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; + if (!strcasecmp(opt, "on-proceed")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROCEED; + } else if (!strcasecmp(opt, "on-progress")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_PROGRESS; + } else if (!strcasecmp(opt, "on-alert")) { + signal_data->early_media_flags |= SNGISDN_EARLY_MEDIA_ON_ALERT; + } else { + ftdm_log(FTDM_LOG_ERROR, "Unsupported early-media option %s\n", opt); + return FTDM_FAIL; + } + ftdm_log(FTDM_LOG_DEBUG, "Early media opt:0x%x\n", signal_data->early_media_flags); + return FTDM_SUCCESS; +} + + static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) { sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) span->signal_data; @@ -249,6 +267,7 @@ static ftdm_status_t set_switchtype_defaults(ftdm_span_t *span) return FTDM_SUCCESS; } + ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) { unsigned paramindex; @@ -351,10 +370,14 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ parse_yesno(var, val, &signal_data->raw_trace_q931); } else if (!strcasecmp(var, "q921-raw-trace")) { parse_yesno(var, val, &signal_data->raw_trace_q921); + } else if (!strcasecmp(var, "early-media-override")) { + if (parse_early_media(val, span) != FTDM_SUCCESS) { + return FTDM_FAIL; + } } else { ftdm_log(FTDM_LOG_WARNING, "Ignoring unknown parameter %s\n", ftdm_parameters[paramindex].var); } - } + } /* for (paramindex = 0; ftdm_parameters[paramindex].var; paramindex++) */ if (signal_data->switchtype == SNGISDN_SWITCH_INVALID) { ftdm_log(FTDM_LOG_ERROR, "%s: switchtype not specified", span->name); @@ -366,10 +389,11 @@ ftdm_status_t ftmod_isdn_parse_cfg(ftdm_conf_parameter_t *ftdm_parameters, ftdm_ } if (span->default_caller_data.bearer_layer1 == FTDM_INVALID_INT_PARM) { - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) { - span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; - } else { + if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN || + signal_data->switchtype == SNGISDN_SWITCH_QSIG) { span->default_caller_data.bearer_layer1 = IN_UIL1_G711ALAW; + } else { + span->default_caller_data.bearer_layer1 = IN_UIL1_G711ULAW; } } return FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c index 7b7c748c7a..0b52011d42 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_stack_hndl.c @@ -167,12 +167,12 @@ void sngisdn_process_con_ind (sngisdn_event_data_t *sngisdn_event) char retrieved_str[255]; ret_val = sng_isdn_retrieve_facility_caller_name(conEvnt->facilityStr.facilityStr.val, conEvnt->facilityStr.facilityStr.len, retrieved_str); - /* - return values for "sng_isdn_retrieve_facility_information_following": - If there will be no information following, or fails to decode IE, returns -1 - If there will be no information following, but current FACILITY IE contains a caller name, returns 0 - If there will be information following, returns 1 - */ + /* + return values for "sng_isdn_retrieve_facility_information_following": + If there will be no information following, or fails to decode IE, returns -1 + If there will be no information following, but current FACILITY IE contains a caller name, returns 0 + If there will be information following, returns 1 + */ if (ret_val == 1) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Expecting Caller name in FACILITY\n"); @@ -346,6 +346,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) sngisdn_chan_data_t *sngisdn_info = sngisdn_event->sngisdn_info; ftdm_channel_t *ftdmchan = sngisdn_info->ftdmchan; + sngisdn_span_data_t *signal_data = (sngisdn_span_data_t*) ftdmchan->span->signal_data; CnStEvnt *cnStEvnt = &sngisdn_event->event.cnStEvnt; @@ -384,7 +385,7 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) case FTDM_CHANNEL_STATE_DIALING: case FTDM_CHANNEL_STATE_PROCEED: case FTDM_CHANNEL_STATE_PROGRESS: - case FTDM_CHANNEL_STATE_RINGING: + case FTDM_CHANNEL_STATE_RINGING: if (cnStEvnt->progInd.eh.pres && cnStEvnt->progInd.progDesc.val == IN_PD_IBAVAIL) { ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media available\n"); sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); @@ -393,16 +394,34 @@ void sngisdn_process_cnst_ind (sngisdn_event_data_t *sngisdn_event) } switch (evntType) { case MI_CALLPROC: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROCEED)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on proceed\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (ftdmchan->state == FTDM_CHANNEL_STATE_DIALING) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROCEED); } break; case MI_ALERTING: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_ALERT)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on alert\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (ftdmchan->state == FTDM_CHANNEL_STATE_PROCEED) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_RINGING); } break; case MI_PROGRESS: + if (!sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY) && + (signal_data->early_media_flags & SNGISDN_EARLY_MEDIA_ON_PROGRESS)) { + + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Early media override on progress\n"); + sngisdn_set_flag(sngisdn_info, FLAG_MEDIA_READY); + } if (sngisdn_test_flag(sngisdn_info, FLAG_MEDIA_READY)) { ftdm_set_state(ftdmchan, FTDM_CHANNEL_STATE_PROGRESS_MEDIA); } else if (ftdmchan->state != FTDM_CHANNEL_STATE_PROGRESS) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c index 9c1b7baf79..23fe08b983 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_isdn/ftmod_sangoma_isdn_support.c @@ -873,29 +873,32 @@ ftdm_status_t set_bear_cap_ie(ftdm_channel_t *ftdmchan, BearCap *bearCap) bearCap->tranMode.pres = PRSNT_NODEF; bearCap->tranMode.val = IN_TM_CIRCUIT; - if (!FTDM_SPAN_IS_BRI(ftdmchan->span)) { - /* Trillium stack rejests lyr1Ident on BRI, but Netbricks always sends it. - Check with Trillium if this ever causes calls to fail in the field */ + bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; + bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - /* PRI only params */ - bearCap->usrInfoLyr1Prot.pres = PRSNT_NODEF; - bearCap->usrInfoLyr1Prot.val = sngisdn_get_usrInfoLyr1Prot_from_user(ftdmchan->caller_data.bearer_layer1); - - if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN && - bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { - - /* We are bridging a call from T1 */ - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; - - } else if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { - - /* We are bridging a call from E1 */ - bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; - } - - bearCap->lyr1Ident.pres = PRSNT_NODEF; - bearCap->lyr1Ident.val = IN_L1_IDENT; + switch (signal_data->switchtype) { + case SNGISDN_SWITCH_NI2: + case SNGISDN_SWITCH_4ESS: + case SNGISDN_SWITCH_5ESS: + case SNGISDN_SWITCH_DMS100: + case SNGISDN_SWITCH_INSNET: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ALAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to u-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ULAW; + } + break; + case SNGISDN_SWITCH_EUROISDN: + case SNGISDN_SWITCH_QSIG: + if (bearCap->usrInfoLyr1Prot.val == IN_UIL1_G711ULAW) { + ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Overriding bearer cap to a-law\n"); + bearCap->usrInfoLyr1Prot.val = IN_UIL1_G711ALAW; + } + break; } + + bearCap->lyr1Ident.pres = PRSNT_NODEF; + bearCap->lyr1Ident.val = IN_L1_IDENT; + return FTDM_SUCCESS; } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c index e7378bf2ea..15fc1ef5db 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cfg.c @@ -44,6 +44,7 @@ /* PROTOTYPES *****************************************************************/ int ft_to_sngss7_cfg_all(void); +int ftmod_ss7_relay_gen_config(void); int ftmod_ss7_mtp1_gen_config(void); int ftmod_ss7_mtp2_gen_config(void); int ftmod_ss7_mtp3_gen_config(void); @@ -65,6 +66,8 @@ int ftmod_ss7_isup_ckt_config(int id); int ftmod_ss7_isup_isap_config(int id); int ftmod_ss7_cc_isap_config(int id); + +int ftmod_ss7_relay_chan_config(int id); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -75,58 +78,156 @@ int ft_to_sngss7_cfg_all(void) /* check if we have done gen_config already */ if (!(g_ftdm_sngss7_data.gen_config)) { + /* start of by checking if the license and sig file are valid */ if (sng_validate_license(g_ftdm_sngss7_data.cfg.license, - g_ftdm_sngss7_data.cfg.signature, - g_ftdm_sngss7_data.cfg.spc)) { + g_ftdm_sngss7_data.cfg.signature)) { SS7_CRITICAL("License verification failed..ending!\n"); return 1; } - if (ftmod_ss7_mtp1_gen_config()) { - SS7_CRITICAL("MTP1 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP1 General configuration DONE\n"); + /* if the procId is not 0 then we are using relay mode */ + if (g_ftdm_sngss7_data.cfg.procId != 0) { + /* set the desired procID value */ + sng_set_procId((uint16_t)g_ftdm_sngss7_data.cfg.procId); } - if (ftmod_ss7_mtp2_gen_config()) { - SS7_CRITICAL("MTP2 General configuration FAILED!\n"); + /* start up the stack manager */ + if (sng_isup_init_sm()) { + SS7_CRITICAL("Failed to start Stack Manager\n"); return 1; } else { - SS7_INFO("MTP2 General configuration DONE\n"); + SS7_INFO("Started Stack Manager!\n"); } - if (ftmod_ss7_mtp3_gen_config()) { - SS7_CRITICAL("MTP3 General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP3 General configuration DONE\n"); - } + /* check if the configuration had a Relay Channel */ + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) { + /* start up the relay task */ + if (sng_isup_init_relay()) { + SS7_CRITICAL("Failed to start Relay\n"); + return 1; + } else { + SS7_INFO("Started Relay!\n"); + } - if (ftmod_ss7_isup_gen_config()) { - SS7_CRITICAL("ISUP General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("ISUP General configuration DONE\n"); - } + /* run general configuration on the relay task */ + if (ftmod_ss7_relay_gen_config()) { + SS7_CRITICAL("Relay General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("Relay General configuration DONE\n"); + } - if (ftmod_ss7_cc_gen_config()) { - SS7_CRITICAL("CC General configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("CC General configuration DONE\n"); - } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) { + if (sng_isup_init_cc()) { + SS7_CRITICAL("Failed to start Call-Control\n"); + return 1; + } else { + SS7_INFO("Started Call-Control!\n"); + } + if (ftmod_ss7_cc_gen_config()) { + SS7_CRITICAL("CC General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("CC General configuration DONE\n"); + } + if (ftmod_ss7_cc_isap_config(1)) { + SS7_CRITICAL("CC ISAP configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("CC ISAP configuration DONE!\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { + if (sng_isup_init_isup()) { + SS7_CRITICAL("Failed to start ISUP\n"); + return 1; + } else { + SS7_INFO("Started ISUP!\n"); + } + if (ftmod_ss7_isup_gen_config()) { + SS7_CRITICAL("ISUP General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("ISUP General configuration DONE\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) { + if (sng_isup_init_mtp3()) { + SS7_CRITICAL("Failed to start MTP3\n"); + return 1; + } else { + SS7_INFO("Started MTP3!\n"); + } + + if (ftmod_ss7_mtp3_gen_config()) { + SS7_CRITICAL("MTP3 General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP3 General configuration DONE\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) */ + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { + if (sng_isup_init_mtp2()) { + SS7_CRITICAL("Failed to start MTP2\n"); + return 1; + } else { + SS7_INFO("Started MTP2!\n"); + } + if (sng_isup_init_mtp1()) { + SS7_CRITICAL("Failed to start MTP2\n"); + return 1; + } else { + SS7_INFO("Started MTP1!\n"); + } + if (ftmod_ss7_mtp1_gen_config()) { + SS7_CRITICAL("MTP1 General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP1 General configuration DONE\n"); + } + if (ftmod_ss7_mtp2_gen_config()) { + SS7_CRITICAL("MTP2 General configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP2 General configuration DONE\n"); + } + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) */ /* update the global gen_config so we don't do it again */ g_ftdm_sngss7_data.gen_config = 1; - } + } /* if (!(g_ftdm_sngss7_data.gen_config)) */ + /* go through all the relays channels and configure it */ + x = 1; + while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) { + /* check if this relay channel has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.relay[x].flags & SNGSS7_CONFIGURED)) { + + /* send the specific configuration */ + if (ftmod_ss7_relay_chan_config(x)) { + SS7_CRITICAL("Relay Channel %d configuration FAILED!\n", x); + return 1; + } else { + SS7_INFO("Relay Channel %d configuration DONE!\n", x); + } + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.relay[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ + x++; + } /* while (g_ftdm_sngss7_data.cfg.relay[x].id != 0) */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { + while (x < (MAX_MTP_LINKS + 1)) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.mtpLink[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.mtp1Link[x].flags & SNGSS7_CONFIGURED) && + (g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0)) { /* configure mtp1 */ if (ftmod_ss7_mtp1_psap_config(x)) { @@ -136,6 +237,18 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP1 PSAP %d configuration DONE!\n", x); } + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtp1Link[x].flags |= SNGSS7_CONFIGURED; + } + x++; + } /* while (g_ftdm_sngss7_data.cfg.mtp1Link[x].id != 0) */ + + x = 1; + while (x < (MAX_MTP_LINKS + 1)) { + /* check if this link has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.mtp2Link[x].flags & SNGSS7_CONFIGURED) && + (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0)) { + /* configure mtp2 */ if (ftmod_ss7_mtp2_dlsap_config(x)) { SS7_CRITICAL("MTP2 DLSAP %d configuration FAILED!\n",x); @@ -144,6 +257,18 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP2 DLSAP %d configuration DONE!\n", x); } + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtp2Link[x].flags |= SNGSS7_CONFIGURED; + } + x++; + } /* while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) */ + + x = 1; + while (x < (MAX_MTP_LINKS + 1)) { + /* check if this link has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.mtp3Link[x].flags & SNGSS7_CONFIGURED) && + (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0)) { + /* configure mtp3 */ if (ftmod_ss7_mtp3_dlsap_config(x)) { SS7_CRITICAL("MTP3 DLSAP %d configuration FAILED!\n", x); @@ -152,17 +277,17 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP3 DLSAP %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpLink[x].flags |= CONFIGURED; + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtp3Link[x].flags |= SNGSS7_CONFIGURED; } x++; - } /* while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) */ + } /* while (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) */ x = 1; while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & SNGSS7_CONFIGURED)) { if (ftmod_ss7_mtp3_nsap_config(x)) { SS7_CRITICAL("MTP3 NSAP %d configuration FAILED!\n", x); @@ -178,9 +303,9 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("ISUP NSAP %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.nsap[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */ @@ -188,7 +313,7 @@ int ft_to_sngss7_cfg_all(void) x = 1; while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & SNGSS7_CONFIGURED)) { if (ftmod_ss7_mtp3_linkset_config(x)) { SS7_CRITICAL("MTP3 LINKSET %d configuration FAILED!\n", x); @@ -197,9 +322,9 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP3 LINKSET %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */ @@ -207,7 +332,7 @@ int ft_to_sngss7_cfg_all(void) x = 1; while ((g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0)) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.mtpRoute[x].flags & CONFIGURED)) { + if (!(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); @@ -216,31 +341,33 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("MTP3 ROUTE %d configuration DONE!\n",x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtpRoute[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) */ - if (!(g_ftdm_sngss7_data.cfg.mtpRoute[0].flags & CONFIGURED)) { - - if (ftmod_ss7_mtp3_route_config(0)) { - SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); - return 1; - } else { - SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); - } - - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.mtpRoute[0].flags |= CONFIGURED; - } /* if !CONFIGURED */ + if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) { + if (!(g_ftdm_sngss7_data.cfg.mtpRoute[0].flags & SNGSS7_CONFIGURED)) { + + if (ftmod_ss7_mtp3_route_config(0)) { + SS7_CRITICAL("MTP3 ROUTE 0 configuration FAILED!\n"); + return 1; + } else { + SS7_INFO("MTP3 ROUTE 0 configuration DONE!\n"); + } + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.mtpRoute[0].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ + } x = 1; while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) { /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & CONFIGURED)) { + if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & SNGSS7_CONFIGURED)) { if (ftmod_ss7_isup_isap_config(x)) { SS7_CRITICAL("ISUP ISAP %d configuration FAILED!\n", x); @@ -249,57 +376,51 @@ int ft_to_sngss7_cfg_all(void) SS7_INFO("ISUP ISAP %d configuration DONE!\n", x); } - if (ftmod_ss7_cc_isap_config(x)) { - SS7_CRITICAL("CC ISAP %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("CC ISAP %d configuration DONE!\n", x); - } - - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isap[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ x++; } /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) { - /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & CONFIGURED)) { - - if (ftmod_ss7_isup_intf_config(x)) { - SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); - return 1; - } else { - SS7_INFO("ISUP INTF %d configuration DONE!\n", x); - /* set the interface to paused */ - sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); - } - - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ - - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) */ - - x = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - /* check if this link has been configured already */ - if (!(g_ftdm_sngss7_data.cfg.isupCkt[x].flags & CONFIGURED)) { - if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == 0) { - if (ftmod_ss7_isup_ckt_config(x)) { - SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { + x = 1; + while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) { + /* check if this link has been configured already */ + if (!(g_ftdm_sngss7_data.cfg.isupIntf[x].flags & SNGSS7_CONFIGURED)) { + + if (ftmod_ss7_isup_intf_config(x)) { + SS7_CRITICAL("ISUP INTF %d configuration FAILED!\n", x); return 1; } else { - SS7_INFO("ISUP CKT %d configuration DONE!\n", x); + SS7_INFO("ISUP INTF %d configuration DONE!\n", x); + /* set the interface to paused */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[x], SNGSS7_PAUSED); } + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isupIntf[x].flags |= SNGSS7_CONFIGURED; + } /* if !SNGSS7_CONFIGURED */ + + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) */ + } /* if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) */ + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + if (ftmod_ss7_isup_ckt_config(x)) { + SS7_CRITICAL("ISUP CKT %d configuration FAILED!\n", x); + return 1; + } else { + SS7_INFO("ISUP CKT %d configuration DONE!\n", x); } - /* set the CONFIGURED flag */ - g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= CONFIGURED; - } /* if !CONFIGURED */ + } /* if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED; x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ @@ -307,6 +428,44 @@ int ft_to_sngss7_cfg_all(void) return 0; } +/******************************************************************************/ +int ftmod_ss7_relay_gen_config(void) +{ + RyMngmt cfg; /*configuration structure*/ + Pst pst; /*post structure*/ + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + /* clear the configuration structure */ + memset(&cfg, 0x0, sizeof(RyMngmt)); + + /* fill in some general sections of the header */ + smHdrInit(&cfg.hdr); + + /* fill in the post structure */ + smPstInit( &cfg.t.cfg.s.ryGenCfg.lmPst ); + + /*fill in the specific fields of the header */ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTRY; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STGEN; + + cfg.t.cfg.s.ryGenCfg.lmPst.srcEnt = ENTRY; + cfg.t.cfg.s.ryGenCfg.lmPst.dstEnt = ENTSM; + + cfg.t.cfg.s.ryGenCfg.nmbChan = 10; + cfg.t.cfg.s.ryGenCfg.tmrRes = RY_PERIOD; + cfg.t.cfg.s.ryGenCfg.usta = 1; + + + return(sng_cfg_relay(&pst, &cfg)); +} + /******************************************************************************/ int ftmod_ss7_mtp1_gen_config(void) { @@ -575,7 +734,7 @@ int ftmod_ss7_mtp1_psap_config(int id) { L1Mngmt cfg; Pst pst; - sng_mtp_link_t *k = &g_ftdm_sngss7_data.cfg.mtpLink[id]; + sng_mtp1_link_t *k = &g_ftdm_sngss7_data.cfg.mtp1Link[id]; /* initalize the post structure */ smPstInit(&pst); @@ -597,8 +756,8 @@ int ftmod_ss7_mtp1_psap_config(int id) cfg.hdr.elmId.elmntInst1 = k->id; - cfg.t.cfg.s.l1PSAP.span = k->mtp1.span; - cfg.t.cfg.s.l1PSAP.chan = k->mtp1.chan; + cfg.t.cfg.s.l1PSAP.span = k->span; + cfg.t.cfg.s.l1PSAP.chan = k->chan; cfg.t.cfg.s.l1PSAP.spId = k->id; return(sng_cfg_mtp1(&pst, &cfg)); @@ -609,7 +768,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id) { SdMngmt cfg; Pst pst; - sng_mtp_link_t *k = &g_ftdm_sngss7_data.cfg.mtpLink[id]; + sng_mtp2_link_t *k = &g_ftdm_sngss7_data.cfg.mtp2Link[id]; /* initalize the post structure */ smPstInit( &pst); @@ -633,10 +792,15 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.mem.region = S_REG; /* memory region */ cfg.t.cfg.s.sdDLSAP.mem.pool = S_POOL; /* memory pool */ - cfg.t.cfg.s.sdDLSAP.swtch = k->mtp2.linkType; /* protocol type */ + cfg.t.cfg.s.sdDLSAP.swtch = k->linkType; /* protocol type */ cfg.t.cfg.s.sdDLSAP.priorDl = PRIOR0; /* priority for data link layer */ cfg.t.cfg.s.sdDLSAP.routeDl = RTESPEC; /* route for data link layer */ cfg.t.cfg.s.sdDLSAP.selectorDl = 0; /* upper interface selector */ + if (k->mtp1ProcId > 0) { + cfg.t.cfg.s.sdDLSAP.dstProcId = k->mtp1ProcId; /* the procid of MAC/L1/MTP1 */ + } else { + cfg.t.cfg.s.sdDLSAP.dstProcId = SFndProcId(); /* the procid of MAC/L1/MTP1 */ + } cfg.t.cfg.s.sdDLSAP.dstProcId = SFndProcId(); /* the procid of MAC/L1/MTP1 */ cfg.t.cfg.s.sdDLSAP.entMac = ENTL1; /* entity for MAC */ cfg.t.cfg.s.sdDLSAP.instMac = S_INST; /* instance for MAC */ @@ -646,22 +810,22 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.memMac.region = S_REG; /* memory region and pool id for MAC */ cfg.t.cfg.s.sdDLSAP.memMac.pool = S_POOL; cfg.t.cfg.s.sdDLSAP.maxOutsFrms = MAX_SD_OUTSTANDING; /* maximum outstanding frames */ - cfg.t.cfg.s.sdDLSAP.errType = k->mtp2.errorType; + cfg.t.cfg.s.sdDLSAP.errType = k->errorType; cfg.t.cfg.s.sdDLSAP.t1.enb = TRUE; /* timer 1 - Alignment Ready Timer */ - cfg.t.cfg.s.sdDLSAP.t1.val = k->mtp2.t1; + cfg.t.cfg.s.sdDLSAP.t1.val = k->t1; cfg.t.cfg.s.sdDLSAP.t2.enb = TRUE; /* timer 2 - Not Aligned Timer */ - cfg.t.cfg.s.sdDLSAP.t2.val = k->mtp2.t2; + cfg.t.cfg.s.sdDLSAP.t2.val = k->t2; cfg.t.cfg.s.sdDLSAP.t3.enb = TRUE; /* timer 3 - Aligned Timer */ - cfg.t.cfg.s.sdDLSAP.t3.val = k->mtp2.t3; + cfg.t.cfg.s.sdDLSAP.t3.val = k->t3; cfg.t.cfg.s.sdDLSAP.t5.enb = TRUE; /* timer 5 - Sending SIB timer */ - cfg.t.cfg.s.sdDLSAP.t5.val = k->mtp2.t5; + cfg.t.cfg.s.sdDLSAP.t5.val = k->t5; cfg.t.cfg.s.sdDLSAP.t6.enb = TRUE; /* timer 6 - Remote Congestion Timer */ - cfg.t.cfg.s.sdDLSAP.t6.val = k->mtp2.t6; + cfg.t.cfg.s.sdDLSAP.t6.val = k->t6; cfg.t.cfg.s.sdDLSAP.t7.enb = TRUE; /* timer 7 - Excessive delay of acknowledgement timer */ - cfg.t.cfg.s.sdDLSAP.t7.val = k->mtp2.t7; - cfg.t.cfg.s.sdDLSAP.provEmrgcy = k->mtp2.t4e; /* emergency proving period */ - cfg.t.cfg.s.sdDLSAP.provNormal = k->mtp2.t4n; /* normal proving period */ - cfg.t.cfg.s.sdDLSAP.lssuLen = k->mtp2.lssuLength; /* one or two byte LSSU length */ + cfg.t.cfg.s.sdDLSAP.t7.val = k->t7; + cfg.t.cfg.s.sdDLSAP.provEmrgcy = k->t4e; /* emergency proving period */ + cfg.t.cfg.s.sdDLSAP.provNormal = k->t4n; /* normal proving period */ + cfg.t.cfg.s.sdDLSAP.lssuLen = k->lssuLength; /* one or two byte LSSU length */ cfg.t.cfg.s.sdDLSAP.maxFrmLen = MAX_SD_FRAME_LEN; /* max frame length for MSU */ cfg.t.cfg.s.sdDLSAP.congDisc = FALSE; /* congestion discard TRUE or FALSE */ cfg.t.cfg.s.sdDLSAP.sdT = MAX_SD_SUERM; /* SUERM error rate threshold */ @@ -670,7 +834,7 @@ int ftmod_ss7_mtp2_dlsap_config(int id) cfg.t.cfg.s.sdDLSAP.sdN1 = MAX_SD_MSU_RETRANS; /* maximum number of MSUs for retransmission */ cfg.t.cfg.s.sdDLSAP.sdN2 = MAX_SD_OCTETS_RETRANS; /* maximum number of MSU octets for retrans */ cfg.t.cfg.s.sdDLSAP.sdCp = MAX_SD_ALIGN_ATTEMPTS; /* maximum number of alignment attempts */ - cfg.t.cfg.s.sdDLSAP.spIdSE = k->mtp2.mtp1Id; /* service provider id */ + cfg.t.cfg.s.sdDLSAP.spIdSE = k->mtp1Id; /* service provider id */ cfg.t.cfg.s.sdDLSAP.sdtFlcStartTr = 256; /* SDT interface flow control start thresh */ cfg.t.cfg.s.sdDLSAP.sdtFlcEndTr = 512; /* SDT interface flow control end thresh */ @@ -707,7 +871,6 @@ int ftmod_ss7_mtp2_dlsap_config(int id) #endif /*RUG*/ return(sng_cfg_mtp2(&pst, &cfg)); - return 0; } /******************************************************************************/ @@ -715,7 +878,7 @@ int ftmod_ss7_mtp3_dlsap_config(int id) { Pst pst; SnMngmt cfg; - sng_mtp_link_t *k = &g_ftdm_sngss7_data.cfg.mtpLink[id]; + sng_mtp3_link_t *k = &g_ftdm_sngss7_data.cfg.mtp3Link[id]; /* initalize the post structure */ @@ -738,14 +901,14 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.hdr.elmId.elmntInst1 = k->id; - cfg.t.cfg.s.snDLSAP.lnkSetId = k->mtp3.linkSetId; /* link set ID */ - cfg.t.cfg.s.snDLSAP.opc = k->mtp3.spc; /* Originating Postatic int Code */ - cfg.t.cfg.s.snDLSAP.adjDpc = k->mtp3.apc; /* Adlacent Destination Postatic int Code */ + cfg.t.cfg.s.snDLSAP.lnkSetId = k->linkSetId; /* link set ID */ + cfg.t.cfg.s.snDLSAP.opc = k->spc; /* Originating Postatic int Code */ + cfg.t.cfg.s.snDLSAP.adjDpc = k->apc; /* Adlacent Destination Postatic int Code */ cfg.t.cfg.s.snDLSAP.lnkPrior = 0; /* link priority within the link set */ cfg.t.cfg.s.snDLSAP.msgSize = MAX_SN_MSG_SIZE; /* message length */ cfg.t.cfg.s.snDLSAP.msgPrior = 0; /* management message priority */ - cfg.t.cfg.s.snDLSAP.lnkType = k->mtp3.linkType; /* link type ANSI, ITU, BICI or CHINA */ - cfg.t.cfg.s.snDLSAP.upSwtch = k->mtp3.switchType; /* user part switch type */ + cfg.t.cfg.s.snDLSAP.lnkType = k->linkType; /* link type ANSI, ITU, BICI or CHINA */ + cfg.t.cfg.s.snDLSAP.upSwtch = k->switchType; /* user part switch type */ cfg.t.cfg.s.snDLSAP.maxSLTtry = MAX_SLTM_RETRIES; /* maximun times to retry SLTM */ cfg.t.cfg.s.snDLSAP.p0QLen = 32; /* size of the priority 0 Q */ cfg.t.cfg.s.snDLSAP.p1QLen = 32; /* size of the priority 1 Q */ @@ -756,7 +919,7 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.maxCredit = MAX_SN_CREDIT; /* max credit */ #endif /* SDT2 */ cfg.t.cfg.s.snDLSAP.lnkId = 0; /* signalling link allocation procedure identity */ - cfg.t.cfg.s.snDLSAP.lnkTstSLC = k->mtp3.slc; /* link selection code for link test */ + cfg.t.cfg.s.snDLSAP.lnkTstSLC = k->slc; /* link selection code for link test */ cfg.t.cfg.s.snDLSAP.tstLen = 6; /* link test pattern length */ cfg.t.cfg.s.snDLSAP.tst[0] = 'K'; /* link test pattern */ cfg.t.cfg.s.snDLSAP.tst[1] = 'O'; /* link test pattern */ @@ -764,8 +927,8 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.tst[3] = 'R'; /* link test pattern */ cfg.t.cfg.s.snDLSAP.tst[4] = 'A'; /* link test pattern */ cfg.t.cfg.s.snDLSAP.tst[5] = 'D'; /* link test pattern */ - cfg.t.cfg.s.snDLSAP.ssf = k->mtp3.ssf; /* sub service field */ - cfg.t.cfg.s.snDLSAP.dstProcId = SFndProcId(); /* destination processor id */ + cfg.t.cfg.s.snDLSAP.ssf = k->ssf; /* sub service field */ + cfg.t.cfg.s.snDLSAP.dstProcId = k->mtp2ProcId; /* destination processor id */ cfg.t.cfg.s.snDLSAP.dstEnt = ENTSD; /* entity */ cfg.t.cfg.s.snDLSAP.dstInst = S_INST; /* instance */ cfg.t.cfg.s.snDLSAP.prior = PRIOR0; /* priority */ @@ -773,9 +936,9 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.selector = 0; /* lower layer selector */ cfg.t.cfg.s.snDLSAP.mem.region = S_REG; /* memory region id */ cfg.t.cfg.s.snDLSAP.mem.pool = S_POOL; /* memory pool id */ - cfg.t.cfg.s.snDLSAP.spId = k->mtp3.mtp2Id ;/* service provider id */ + cfg.t.cfg.s.snDLSAP.spId = k->mtp2Id; /* service provider id */ - switch (k->mtp3.linkType) { + switch (k->linkType) { /**************************************************************************/ case (LSN_SW_ANS): case (LSN_SW_ANS96): @@ -793,9 +956,9 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.dpcLen = DPC14; /* dpc length 14 bits */ break; /**************************************************************************/ - } /* switch (k->mtp3.linkType) */ + } /* switch (k->linkType) */ - switch (k->mtp3.linkType) { + switch (k->linkType) { /**************************************************************************/ case (LSN_SW_ANS): case (LSN_SW_ANS96): @@ -811,51 +974,51 @@ int ftmod_ss7_mtp3_dlsap_config(int id) cfg.t.cfg.s.snDLSAP.flushContFlag = FALSE; /* flush continue handling */ break; /**************************************************************************/ - } /* switch (k->mtp3.linkType) */ + } /* switch (k->linkType) */ cfg.t.cfg.s.snDLSAP.tmr.t1.enb = TRUE; /* t1 - delay to avoid missequencing on changeover */ - cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->mtp3.t1; + cfg.t.cfg.s.snDLSAP.tmr.t1.val = k->t1; cfg.t.cfg.s.snDLSAP.tmr.t2.enb = TRUE; /* t2 - waiting for changeover ack */ - cfg.t.cfg.s.snDLSAP.tmr.t2.val = k->mtp3.t2; + cfg.t.cfg.s.snDLSAP.tmr.t2.val = k->t2; cfg.t.cfg.s.snDLSAP.tmr.t3.enb = TRUE; /* t3 - delay to avoid missequencing on changeback */ - cfg.t.cfg.s.snDLSAP.tmr.t3.val = k->mtp3.t3; + cfg.t.cfg.s.snDLSAP.tmr.t3.val = k->t3; cfg.t.cfg.s.snDLSAP.tmr.t4.enb = TRUE; /* t4 - waiting for first changeback ack */ - cfg.t.cfg.s.snDLSAP.tmr.t4.val = k->mtp3.t4; + cfg.t.cfg.s.snDLSAP.tmr.t4.val = k->t4; cfg.t.cfg.s.snDLSAP.tmr.t5.enb = TRUE; /* t5 - waiting for second changeback ack */ - cfg.t.cfg.s.snDLSAP.tmr.t5.val = k->mtp3.t5; + cfg.t.cfg.s.snDLSAP.tmr.t5.val = k->t5; cfg.t.cfg.s.snDLSAP.tmr.t7.enb = TRUE; /* t7 - waiting for link connection ack */ - cfg.t.cfg.s.snDLSAP.tmr.t7.val = k->mtp3.t7; + cfg.t.cfg.s.snDLSAP.tmr.t7.val = k->t7; cfg.t.cfg.s.snDLSAP.tmr.t12.enb = TRUE; /* t12 - waiting for uninhibit ack */ - cfg.t.cfg.s.snDLSAP.tmr.t12.val = k->mtp3.t12; + cfg.t.cfg.s.snDLSAP.tmr.t12.val = k->t12; cfg.t.cfg.s.snDLSAP.tmr.t13.enb = TRUE; /* t13 - waiting for forced uninhibit */ - cfg.t.cfg.s.snDLSAP.tmr.t13.val = k->mtp3.t13; + cfg.t.cfg.s.snDLSAP.tmr.t13.val = k->t13; cfg.t.cfg.s.snDLSAP.tmr.t14.enb = TRUE; /* t14 - waiting for inhibition ack */ - cfg.t.cfg.s.snDLSAP.tmr.t14.val = k->mtp3.t14; + cfg.t.cfg.s.snDLSAP.tmr.t14.val = k->t14; cfg.t.cfg.s.snDLSAP.tmr.t17.enb = TRUE; /* t17 - delay to avoid oscillation of initial alignment failure */ - cfg.t.cfg.s.snDLSAP.tmr.t17.val = k->mtp3.t17; + cfg.t.cfg.s.snDLSAP.tmr.t17.val = k->t17; cfg.t.cfg.s.snDLSAP.tmr.t22.enb = TRUE; /* t22 - local inhibit test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t22.val = k->mtp3.t22; + cfg.t.cfg.s.snDLSAP.tmr.t22.val = k->t22; cfg.t.cfg.s.snDLSAP.tmr.t23.enb = TRUE; /* t23 - remote inhibit test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t23.val = k->mtp3.t23; + cfg.t.cfg.s.snDLSAP.tmr.t23.val = k->t23; cfg.t.cfg.s.snDLSAP.tmr.t24.enb = TRUE; /* t24 - stabilizing timer */ - cfg.t.cfg.s.snDLSAP.tmr.t24.val = k->mtp3.t24; + cfg.t.cfg.s.snDLSAP.tmr.t24.val = k->t24; cfg.t.cfg.s.snDLSAP.tmr.t31.enb = TRUE; /* t31 - BSN requested timer */ - cfg.t.cfg.s.snDLSAP.tmr.t31.val = k->mtp3.t31; + cfg.t.cfg.s.snDLSAP.tmr.t31.val = k->t31; cfg.t.cfg.s.snDLSAP.tmr.t32.enb = TRUE; /* t32 - SLT timer */ - cfg.t.cfg.s.snDLSAP.tmr.t32.val = k->mtp3.t32; + cfg.t.cfg.s.snDLSAP.tmr.t32.val = k->t32; cfg.t.cfg.s.snDLSAP.tmr.t33.enb = TRUE; /* t33 - connecting timer */ - cfg.t.cfg.s.snDLSAP.tmr.t33.val = k->mtp3.t33; + cfg.t.cfg.s.snDLSAP.tmr.t33.val = k->t33; cfg.t.cfg.s.snDLSAP.tmr.t34.enb = TRUE; /* t34 - periodic signalling link test timer */ - cfg.t.cfg.s.snDLSAP.tmr.t34.val = k->mtp3.t34; + cfg.t.cfg.s.snDLSAP.tmr.t34.val = k->t34; #if (SS7_ANS92 || SS7_ANS88 || SS7_ANS96 || defined(TDS_ROLL_UPGRADE_SUPPORT)) cfg.t.cfg.s.snDLSAP.tmr.t35.enb = TRUE; /* t35 - false link congestion timer, same as t31 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t35.val = k->mtp3.t35; + cfg.t.cfg.s.snDLSAP.tmr.t35.val = k->t35; cfg.t.cfg.s.snDLSAP.tmr.t36.enb = TRUE; /* t36 - false link congestion timer, same as t33 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t36.val = k->mtp3.t36; + cfg.t.cfg.s.snDLSAP.tmr.t36.val = k->t36; cfg.t.cfg.s.snDLSAP.tmr.t37.enb = TRUE; /* t37 - false link congestion timer, same as t34 of ANSI'96*/ - cfg.t.cfg.s.snDLSAP.tmr.t37.val = k->mtp3.t37; + cfg.t.cfg.s.snDLSAP.tmr.t37.val = k->t37; cfg.t.cfg.s.snDLSAP.tmr.tCraft.enb = TRUE; /* link referral craft timer - T19 in ANSI */ - cfg.t.cfg.s.snDLSAP.tmr.tCraft.val = k->mtp3.tcraft; + cfg.t.cfg.s.snDLSAP.tmr.tCraft.val = k->tcraft; #endif #ifdef SDT2 cfg.t.cfg.s.snDLSAP.tmr.tFlc.enb = TRUE; /* flow control timer */ @@ -1217,6 +1380,11 @@ int ftmod_ss7_isup_ckt_config(int id) /* insert the destination Entity */ pst.dstEnt = ENTSI; + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + /*clear the configuration structure*/ memset(&cfg, 0x0, sizeof(SiMngmt)); @@ -1417,11 +1585,11 @@ int ftmod_ss7_isup_isap_config(int id) } /******************************************************************************/ -int ftmod_ss7_cc_isap_config(int id) +int ftmod_ss7_cc_isap_config(int dstProcId) { CcMngmt cfg; Pst pst; - sng_isap_t *k = &g_ftdm_sngss7_data.cfg.isap[id]; + /* initalize the post structure */ smPstInit(&pst); @@ -1441,11 +1609,11 @@ int ftmod_ss7_cc_isap_config(int id) cfg.hdr.entId.inst = S_INST; cfg.hdr.elmId.elmnt = STISAP; - cfg.hdr.elmId.elmntInst1 = k->id; + cfg.hdr.elmId.elmntInst1 = 1; - cfg.t.cfg.s.ccISAP.suId = k->suId; - cfg.t.cfg.s.ccISAP.spId = k->spId; - cfg.t.cfg.s.ccISAP.pst.dstProcId = SFndProcId(); + cfg.t.cfg.s.ccISAP.suId = 1; + cfg.t.cfg.s.ccISAP.spId = 1; + cfg.t.cfg.s.ccISAP.pst.dstProcId = dstProcId; cfg.t.cfg.s.ccISAP.pst.dstEnt = ENTSI; cfg.t.cfg.s.ccISAP.pst.dstInst = S_INST; cfg.t.cfg.s.ccISAP.pst.srcProcId = SFndProcId(); @@ -1461,6 +1629,70 @@ int ftmod_ss7_cc_isap_config(int id) } /******************************************************************************/ +int ftmod_ss7_relay_chan_config(int id) +{ + RyMngmt cfg; /*configuration structure*/ + Pst pst; /*post structure*/ + sng_relay_t *k = &g_ftdm_sngss7_data.cfg.relay[id]; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + /* clear the configuration structure */ + memset(&cfg, 0x0, sizeof(RyMngmt)); + + /* fill in some general sections of the header */ + smHdrInit(&cfg.hdr); + + /*fill in the specific fields of the header */ + cfg.hdr.msgType = TCFG; + cfg.hdr.entId.ent = ENTRY; + cfg.hdr.entId.inst = S_INST; + cfg.hdr.elmId.elmnt = STCHCFG; + + cfg.hdr.elmId.elmntInst1 = k->id; + + cfg.t.cfg.s.ryChanCfg.id = k->id; /* channel id */ + cfg.t.cfg.s.ryChanCfg.type = k->type; /* channel type */ +/* cfg.t.cfg.s.ryChanCfg.msInd =;*/ /* master/slave indicator */ + if (k->type == LRY_CT_TCP_LISTEN) { + cfg.t.cfg.s.ryChanCfg.low = 0; /* low proc id for channel */ + cfg.t.cfg.s.ryChanCfg.high = 0; /* high proc id for channel */ + } else { + cfg.t.cfg.s.ryChanCfg.low = k->procId; /* low proc id for channel */ + cfg.t.cfg.s.ryChanCfg.high = k->procId; /* high proc id for channel */ + } + cfg.t.cfg.s.ryChanCfg.nmbScanQ = MAX_RELAY_NMBSCAN; /* number of times to scan the queue */ + cfg.t.cfg.s.ryChanCfg.flags = LRY_FLG_INTR; /* flags */ + cfg.t.cfg.s.ryChanCfg.congThrsh = MAX_RELAY_CONGTHRSH; /* congestion threshold */ + cfg.t.cfg.s.ryChanCfg.dropThrsh = 0; /* drop threshold */ + cfg.t.cfg.s.ryChanCfg.contThrsh = MAX_RELAY_CONGTHRSH + 1; /* continue threshold */ + cfg.t.cfg.s.ryChanCfg.kaTxTmr.enb = 1; /* keep alive transmit timer config */ + cfg.t.cfg.s.ryChanCfg.kaTxTmr.val = RY_TX_KP_ALIVE_TMR; + cfg.t.cfg.s.ryChanCfg.kaRxTmr.enb = 1; /* keep alive receive timer config */ + cfg.t.cfg.s.ryChanCfg.kaRxTmr.val = RY_RX_KP_ALIVE_TMR; + cfg.t.cfg.s.ryChanCfg.btTmr.enb = 1; /* boot timer */ + cfg.t.cfg.s.ryChanCfg.btTmr.val = RY_BT_TMR; + cfg.t.cfg.s.ryChanCfg.region = S_REG; /* Relay region */ + cfg.t.cfg.s.ryChanCfg.pool = S_POOL; /* Relay pool */ +#if (RY_ENBUDPSOCK || RY_ENBTCPSOCK) + cfg.t.cfg.s.ryChanCfg.listenPortNo = k->port; /* Listen Port of Rx Relay Channel*/ + strncpy(cfg.t.cfg.s.ryChanCfg.transmittoHostName, k->hostname, (size_t)RY_REMHOSTNAME_SIZE); + cfg.t.cfg.s.ryChanCfg.transmittoPortNo = k->port; /* TransmitTo PortId for Tx Relay Channel */ + cfg.t.cfg.s.ryChanCfg.targetProcId = k->procId; /* procId of the node present in the other end of this channel */ +# ifdef LRY1 + cfg.t.cfg.s.ryChanCfg.sockParam =; /* Socket Parameters */ +# endif /* LRY1 */ +# ifdef LRYV2 + cfg.t.cfg.s.ryChanCfg.selfHostName[RY_REMHOSTNAME_SIZE]; +# endif /* LRY2 */ +#endif /* RY_ENBUDPSOCK || RY_ENBTCPSOCK */ + + return(sng_cfg_relay(&pst, &cfg)); +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c index dc2d24f42a..4ab4359c93 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cli.c @@ -46,6 +46,8 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream); +static ftdm_status_t handle_show_procId(ftdm_stream_handle_t *stream); + static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level); static ftdm_status_t handle_set_message_trace(ftdm_stream_handle_t *stream, int on, int level); static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name); @@ -67,6 +69,8 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int chan, int range, int verbose); +static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char *name); @@ -76,9 +80,12 @@ static ftdm_status_t handle_deactivate_linkset(ftdm_stream_handle_t *stream, cha static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name); -static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *name); static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name); +static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *name); + static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan); static ftdm_status_t check_arg_count(int args, int min); /******************************************************************************/ @@ -111,18 +118,29 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha if (!strcasecmp(argv[c], "status")) { /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; c++; - if (!strcasecmp(argv[c], "link")) { + if (!strcasecmp(argv[c], "mtp3")) { /******************************************************************/ c++; - handle_status_link(stream, argv[c]); + handle_status_mtp3link(stream, argv[c]); + /******************************************************************/ + } else if (!strcasecmp(argv[c], "mtp2")) { + /******************************************************************/ + c++; + handle_status_mtp2link(stream, argv[c]); /******************************************************************/ } else if (!strcasecmp(argv[c], "linkset")) { /******************************************************************/ c++; handle_status_linkset(stream, argv[c]); /******************************************************************/ + } else if (!strcasecmp(argv[c], "relay")) { + /******************************************************************/ + c++; + handle_status_relay(stream, argv[c]); + /******************************************************************/ } else if (!strcasecmp(argv[c], "span")) { /******************************************************************/ if (check_arg_count(argc, 6)) goto handle_cli_error_argc; @@ -256,6 +274,10 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha sts.rx_frm, sts.rx_err, sts.rx_fisu, sts.rx_lssu, sts.rx_msu); */ /**********************************************************************/ + } else if (!strcasecmp(argv[c], "procid")) { + /**********************************************************************/ + handle_show_procId(stream); + /**********************************************************************/ } else { /**********************************************************************/ stream->write_function(stream, "Unknown \"show\" command\n"); @@ -534,6 +556,44 @@ ftdm_status_t ftdm_sngss7_handle_cli_cmd(ftdm_stream_handle_t *stream, const cha /**********************************************************************/ } /**************************************************************************/ + } else if (!strcasecmp(argv[c], "bind")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_bind_link(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"bind\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ + } else if (!strcasecmp(argv[c], "unbind")) { + /**************************************************************************/ + if (check_arg_count(argc, 2)) goto handle_cli_error_argc; + c++; + + if (!strcasecmp(argv[c], "link")) { + /**********************************************************************/ + if (check_arg_count(argc, 3)) goto handle_cli_error_argc; + c++; + + handle_unbind_link(stream, argv[c]); + /**********************************************************************/ + } else { + /**********************************************************************/ + stream->write_function(stream, "Unknown \"bind\" command\n"); + goto handle_cli_error; + /**********************************************************************/ + } + /**************************************************************************/ } else if (!strcasecmp(argv[c], "activate")) { /**************************************************************************/ if (check_arg_count(argc, 2)) goto handle_cli_error_argc; @@ -649,6 +709,16 @@ static ftdm_status_t handle_print_usuage(ftdm_stream_handle_t *stream) return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_show_procId(ftdm_stream_handle_t *stream) +{ + int procId = sng_get_procId(); + + stream->write_function(stream, "Local ProcId = %d\n", procId); + + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t handle_set_function_trace(ftdm_stream_handle_t *stream, int on, int level) { @@ -693,7 +763,7 @@ static ftdm_status_t handle_show_free(ftdm_stream_handle_t *stream, int span, in int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; free = 0; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -756,7 +826,7 @@ static ftdm_status_t handle_show_inuse(ftdm_stream_handle_t *stream, int span, i int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; in_use = 0; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -826,7 +896,7 @@ static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; in_reset = 0; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -848,10 +918,10 @@ static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, } if ((ftdmchan->physical_span_id == lspan) && (ftdmchan->physical_chan_id == lchan)) { - if ((sngss7_test_flag(ss7_info, FLAG_RESET_RX)) || - (sngss7_test_flag(ss7_info, FLAG_RESET_TX)) || - (sngss7_test_flag(ss7_info, FLAG_GRP_RESET_RX)) || - (sngss7_test_flag(ss7_info, FLAG_GRP_RESET_TX))) { + if ((sngss7_test_ckt_flag(ss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_RESET_TX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_RESET_RX)) || + (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_RESET_TX))) { if (verbose) { stream->write_function(stream, "span=%2d|chan=%2d|cic=%4d|in_reset=Y\n", @@ -862,7 +932,7 @@ static ftdm_status_t handle_show_inreset(ftdm_stream_handle_t *stream, int span, /*increment the count of circuits in reset */ in_reset++; - } /* if ((sngss7_test_flag(ss7_info, FLAG_RESET_RX) ... */ + } /* if ((sngss7_test_ckt_flag(ss7_info, FLAG_RESET_RX) ... */ } /* if ( span and chan) */ } /* if ( cic != 0) */ @@ -885,7 +955,7 @@ static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, i int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -913,7 +983,7 @@ static ftdm_status_t handle_show_flags(ftdm_stream_handle_t *stream, int span, i for (bit = 0; bit < 33; bit++) { stream->write_function(stream, "|"); - if (ss7_info->flags & ( 0x1 << bit)) { + if (ss7_info->ckt_flags & ( 0x1 << bit)) { stream->write_function(stream, "%2d=1", bit); } else { stream->write_function(stream, "%2d=0", bit); @@ -941,7 +1011,7 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -967,37 +1037,37 @@ static ftdm_status_t handle_show_blocks(ftdm_stream_handle_t *stream, int span, ftdmchan->physical_chan_id, ss7_info->circuit->cic); - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + if((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { stream->write_function(stream, "l_mn=Y|"); }else { stream->write_function(stream, "l_mn=N|"); } - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { stream->write_function(stream, "r_mn=Y|"); }else { stream->write_function(stream, "r_mn=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { stream->write_function(stream, "l_hw=Y|"); }else { stream->write_function(stream, "l_hw=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { stream->write_function(stream, "r_hw=Y|"); }else { stream->write_function(stream, "r_hw=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { stream->write_function(stream, "l_mngmt=Y|"); }else { stream->write_function(stream, "l_mngmt=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { stream->write_function(stream, "l_ucic=Y|"); }else { stream->write_function(stream, "l_ucic=N|"); @@ -1026,7 +1096,7 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, ftdm_signaling_status_t sigstatus = FTDM_SIG_STATE_DOWN; sng_isup_ckt_t *ckt; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { /* extract the circuit to make it easier to work with */ ckt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; @@ -1071,43 +1141,37 @@ static ftdm_status_t handle_show_status(ftdm_stream_handle_t *stream, int span, ftdm_signaling_status2str(sigstatus), ftdm_channel_state2str(ftdmchan->state)); - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { + if((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX)) || (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_TX))) { stream->write_function(stream, "l_mn=Y|"); }else { stream->write_function(stream, "l_mn=N|"); } - if((sngss7_test_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if((sngss7_test_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_RX)) || (sngss7_test_ckt_flag(ss7_info, FLAG_GRP_MN_BLOCK_RX))) { stream->write_function(stream, "r_mn=Y|"); }else { stream->write_function(stream, "r_mn=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_TX)) { stream->write_function(stream, "l_hw=Y|"); }else { stream->write_function(stream, "l_hw=N|"); } - if(sngss7_test_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { + if(sngss7_test_ckt_flag(ss7_info, FLAG_GRP_HW_BLOCK_RX)) { stream->write_function(stream, "r_hw=Y|"); }else { stream->write_function(stream, "r_hw=N|"); } - - if(sngss7_test_flag(ss7_info, FLAG_CKT_LC_BLOCK_RX)) { - stream->write_function(stream, "l_mngmt=Y|"); + + if(sngss7_test_ckt_flag(ss7_info, FLAG_RELAY_DOWN)) { + stream->write_function(stream, "relay=Y|"); }else { - stream->write_function(stream, "l_mngmt=N|"); - } + stream->write_function(stream, "relay=N|"); + } - if(sngss7_test_flag(ss7_info, FLAG_CKT_UCIC_BLOCK)) { - stream->write_function(stream, "l_ucic=Y|"); - }else { - stream->write_function(stream, "l_ucic=N|"); - } - - stream->write_function(stream, "flags=0x%X",ss7_info->flags); + stream->write_function(stream, "flags=0x%X",ss7_info->ckt_flags); stream->write_function(stream, "\n"); } /* if ( hole, sig, voice) */ @@ -1127,7 +1191,7 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -1162,7 +1226,7 @@ static ftdm_status_t handle_tx_blo(ftdm_stream_handle_t *stream, int span, int c continue; } else { /* throw the ckt block flag */ - sngss7_set_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); + sngss7_set_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1193,7 +1257,7 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { ss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -1228,10 +1292,10 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c continue; } else { /* throw the ckt block flag */ - sngss7_set_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); + sngss7_set_ckt_flag(ss7_info, FLAG_CKT_MN_UNBLK_TX); /* clear the block flag */ - sngss7_clear_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); + sngss7_clear_ckt_flag(ss7_info, FLAG_CKT_MN_BLOCK_TX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1254,18 +1318,18 @@ static ftdm_status_t handle_tx_ubl(ftdm_stream_handle_t *stream, int span, int c } /******************************************************************************/ -static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name) +static ftdm_status_t handle_status_mtp3link(ftdm_stream_handle_t *stream, char *name) { int x = 0; SnMngmt sta; /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the status request */ - if (ftmod_ss7_mtplink_sta(x, &sta)) { + if (ftmod_ss7_mtp3link_sta(x, &sta)) { stream->write_function(stream, "Failed to read link=%s status\n", name); return FTDM_FAIL; } @@ -1273,9 +1337,9 @@ static ftdm_status_t handle_status_link(ftdm_stream_handle_t *stream, char *name /* print the results */ stream->write_function(stream, "%s|span=%d|chan=%d|sap=%d|state=%s|l_blk=%s|r_blk=%s|l_inhbt=%s|r_inhbt=%s\n", name, - g_ftdm_sngss7_data.cfg.mtpLink[x].mtp1.span, - g_ftdm_sngss7_data.cfg.mtpLink[x].mtp1.chan, - g_ftdm_sngss7_data.cfg.mtpLink[x].id, + g_ftdm_sngss7_data.cfg.mtp1Link[x].span, + g_ftdm_sngss7_data.cfg.mtp1Link[x].chan, + g_ftdm_sngss7_data.cfg.mtp3Link[x].id, DECODE_LSN_LINK_STATUS(sta.t.ssta.s.snDLSAP.state), (sta.t.ssta.s.snDLSAP.locBlkd) ? "Y":"N", (sta.t.ssta.s.snDLSAP.remBlkd) ? "Y":"N", @@ -1295,6 +1359,50 @@ success: return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_status_mtp2link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + SdMngmt sta; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp2Link[x].name, name)) { + + /* send the status request */ + if (ftmod_ss7_mtp2link_sta(x, &sta)) { + stream->write_function(stream, "Failed to read link=%s status\n", name); + return FTDM_FAIL; + } + + /* print the results */ + stream->write_function(stream, "%s|span=%d|chan=%d|sap=%d|state=%s|outsFrm=%d|drpdFrm=%d|lclStatus=%s|rmtStatus=%s|fsn=%d|bsn=%d\n", + name, + g_ftdm_sngss7_data.cfg.mtp1Link[x].span, + g_ftdm_sngss7_data.cfg.mtp1Link[x].chan, + g_ftdm_sngss7_data.cfg.mtp2Link[x].id, + DECODE_LSD_LINK_STATUS(sta.t.ssta.s.sdDLSAP.hlSt), + sta.t.ssta.s.sdDLSAP.psOutsFrm, + sta.t.ssta.s.sdDLSAP.cntMaDrop, + (sta.t.ssta.s.sdDLSAP.lclBsy) ? "Y":"N", + (sta.t.ssta.s.sdDLSAP.remBsy) ? "Y":"N", + sta.t.ssta.s.sdDLSAP.fsn, + sta.t.ssta.s.sdDLSAP.bsn); + + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Failed to find link=\"%s\"\n", name); + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t handle_status_linkset(ftdm_stream_handle_t *stream, char *name) { @@ -1338,17 +1446,17 @@ static ftdm_status_t handle_set_inhibit(ftdm_stream_handle_t *stream, char *name /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the inhibit request */ - if (ftmod_ss7_inhibit_mtplink(x)) { + if (ftmod_ss7_inhibit_mtp3link(x)) { stream->write_function(stream, "Failed to inhibit link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1370,17 +1478,17 @@ static ftdm_status_t handle_set_uninhibit(ftdm_stream_handle_t *stream, char *na /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_uninhibit_mtplink(x)) { + if (ftmod_ss7_uninhibit_mtp3link(x)) { stream->write_function(stream, "Failed to uninhibit link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1404,7 +1512,7 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c int lspan; int lchan; - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { sngss7_info = (sngss7_chan_data_t *)g_ftdm_sngss7_data.cfg.isupCkt[x].obj; @@ -1429,7 +1537,7 @@ static ftdm_status_t handle_tx_rsc(ftdm_stream_handle_t *stream, int span, int c ftdm_mutex_lock(ftdmchan->mutex); /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); switch (ftdmchan->state) { /**************************************************************************/ @@ -1476,7 +1584,7 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1500,9 +1608,9 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c continue; } else { /* throw the grp reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); if (ftdmchan->physical_chan_id == chan) { - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; sngss7_span->tx_grs.range = range-1; } @@ -1523,7 +1631,7 @@ static ftdm_status_t handle_tx_grs(ftdm_stream_handle_t *stream, int span, int c x++; } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x]id != 0) */ - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1565,7 +1673,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1582,7 +1690,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c ftdm_mutex_lock(ftdmchan->mutex); /* throw the grp maint. block flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); /* bring the sig status down */ sigev.chan_id = ftdmchan->chan_id; @@ -1622,7 +1730,7 @@ static ftdm_status_t handle_tx_cgb(ftdm_stream_handle_t *stream, int span, int c /* send the circuit group block */ ft_to_sngss7_cgb(main_chan); - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1665,7 +1773,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1682,7 +1790,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c ftdm_mutex_lock(ftdmchan->mutex); /* throw the grp maint. block flag */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX); /* bring the sig status up */ sigev.chan_id = ftdmchan->chan_id; @@ -1722,7 +1830,7 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c /* send the circuit group block */ ft_to_sngss7_cgu(main_chan); - x=1; + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { @@ -1745,6 +1853,68 @@ static ftdm_status_t handle_tx_cgu(ftdm_stream_handle_t *stream, int span, int c return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_bind_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_bind_mtp3link(g_ftdm_sngss7_data.cfg.mtp3Link[x].mtp2Id)) { + stream->write_function(stream, "Failed to bind link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_mtp3link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static ftdm_status_t handle_unbind_link(ftdm_stream_handle_t *stream, char *name) +{ + int x = 0; + + /* find the link request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { + + /* send the uninhibit request */ + if (ftmod_ss7_unbind_mtp3link(g_ftdm_sngss7_data.cfg.mtp3Link[x].mtp2Id)) { + stream->write_function(stream, "Failed to bind link=%s\n", name); + return FTDM_FAIL; + } + + /* print the new status of the link */ + handle_status_mtp3link(stream, &name[0]); + goto success; + } + + /* move to the next link */ + x++; + } /* while (id != 0) */ + + stream->write_function(stream, "Could not find link=%s\n", name); + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *name) { @@ -1752,17 +1922,17 @@ static ftdm_status_t handle_activate_link(ftdm_stream_handle_t *stream, char *na /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_activate_mtplink(x)) { + if (ftmod_ss7_activate_mtp3link(x)) { stream->write_function(stream, "Failed to activate link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1783,17 +1953,17 @@ static ftdm_status_t handle_deactivate_link(ftdm_stream_handle_t *stream, char * /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the deactivate request */ - if (ftmod_ss7_deactivate2_mtplink(x)) { + if (ftmod_ss7_deactivate2_mtp3link(x)) { stream->write_function(stream, "Failed to deactivate link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1877,17 +2047,17 @@ static ftdm_status_t handle_tx_lpo(ftdm_stream_handle_t *stream, char *name) /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_lpo_mtplink(x)) { + if (ftmod_ss7_lpo_mtp3link(x)) { stream->write_function(stream, "Failed set LPO link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1908,17 +2078,17 @@ static ftdm_status_t handle_tx_lpr(ftdm_stream_handle_t *stream, char *name) /* find the link request by it's name */ x = 1; - while(g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpLink[x].name, name)) { + while(g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtp3Link[x].name, name)) { /* send the uninhibit request */ - if (ftmod_ss7_lpr_mtplink(x)) { + if (ftmod_ss7_lpr_mtp3link(x)) { stream->write_function(stream, "Failed set LPR link=%s\n", name); return FTDM_FAIL; } /* print the new status of the link */ - handle_status_link(stream, &name[0]); + handle_status_mtp3link(stream, &name[0]); goto success; } @@ -1932,6 +2102,47 @@ success: return FTDM_SUCCESS; } +/******************************************************************************/ +static ftdm_status_t handle_status_relay(ftdm_stream_handle_t *stream, char *name) +{ + RyMngmt sta; + int x = 0; + + memset(&sta, 0x0, sizeof(sta)); + + + /* find the channel request by it's name */ + x = 1; + while(g_ftdm_sngss7_data.cfg.relay[x].id != 0) { + if (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[x].name, name)) { + + if (ftmod_ss7_relay_status(g_ftdm_sngss7_data.cfg.relay[x].id, &sta)) { + stream->write_function(stream, "Failed to read relay =%s status\n", name); + return FTDM_FAIL; + } + + /* print the results */ + stream->write_function(stream, "%s|sap=%d|type=%d|port=%d|hostname=%s|procId=%d|status=%s\n", + name, + g_ftdm_sngss7_data.cfg.relay[x].id, + g_ftdm_sngss7_data.cfg.relay[x].type, + g_ftdm_sngss7_data.cfg.relay[x].port, + g_ftdm_sngss7_data.cfg.relay[x].hostname, + g_ftdm_sngss7_data.cfg.relay[x].procId, + DECODE_LRY_CHAN_STATUS(sta.t.ssta.rySta.cStatus)); + + goto success; + } + + /* move to the next link */ + x++; + + } /* g_ftdm_sngss7_data.cfg.relay[x].id */ + +success: + return FTDM_SUCCESS; +} + /******************************************************************************/ static ftdm_status_t extract_span_chan(char *argv[10], int pos, int *span, int *chan) { diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c index 87733dd594..c1b18e529a 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_cntrl.c @@ -48,19 +48,31 @@ static int ftmod_ss7_enable_isap(int suId); static int ftmod_ss7_enable_nsap(int suId); static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId); -int ftmod_ss7_inhibit_mtplink(uint32_t id); -int ftmod_ss7_uninhibit_mtplink(uint32_t id); +int ftmod_ss7_inhibit_mtp3link(uint32_t id); +int ftmod_ss7_uninhibit_mtp3link(uint32_t id); -int ftmod_ss7_activate_mtplink(uint32_t id); -int ftmod_ss7_deactivate_mtplink(uint32_t id); -int ftmod_ss7_deactivate2_mtplink(uint32_t id); +int ftmod_ss7_bind_mtp3link(uint32_t id); +int ftmod_ss7_unbind_mtp3link(uint32_t id); +int ftmod_ss7_activate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate2_mtp3link(uint32_t id); int ftmod_ss7_activate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); -int ftmod_ss7_lpo_mtplink(uint32_t id); -int ftmod_ss7_lpr_mtplink(uint32_t id); +int ftmod_ss7_lpo_mtp3link(uint32_t id); +int ftmod_ss7_lpr_mtp3link(uint32_t id); + +int ftmod_ss7_shutdown_isup(void); +int ftmod_ss7_shutdown_mtp3(void); +int ftmod_ss7_shutdown_mtp2(void); +int ftmod_ss7_shutdown_relay(void); + +int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId); +int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); + +int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -71,7 +83,7 @@ int ft_to_sngss7_activate_all(void) x = 1; while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) { /* check if this link has already been actived */ - if (!(g_ftdm_sngss7_data.cfg.isap[x].flags & ACTIVE)) { + if (!(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); @@ -80,9 +92,9 @@ int ft_to_sngss7_activate_all(void) SS7_INFO("ISAP %d Enable: OK\n", x); } - /* set the ACTIVE flag */ - g_ftdm_sngss7_data.cfg.isap[x].flags |= ACTIVE; - } /* if !ACTIVE */ + /* set the SNGSS7_ACTIVE flag */ + g_ftdm_sngss7_data.cfg.isap[x].flags |= SNGSS7_ACTIVE; + } /* if !SNGSS7_ACTIVE */ x++; } /* while (g_ftdm_sngss7_data.cfg.isap[x].id != 0) */ @@ -90,7 +102,7 @@ int ft_to_sngss7_activate_all(void) x = 1; while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) { /* check if this link has already been actived */ - if (!(g_ftdm_sngss7_data.cfg.nsap[x].flags & ACTIVE)) { + if (!(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); @@ -99,31 +111,33 @@ int ft_to_sngss7_activate_all(void) SS7_INFO("NSAP %d Enable: OK\n", x); } - /* set the ACTIVE flag */ - g_ftdm_sngss7_data.cfg.nsap[x].flags |= ACTIVE; - } /* if !ACTIVE */ + /* set the SNGSS7_ACTIVE flag */ + g_ftdm_sngss7_data.cfg.nsap[x].flags |= SNGSS7_ACTIVE; + } /* if !SNGSS7_ACTIVE */ x++; } /* while (g_ftdm_sngss7_data.cfg.nsap[x].id != 0) */ - x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { - /* check if this link has already been actived */ - if (!(g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags & 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 ACTIVE flag */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].flags |= ACTIVE; - } /* if !ACTIVE */ - - x++; - } /* while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */ + if (g_ftdm_sngss7_data.cfg.mtpRoute[1].id != 0) { + x = 1; + while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { + /* check if this link has already been actived */ + if (!(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 (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) */ + } return 0; } @@ -223,7 +237,7 @@ static int ftmod_ss7_enable_mtpLinkSet(int lnkSetId) } /******************************************************************************/ -int ftmod_ss7_inhibit_mtplink(uint32_t id) +int ftmod_ss7_inhibit_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -253,7 +267,7 @@ int ftmod_ss7_inhibit_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_uninhibit_mtplink(uint32_t id) +int ftmod_ss7_uninhibit_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -283,7 +297,7 @@ int ftmod_ss7_uninhibit_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_activate_mtplink(uint32_t id) +int ftmod_ss7_bind_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -304,7 +318,67 @@ int ftmod_ss7_activate_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; + + cntrl.t.cntrl.action = ABND; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_unbind_mtp3link(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; + + cntrl.t.cntrl.action = AUBND_DIS; /* unbind and disable */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_activate_mtp3link(uint32_t id) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STDLSAP; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = AENA; /* Activate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -313,7 +387,7 @@ int ftmod_ss7_activate_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_deactivate_mtplink(uint32_t id) +int ftmod_ss7_deactivate_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -334,7 +408,7 @@ int ftmod_ss7_deactivate_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ADISIMM; /* Deactivate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -343,7 +417,7 @@ int ftmod_ss7_deactivate_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_deactivate2_mtplink(uint32_t id) +int ftmod_ss7_deactivate2_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -364,7 +438,7 @@ int ftmod_ss7_deactivate2_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ADISIMM_L2; /* Deactivate...layer 2 only */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -463,7 +537,7 @@ int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_lpo_mtplink(uint32_t id) +int ftmod_ss7_lpo_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -484,7 +558,7 @@ int ftmod_ss7_lpo_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ACTION_LPO; /* Activate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -493,7 +567,7 @@ int ftmod_ss7_lpo_mtplink(uint32_t id) } /******************************************************************************/ -int ftmod_ss7_lpr_mtplink(uint32_t id) +int ftmod_ss7_lpr_mtp3link(uint32_t id) { SnMngmt cntrl; Pst pst; @@ -514,7 +588,7 @@ int ftmod_ss7_lpr_mtplink(uint32_t id) cntrl.hdr.entId.ent = ENTSN; cntrl.hdr.entId.inst = S_INST; cntrl.hdr.elmId.elmnt = STDLSAP; - cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + cntrl.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; cntrl.t.cntrl.action = ACTION_LPR; /* Activate */ cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ @@ -523,6 +597,216 @@ int ftmod_ss7_lpr_mtplink(uint32_t id) } /******************************************************************************/ +int ftmod_ss7_shutdown_isup(void) +{ + SiMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSI; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SiMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSI; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* shutdown */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_isup(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_shutdown_mtp3(void) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_shutdown_mtp2(void) +{ + SdMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSD; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SdMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSD; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_mtp2(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_shutdown_relay(void) +{ + RyMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(RyMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTRY; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGEN; + + cntrl.t.cntrl.action = ASHUTDOWN; /* Activate */ + cntrl.t.cntrl.subAction = SAELMNT; /* specificed element */ + + return (sng_cntrl_relay(&pst, &cntrl)); +} + +/******************************************************************************/ +int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ + + cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ + + cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */ + cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); + +} + +/******************************************************************************/ +int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId) +{ + SnMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSN; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(SnMngmt)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSN; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGRDLSAP; /* group DLSAP */ + + cntrl.t.cntrl.ctlType.groupKey.dstProcId = procId; /* all SAPS to this ProcId */ + + cntrl.t.cntrl.action = ABND_ENA; /* bind and enable */ + cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ + + return (sng_cntrl_mtp3(&pst, &cntrl)); + +} + +/******************************************************************************/ +int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId) +{ + SdMngmt cntrl; + Pst pst; + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSD; + + /* initalize the control structure */ + memset(&cntrl, 0x0, sizeof(cntrl)); + + /* initalize the control header */ + smHdrInit(&cntrl.hdr); + + cntrl.hdr.msgType = TCNTRL; /* this is a control request */ + cntrl.hdr.entId.ent = ENTSD; + cntrl.hdr.entId.inst = S_INST; + cntrl.hdr.elmId.elmnt = STGRNSAP; /* group NSAP */ + + cntrl.t.cntrl.par.dstProcId = procId; /* all SAPS to this ProcId */ + + cntrl.t.cntrl.action = AUBND_DIS; /* disable and unbind */ + cntrl.t.cntrl.subAction = SAGR_DSTPROCID; /* specificed element */ + + return (sng_cntrl_mtp2(&pst, &cntrl)); + +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c index dcfb7f79e0..3a6fca7376 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_handle.c @@ -99,21 +99,21 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM (glare)\n", sngss7_info->circuit->cic); } else { SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx IAM\n", sngss7_info->circuit->cic); } /* check if the circuit has a remote block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { /* as per Q.764, 2.8.2.3 xiv ... remove the block from this channel */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); /* KONRAD FIX ME : check in case there is a ckt and grp block */ } @@ -134,7 +134,7 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdmchan->physical_chan_id); /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); ftdmchan->caller_data.hangup_cause = 41; @@ -253,26 +253,26 @@ handle_glare: sngss7_info->glare.circuit = circuit; memcpy(&sngss7_info->glare.iam, siConEvnt, sizeof(*siConEvnt)); - if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) { /* glare, throw the flag */ - sngss7_set_flag(sngss7_info, FLAG_GLARE); + sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE); /* setup the hangup cause */ ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */ /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* move the state of the channel to Terminating to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); - } /* if (!(sngss7_test_flag(sngss7_info, FLAG_GLARE))) */ + } /* if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) */ break; /**************************************************************************/ default: /* should not have gotten an IAM while in this state */ SS7_ERROR_CHAN(ftdmchan, "Got IAM on channel in invalid state(%s)...reset!\n", ftdm_channel_state2str (ftdmchan->state)); /* reset the cic */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* move the state of the channel to RESTART to force a reset */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -341,7 +341,7 @@ ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_channel_state2str (ftdmchan->state)); /* reset the cic */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* go to RESTART */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -545,7 +545,7 @@ ftdm_status_t handle_con_cfm(uint32_t suInstId, uint32_t spInstId, uint32_t circ SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Rx ANM/CON\n", sngss7_info->circuit->cic); /* throw the TX reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); /* go to RESTART */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -597,7 +597,7 @@ ftdm_status_t handle_rel_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ } /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); /* move the state of the channel to CANCEL to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -618,7 +618,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); } /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* move the state of the channel to TERMINATING to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -631,7 +631,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); /* since we need to acknowledge the hang up set the flag for remote release */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* go to hangup complete to send the RLC */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_HANGUP_COMPLETE); @@ -645,7 +645,7 @@ ftdm_channel_command(ftdmchan, FTDM_COMMAND_DISABLE_LOOP, NULL); default: /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); /* set the state to RESTART */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -1134,13 +1134,13 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci /* lock the channel */ ftdm_mutex_lock(ftdmchan->mutex); - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { /* the glare flag is already up so it was caught ... do nothing */ SS7_DEBUG_CHAN(ftdmchan, "Glare flag is already up...nothing to do!%s\n", " "); } else { SS7_DEBUG_CHAN(ftdmchan, "Glare flag is not up yet...indicating glare from reattempt!%s\n", " "); /* glare, throw the flag */ - sngss7_set_flag(sngss7_info, FLAG_GLARE); + sngss7_set_ckt_flag(sngss7_info, FLAG_GLARE); /* clear any existing glare data from the channel */ memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t)); @@ -1149,7 +1149,7 @@ ftdm_status_t handle_reattempt(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdmchan->caller_data.hangup_cause = 34; /* Circuit Congrestion */ /* this is a remote hangup request */ - sngss7_set_flag(sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_REMOTE_REL); /* move the state of the channel to Terminating to end the call */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_TERMINATING); @@ -1179,7 +1179,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); /* go through all the circuits now and find any other circuits on this infId */ - i = 1; + i = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { /* check that the infId matches and that this is not a siglink */ @@ -1200,7 +1200,7 @@ ftdm_status_t handle_pause(uint32_t suInstId, uint32_t spInstId, uint32_t circui if (ftdm_test_flag(ftdmchan->span, FTDM_SPAN_IN_THREAD)) { SS7_DEBUG_CHAN(ftdmchan, "Rx PAUSE%s\n", ""); /* set the pause flag on the channel */ - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); } /* unlock the channel again before we exit */ @@ -1234,7 +1234,7 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu sngss7_clear_flag(&g_ftdm_sngss7_data.cfg.isupIntf[infId], SNGSS7_PAUSED); /* go through all the circuits now and find any other circuits on this infId */ - i = 1; + i = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; while (g_ftdm_sngss7_data.cfg.isupCkt[i].id != 0) { /* check that the infId matches and that this is not a siglink */ @@ -1252,14 +1252,14 @@ ftdm_status_t handle_resume(uint32_t suInstId, uint32_t spInstId, uint32_t circu ftdm_mutex_lock(ftdmchan->mutex); /* only resume if we are paused */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { SS7_DEBUG_CHAN(ftdmchan, "Rx RESUME%s\n", ""); /* set the resume flag on the channel */ - sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); /* clear the paused flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); } /* unlock the channel again before we exit */ @@ -1421,12 +1421,12 @@ ftdm_status_t handle_blo_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_mutex_lock(ftdmchan->mutex); /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_WARN("Received BLO on circuit that is already blocked!\n"); } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1484,15 +1484,15 @@ ftdm_status_t handle_ubl_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_mutex_lock(ftdmchan->mutex); /* check if the channel is blocked */ - if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX))) { SS7_WARN("Received UBL on circuit that is not blocked!\n"); } /* throw the unblock flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_MN_UNBLK_RX); /* clear the block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1550,7 +1550,7 @@ ftdm_status_t handle_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ ftdm_mutex_lock(ftdmchan->mutex); /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); switch (ftdmchan->state) { /**************************************************************************/ @@ -1595,7 +1595,7 @@ ftdm_status_t handle_local_rsc_req(uint32_t suInstId, uint32_t spInstId, uint32_ ftdm_mutex_lock(ftdmchan->mutex); /* throw the reset flag */ - sngss7_set_flag(sngss7_info, FLAG_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_RX); switch (ftdmchan->state) { /**************************************************************************/ @@ -1643,9 +1643,9 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ /**********************************************************************/ case FTDM_CHANNEL_STATE_RESTART: - if ( sngss7_test_flag(sngss7_info, FLAG_RESET_TX) ) { + if ( sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX) ) { /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); /* go to DOWN */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); @@ -1667,7 +1667,7 @@ ftdm_status_t handle_rsc_rsp(uint32_t suInstId, uint32_t spInstId, uint32_t circ case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); /* go to DOWN */ /*ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN);*/ @@ -1795,12 +1795,12 @@ ftdm_status_t handle_local_blk(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdm_mutex_lock(ftdmchan->mutex); /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { SS7_WARN("Received local BLO on circuit that is already blocked!\n"); } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1831,12 +1831,12 @@ ftdm_status_t handle_local_ubl(uint32_t suInstId, uint32_t spInstId, uint32_t ci ftdm_mutex_lock(ftdmchan->mutex); /* check if the circuit is already blocked or not */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { SS7_WARN("Received local UBL on circuit that is already unblocked!\n"); } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_LC_UNBLK_RX); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1878,7 +1878,7 @@ ftdm_status_t handle_ucic(uint32_t suInstId, uint32_t spInstId, uint32_t circuit ftdm_mutex_lock(ftdmchan->mutex); /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -1982,11 +1982,11 @@ ftdm_status_t handle_cgb_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ switch (blockType) { /**********************************************************************/ case 0: /* maintenance oriented */ - sngss7_set_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); break; /**********************************************************************/ case 1: /* hardware failure oriented */ - sngss7_set_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); break; /**********************************************************************/ case 2: /* reserved for national use */ @@ -2113,11 +2113,11 @@ ftdm_status_t handle_cgu_req(uint32_t suInstId, uint32_t spInstId, uint32_t circ switch (blockType) { /**********************************************************************/ case 0: /* maintenance oriented */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX); break; /**********************************************************************/ case 1: /* hardware failure oriented */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX); break; /**********************************************************************/ case 2: /* reserved for national use */ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c index 72bd1c3fb2..76984b907b 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_in.c @@ -409,13 +409,80 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint sngss7_chan_data_t *sngss7_info = NULL; ftdm_channel_t *ftdmchan = NULL; sngss7_event_data_t *sngss7_event = NULL; + uint32_t intfId; + int x; - /* get the ftdmchan and ss7_chan_data from the circuit */ - if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { - SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); - SS7_FUNC_TRACE_EXIT(__FUNCTION__); - return; - } + /* check if the eventType is a pause/resume */ + switch (evntType) { + /**************************************************************************/ + case (SIT_STA_PAUSEIND): + case (SIT_STA_RESUMEIND): + + /* the circuit for this type of event may not exist on the local system + * so first check if the circuit is local + */ + if ((circuit >= (g_ftdm_sngss7_data.cfg.procId * 1000)) && + (circuit < ((g_ftdm_sngss7_data.cfg.procId +1) * 1000))) { + + /* the circuit is on the local system, handle normally */ + goto sta_ind_local; + } + + /* the circuit is not local, so find a local circuit with the same intfId + * by finding the orginial circuit in our array first, finding the intfId + * from there, then go through the local circuits to see if we find a + * match and use that circuit instead + */ + intfId = g_ftdm_sngss7_data.cfg.isupCkt[circuit].infId; + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while ((g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) && + (g_ftdm_sngss7_data.cfg.isupCkt[x].id < ((g_ftdm_sngss7_data.cfg.procId +1) * 1000))) { + /**********************************************************************/ + /* confirm this is a voice channel and not a gap/sig (no ftdmchan there) */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type != VOICE) goto move_along; + + /* compare the intfIds */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].infId == intfId) { + /* we have a match, setup the pointers to the correct values */ + circuit = x; + + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + /* bounce out of the loop */ + break; + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].intfId == intfId) */ + +move_along: + /* move along ... nothing to see here */ + x++; + + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + /* check if we found any circuits that are on the intfId, drop the message + * if none are found + */ + if (ftdmchan == NULL) goto sta_ind_end; + + break; + /**************************************************************************/ + default: +sta_ind_local: + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(circuit, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", circuit); + SS7_FUNC_TRACE_EXIT(__FUNCTION__); + return; + } + + break; + /**************************************************************************/ + } /* switch (evntType) */ /* initalize the sngss7_event */ sngss7_event = ftdm_malloc(sizeof(*sngss7_event)); @@ -440,6 +507,7 @@ void sngss7_sta_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, uint /* enqueue this event */ ftdm_queue_enqueue(((sngss7_span_data_t*)sngss7_info->ftdmchan->span->signal_data)->event_queue, sngss7_event); +sta_ind_end: SS7_FUNC_TRACE_EXIT(__FUNCTION__); } diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c index 3f507d6648..f4143fc864 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_logger.c @@ -48,6 +48,8 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); 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); + /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -77,8 +79,8 @@ void handle_sng_log(uint8_t level, char *fmt,...) ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data); break; /**************************************************************************/ - case SNG_LOGLEVEL_STATS: - ftdm_log(FTDM_LOG_INFO, "sng_ss7->%s", data); + case SNG_LOGLEVEL_NOTICE: + ftdm_log(FTDM_LOG_NOTICE, "sng_ss7->%s", data); break; /**************************************************************************/ case SNG_LOGLEVEL_ERROR: @@ -132,17 +134,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } @@ -173,17 +175,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", @@ -196,17 +198,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %s\n", @@ -220,17 +222,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)|Oldest BSN(%d)|Tx Queue Len(%d)|Outstanding Frames(%d)\n", @@ -246,17 +248,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : RTB Queue Len(%d)\n", @@ -269,17 +271,17 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->t.usta.evntParm[0]) { + while (g_ftdm_sngss7_data.cfg.mtp2Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == sta->t.usta.evntParm[0]) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp2Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->t.usta.evntParm[0]); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp2Link[x].name); } ftdm_log(FTDM_LOG_ERROR,"[MTP2]%s %s : %d\n", @@ -290,9 +292,11 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta) /**********************************************************************/ case (LCM_EVENT_UI_INV_EVT): case (LCM_EVENT_LI_INV_EVT): - ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s : %s : Primitive (%d)\n", + ftdm_log(FTDM_LOG_ERROR,"[MTP2] %s(%d) : %s(%d) : Primitive (%d)\n", DECODE_LSD_EVENT(sta->t.usta.alarm.event), + sta->t.usta.alarm.event, DECODE_LCM_CAUSE(sta->t.usta.alarm.cause), + sta->t.usta.alarm.cause, sta->t.usta.evntParm[0]); break; /**********************************************************************/ @@ -362,22 +366,23 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) /* find the name for the sap in question */ x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[x].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == sta->hdr.elmId.elmntInst1) { + while (g_ftdm_sngss7_data.cfg.mtp3Link[x].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == sta->hdr.elmId.elmntInst1) { break; } x++; } - if (g_ftdm_sngss7_data.cfg.mtpLink[x].id == 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[x].id == 0) { sprintf(buf, "[SAPID:%d]", sta->hdr.elmId.elmntInst1); } else { - sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtpLink[x].name); + sprintf(buf, "[%s]", g_ftdm_sngss7_data.cfg.mtp3Link[x].name); } switch (sta->t.usta.alarm.event) { /**********************************************************************/ case (LSN_EVENT_INV_OPC_OTHER_END): + ftdm_log(FTDM_LOG_ERROR,"[MTP3]%s %s : %s : OPC(0x%X%X%X%X)\n", buf, DECODE_LSN_EVENT(sta->t.usta.alarm.event), @@ -460,7 +465,7 @@ void handle_sng_mtp3_alarm(Pst *pst, SnMngmt *sta) break; /**********************************************************************/ default: - ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%d%d%d%d] %s : %s\n", + ftdm_log(FTDM_LOG_ERROR,"[MTP3][DPC:0x%X%X%X%X] %s : %s\n", sta->t.usta.evntParm[0], sta->t.usta.evntParm[1], sta->t.usta.evntParm[2], @@ -744,7 +749,63 @@ void handle_sng_cc_alarm(Pst *pst, CcMngmt *sta) return; } /* handle_cc_alarm */ + /******************************************************************************/ +void handle_sng_relay_alarm(Pst *pst, RyMngmt *sta) +{ + + + switch (sta->hdr.elmId.elmnt) { + /**************************************************************************/ + case (LRY_USTA_ERR): /* ERROR */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Error: tx procId %d: err procId %d: channel %d: seq %s: reason %s\n", + sta->t.usta.s.ryErrUsta.sendPid, + sta->t.usta.s.ryErrUsta.errPid, + sta->t.usta.s.ryErrUsta.id, + DECODE_LRY_SEQ(sta->t.usta.s.ryErrUsta.sequence), + DECODE_LRY_REASON(sta->t.usta.s.ryErrUsta.reason)); + + /* process the event */ + handle_relay_disconnect_on_error(sta); + + break; + /**************************************************************************/ + case (LRY_USTA_CNG): /* Congestion */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Congestion: tx procId %d: rem procId %d: channel %d: %s\n", + sta->t.usta.s.ryCongUsta.sendPid, + sta->t.usta.s.ryCongUsta.remPid, + sta->t.usta.s.ryCongUsta.id, + DECODE_LRY_CONG_FLAGS(sta->t.usta.s.ryCongUsta.flags)); + break; + /**************************************************************************/ + case (LRY_USTA_UP): /* channel up */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel UP: tx procId %d: channel %d\n", + sta->t.usta.s.ryUpUsta.sendPid, + sta->t.usta.s.ryUpUsta.id); + + /* process the event */ + handle_relay_connect(sta); + + break; + /**************************************************************************/ + case (LRY_USTA_DN): /* channel down */ + ftdm_log(FTDM_LOG_ERROR,"[RELAY] Channel DOWN: tx procId %d: channel %d\n", + sta->t.usta.s.ryUpUsta.sendPid, + sta->t.usta.s.ryUpUsta.id); + + /* process the event */ + handle_relay_disconnect_on_down(sta); + + break; + /**************************************************************************/ + default: + ftdm_log(FTDM_LOG_ERROR,"Unknown Relay Alram\n"); + break; + /**************************************************************************/ + } /* switch (sta->hdr.elmId.elmnt) */ + + return; +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c index 9016771671..adee000abb 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.c @@ -495,8 +495,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_COLLECT: /* IAM received but wating on digits */ - isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - if (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED) { SS7_DEBUG("re-entering state from processing block/unblock request ... do nothing\n"); break; @@ -516,8 +514,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); - } else if (i >= isup_intf->min_digits) { - SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, isup_intf->min_digits); + } else if (i >= sngss7_info->circuit->min_digits) { + SS7_DEBUG_CHAN(ftdmchan, "Received %d digits (min digits = %d)\n", i, sngss7_info->circuit->min_digits); /*now go to the RING state */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RING); @@ -527,7 +525,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) if (ftdmchan->last_state != FTDM_CHANNEL_STATE_IDLE) { SS7_INFO_CHAN(ftdmchan,"Received %d out of %d so far: %s...starting T35\n", i, - isup_intf->min_digits, + sngss7_info->circuit->min_digits, ftdmchan->caller_data.dnis.digits); /* start ISUP t35 */ @@ -543,7 +541,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) ftdmchan->caller_data.hangup_cause = 41; /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); /* end the call */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_CANCEL); @@ -673,7 +671,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* set the flag to indicate this hangup is started from the remote side */ - sngss7_set_flag (sngss7_info, FLAG_REMOTE_REL); + sngss7_set_ckt_flag (sngss7_info, FLAG_REMOTE_REL); /*this state is set when the line is hanging up */ sigev.event_id = FTDM_SIGEVENT_STOP; @@ -689,15 +687,15 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* check for remote hangup flag */ - if (sngss7_test_flag (sngss7_info, FLAG_REMOTE_REL)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { /* remote release ...do nothing here */ SS7_DEBUG_CHAN(ftdmchan,"Hanging up remotely requested call!%s\n", ""); - } else if (sngss7_test_flag (sngss7_info, FLAG_GLARE)) { + } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_GLARE)) { /* release due to glare */ SS7_DEBUG_CHAN(ftdmchan,"Hanging up requested call do to glare%s\n", ""); } else { /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag (sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag (sngss7_info, FLAG_LOCAL_REL); /*this state is set when FS is hanging up...so tell the stack */ ft_to_sngss7_rel (ftdmchan); @@ -718,16 +716,16 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) break; } - if (sngss7_test_flag (sngss7_info, FLAG_REMOTE_REL)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_REMOTE_REL)) { /* check if this hangup is from a tx RSC */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) { /* go to RESTART State until RSCa is received */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_RESTART); } else { /* if the hangup is from a rx RSC, rx GRS, or glare don't sent RLC */ - if (!(sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GLARE))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE))) { /* send out the release complete */ ft_to_sngss7_rlc (ftdmchan); @@ -738,17 +736,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } SS7_DEBUG_CHAN(ftdmchan,"Completing remotely requested hangup!%s\n", ""); - } else if (sngss7_test_flag (sngss7_info, FLAG_LOCAL_REL)) { + } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_LOCAL_REL)) { /* if this hang up is do to a rx RESET we need to sit here till the RSP arrives */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX_RSP)) { /* go to the down state as we have already received RSC-RLC */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN); } /* if it's a local release the user sends us to down */ SS7_DEBUG_CHAN(ftdmchan,"Completing locally requested hangup!%s\n", ""); - } else if (sngss7_test_flag (sngss7_info, FLAG_GLARE)) { + } else if (sngss7_test_ckt_flag (sngss7_info, FLAG_GLARE)) { SS7_DEBUG_CHAN(ftdmchan,"Completing requested hangup due to glare!%s\n", ""); ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN); @@ -767,18 +765,18 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* check if there is a reset response that needs to be sent */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) { /* send a RSC-RLC */ ft_to_sngss7_rsca (ftdmchan); /* clear the reset flag */ clear_rx_rsc_flags(sngss7_info); - } /* if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) */ + } /* if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) */ /* check if there was a GRS that needs a GRA */ - if ((sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) && - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) && - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) && + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) && + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT))) { /* check if this is the base circuit and send out the GRA * we insure that this is the last circuit to have the state change queued @@ -794,40 +792,40 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the grp reset flag */ clear_rx_grs_flags(sngss7_info); - }/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */ + }/* if ( sngss7_test_ckt_flag ( sngss7_info, FLAG_GRP_RESET_RX ) ) */ /* check if we got the reset response */ - if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) { /* clear the reset flag */ clear_tx_rsc_flags(sngss7_info); - } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX_RSP)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP)) */ - if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { /* clear the reset flag */ clear_tx_grs_flags(sngss7_info); /* clean out the spans GRA structure */ clear_rx_gra_data(sngss7_info); - } /* if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) */ /* check if we came from reset (aka we just processed a reset) */ if ((ftdmchan->last_state == FTDM_CHANNEL_STATE_RESTART) || (ftdmchan->last_state == FTDM_CHANNEL_STATE_SUSPENDED)) { /* check if reset flags are up indicating there is more processing to do yet */ - if (!(sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) && - !(sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) && - !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) && - !(sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { + if (!(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) && + !(sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) && + !(sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) && + !(sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX))) { /* now check if there is an active block */ - if (!(sngss7_test_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { + if (!(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_LC_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { /* check if the sig status is down, and bring it up if it isn't */ if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) { @@ -839,7 +837,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if (!ftdm_test_flag (ftdmchan, FTDM_CHANNEL_SIG_UP)) */ } /* if !blocked */ } else { - SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan,"Reset flags present (0x%X)\n", sngss7_info->ckt_flags); /* there is still another reset pending so go back to reset*/ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_RESTART); @@ -858,8 +856,8 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) sngss7_info->spId = 0; /* clear any call related flags */ - sngss7_clear_flag (sngss7_info, FLAG_REMOTE_REL); - sngss7_clear_flag (sngss7_info, FLAG_LOCAL_REL); + sngss7_clear_ckt_flag (sngss7_info, FLAG_REMOTE_REL); + sngss7_clear_ckt_flag (sngss7_info, FLAG_LOCAL_REL); if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) { @@ -869,10 +867,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_OPEN)) */ /* check if there is a glared call that needs to be processed */ - if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) { /* clear the glare flag */ - sngss7_clear_flag (sngss7_info, FLAG_GLARE); + sngss7_clear_ckt_flag (sngss7_info, FLAG_GLARE); /* check if we have an IAM stored...if we don't have one just exit */ if (sngss7_info->glare.circuit != 0) { @@ -885,23 +883,23 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* clear the glare info */ memset(&sngss7_info->glare, 0x0, sizeof(sngss7_glare_data_t)); } /* if (sngss7_info->glare.circuit != 0) */ - } /* if (sngss7_test_flag(sngss7_info, FLAG_GLARE)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_GLARE)) */ break; /**************************************************************************/ case FTDM_CHANNEL_STATE_RESTART: /* CICs needs a Reset */ - if (sngss7_test_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) { - if ((sngss7_test_flag(sngss7_info, FLAG_RESET_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX))) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK)) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX))) { SS7_DEBUG_CHAN(ftdmchan,"Incoming Reset request on CIC in UCIC block, removing UCIC block%s\n", ""); /* set the unblk flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); /* clear the block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* process the flag */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -915,28 +913,28 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) * we can also check if we are in a PAUSED state (no point in sending message */ if ((ftdmchan->last_state != FTDM_CHANNEL_STATE_HANGUP_COMPLETE) && - (!sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED))) { + (!sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED))) { /* check if this is an outgoing RSC */ - if ((sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_RESET_SENT))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_SENT))) { /* send a reset request */ ft_to_sngss7_rsc (ftdmchan); - sngss7_set_flag(sngss7_info, FLAG_RESET_SENT); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_SENT); - } /* if (sngss7_test_flag(sngss7_info, FLAG_RESET_TX)) */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_RESET_TX)) */ /* check if this is the first channel of a GRS (this flag is thrown when requesting reset) */ - if ( (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) && - !(sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_SENT)) && - (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_BASE))) { + if ( (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) && + !(sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT)) && + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE))) { /* send out the grs */ ft_to_sngss7_grs (ftdmchan); - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_SENT); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT); - }/* if ( sngss7_test_flag ( sngss7_info, FLAG_GRP_RESET_TX ) ) */ + }/* if ( sngss7_test_ckt_flag ( sngss7_info, FLAG_GRP_RESET_TX ) ) */ } /* if ( last_state != HANGUP && !PAUSED */ /* if the sig_status is up...bring it down */ @@ -946,10 +944,10 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) ftdm_span_send_signal (ftdmchan->span, &sigev); } - if (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX)) { /* set the grp reset done flag so we know we have finished this reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - } /* if (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX)) */ + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); + } /* if (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX)) */ if (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_INUSE)) { @@ -987,17 +985,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /* switch (ftdmchan->last_state) */ } else { /* check if this an incoming RSC or we have a response already */ - if (sngss7_test_flag (sngss7_info, FLAG_RESET_RX) || - sngss7_test_flag (sngss7_info, FLAG_RESET_TX_RSP) || - sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) || - sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX) || + sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX_RSP) || + sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX_RSP) || + sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX_CMPLT)) { - SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan, "Reset processed moving to DOWN (0x%X)\n", sngss7_info->ckt_flags); /* go to a down state to clear the channel and send the response */ ftdm_set_state_locked (ftdmchan, FTDM_CHANNEL_STATE_DOWN); } else { - SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan, "Waiting on Reset Rsp/Grp Reset to move to DOWN (0x%X)\n", sngss7_info->ckt_flags); } } @@ -1005,20 +1003,20 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /**************************************************************************/ case FTDM_CHANNEL_STATE_SUSPENDED: /* circuit has been blocked */ - SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->flags); + SS7_DEBUG_CHAN(ftdmchan,"Current flags: 0x%X\n", sngss7_info->ckt_flags); /**********************************************************************/ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { SS7_DEBUG_CHAN(ftdmchan, "Processing RESUME%s\n", ""); /* clear the RESUME flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); /* if there are any resets present */ - if ((sngss7_test_flag (sngss7_info, FLAG_RESET_TX)) || - (sngss7_test_flag (sngss7_info, FLAG_RESET_RX)) || - (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_TX)) || - (sngss7_test_flag (sngss7_info, FLAG_GRP_RESET_RX))) { + if ((sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_TX)) || + (sngss7_test_ckt_flag (sngss7_info, FLAG_RESET_RX)) || + (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_TX)) || + (sngss7_test_ckt_flag (sngss7_info, FLAG_GRP_RESET_RX))) { /* go back to the reset state */ goto suspend_goto_restart; @@ -1034,7 +1032,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { SS7_DEBUG_CHAN(ftdmchan, "Processing PAUSE%s\n", ""); /* bring the sig status down */ @@ -1044,9 +1042,9 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) /* go back to the last state */ goto suspend_goto_last; - } /* if (sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ + } /* if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) { */ /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_RX flag %s\n", ""); /* bring the sig status down */ @@ -1061,11 +1059,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){ + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX)){ SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_RX flag %s\n", ""); /* clear the unblock flag */ - sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_clear_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); /* bring the sig status up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; @@ -1080,7 +1078,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_BLOCK_TX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_BLOCK_TX flag %s\n", ""); /* bring the sig status down */ @@ -1095,11 +1093,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)){ + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX)){ SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_MN_UNBLK_TX flag %s\n", ""); /* clear the unblock flag */ - sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); + sngss7_clear_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_TX); /* bring the sig status up */ sigev.event_id = FTDM_SIGEVENT_SIGSTATUS_CHANGED; @@ -1114,7 +1112,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) } /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_LC_BLOCK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_BLOCK_RX flag %s\n", ""); /* send a BLA */ @@ -1124,11 +1122,11 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_LC_UNBLK_RX)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_LC_UNBLK_RX flag %s\n", ""); /* clear the unblock flag */ - sngss7_clear_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); + sngss7_clear_ckt_flag (sngss7_info, FLAG_CKT_MN_UNBLK_RX); /* send a uba */ /*ft_to_sngss7_uba(ftdmchan);*/ @@ -1137,7 +1135,7 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } /**********************************************************************/ - if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_UCIC_BLOCK)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_BLOCK flag %s\n", ""); /* bring the channel signaling status to down */ @@ -1157,17 +1155,17 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan) goto suspend_goto_last; } - if (sngss7_test_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) { + if (sngss7_test_ckt_flag (sngss7_info, FLAG_CKT_UCIC_UNBLK)) { SS7_DEBUG_CHAN(ftdmchan, "Processing CKT_UCIC_UNBLK flag %s\n", "");; /* remove the UCIC block flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* remove the UCIC unblock flag */ - sngss7_clear_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); + sngss7_clear_ckt_flag(sngss7_info, FLAG_CKT_UCIC_UNBLK); /* throw the channel into reset to sync states */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); /* bring the channel into restart again */ goto suspend_goto_restart; @@ -1232,9 +1230,9 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) } /* check if there is a remote block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { /* the channel is blocked...can't send any calls here */ SS7_ERROR_CHAN(ftdmchan, "Requested channel is remotely blocked, re-hunt channel!%s\n", " "); @@ -1242,9 +1240,9 @@ static FIO_CHANNEL_OUTGOING_CALL_FUNCTION(ftdm_sangoma_ss7_outgoing_call) } /* check if there is a local block */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_HW_BLOCK_TX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_TX))) { /* KONRAD FIX ME : we should check if this is a TEST call and allow it */ @@ -1339,48 +1337,6 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) SS7_INFO ("Starting span %s:%u.\n", span->name, span->span_id); - /* throw the channels in pause */ - for (x = 1; x < (span->chan_count + 1); x++) { - /* extract the channel structure and sngss7 channel data */ - ftdmchan = span->channels[x]; - if (ftdmchan->call_data == NULL) continue; - sngss7_info = ftdmchan->call_data; - sngss7_span = ftdmchan->span->signal_data; - sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; - - - /* lock the channel */ - ftdm_mutex_lock(ftdmchan->mutex); - - /* check if the interface is paused or resumed */ - if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { - /* throw the pause flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_RESUME); - sngss7_set_flag(sngss7_info, FLAG_INFID_PAUSED); - } else { - /* throw the pause flag */ - sngss7_clear_flag(sngss7_info, FLAG_INFID_PAUSED); - sngss7_set_flag(sngss7_info, FLAG_INFID_RESUME); - } -#if 0 - /* throw the grp reset flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX); - if (x == 1) { - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; - sngss7_span->tx_grs.range = span->chan_count -1; - } -#else - /* throw the channel into reset */ - sngss7_set_flag(sngss7_info, FLAG_RESET_TX); -#endif - /* throw the channel to suspend */ - ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); - - /* unlock the channel */ - ftdm_mutex_unlock(ftdmchan->mutex); - } - /* clear the monitor thread stop flag */ ftdm_clear_flag (span, FTDM_SPAN_STOP_THREAD); ftdm_clear_flag (span, FTDM_SPAN_IN_THREAD); @@ -1397,6 +1353,52 @@ static ftdm_status_t ftdm_sangoma_ss7_start(ftdm_span_t * span) return FTDM_FAIL; } + /* confirm the state of all isup interfaces*/ + check_status_of_all_isup_intf(); + + /* throw the channels in pause */ + for (x = 1; x < (span->chan_count + 1); x++) { + /* extract the channel structure and sngss7 channel data */ + ftdmchan = span->channels[x]; + if (ftdmchan->call_data == NULL) continue; + sngss7_info = ftdmchan->call_data; + sngss7_span = ftdmchan->span->signal_data; + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; + + /* lock the channel */ + ftdm_mutex_lock(ftdmchan->mutex); + + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is PAUSED\n", sngss7_intf->id); + /* throw the pause flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + } else { + SS7_DEBUG_CHAN(ftdmchan, "ISUP intf %d is RESUMED\n", sngss7_intf->id); + /* throw the resume flag */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + } +#if 0 + /* throw the grp reset flag */ + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); + if (x == 1) { + sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_span->tx_grs.circuit = sngss7_info->circuit->id; + sngss7_span->tx_grs.range = span->chan_count -1; + } +#else + /* throw the channel into reset */ + sngss7_set_ckt_flag(sngss7_info, FLAG_RESET_TX); +#endif + /* throw the channel to suspend */ + ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); + + /* unlock the channel */ + ftdm_mutex_unlock(ftdmchan->mutex); + } + SS7_DEBUG ("Finished starting span %s:%u.\n", span->name, span->span_id); return FTDM_SUCCESS; @@ -1537,7 +1539,6 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sng_event.cc.sng_umsg_ind = sngss7_umsg_ind; sng_event.cc.sng_susp_ind = sngss7_susp_ind; sng_event.cc.sng_resm_ind = sngss7_resm_ind; - sng_event.cc.sng_ssp_sta_cfm = sngss7_ssp_sta_cfm; sng_event.sm.sng_log = handle_sng_log; sng_event.sm.sng_mtp1_alarm = handle_sng_mtp1_alarm; @@ -1545,9 +1546,10 @@ static FIO_SIG_LOAD_FUNCTION(ftdm_sangoma_ss7_init) sng_event.sm.sng_mtp3_alarm = handle_sng_mtp3_alarm; 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; /* initalize sng_ss7 library */ - sng_isup_init (&sng_event); + sng_isup_init_gen(&sng_event); /* print the version of the library being used */ sng_isup_version(&major, &minor, &build); @@ -1566,7 +1568,32 @@ static FIO_SIG_UNLOAD_FUNCTION(ftdm_sangoma_ss7_unload) ftdm_log (FTDM_LOG_INFO, "Starting ftmod_sangoma_ss7 unload...\n"); - sng_isup_free(); + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC)) { + sng_isup_free_cc(); + } + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP)) { + ftmod_ss7_shutdown_isup(); + sng_isup_free_isup(); + } + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3)) { + ftmod_ss7_shutdown_mtp3(); + sng_isup_free_mtp3(); + } + + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { + ftmod_ss7_shutdown_mtp2(); + sng_isup_free_mtp2(); + sng_isup_free_mtp1(); + } + + ftmod_ss7_shutdown_relay(); + sng_isup_free_relay(); + + sng_isup_free_sm(); + + sng_isup_free_gen(); ftdm_log (FTDM_LOG_INFO, "Finished ftmod_sangoma_ss7 unload!\n"); return FTDM_SUCCESS; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h index f28547f9fe..5272aa8bac 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_main.h @@ -82,12 +82,6 @@ typedef enum { HOLE } sng_ckt_type_t; -typedef enum { - CONFIGURED = (1 << 0), - ACTIVE = (1 << 1), - SNGSS7_PAUSED = (1 << 7) -} sng_flag_t; - typedef enum { SNGSS7_LPA_FOR_COT = (1 << 0), /* send LPA when COT arrives */ SNGSS7_ACM_OBCI_BITA = (1 << 10) /* in-band indication */ @@ -98,84 +92,124 @@ typedef enum { SNG_CALLING = 2 } sng_addr_type_t; -typedef struct sng_mtp_link { - char name[MAX_NAME_LEN]; - uint32_t id; - uint32_t flags; - struct { - uint32_t span; - uint32_t chan; - } mtp1; - struct { - uint32_t lssuLength; - uint32_t errorType; - uint32_t linkType; - uint32_t mtp1Id; - uint32_t t1; - uint32_t t2; - uint32_t t3; - uint32_t t4n; - uint32_t t4e; - uint32_t t5; - uint32_t t6; - uint32_t t7; - } mtp2; - struct { - uint32_t priority; - uint32_t linkType; - uint32_t switchType; - uint32_t apc; - uint32_t spc; - uint32_t ssf; - uint32_t slc; - uint32_t linkSetId; - uint32_t mtp2Id; - uint32_t t1; - uint32_t t2; - uint32_t t3; - uint32_t t4; - uint32_t t5; - uint32_t t6; - uint32_t t7; - uint32_t t8; - uint32_t t9; - uint32_t t10; - uint32_t t11; - uint32_t t12; - uint32_t t13; - uint32_t t14; - uint32_t t15; - uint32_t t16; - uint32_t t17; - uint32_t t18; - uint32_t t19; - uint32_t t20; - uint32_t t21; - uint32_t t22; - uint32_t t23; - uint32_t t24; - uint32_t t25; - uint32_t t27; - uint32_t t28; - uint32_t t29; - uint32_t t30; - uint32_t t31; - uint32_t t32; - uint32_t t33; - uint32_t t34; - uint32_t t35; - uint32_t t36; - uint32_t t37; - uint32_t tcraft; - uint32_t tflc; - uint32_t tbnd; - } mtp3; -} sng_mtp_link_t; +typedef struct sng_mtp2_error_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_type; +} sng_mtp2_error_type_t; + +typedef struct sng_link_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_mtp2_type; + uint32_t tril_mtp3_type; +} sng_link_type_t; + +typedef struct sng_switch_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_mtp3_type; + uint32_t tril_isup_type; +} sng_switch_type_t; + +typedef struct sng_ssf_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_type; +} sng_ssf_type_t; + +typedef struct sng_cic_cntrl_type { + int init; + char sng_type[MAX_NAME_LEN]; + uint32_t tril_type; +} sng_cic_cntrl_type_t; + +typedef struct sng_mtp1_link { + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t id; + uint32_t span; + uint32_t chan; +} sng_mtp1_link_t; + +typedef struct sng_mtp2_link { + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t id; + uint32_t lssuLength; + uint32_t errorType; + uint32_t linkType; + uint32_t mtp1Id; + uint32_t mtp1ProcId; + uint32_t t1; + uint32_t t2; + uint32_t t3; + uint32_t t4n; + uint32_t t4e; + uint32_t t5; + uint32_t t6; + uint32_t t7; +} sng_mtp2_link_t; + +typedef struct sng_mtp3_link { + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t id; + uint32_t priority; + uint32_t linkType; + uint32_t switchType; + uint32_t apc; + uint32_t spc; + uint32_t ssf; + uint32_t slc; + uint32_t linkSetId; + uint32_t mtp2Id; + uint32_t mtp2ProcId; + uint32_t t1; + uint32_t t2; + uint32_t t3; + uint32_t t4; + uint32_t t5; + uint32_t t6; + uint32_t t7; + uint32_t t8; + uint32_t t9; + uint32_t t10; + uint32_t t11; + uint32_t t12; + uint32_t t13; + uint32_t t14; + uint32_t t15; + uint32_t t16; + uint32_t t17; + uint32_t t18; + uint32_t t19; + uint32_t t20; + uint32_t t21; + uint32_t t22; + uint32_t t23; + uint32_t t24; + uint32_t t25; + uint32_t t27; + uint32_t t28; + uint32_t t29; + uint32_t t30; + uint32_t t31; + uint32_t t32; + uint32_t t33; + uint32_t t34; + uint32_t t35; + uint32_t t36; + uint32_t t37; + uint32_t tcraft; + uint32_t tflc; + uint32_t tbnd; +} sng_mtp3_link_t; typedef struct sng_link_set { - uint32_t id; char name[MAX_NAME_LEN]; uint32_t flags; + uint32_t id; uint32_t apc; uint32_t linkType; uint32_t switchType; @@ -186,9 +220,9 @@ typedef struct sng_link_set { } sng_link_set_t; typedef struct sng_route { - uint32_t id; char name[MAX_NAME_LEN]; uint32_t flags; + uint32_t id; uint32_t dpc; uint32_t cmbLinkSetId; uint32_t linkSetId; @@ -211,10 +245,10 @@ typedef struct sng_route { } sng_route_t; typedef struct sng_isup_intf { - uint32_t id; char name[MAX_NAME_LEN]; uint32_t options; uint32_t flags; + uint32_t id; uint32_t spc; uint32_t dpc; uint32_t switchType; @@ -222,9 +256,6 @@ typedef struct sng_isup_intf { uint32_t mtpRouteId; uint32_t ssf; uint32_t isap; - uint32_t clg_nadi; - uint32_t cld_nadi; - uint32_t min_digits; uint16_t t4; uint32_t t10; uint32_t t11; @@ -241,7 +272,6 @@ typedef struct sng_isup_intf { uint32_t t29; uint32_t t30; uint32_t t32; - uint32_t t35; uint32_t t37; uint32_t t38; uint32_t t39; @@ -251,15 +281,23 @@ typedef struct sng_isup_intf { } sng_isup_inf_t; typedef struct sng_isup_ckt { - uint32_t id; + uint32_t options; uint32_t flags; + uint32_t ckt_flags; + uint32_t procId; + uint32_t id; + uint32_t ccSpanId; uint32_t span; uint32_t chan; uint32_t type; /* VOICE/SIG/HOLE */ uint32_t cic; uint32_t infId; - uint32_t ssf; uint32_t typeCntrl; + uint32_t ssf; + uint32_t switchType; + uint32_t clg_nadi; + uint32_t cld_nadi; + uint32_t min_digits; void *obj; uint16_t t3; uint16_t t12; @@ -268,12 +306,13 @@ typedef struct sng_isup_ckt { uint16_t t15; uint16_t t16; uint16_t t17; + uint32_t t35; uint16_t tval; } sng_isup_ckt_t; typedef struct sng_nsap { - uint32_t id; uint32_t flags; + uint32_t id; uint32_t suId; uint32_t spId; uint32_t nwId; @@ -311,15 +350,30 @@ typedef struct sng_isap { uint32_t tfnlrelrsp; } sng_isap_t; +typedef struct sng_relay { + uint32_t id; + char name[MAX_NAME_LEN]; + uint32_t flags; + uint32_t type; + uint32_t port; + char hostname[RY_REMHOSTNAME_SIZE]; + uint32_t procId; +} sng_relay_t; + typedef struct sng_ss7_cfg { uint32_t spc; + uint32_t procId; char license[MAX_PATH]; char signature[MAX_PATH]; - sng_mtp_link_t mtpLink[MAX_MTP_LINKS+1]; + uint32_t flags; + sng_relay_t relay[MAX_RELAY_CHANNELS+1]; + sng_mtp1_link_t mtp1Link[MAX_MTP_LINKS+1]; + sng_mtp2_link_t mtp2Link[MAX_MTP_LINKS+1]; + sng_mtp3_link_t mtp3Link[MAX_MTP_LINKS+1]; sng_link_set_t mtpLinkSet[MAX_MTP_LINKSETS+1]; sng_route_t mtpRoute[MAX_MTP_ROUTES+1]; sng_isup_inf_t isupIntf[MAX_ISUP_INFS+1]; - sng_isup_ckt_t isupCkt[MAX_ISUP_CKTS+1]; + sng_isup_ckt_t isupCkt[10000]; /* KONRAD - only need 2000 ( and 0-1000 aren't used) since other servers are registerd else where */ sng_nsap_t nsap[MAX_NSAPS+1]; sng_isap_t isap[MAX_ISAPS+1]; }sng_ss7_cfg_t; @@ -365,7 +419,7 @@ typedef struct sngss7_chan_data { uint32_t spInstId; uint32_t spId; uint8_t globalFlg; - uint32_t flags; + uint32_t ckt_flags; sngss7_glare_data_t glare; sngss7_timer_data_t t35; }sngss7_chan_data_t; @@ -407,8 +461,6 @@ typedef struct sngss7_event_data } sngss7_event_data_t; - - typedef enum { FLAG_RESET_RX = (1 << 0), FLAG_RESET_TX = (1 << 1), @@ -439,15 +491,39 @@ typedef enum { FLAG_GRP_MN_BLOCK_RX = (1 << 26), FLAG_GRP_MN_BLOCK_TX = (1 << 27), FLAG_GRP_HW_UNBLK_TX = (1 << 28), - FLAG_GRP_MN_UNBLK_TX = (1 << 29) -} flag_t; + FLAG_GRP_MN_UNBLK_TX = (1 << 29), + FLAG_RELAY_DOWN = (1 << 30) +} sng_ckt_flag_t; + +/* valid for every cfg array except circuits */ +typedef enum { + SNGSS7_CONFIGURED = (1 << 0), + SNGSS7_ACTIVE = (1 << 1), + SNGSS7_RELAY_INIT = (1 << 3), + SNGSS7_PAUSED = (1 << 7) /* for isup interfaces */ +} sng_cfg_flag_t; + +typedef enum { + SNGSS7_SM = (1 << 0), + SNGSS7_RY = (1 << 1), + SNGSS7_MTP1 = (1 << 2), + SNGSS7_MTP2 = (1 << 3), + SNGSS7_MTP3 = (1 << 4), + SNGSS7_ISUP = (1 << 5), + SNGSS7_CC = (1 << 6) +} sng_task_flag_t; /******************************************************************************/ /* GLOBALS ********************************************************************/ -extern ftdm_sngss7_data_t g_ftdm_sngss7_data; -extern uint32_t sngss7_id; -extern ftdm_sched_t *sngss7_sched; -extern int cmbLinkSetId; +extern ftdm_sngss7_data_t g_ftdm_sngss7_data; +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[]; +extern sng_mtp2_error_type_t sng_mtp2_error_type_map[]; +extern sng_cic_cntrl_type_t sng_cic_cntrl_type_map[]; +extern uint32_t sngss7_id; +extern ftdm_sched_t *sngss7_sched; +extern int cmbLinkSetId; /******************************************************************************/ /* PROTOTYPES *****************************************************************/ @@ -461,6 +537,12 @@ void handle_sng_mtp2_alarm(Pst *pst, SdMngmt *sta); 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); + +/* in ftmod_sangoma_ss7_relay.c */ +ftdm_status_t handle_relay_connect(RyMngmt *sta); +ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta); +ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta); /* in ftmod_sangoma_ss7_cfg.c */ int ft_to_sngss7_cfg_all(void); @@ -484,20 +566,36 @@ int ftmod_ss7_cc_isap_config(int id); /* in ftmod_sangoma_ss7_cntrl.c */ int ft_to_sngss7_activate_all(void); -int ftmod_ss7_inhibit_mtplink(uint32_t id); -int ftmod_ss7_uninhibit_mtplink(uint32_t id); -int ftmod_ss7_activate_mtplink(uint32_t id); -int ftmod_ss7_deactivate_mtplink(uint32_t id); -int ftmod_ss7_deactivate2_mtplink(uint32_t id); +int ftmod_ss7_inhibit_mtp3link(uint32_t id); +int ftmod_ss7_uninhibit_mtp3link(uint32_t id); +int ftmod_ss7_bind_mtp3link(uint32_t id); +int ftmod_ss7_unbind_mtp3link(uint32_t id); +int ftmod_ss7_activate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate_mtp3link(uint32_t id); +int ftmod_ss7_deactivate2_mtp3link(uint32_t id); int ftmod_ss7_activate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate_mtplinkSet(uint32_t id); int ftmod_ss7_deactivate2_mtplinkSet(uint32_t id); -int ftmod_ss7_lpo_mtplink(uint32_t id); -int ftmod_ss7_lpr_mtplink(uint32_t id); +int ftmod_ss7_lpo_mtp3link(uint32_t id); +int ftmod_ss7_lpr_mtp3link(uint32_t id); + +int ftmod_ss7_shutdown_isup(void); +int ftmod_ss7_shutdown_mtp3(void); +int ftmod_ss7_shutdown_mtp2(void); +int ftmod_ss7_shutdown_relay(void); + +int ftmod_ss7_disable_grp_mtp3Link(uint32_t procId); +int ftmod_ss7_enable_grp_mtp3Link(uint32_t procId); + +int ftmod_ss7_disable_grp_mtp2Link(uint32_t procId); /* in ftmod_sangoma_ss7_sta.c */ -int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm); +int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm); +int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status); +int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm); /* in ftmod_sangoma_ss7_out.c */ @@ -607,6 +705,14 @@ ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); +int find_mtp2_error_type_in_map(const char *err_type); +int find_link_type_in_map(const char *linkType); +int find_switch_type_in_map(const char *switchType); +int find_ssf_type_in_map(const char *ssfType); +int find_cic_cntrl_in_map(const char *cntrlType); + +ftdm_status_t check_status_of_all_isup_intf(void); + /* in ftmod_sangoma_ss7_timers.c */ void handle_isup_t35(void *userdata); /******************************************************************************/ @@ -739,6 +845,10 @@ void handle_isup_t35(void *userdata); #define sngss7_clear_flag(obj, flag) ((obj)->flags &= ~(flag)) #define sngss7_set_flag(obj, flag) ((obj)->flags |= (flag)) +#define sngss7_test_ckt_flag(obj, flag) ((obj)->ckt_flags & flag) +#define sngss7_clear_ckt_flag(obj, flag) ((obj)->ckt_flags &= ~(flag)) +#define sngss7_set_ckt_flag(obj, flag) ((obj)->ckt_flags |= (flag)) + #define sngss7_test_options(obj, option) ((obj)->options & option) #define sngss7_clear_options(obj, option) ((obj)->options &= ~(option)) #define sngss7_set_options(obj, option) ((obj)->options |= (option)) diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c index ec8d7df12a..06b0b2183e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_out.c @@ -125,9 +125,9 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.txMedReq.trMedReq.pres = PRSNT_NODEF; iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability; - if ((g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS88) || - (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS92) || - (g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].switchType == LSI_SW_ANS95)) { + if ((g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS88) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS92) || + (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].switchType == LSI_SW_ANS95)) { /* include only if we're running ANSI */ iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF; @@ -178,7 +178,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) iam.usrServInfoA.rateMultiplier.pres = PRSNT_NODEF; iam.usrServInfoA.rateMultiplier.val = 0x1; /* 1x rate multipler */ } /* if ANSI */ - + /* copy down the called number information */ copy_cdPtyNum_to_sngss7 (&ftdmchan->caller_data, &iam.cdPtyNum); @@ -192,7 +192,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling NADI value \"%s\"\n", clg_nadi); iam.cgPtyNum.natAddrInd.val = atoi(clg_nadi); } else { - iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].clg_nadi; + iam.cgPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].clg_nadi; SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLG, using \"%d\"\n", iam.cgPtyNum.natAddrInd.val); } @@ -201,7 +201,7 @@ void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan) SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called NADI value \"%s\"\n", cld_nadi); iam.cdPtyNum.natAddrInd.val = atoi(cld_nadi); } else { - iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId].cld_nadi; + iam.cdPtyNum.natAddrInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].cld_nadi; SS7_DEBUG_CHAN(ftdmchan,"No user supplied NADI value found for CLD, using \"%d\"\n", iam.cdPtyNum.natAddrInd.val); } @@ -310,7 +310,6 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) SS7_FUNC_TRACE_ENTER (__FUNCTION__); sngss7_chan_data_t *sngss7_info = ftdmchan->call_data; - sng_isup_inf_t *isup_intf = &g_ftdm_sngss7_data.cfg.isupIntf[sngss7_info->circuit->infId]; SiCnStEvnt acm; memset (&acm, 0x0, sizeof (acm)); @@ -360,8 +359,8 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan) acm.bckCallInd.sccpMethInd.val = SCCPMTH_NOIND; /* fill in any optional parameters */ - if (sngss7_test_options(isup_intf, SNGSS7_ACM_OBCI_BITA)) { - SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", isup_intf->options); + if (sngss7_test_options(&g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id], SNGSS7_ACM_OBCI_BITA)) { + SS7_DEBUG_CHAN(ftdmchan, "Found ACM_OBCI_BITA flag:0x%X\n", g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].options); acm.optBckCalInd.eh.pres = PRSNT_NODEF; acm.optBckCalInd.inbndInfoInd.pres = PRSNT_NODEF; acm.optBckCalInd.inbndInfoInd.val = 0x1; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c new file mode 100644 index 0000000000..05ea69ea69 --- /dev/null +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_relay.c @@ -0,0 +1,318 @@ +/* + * Copyright (c) 2009|Konrad Hammel + * 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. + */ + +/* INCLUDE ********************************************************************/ +#include "ftmod_sangoma_ss7_main.h" +/******************************************************************************/ + +/* DEFINES ********************************************************************/ +/******************************************************************************/ + +/* GLOBALS ********************************************************************/ +/******************************************************************************/ + +/* PROTOTYPES *****************************************************************/ +ftdm_status_t handle_relay_connect(RyMngmt *sta); +ftdm_status_t handle_relay_disconnect(RyMngmt *sta); + +static ftdm_status_t enable_all_ckts_for_relay(void); +static ftdm_status_t reconfig_all_ckts_for_relay(void); +static ftdm_status_t disable_all_ckts_for_relay(void); +static ftdm_status_t block_all_ckts_for_relay(uint32_t procId); +static ftdm_status_t disable_all_sigs_for_relay(uint32_t procId); +static ftdm_status_t disble_all_mtp2_sigs_for_relay(void); +/******************************************************************************/ + +/* FUNCTIONS ******************************************************************/ +ftdm_status_t handle_relay_connect(RyMngmt *sta) +{ + sng_relay_t *sng_relay = &g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id]; + + + /* test if this is the first time the channel comes up */ + if (!sngss7_test_flag(sng_relay, SNGSS7_RELAY_INIT)) { + SS7_DEBUG("Relay Channel %d initial connection UP\n", sng_relay->id); + + /* mark the channel as being up */ + sngss7_set_flag(sng_relay, SNGSS7_RELAY_INIT); + } else { + SS7_DEBUG("Relay Channel %d connection UP\n", sng_relay->id); + + /* react based on type of channel */ + switch (sng_relay->type) { + /******************************************************************/ + case (LRY_CT_TCP_CLIENT): + /* reconfigure all ISUP ckts, since the main system would have lost all configs */ + if (reconfig_all_ckts_for_relay()) { + SS7_ERROR("Failed to reconfigure ISUP Ckts!\n"); + + /* we're done....this is very bad! */ + } else { + enable_all_ckts_for_relay(); + } + + break; + /******************************************************************/ + case (LRY_CT_TCP_SERVER): + /*unblock_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid);*/ + ftmod_ss7_enable_grp_mtp3Link(sta->t.usta.s.ryUpUsta.id); + + break; + /******************************************************************/ + default: + break; + /******************************************************************/ + } /* switch (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type) */ + } /* intial up? */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_relay_disconnect_on_error(RyMngmt *sta) +{ + + /* check which procId is in error, if it is 1, disable the ckts */ + if (sta->t.usta.s.ryErrUsta.errPid == 1 ) { + disable_all_ckts_for_relay(); + + disble_all_mtp2_sigs_for_relay(); + } + + /* check if the channel is a server, means we just lost a MGW */ + if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryErrUsta.errPid].type == LRY_CT_TCP_SERVER) { + block_all_ckts_for_relay(sta->t.usta.s.ryErrUsta.errPid); + + disable_all_sigs_for_relay(sta->t.usta.s.ryErrUsta.errPid); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t handle_relay_disconnect_on_down(RyMngmt *sta) +{ + + /* check if the channel is a server, means we just lost a MGW */ + if (g_ftdm_sngss7_data.cfg.relay[sta->t.usta.s.ryUpUsta.id].type == LRY_CT_TCP_SERVER) { + block_all_ckts_for_relay(sta->t.usta.s.ryUpUsta.id); + + disable_all_sigs_for_relay(sta->t.usta.s.ryUpUsta.id); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t disable_all_ckts_for_relay(void) +{ + sngss7_chan_data_t *sngss7_info = NULL; + ftdm_channel_t *ftdmchan = NULL; + int x; + + SS7_INFO("Disabling all ckts becuase of Relay loss\n"); + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**********************************************************************/ + /* make sure this is voice channel */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCkt[x].id, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCkt[x].id); + x++; + continue; + } + + /* throw the relay_down flag */ + sngss7_set_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); + + /* throw the channel infId status flags to PAUSED ... they will be executed next process cycle */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t enable_all_ckts_for_relay(void) +{ + sngss7_chan_data_t *sngss7_info = NULL; + sng_isup_inf_t *sngIntf = NULL; + ftdm_channel_t *ftdmchan = NULL; + int x; + + SS7_INFO("Enabling all ckts becuase of Relay connection\n"); + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**********************************************************************/ + /* make sure this is voice channel */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + /* get the ftdmchan and ss7_chan_data from the circuit */ + if (extract_chan_data(g_ftdm_sngss7_data.cfg.isupCkt[x].id, &sngss7_info, &ftdmchan)) { + SS7_ERROR("Failed to extract channel data for circuit = %d!\n", g_ftdm_sngss7_data.cfg.isupCkt[x].id); + x++; + continue; + } + + /* bring the relay_down flag down */ + sngss7_clear_ckt_flag(sngss7_info, FLAG_RELAY_DOWN); + + sngIntf = &g_ftdm_sngss7_data.cfg.isupIntf[g_ftdm_sngss7_data.cfg.isupCkt[x].infId]; + + /* check if the interface is paused or resumed */ + if (sngss7_test_flag(sngIntf, SNGSS7_PAUSED)) { + /* don't bring the channel resume flag up...the interface is down */ + SS7_DEBUG_CHAN(ftdmchan, "ISUP interface (%d) set to paused, not resuming channel\n", sngIntf->id); + } else { + SS7_DEBUG_CHAN(ftdmchan, "ISUP interface (%d) set to resume, resuming channel\n", sngIntf->id); + /* throw the channel infId status flags to PAUSED ... they will be executed next process cycle */ + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_RESUME); + sngss7_set_ckt_flag(sngss7_info, FLAG_INFID_PAUSED); + } + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t reconfig_all_ckts_for_relay(void) +{ +#if 1 + int x; + int ret; + + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + + ret = ftmod_ss7_isup_ckt_config(x); + if (ret) { + SS7_CRITICAL("ISUP CKT %d configuration FAILED (%d)!\n", x, ret); + return 1; + } else { + SS7_INFO("ISUP CKT %d configuration DONE!\n", x); + } + + } /* if ( g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* set the SNGSS7_CONFIGURED flag */ + g_ftdm_sngss7_data.cfg.isupCkt[x].flags |= SNGSS7_CONFIGURED; + + x++; + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ +#endif + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t block_all_ckts_for_relay(uint32_t procId) +{ + int x; + + SS7_INFO("BLOcking all ckts on ProcID = %d\n", procId); + + /* we just lost connection to this procId, send out a block for all these circuits */ + x = (procId * 1000) + 1; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**************************************************************************/ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) { + /* send out a BLO */ + sng_cc_sta_request (1, + 0, + 0, + g_ftdm_sngss7_data.cfg.isupCkt[x].id, + 0, + SIT_STA_CIRBLOREQ, + NULL); + + } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].type == VOICE) */ + + /* move along */ + x++; + /**************************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t disable_all_sigs_for_relay(uint32_t procId) +{ + SS7_INFO("Disalbing all sig links on ProcID = %d\n", procId); + + ftmod_ss7_disable_grp_mtp3Link(procId); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +ftdm_status_t disble_all_mtp2_sigs_for_relay(void) +{ + /* check if there is a local mtp2 link*/ + if (sngss7_test_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2)) { + SS7_INFO("Disalbing all mtp2 sig links on local system\n"); + + ftmod_ss7_disable_grp_mtp2Link(1); + } + + return FTDM_SUCCESS; + +} + +/******************************************************************************/ +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ +/******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c index 1235238452..2f507a2ad4 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_sta.c @@ -42,12 +42,43 @@ /******************************************************************************/ /* PROTOTYPES *****************************************************************/ -int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm); +int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm); +int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm); int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm); +int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status); +int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ -int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm) +int ftmod_ss7_mtp1link_sta(uint32_t id, L1Mngmt *cfm) +{ + + return 1; +} + +/******************************************************************************/ +int ftmod_ss7_mtp2link_sta(uint32_t id, SdMngmt *cfm) +{ + SdMngmt sta; + Pst pst; + + memset(&sta, 0x0, sizeof(sta)); + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSD; + + sta.hdr.elmId.elmnt = STDLSAP; + sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp2Link[id].id; + + return(sng_sta_mtp2(&pst, &sta, cfm)); +} + +/******************************************************************************/ +int ftmod_ss7_mtp3link_sta(uint32_t id, SnMngmt *cfm) { SnMngmt sta; Pst pst; @@ -60,8 +91,13 @@ int ftmod_ss7_mtplink_sta(uint32_t id, SnMngmt *cfm) /* insert the destination Entity */ pst.dstEnt = ENTSN; + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + sta.hdr.elmId.elmnt = STDLSAP; - sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLink[id].id; + sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtp3Link[id].id; return(sng_sta_mtp3(&pst, &sta, cfm)); } @@ -80,13 +116,77 @@ int ftmod_ss7_mtplinkSet_sta(uint32_t id, SnMngmt *cfm) /* insert the destination Entity */ pst.dstEnt = ENTSN; + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + sta.hdr.elmId.elmnt = STLNKSET; sta.hdr.elmId.elmntInst1 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].id; sta.hdr.elmId.elmntInst2 = g_ftdm_sngss7_data.cfg.mtpLinkSet[id].links[0]; return(sng_sta_mtp3(&pst, &sta, cfm)); } + /******************************************************************************/ +int ftmod_ss7_isup_intf_sta(uint32_t id, uint8_t *status) +{ + SiMngmt sta; + SiMngmt cfm; + Pst pst; + int ret; + + memset(&sta, 0x0, sizeof(sta)); + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTSI; + + /* check the for the correct ProcId and make sure it goes to the right system */ + if (g_ftdm_sngss7_data.cfg.procId != 1) { + pst.dstProcId = 1; + } + + /* request the status of an inftId */ + sta.hdr.entId.ent = ENTSI; + sta.hdr.entId.inst = S_INST; + sta.hdr.msgType = TSSTA; + sta.hdr.elmId.elmnt = SI_STINTF; + + sta.t.ssta.elmntId.intfId = id; + + ret = sng_sta_isup(&pst, &sta, &cfm); + + *status = cfm.t.ssta.cfm.s.intf.state; + + return(ret); +} + +/******************************************************************************/ +int ftmod_ss7_relay_status(uint32_t id, RyMngmt *cfm) +{ + RyMngmt sta; + Pst pst; + + memset(&sta, 0x0, sizeof(sta)); + + /* initalize the post structure */ + smPstInit(&pst); + + /* insert the destination Entity */ + pst.dstEnt = ENTRY; + + sta.hdr.entId.ent = ENTRY; + sta.hdr.entId.inst = S_INST; + sta.hdr.msgType = TSSTA; + sta.hdr.elmId.elmnt = STCHSTA; + sta.hdr.elmId.elmntInst1 = id; + + + return(sng_sta_relay(&pst, &sta, cfm)); +} /******************************************************************************/ /* For Emacs: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c index 23617c9147..683caf2352 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_support.c @@ -75,6 +75,14 @@ ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info); ftdm_status_t encode_subAddrIE_nsap(const char *subAddr, char *subAddrIE, int type); ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int type); + +int find_mtp2_error_type_in_map(const char *err_type); +int find_link_type_in_map(const char *linkType); +int find_switch_type_in_map(const char *switchType); +int find_ssf_type_in_map(const char *ssfType); +int find_cic_cntrl_in_map(const char *cntrlType); + +ftdm_status_t check_status_of_all_isup_intf(void); /******************************************************************************/ /* FUNCTIONS ******************************************************************/ @@ -432,7 +440,7 @@ int check_cics_in_range(sngss7_chan_data_t *sngss7_info) } /* check if the channel still has the reset flag done is up */ - if (!sngss7_test_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) { + if (!sngss7_test_ckt_flag(tmp_sngss7_info, FLAG_GRP_RESET_RX_DN)) { SS7_DEBUG_CHAN(tmp_ftdmchan, "[CIC:%d] Still processing reset...\n", tmp_sngss7_info->circuit->cic); return 0; } @@ -475,19 +483,19 @@ ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_in int check_for_reset(sngss7_chan_data_t *sngss7_info) { - if (sngss7_test_flag(sngss7_info,FLAG_RESET_RX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_RESET_RX)) { return 1; } - if (sngss7_test_flag(sngss7_info,FLAG_RESET_TX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_RESET_TX)) { return 1; } - if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_RX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_GRP_RESET_RX)) { return 1; } - if (sngss7_test_flag(sngss7_info,FLAG_GRP_RESET_TX)) { + if (sngss7_test_ckt_flag(sngss7_info,FLAG_GRP_RESET_TX)) { return 1; } @@ -498,11 +506,13 @@ int check_for_reset(sngss7_chan_data_t *sngss7_info) /******************************************************************************/ unsigned long get_unique_id(void) { + int procId = sng_get_procId(); - if (sngss7_id < 420000000) { + /* id values are between (procId * 1,000,000) and ((procId + 1) * 1,000,000) */ + if (sngss7_id < ((procId + 1) * 1000000) ) { sngss7_id++; } else { - sngss7_id = 1; + sngss7_id = procId * 1000000; } return(sngss7_id); @@ -525,7 +535,7 @@ ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) } /* check if the GRP_RESET_RX flag is already up */ - if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX)) { /* we have already processed this channel...move along */ continue; } @@ -543,7 +553,7 @@ ftdm_status_t check_if_rx_grs_started(ftdm_span_t *ftdmspan) (g_ftdm_sngss7_data.cfg.isupCkt[sngss7_span->rx_grs.circuit].cic + sngss7_span->rx_grs.range)); /* flag the channel as having received a reset */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX); switch (ftdmchan->state) { /**************************************************************************/ @@ -598,10 +608,10 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) /* check if there is a state change pending on the channel */ if (!ftdm_test_flag(ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { /* check the state to the GRP_RESET_RX_DN flag */ - if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { + if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) { /* this channel is still resetting...do nothing */ goto GRS_UNLOCK_ALL; - } /* if (!sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ + } /* if (!sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN)) */ } else { /* state change pending */ goto GRS_UNLOCK_ALL; @@ -625,16 +635,16 @@ ftdm_status_t check_if_rx_grs_processed(ftdm_span_t *ftdmspan) } /* throw the GRP reset flag complete flag */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); /* move the channel to the down state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); /* update the status map if the ckt is in blocked state */ - if ((sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || - (sngss7_test_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_CKT_MN_BLOCK_TX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX)) || + (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_MN_BLOCK_RX))) { sngss7_span->rx_grs.status[byte] = (sngss7_span->rx_grs.status[byte] | (1 << bit)); } /* if blocked */ @@ -679,7 +689,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) } /* check if the channel is already procoessing the GRA */ - if (sngss7_test_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP)) { /* move along */ continue; } @@ -701,7 +711,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) case FTDM_CHANNEL_STATE_RESTART: /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); /* go to DOWN */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_DOWN); @@ -720,7 +730,7 @@ ftdm_status_t check_if_rx_gra_started(ftdm_span_t *ftdmspan) case FTDM_CHANNEL_STATE_HANGUP_COMPLETE: /* throw the FLAG_RESET_TX_RSP to indicate we have acknowledgement from the remote side */ - sngss7_set_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + sngss7_set_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); break; /**********************************************************************/ @@ -775,7 +785,7 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) sigev.channel = ftdmchan; /* if we have the PAUSED flag and the sig status is still UP */ - if ((sngss7_test_flag(sngss7_info, FLAG_INFID_PAUSED)) && + if ((sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_PAUSED)) && (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_SIG_UP))) { /* clear up any pending state changes */ @@ -790,7 +800,7 @@ ftdm_status_t check_for_res_sus_flag(ftdm_span_t *ftdmspan) /* if the RESUME flag is up go to SUSPENDED to process the flag */ /* after doing this the flag will be cleared */ - if (sngss7_test_flag(sngss7_info, FLAG_INFID_RESUME)) { + if (sngss7_test_ckt_flag(sngss7_info, FLAG_INFID_RESUME)) { /* clear up any pending state changes */ while (ftdm_test_flag (ftdmchan, FTDM_CHANNEL_STATE_CHANGE)) { @@ -839,7 +849,7 @@ ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan) } /* throw the ckt block flag */ - sngss7_set_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); + sngss7_set_ckt_flag(sngss7_info, FLAG_CKT_UCIC_BLOCK); /* set the channel to suspended state */ ftdm_set_state_locked(ftdmchan, FTDM_CHANNEL_STATE_SUSPENDED); @@ -858,9 +868,9 @@ ftdm_status_t process_span_ucic(ftdm_span_t *ftdmspan) ftdm_status_t clear_rx_grs_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an incoming GRS */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_DN); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_RX_CMPLT); return FTDM_SUCCESS; } @@ -892,10 +902,10 @@ ftdm_status_t clear_rx_gra_data(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_tx_grs_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an outgoing GRS */ - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_BASE); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_SENT); - sngss7_clear_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_BASE); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_SENT); + sngss7_clear_ckt_flag(sngss7_info, FLAG_GRP_RESET_TX_RSP); return FTDM_SUCCESS; } @@ -918,7 +928,7 @@ ftdm_status_t clear_tx_grs_data(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an incoming RSC */ - sngss7_clear_flag(sngss7_info, FLAG_RESET_RX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_RX); return FTDM_SUCCESS; } @@ -927,9 +937,9 @@ ftdm_status_t clear_rx_rsc_flags(sngss7_chan_data_t *sngss7_info) ftdm_status_t clear_tx_rsc_flags(sngss7_chan_data_t *sngss7_info) { /* clear all the flags related to an outgoing RSC */ - sngss7_clear_flag(sngss7_info, FLAG_RESET_TX); - sngss7_clear_flag(sngss7_info, FLAG_RESET_SENT); - sngss7_clear_flag(sngss7_info, FLAG_RESET_TX_RSP); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_TX); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_SENT); + sngss7_clear_ckt_flag(sngss7_info, FLAG_RESET_TX_RSP); return FTDM_SUCCESS; } @@ -1147,6 +1157,197 @@ ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int typ return FTDM_SUCCESS; } +/******************************************************************************/ +int find_mtp2_error_type_in_map(const char *err_type) +{ + int i = 0; + + while (sng_mtp2_error_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(err_type, sng_mtp2_error_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_mtp2_error_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_mtp2_error_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_mtp2_error_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_link_type_in_map(const char *linkType) +{ + int i = 0; + + while (sng_link_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(linkType, sng_link_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_link_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_link_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_link_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_switch_type_in_map(const char *switchType) +{ + int i = 0; + + while (sng_switch_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(switchType, sng_switch_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_switch_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_switch_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_switch_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_ssf_type_in_map(const char *ssfType) +{ + int i = 0; + + while (sng_ssf_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(ssfType, sng_ssf_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_ssf_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_ssf_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_ssf_type_map[i].init == 0) */ +} + +/******************************************************************************/ +int find_cic_cntrl_in_map(const char *cntrlType) +{ + int i = 0; + + while (sng_cic_cntrl_type_map[i].init == 1) { + /* check if string matches the sng_type name */ + if (!strcasecmp(cntrlType, sng_cic_cntrl_type_map[i].sng_type)) { + /* we've found a match break from the loop */ + break; + } else { + /* move on to the next on */ + i++; + } + } /* while (sng_cic_cntrl_type_map[i].init == 1) */ + + /* check how we exited the loop */ + if (sng_cic_cntrl_type_map[i].init == 0) { + return -1; + } else { + return i; + } /* if (sng_cic_cntrl_type_map[i].init == 0) */ +} + +/******************************************************************************/ +ftdm_status_t check_status_of_all_isup_intf(void) +{ + sng_isup_inf_t *sngss7_intf = NULL; + uint8_t status = 0xff; + int x; + + /* go through all the isupIntfs and ask the stack to give their current state */ + x = 1; + for (x = 1; x < (MAX_ISUP_INFS + 1); x++) { + /**************************************************************************/ + + if (g_ftdm_sngss7_data.cfg.isupIntf[x].id == 0) continue; + + sngss7_intf = &g_ftdm_sngss7_data.cfg.isupIntf[x]; + + if (ftmod_ss7_isup_intf_sta(sngss7_intf->id, &status)) { + SS7_ERROR("Failed to get status of ISUP intf %d\n", sngss7_intf->id); + continue; + } + + switch (status){ + /**********************************************************************/ + case (SI_INTF_AVAIL): + SS7_DEBUG("State of ISUP intf %d = AVAIL\n", sngss7_intf->id); + + /* check the current state for interface that we know */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + /* we thing the intf is paused...put into resume */ + sngss7_clear_flag(sngss7_intf, SNGSS7_PAUSED); + } else { + /* nothing to since we already know that interface is active */ + } + break; + /**********************************************************************/ + case (SI_INTF_UNAVAIL): + SS7_DEBUG("State of ISUP intf %d = UNAVAIL\n", sngss7_intf->id); + /* check the current state for interface that we know */ + if (sngss7_test_flag(sngss7_intf, SNGSS7_PAUSED)) { + /* nothing to since we already know that interface is active */ + } else { + /* put the interface into pause */ + sngss7_set_flag(sngss7_intf, SNGSS7_PAUSED); + } + break; + /**********************************************************************/ + case (SI_INTF_CONG1): + SS7_DEBUG("State of ISUP intf %d = Congestion 1\n", sngss7_intf->id); + break; + /**********************************************************************/ + case (SI_INTF_CONG2): + SS7_DEBUG("State of ISUP intf %d = Congestion 2\n", sngss7_intf->id); + break; + /**********************************************************************/ + case (SI_INTF_CONG3): + SS7_DEBUG("State of ISUP intf %d = Congestion 3\n", sngss7_intf->id); + break; + /**********************************************************************/ + default: + /* should do something here to handle the possiblity of an unknown case */ + SS7_ERROR("Unknown ISUP intf Status code (%d) for Intf = %d\n", status, sngss7_intf->id); + break; + /**********************************************************************/ + } /* switch (status) */ + + /**************************************************************************/ + } /* for (x = 1; x < MAX_ISUP_INFS + 1); i++) */ + + return FTDM_SUCCESS; +} + /******************************************************************************/ /* For Emacs: * Local Variables: diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c index 75b32d6892..c2d493f34e 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_timers.c @@ -61,7 +61,7 @@ void handle_isup_t35(void *userdata) SS7_ERROR("[Call-Control] Timer 35 expired on CIC = %d\n", sngss7_info->circuit->cic); /* set the flag to indicate this hangup is started from the local side */ - sngss7_set_flag(sngss7_info, FLAG_LOCAL_REL); + sngss7_set_ckt_flag(sngss7_info, FLAG_LOCAL_REL); /* hang up on timer expiry */ ftdmchan->caller_data.hangup_cause = 28; diff --git a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c index d4fd1ca9b3..d2fa973393 100644 --- a/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c +++ b/libs/freetdm/src/ftmod/ftmod_sangoma_ss7/ftmod_sangoma_ss7_xml.c @@ -39,6 +39,60 @@ /******************************************************************************/ /* GLOBALS ********************************************************************/ +sng_ssf_type_t sng_ssf_type_map[] = +{ + { 1, "nat" , SSF_NAT }, + { 1, "int" , SSF_INTL }, + { 1, "spare" , SSF_SPARE }, + { 1, "res" , SSF_RES }, + { 0, "", 0 }, +}; + +sng_switch_type_t sng_switch_type_map[] = +{ + { 1, "itu88" , LSI_SW_ITU , LSI_SW_ITU }, + { 1, "itu92" , LSI_SW_ITU , LSI_SW_ITU }, + { 1, "itu97" , LSI_SW_ITU97 , LSI_SW_ITU97 }, + { 1, "itu00" , LSI_SW_ITU2000 , LSI_SW_ITU2000 }, + { 1, "ansi88" , LSI_SW_ANS88 , LSI_SW_ANS88 }, + { 1, "ansi92" , LSI_SW_ANS92 , LSI_SW_ANS92 }, + { 1, "ansi95" , LSI_SW_ANS92 , LSI_SW_ANS92 }, + { 1, "etsiv2" , LSI_SW_ETSI , LSI_SW_ETSI }, + { 1, "etsiv3" , LSI_SW_ETSIV3 , LSI_SW_ETSIV3 }, + { 1, "india" , LSI_SW_INDIA , LSI_SW_INDIA }, + { 1, "uk" , LSI_SW_UK , LSI_SW_UK }, + { 1, "russia" , LSI_SW_RUSSIA , LSI_SW_RUSSIA }, + { 0, "", 0, 0 }, +}; + +sng_link_type_t sng_link_type_map[] = +{ + { 1, "itu88" , LSD_SW_ITU88 , LSN_SW_ITU }, + { 1, "itu92" , LSD_SW_ITU92 , LSN_SW_ITU }, + { 1, "etsi" , LSD_SW_ITU92 , LSN_SW_ITU }, + { 1, "ansi88" , LSD_SW_ANSI88, LSN_SW_ANS }, + { 1, "ansi92" , LSD_SW_ANSI92, LSN_SW_ANS }, + { 1, "ansi96" , LSD_SW_ANSI92, LSN_SW_ANS96 }, + { 0, "", 0, 0 }, +}; + +sng_mtp2_error_type_t sng_mtp2_error_type_map[] = +{ + { 1, "basic", SD_ERR_NRM }, + { 1, "pcr" , SD_ERR_CYC }, + { 0, "", 0 }, +}; + +sng_cic_cntrl_type_t sng_cic_cntrl_type_map[] = +{ + { 1, "bothway" , BOTHWAY }, + { 1, "incoming" , INCOMING }, + { 1, "outgoing" , OUTGOING }, + { 1, "controlling" , CONTROLLING }, + { 1, "controlled" , CONTROLLED }, + { 0, "", 0 }, +}; + typedef struct sng_timeslot { int channel; @@ -47,13 +101,28 @@ typedef struct sng_timeslot int hole; }sng_timeslot_t; -typedef struct sng_isupCkt +typedef struct sng_span { + char name[MAX_NAME_LEN]; ftdm_span_t *span; - uint32_t cicbase; - uint32_t typeCntrl; - char ch_map[MAX_CIC_MAP_LENGTH]; + uint32_t ccSpanId; +} sng_span_t; + +typedef struct sng_ccSpan +{ + char name[MAX_NAME_LEN]; + uint32_t options; + uint32_t id; + uint32_t procId; uint32_t isupInf; + uint32_t cicbase; + char ch_map[MAX_CIC_MAP_LENGTH]; + uint32_t typeCntrl; + uint32_t switchType; + uint32_t ssf; + uint32_t clg_nadi; + uint32_t cld_nadi; + uint32_t min_digits; uint32_t t3; uint32_t t12; uint32_t t13; @@ -61,8 +130,9 @@ typedef struct sng_isupCkt uint32_t t15; uint32_t t16; uint32_t t17; + uint32_t t35; uint32_t tval; -} sng_isupCkt_t; +} sng_ccSpan_t; int cmbLinkSetId; /******************************************************************************/ @@ -72,9 +142,22 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup); +static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen); + +static int ftmod_ss7_parse_sng_relay(ftdm_conf_node_t *sng_relay); +static int ftmod_ss7_parse_relay_channel(ftdm_conf_node_t *relay_chan); + +static int ftmod_ss7_parse_mtp1_links(ftdm_conf_node_t *mtp1_links); +static int ftmod_ss7_parse_mtp1_link(ftdm_conf_node_t *mtp1_link); + +static int ftmod_ss7_parse_mtp2_links(ftdm_conf_node_t *mtp2_links); +static int ftmod_ss7_parse_mtp2_link(ftdm_conf_node_t *mtp2_link); + +static int ftmod_ss7_parse_mtp3_links(ftdm_conf_node_t *mtp3_links); +static int ftmod_ss7_parse_mtp3_link(ftdm_conf_node_t *mtp3_link); + static int ftmod_ss7_parse_mtp_linksets(ftdm_conf_node_t *mtp_linksets); static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset); -static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *mtpLink); static int ftmod_ss7_parse_mtp_routes(ftdm_conf_node_t *mtp_routes); static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route); @@ -82,19 +165,22 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route); static int ftmod_ss7_parse_isup_interfaces(ftdm_conf_node_t *isup_interfaces); static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface); -static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink); +static int ftmod_ss7_parse_cc_spans(ftdm_conf_node_t *cc_spans); +static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span); +static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel); +static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link); +static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp1Link); +static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp1Link); static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet); - static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route); static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route); - static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup); static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap); - +static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan); static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, int ssf); +static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan); -static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt); static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot); /******************************************************************************/ @@ -103,18 +189,17 @@ static int ftmod_ss7_next_timeslot(char *ch_map, sng_timeslot_t *timeslot); int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *span) { int i = 0; - int x = 0; const char *var = NULL; const char *val = NULL; ftdm_conf_node_t *ptr = NULL; sng_route_t self_route; - sng_isupCkt_t isupCkt; + sng_span_t sngSpan; /* clean out the isup ckt */ - memset(&isupCkt, 0x0, sizeof(sng_isupCkt_t)); + memset(&sngSpan, 0x0, sizeof(sngSpan)); /* clean out the self route */ - memset(&self_route, 0x0, sizeof(sng_route_t)); + memset(&self_route, 0x0, sizeof(self_route)); var = ftdm_parameters[i].var; val = ftdm_parameters[i].val; @@ -136,92 +221,23 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa i++; while (ftdm_parameters[i].var != NULL) { + /**************************************************************************/ var = ftdm_parameters[i].var; val = ftdm_parameters[i].val; - if (!strcasecmp(var, "ch_map")) { + if (!strcasecmp(var, "dialplan")) { /**********************************************************************/ - strncpy(isupCkt.ch_map, val, MAX_CIC_MAP_LENGTH-1); - SS7_DEBUG("\tFound channel map \"%s\"\n", isupCkt.ch_map); - /**********************************************************************/ - } else if (!strcasecmp(var, "typeCntrl")) { - if (!strcasecmp(val, "bothway")) { - isupCkt.typeCntrl = BOTHWAY; - SS7_DEBUG("\tFound control type \"bothway\"\n"); - } else if (!strcasecmp(val, "incoming")) { - isupCkt.typeCntrl = INCOMING; - SS7_DEBUG("\tFound control type \"incoming\"\n"); - } else if (!strcasecmp(val, "outgoing")) { - isupCkt.typeCntrl = OUTGOING; - SS7_DEBUG("\tFound control type \"outgoing\"\n"); - } else if (!strcasecmp(val, "controlled")) { - isupCkt.typeCntrl = CONTROLLED; - SS7_DEBUG("\tFound control type \"controlled\"\n"); - } else if (!strcasecmp(val, "controlling")) { - isupCkt.typeCntrl = CONTROLLING; - SS7_DEBUG("\tFound control type \"controlling\"\n"); - } else { - SS7_ERROR("Found invalid circuit control type \"%s\"!", val); - goto ftmod_ss7_parse_xml_error; - } - /**********************************************************************/ - } else if (!strcasecmp(var, "cicbase")) { - isupCkt.cicbase = atoi(val); - SS7_DEBUG("\tFound cicbase = %d\n", isupCkt.cicbase); - /**********************************************************************/ - } else if (!strcasecmp(var, "dialplan")) { /* do i give a shit about this??? */ /**********************************************************************/ } else if (!strcasecmp(var, "context")) { + /**********************************************************************/ /* do i give a shit about this??? */ /**********************************************************************/ - } else if (!strcasecmp(var, "isup_interface")) { - /* go through all the existing interfaces and see if we find a match */ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupIntf[x].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[x].name, val)) { - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - x++; - } - - isupCkt.isupInf = x; - SS7_DEBUG("\tFound isup_interface = %s\n",g_ftdm_sngss7_data.cfg.isupIntf[x].name); + } else if (!strcasecmp(var, "ccSpanId")) { /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t3")) { - isupCkt.t3 = atoi(val); - SS7_DEBUG("\tFound isup t3 = \"%d\"\n", isupCkt.t3); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t12")) { - isupCkt.t12 = atoi(val); - SS7_DEBUG("\tFound isup t12 = \"%d\"\n", isupCkt.t12); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t13")) { - isupCkt.t13 = atoi(val); - SS7_DEBUG("\tFound isup t13 = \"%d\"\n", isupCkt.t13); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t14")) { - isupCkt.t14 = atoi(val); - SS7_DEBUG("\tFound isup t14 = \"%d\"\n", isupCkt.t14); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t15")) { - isupCkt.t15 = atoi(val); - SS7_DEBUG("\tFound isup t15 = \"%d\"\n", isupCkt.t15); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t16")) { - isupCkt.t16 = atoi(val); - SS7_DEBUG("\tFound isup t16 = \"%d\"\n", isupCkt.t16); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.t17")) { - isupCkt.t17 = atoi(val); - SS7_DEBUG("\tFound isup t17 = \"%d\"\n", isupCkt.t17); - /**********************************************************************/ - } else if (!strcasecmp(var, "isup.tval")) { - isupCkt.tval = atoi(val); - SS7_DEBUG("\tFound isup tval = \"%d\"\n", isupCkt.tval); + sngSpan.ccSpanId = atoi(val); + SS7_DEBUG("Found an ccSpanId = %d\n",sngSpan.ccSpanId); /**********************************************************************/ } else { SS7_ERROR("Unknown parameter found =\"%s\"...ignoring it!\n", var); @@ -231,24 +247,11 @@ int ftmod_ss7_parse_xml(ftdm_conf_parameter_t *ftdm_parameters, ftdm_span_t *spa i++; } /* while (ftdm_parameters[i].var != NULL) */ - /* setup the self mtp3 route */ - i = g_ftdm_sngss7_data.cfg.isupIntf[x].mtpRouteId; - - if(ftmod_ss7_fill_in_self_route(g_ftdm_sngss7_data.cfg.isupIntf[x].spc, - g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType, - g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType, - g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf)) { - - SS7_ERROR("Failed to fill in self route structure!\n"); - goto ftmod_ss7_parse_xml_error; - - } - /* fill the pointer to span into isupCkt */ - isupCkt.span = span; + sngSpan.span = span; /* setup the circuits structure */ - if(ftmod_ss7_fill_in_circuits(&isupCkt)) { + if(ftmod_ss7_fill_in_circuits(&sngSpan)) { SS7_ERROR("Failed to fill in circuits structure!\n"); goto ftmod_ss7_parse_xml_error; } @@ -262,9 +265,15 @@ ftmod_ss7_parse_xml_error: /******************************************************************************/ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) { + ftdm_conf_node_t *gen_config = NULL; + ftdm_conf_node_t *relay_channels = NULL; + ftdm_conf_node_t *mtp1_links = NULL; + ftdm_conf_node_t *mtp2_links = NULL; + ftdm_conf_node_t *mtp3_links = NULL; ftdm_conf_node_t *mtp_linksets = NULL; ftdm_conf_node_t *mtp_routes = NULL; ftdm_conf_node_t *isup_interfaces = NULL; + ftdm_conf_node_t *cc_spans = NULL; ftdm_conf_node_t *tmp_node = NULL; /* confirm that we are looking at sng_isup */ @@ -275,51 +284,145 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) SS7_DEBUG("Parsing \"sng_isup\"...\n"); } - /* extract the 3 main sections of the sng_isup block */ + /* extract the main sections of the sng_isup block */ tmp_node = sng_isup->child; - while (tmp_node != NULL) { - if (!strcasecmp(tmp_node->name, "mtp_linksets")) { + while (tmp_node != NULL) { + /**************************************************************************/ + /* check the type of structure */ + if (!strcasecmp(tmp_node->name, "sng_gen")) { + /**********************************************************************/ + if (gen_config == NULL) { + gen_config = tmp_node; + SS7_DEBUG("Found a \"sng_gen\" section!\n"); + } else { + SS7_ERROR("Found a second \"sng_gen\" section\n!"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "sng_relay")) { + /**********************************************************************/ + if (relay_channels == NULL) { + relay_channels = tmp_node; + SS7_DEBUG("Found a \"sng_relay\" section!\n"); + } else { + SS7_ERROR("Found a second \"sng_relay\" section\n!"); + return FTDM_FAIL; + } + /**********************************************************************/ + }else if (!strcasecmp(tmp_node->name, "mtp1_links")) { + /**********************************************************************/ + if (mtp1_links == NULL) { + mtp1_links = tmp_node; + SS7_DEBUG("Found a \"mtp1_links\" section!\n"); + } else { + SS7_ERROR("Found a second \"mtp1_links\" section!\n"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "mtp2_links")) { + /**********************************************************************/ + if (mtp2_links == NULL) { + mtp2_links = tmp_node; + SS7_DEBUG("Found a \"mtp2_links\" section!\n"); + } else { + SS7_ERROR("Found a second \"mtp2_links\" section!\n"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "mtp3_links")) { + /**********************************************************************/ + if (mtp3_links == NULL) { + mtp3_links = tmp_node; + SS7_DEBUG("Found a \"mtp3_links\" section!\n"); + } else { + SS7_ERROR("Found a second \"mtp3_links\" section!\n"); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "mtp_linksets")) { + /**********************************************************************/ if (mtp_linksets == NULL) { mtp_linksets = tmp_node; - SS7_DEBUG("\tFound a \"mtp_linksets section!\n"); + SS7_DEBUG("Found a \"mtp_linksets\" section!\n"); } else { - SS7_ERROR("\tFound a second \"mtp_linksets\" section!\n"); + SS7_ERROR("Found a second \"mtp_linksets\" section!\n"); return FTDM_FAIL; } + /**********************************************************************/ } else if (!strcasecmp(tmp_node->name, "mtp_routes")) { + /**********************************************************************/ if (mtp_routes == NULL) { mtp_routes = tmp_node; - SS7_DEBUG("\tFound a \"mtp_routes\" section!\n"); + SS7_DEBUG("Found a \"mtp_routes\" section!\n"); } else { - SS7_ERROR("\tFound a second \"mtp_routes\" section!\n"); + SS7_ERROR("Found a second \"mtp_routes\" section!\n"); return FTDM_FAIL; } + /**********************************************************************/ } else if (!strcasecmp(tmp_node->name, "isup_interfaces")) { + /**********************************************************************/ if (isup_interfaces == NULL) { isup_interfaces = tmp_node; - SS7_DEBUG("\tFound a \"isup_interfaces\" section!\n"); + SS7_DEBUG("Found a \"isup_interfaces\" section!\n"); } else { - SS7_ERROR("\tFound a second \"isup_interfaces\" section\n!"); + SS7_ERROR("Found a second \"isup_interfaces\" section\n!"); return FTDM_FAIL; } + /**********************************************************************/ + } else if (!strcasecmp(tmp_node->name, "cc_spans")) { + /**********************************************************************/ + if (cc_spans == NULL) { + cc_spans = tmp_node; + SS7_DEBUG("Found a \"cc_spans\" section!\n"); + } else { + SS7_ERROR("Found a second \"cc_spans\" 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; - } /* while (tmp_node != NULL) */ /* now try to parse the sections */ + if (ftmod_ss7_parse_sng_gen(gen_config)) { + SS7_ERROR("Failed to parse \"gen_config\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_sng_relay(relay_channels)) { + SS7_ERROR("Failed to parse \"relay_channels\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_mtp1_links(mtp1_links)) { + SS7_ERROR("Failed to parse \"mtp1_links\"!\n"); + return FTDM_FAIL; + } + + if (ftmod_ss7_parse_mtp2_links(mtp2_links)) { + SS7_ERROR("Failed to parse \"mtp2_links\"!\n"); + 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; } - if (ftmod_ss7_parse_mtp_routes(mtp_routes)) { + if (ftmod_ss7_parse_mtp_routes(mtp_routes)) { SS7_ERROR("Failed to parse \"mtp_routes\"!\n"); return FTDM_FAIL; } @@ -329,6 +432,700 @@ static int ftmod_ss7_parse_sng_isup(ftdm_conf_node_t *sng_isup) return FTDM_FAIL; } + if (ftmod_ss7_parse_cc_spans(cc_spans)) { + SS7_ERROR("Failed to parse \"cc_spans\"!\n"); + return FTDM_FAIL; + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen) +{ + ftdm_conf_parameter_t *parm = sng_gen->parameters; + int num_parms = sng_gen->n_parameters; + int i = 0; + + /* extract all the information from the parameters */ + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "procId")) { + /**********************************************************************/ + g_ftdm_sngss7_data.cfg.procId = atoi(parm->val); + SS7_DEBUG("Found a procId = %d\n", g_ftdm_sngss7_data.cfg.procId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "license")) { + /**********************************************************************/ + strcpy(g_ftdm_sngss7_data.cfg.license, parm->val); + strcpy(g_ftdm_sngss7_data.cfg.signature, parm->val); + strcat(g_ftdm_sngss7_data.cfg.signature, ".sig"); + SS7_DEBUG("Found license file = %s\n", g_ftdm_sngss7_data.cfg.license); + SS7_DEBUG("Found signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "spc")) { + /**********************************************************************/ + g_ftdm_sngss7_data.cfg.spc = atoi(parm->val); + SS7_DEBUG("Found SPC = %d\n", g_ftdm_sngss7_data.cfg.spc); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + } /* for (i = 0; i < num_parms; i++) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_sng_relay(ftdm_conf_node_t *sng_relay) +{ + ftdm_conf_node_t *relay_chan = NULL; + + /* confirm that we are looking at sng_relay */ + if (strcasecmp(sng_relay->name, "sng_relay")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"sng_relay\"!\n",sng_relay->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"sng_relay\"...\n"); + } + + relay_chan = sng_relay->child; + + if (relay_chan != NULL) { + while (relay_chan != NULL) { + /* try to the parse relay_channel */ + if (ftmod_ss7_parse_relay_channel(relay_chan)) { + SS7_ERROR("Failed to parse \"relay_channels\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next linkset */ + relay_chan = relay_chan->next; + } /* while (relay_chan != NULL) */ + } /* if (relay_chan != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_relay_channel(ftdm_conf_node_t *relay_chan) +{ + sng_relay_t tmp_chan; + ftdm_conf_parameter_t *parm = relay_chan->parameters; + int num_parms = relay_chan->n_parameters; + int i = 0; + + /* confirm that we are looking at relay_channel */ + if (strcasecmp(relay_chan->name, "relay_channel")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"relay_channel\"!\n",relay_chan->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"relay_channel\"...\n"); + } + + /* initalize the tmp_chan structure */ + memset(&tmp_chan, 0x0, sizeof(tmp_chan)); + + /* extract all the information from the parameters */ + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)tmp_chan.name, parm->val); + SS7_DEBUG("Found an relay_channel named = %s\n", tmp_chan.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "type")) { + /**********************************************************************/ + if (!strcasecmp(parm->val, "listen")) { + tmp_chan.type = LRY_CT_TCP_LISTEN; + SS7_DEBUG("Found a type = LISTEN\n"); + } else if (!strcasecmp(parm->val, "server")) { + tmp_chan.type = LRY_CT_TCP_SERVER; + SS7_DEBUG("Found a type = SERVER\n"); + } else if (!strcasecmp(parm->val, "client")) { + tmp_chan.type = LRY_CT_TCP_CLIENT; + SS7_DEBUG("Found a type = CLIENT\n"); + } else { + SS7_ERROR("Found an invalid \"type\" = %s\n", parm->var); + return FTDM_FAIL; + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "hostname")) { + /**********************************************************************/ + strcpy((char *)tmp_chan.hostname, parm->val); + SS7_DEBUG("Found a hostname = %s\n", tmp_chan.hostname); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "port")) { + /**********************************************************************/ + tmp_chan.port = atoi(parm->val); + SS7_DEBUG("Found a port = %d\n", tmp_chan.port); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "procId")) { + /**********************************************************************/ + tmp_chan.procId = atoi(parm->val); + SS7_DEBUG("Found a procId = %d\n", tmp_chan.procId); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + } /* for (i = 0; i < num_parms; i++) */ + + /* store the channel in the global structure */ + ftmod_ss7_fill_in_relay_channel(&tmp_chan); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp1_links(ftdm_conf_node_t *mtp1_links) +{ + ftdm_conf_node_t *mtp1_link = NULL; + + /* confirm that we are looking at mtp1_links */ + if (strcasecmp(mtp1_links->name, "mtp1_links")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp1_links\"!\n",mtp1_links->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp1_links\"...\n"); + } + + /* extract the mtp_links */ + mtp1_link = mtp1_links->child; + + /* run through all of the links found */ + while (mtp1_link != NULL) { + /* try to the parse mtp_link */ + if (ftmod_ss7_parse_mtp1_link(mtp1_link)) { + SS7_ERROR("Failed to parse \"mtp1_link\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next link */ + mtp1_link = mtp1_link->next; + + } /* while (mtp_linkset != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp1_link(ftdm_conf_node_t *mtp1_link) +{ + sng_mtp1_link_t mtp1Link; + ftdm_conf_parameter_t *parm = mtp1_link->parameters; + int num_parms = mtp1_link->n_parameters; + int i; + + /* initalize the mtp1Link structure */ + memset(&mtp1Link, 0x0, sizeof(mtp1Link)); + + /* confirm that we are looking at an mtp_link */ + if (strcasecmp(mtp1_link->name, "mtp1_link")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp1_link\"!\n",mtp1_link->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp1_link\"...\n"); + } + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)mtp1Link.name, parm->val); + SS7_DEBUG("Found an mtp1_link named = %s\n", mtp1Link.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtp1Link.id = atoi(parm->val); + SS7_DEBUG("Found an mtp1_link id = %d\n", mtp1Link.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "span")) { + /**********************************************************************/ + mtp1Link.span = atoi(parm->val); + SS7_DEBUG("Found an mtp1_link span = %d\n", mtp1Link.span); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "chan")) { + /**********************************************************************/ + mtp1Link.chan = atoi(parm->val); + SS7_DEBUG("Found an mtp1_link chan = %d\n", mtp1Link.chan); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* store the link in global structure */ + ftmod_ss7_fill_in_mtp1_link(&mtp1Link); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp2_links(ftdm_conf_node_t *mtp2_links) +{ + ftdm_conf_node_t *mtp2_link = NULL; + + /* confirm that we are looking at mtp2_links */ + if (strcasecmp(mtp2_links->name, "mtp2_links")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp2_links\"!\n",mtp2_links->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp2_links\"...\n"); + } + + /* extract the mtp_links */ + mtp2_link = mtp2_links->child; + + /* run through all of the links found */ + while (mtp2_link != NULL) { + /* try to the parse mtp_linkset */ + if (ftmod_ss7_parse_mtp2_link(mtp2_link)) { + SS7_ERROR("Failed to parse \"mtp2_link\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next link */ + mtp2_link = mtp2_link->next; + + } /* while (mtp_linkset != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp2_link(ftdm_conf_node_t *mtp2_link) +{ + sng_mtp2_link_t mtp2Link; + ftdm_conf_parameter_t *parm = mtp2_link->parameters; + int num_parms = mtp2_link->n_parameters; + int i; + int ret; + + /* initalize the mtp1Link structure */ + memset(&mtp2Link, 0x0, sizeof(mtp2Link)); + + /* confirm that we are looking at an mtp2_link */ + if (strcasecmp(mtp2_link->name, "mtp2_link")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp2_link\"!\n",mtp2_link->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp2_link\"...\n"); + } + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)mtp2Link.name, parm->val); + SS7_DEBUG("Found an mtp2_link named = %s\n", mtp2Link.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtp2Link.id = atoi(parm->val); + SS7_DEBUG("Found an mtp2_link id = %d\n", mtp2Link.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "mtp1Id")) { + /**********************************************************************/ + mtp2Link.mtp1Id = atoi(parm->val); + SS7_DEBUG("Found an mtp2_link mtp1Id = %d\n", mtp2Link.mtp1Id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "errorType")) { + /**********************************************************************/ + ret = find_mtp2_error_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp2_link errorType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp2Link.errorType = sng_mtp2_error_type_map[ret].tril_type; + SS7_DEBUG("Found an mtp2_link errorType = %s\n", sng_mtp2_error_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "lssuLength")) { + /**********************************************************************/ + mtp2Link.lssuLength = atoi(parm->val); + SS7_DEBUG("Found an mtp2_link lssuLength = %d\n", mtp2Link.lssuLength); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linkType")) { + /**********************************************************************/ + ret = find_link_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp2_link linkType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp2Link.linkType = sng_link_type_map[ret].tril_mtp2_type; + SS7_DEBUG("Found an mtp2_link linkType = %s\n", sng_link_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t1")) { + /**********************************************************************/ + mtp2Link.t1 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t1 = \"%d\"\n",mtp2Link.t1); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t2")) { + /**********************************************************************/ + mtp2Link.t2 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t2 = \"%d\"\n",mtp2Link.t2); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t3")) { + /**********************************************************************/ + mtp2Link.t3 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t3 = \"%d\"\n",mtp2Link.t3); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t4n")) { + /**********************************************************************/ + mtp2Link.t4n = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t4n = \"%d\"\n",mtp2Link.t4n); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t4e")) { + /**********************************************************************/ + mtp2Link.t4e = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t4e = \"%d\"\n",mtp2Link.t4e); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t5")) { + /**********************************************************************/ + mtp2Link.t5 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t5 = \"%d\"\n",mtp2Link.t5); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t6")) { + /**********************************************************************/ + mtp2Link.t6 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t6 = \"%d\"\n",mtp2Link.t6); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t7")) { + /**********************************************************************/ + mtp2Link.t7 = atoi(parm->val); + SS7_DEBUG("Found an mtp2 t7 = \"%d\"\n",mtp2Link.t7); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* store the link in global structure */ + ftmod_ss7_fill_in_mtp2_link(&mtp2Link); + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp3_links(ftdm_conf_node_t *mtp3_links) +{ + ftdm_conf_node_t *mtp3_link = NULL; + + /* confirm that we are looking at mtp3_links */ + if (strcasecmp(mtp3_links->name, "mtp3_links")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp3_links\"!\n",mtp3_links->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp3_links\"...\n"); + } + + /* extract the mtp_links */ + mtp3_link = mtp3_links->child; + + /* run through all of the links found */ + while (mtp3_link != NULL) { + /* try to the parse mtp_linkset */ + if (ftmod_ss7_parse_mtp3_link(mtp3_link)) { + SS7_ERROR("Failed to parse \"mtp3_link\"!\n"); + return FTDM_FAIL; + } + + /* move on to the next link */ + mtp3_link = mtp3_link->next; + + } /* while (mtp_linkset != NULL) */ + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_parse_mtp3_link(ftdm_conf_node_t *mtp3_link) +{ + sng_mtp3_link_t mtp3Link; + ftdm_conf_parameter_t *parm = mtp3_link->parameters; + int num_parms = mtp3_link->n_parameters; + int i; + int ret; + + /* initalize the mtp3Link structure */ + memset(&mtp3Link, 0x0, sizeof(mtp3Link)); + + /* confirm that we are looking at an mtp_link */ + if (strcasecmp(mtp3_link->name, "mtp3_link")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp3_link\"!\n",mtp3_link->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"mtp3_link\"...\n"); + } + + for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + if (!strcasecmp(parm->var, "name")) { + /**********************************************************************/ + strcpy((char *)mtp3Link.name, parm->val); + SS7_DEBUG("Found an mtp3_link named = %s\n", mtp3Link.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtp3Link.id = atoi(parm->val); + SS7_DEBUG("Found an mtp3_link id = %d\n", mtp3Link.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "mtp2Id")) { + /**********************************************************************/ + mtp3Link.mtp2Id = atoi(parm->val); + SS7_DEBUG("Found an mtp3_link mtp2Id = %d\n", mtp3Link.mtp2Id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "mtp2ProcId")) { + /**********************************************************************/ + mtp3Link.mtp2ProcId = atoi(parm->val); + SS7_DEBUG("Found an mtp3_link mtp2ProcId = %d\n", mtp3Link.mtp2ProcId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "priority")) { + /**********************************************************************/ + mtp3Link.priority = atoi(parm->val); + SS7_DEBUG("Found an mtp3 Link priority = %d\n",mtp3Link.priority); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linkType")) { + /**********************************************************************/ + ret = find_link_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp3_link linkType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp3Link.linkType = sng_link_type_map[ret].tril_mtp3_type; + SS7_DEBUG("Found an mtp3_link linkType = %s\n", sng_link_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "switchType")) { + /**********************************************************************/ + ret = find_switch_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp3_link switchType = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp3Link.switchType = sng_switch_type_map[ret].tril_mtp3_type; + SS7_DEBUG("Found an mtp3_link switchType = %s\n", sng_switch_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "ssf")) { + /**********************************************************************/ + ret = find_ssf_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid mtp3_link ssf = %s\n", parm->var); + return FTDM_FAIL; + } else { + mtp3Link.ssf = sng_ssf_type_map[ret].tril_type; + SS7_DEBUG("Found an mtp3_link ssf = %s\n", sng_ssf_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "slc")) { + /**********************************************************************/ + mtp3Link.slc = atoi(parm->val); + SS7_DEBUG("Found an mtp3 Link slc = %d\n",mtp3Link.slc); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "linkset")) { + /**********************************************************************/ + mtp3Link.linkSetId = atoi(parm->val); + SS7_DEBUG("Found an mtp3 Link linkset = %d\n",mtp3Link.linkSetId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t1")) { + /**********************************************************************/ + mtp3Link.t1 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t1 = %d\n",mtp3Link.t1); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t2")) { + /**********************************************************************/ + mtp3Link.t2 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t2 = %d\n",mtp3Link.t2); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t3")) { + /**********************************************************************/ + mtp3Link.t3 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t3 = %d\n",mtp3Link.t3); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t4")) { + /**********************************************************************/ + mtp3Link.t4 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t4 = %d\n",mtp3Link.t4); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t5")) { + /**********************************************************************/ + mtp3Link.t5 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t5 = %d\n",mtp3Link.t5); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t7")) { + /**********************************************************************/ + mtp3Link.t7 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t7 = %d\n",mtp3Link.t7); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t12")) { + /**********************************************************************/ + mtp3Link.t12 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t12 = %d\n",mtp3Link.t12); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t13")) { + /**********************************************************************/ + mtp3Link.t13 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t13 = %d\n",mtp3Link.t13); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t14")) { + /**********************************************************************/ + mtp3Link.t14 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t14 = %d\n",mtp3Link.t14); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t17")) { + /**********************************************************************/ + mtp3Link.t17 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t17 = %d\n",mtp3Link.t17); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t22")) { + /**********************************************************************/ + mtp3Link.t22 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t22 = %d\n",mtp3Link.t22); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t23")) { + /**********************************************************************/ + mtp3Link.t23 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t23 = %d\n",mtp3Link.t23); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t24")) { + /**********************************************************************/ + mtp3Link.t24 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t24 = %d\n",mtp3Link.t24); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t31")) { + mtp3Link.t31 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t31 = %d\n",mtp3Link.t31); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t32")) { + /**********************************************************************/ + mtp3Link.t32 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t32 = %d\n",mtp3Link.t32); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t33")) { + /**********************************************************************/ + mtp3Link.t33 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t33 = %d\n",mtp3Link.t33); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t34")) { + /**********************************************************************/ + mtp3Link.t34 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t34 = %d\n",mtp3Link.t34); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t35")) { + /**********************************************************************/ + mtp3Link.t35 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t35 = %d\n",mtp3Link.t35); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t36")) { + /**********************************************************************/ + mtp3Link.t36 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t36 = %d\n",mtp3Link.t36); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "t37")) { + /**********************************************************************/ + mtp3Link.t37 = atoi(parm->val); + SS7_DEBUG("Found an mtp3 t37 = %d\n",mtp3Link.t37); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "tcraft")) { + /**********************************************************************/ + mtp3Link.tcraft = atoi(parm->val); + SS7_DEBUG("Found an mtp3 tcraft = %d\n",mtp3Link.tcraft); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "tflc")) { + /**********************************************************************/ + mtp3Link.tflc = atoi(parm->val); + SS7_DEBUG("Found an mtp3 tflc = %d\n",mtp3Link.tflc); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "tbnd")) { + /**********************************************************************/ + mtp3Link.tbnd = atoi(parm->val); + SS7_DEBUG("Found an mtp3 tbnd = %d\n",mtp3Link.tbnd); + /**********************************************************************/ + } else { + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter %s!\n", parm->val); + return FTDM_FAIL; + /**********************************************************************/ + } + + /* move to the next parmeter */ + parm = parm + 1; + + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ + + /* store the link in global structure */ + ftmod_ss7_fill_in_mtp3_link(&mtp3Link); + + /* move the linktype, switchtype and ssf to the linkset */ + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType == 0) { + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType = mtp3Link.linkType; + } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType != mtp3Link.linkType) { + SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different linkType: mtp3.id=%d, mtp3.name=%s, mtp3.linktype=%d, linkset.id=%d, linkset.linktype=%d\n", + mtp3Link.id, mtp3Link.name, mtp3Link.linkType, + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].linkType); + return FTDM_FAIL; + } else { + /* should print that all is ok...*/ + } + + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType == 0) { + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType = mtp3Link.switchType; + } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType != mtp3Link.switchType) { + SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different switchType: mtp3.id=%d, mtp3.name=%s, mtp3.switchtype=%d, linkset.id=%d, linkset.switchtype=%d\n", + mtp3Link.id, mtp3Link.name, mtp3Link.switchType, + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].switchType); + return FTDM_FAIL; + } else { + /* should print that all is ok...*/ + } + + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf == 0) { + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf = mtp3Link.ssf; + } else if (g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf != mtp3Link.ssf) { + SS7_ERROR("Trying to add an MTP3 Link to a Linkset with a different ssf: mtp3.id=%d, mtp3.name=%s, mtp3.ssf=%d, linkset.id=%d, linkset.ssf=%d\n", + mtp3Link.id, mtp3Link.name, mtp3Link.ssf, + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].id, g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3Link.linkSetId].ssf); + return FTDM_FAIL; + } else { + /* should print that all is ok...*/ + } + + return FTDM_SUCCESS; } @@ -367,18 +1164,12 @@ static int ftmod_ss7_parse_mtp_linksets(ftdm_conf_node_t *mtp_linksets) /******************************************************************************/ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) { + sng_link_set_t mtpLinkSet; ftdm_conf_parameter_t *parm = mtp_linkset->parameters; - int num_parms = mtp_linkset->n_parameters; - ftdm_conf_node_t *mtp_link = NULL; - sng_mtp_link_t mtpLink[MAX_MTP_LINKS+1]; - sng_link_set_t mtpLinkSet; - int count; - int i; + int num_parms = mtp_linkset->n_parameters; + int i; - /* initialize the mtp_link structures */ - for (i = 0; i < (MAX_MTP_LINKS + 1); i++) { - memset(&mtpLink[i], 0x0, sizeof(mtpLink[i])); - } + /* initalize the mtpLinkSet structure */ memset(&mtpLinkSet, 0x0, sizeof(mtpLinkSet)); /* confirm that we are looking at mtp_linkset */ @@ -391,387 +1182,52 @@ static int ftmod_ss7_parse_mtp_linkset(ftdm_conf_node_t *mtp_linkset) /* extract all the information from the parameters */ for (i = 0; i < num_parms; i++) { - /**********************************************************************/ + /**************************************************************************/ + if (!strcasecmp(parm->var, "name")) { - strncpy((char *)mtpLinkSet.name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"mtp_linkset\" named = %s\n", mtpLinkSet.name); + /**********************************************************************/ + strcpy((char *)mtpLinkSet.name, parm->val); + SS7_DEBUG("Found an mtpLinkSet named = %s\n", mtpLinkSet.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtpLinkSet.id = atoi(parm->val); + SS7_DEBUG("Found mtpLinkSet id = %d\n", mtpLinkSet.id); /**********************************************************************/ } else if (!strcasecmp(parm->var, "apc")) { + /**********************************************************************/ mtpLinkSet.apc = atoi(parm->val); - SS7_DEBUG("\tFound mtpLinkSet->apc = %d\n", mtpLinkSet.apc); + SS7_DEBUG("Found mtpLinkSet apc = %d\n", mtpLinkSet.apc); /**********************************************************************/ } else if (!strcasecmp(parm->var, "minActive")) { + /**********************************************************************/ mtpLinkSet.minActive = atoi(parm->val); - SS7_DEBUG("\tFound mtpLinkSet->minActive = %d\n", mtpLinkSet.minActive); + SS7_DEBUG("Found mtpLinkSet minActive = %d\n", mtpLinkSet.minActive); /**********************************************************************/ } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); return FTDM_FAIL; + /**********************************************************************/ } /* move to the next parmeter */ parm = parm + 1; - + /**************************************************************************/ } /* for (i = 0; i < num_parms; i++) */ - /* grab the first mtp-link (which sits below the mtp_links section) */ - mtp_link = mtp_linkset->child->child; - - /* initalize the link counter */ - count = 0; - - /* run through all of the mtp_links found */ - while (mtp_link != NULL) { - /* try to the parse mtp_linkset */ - if (ftmod_ss7_parse_mtp_link(mtp_link, &mtpLink[count] )) { - SS7_ERROR("Failed to parse \"mtp_link\"!\n"); - return FTDM_FAIL; - } - - /* incremenet the link counter */ - count++; - - /* move on to the next link */ - mtp_link = mtp_link->next; - - } /* while (mtp_link != NULL) */ - - /* confirm we have the right number of links */ - if (count < 1 || count > 15 ) { - SS7_ERROR("Invalid number of mtp_links found (%d)\n", count); - return FTDM_FAIL; - } - - /* now we need to see if this linkset exists already or not and grab an Id */ - i = 1; - while (g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id != 0) { - if (!strcasecmp((const char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[i].name, (const char *)mtpLinkSet.name)) { - /* we've found the linkset...so it has already been configured */ - break; - } - i++; - /* add in error check to make sure we don't go out-of-bounds */ - } - - /* if the id value is 0 that means we didn't find the linkset */ - if (g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id == 0) { - mtpLinkSet.id = i; - SS7_DEBUG("found new mtpLinkSet, id is = %d\n", mtpLinkSet.id); - } else { - mtpLinkSet.id = i; - SS7_DEBUG("found existing mtpLinkSet, id is = %d\n", mtpLinkSet.id); - } - - /* we now have all the information to fill in the Libsng_ss7 structures */ - i = 0; - count = 0; - while (mtpLink[i].mtp1.span != 0 ){ - - /* have to grab a couple of values from the linkset */ - mtpLink[i].mtp3.apc = mtpLinkSet.apc; - mtpLink[i].mtp3.linkSetId = mtpLinkSet.id; - - ftmod_ss7_fill_in_mtpLink(&mtpLink[i]); - - /* increment the links counter */ - count++; - - /* increment the index value */ - i++; - } - - mtpLinkSet.linkType = mtpLink[0].mtp3.linkType; - mtpLinkSet.switchType = mtpLink[0].mtp3.switchType; - mtpLinkSet.ssf = mtpLink[0].mtp3.ssf; - ftmod_ss7_fill_in_mtpLinkSet(&mtpLinkSet); - return FTDM_SUCCESS; -} - -/******************************************************************************/ -static int ftmod_ss7_parse_mtp_link(ftdm_conf_node_t *mtp_link, sng_mtp_link_t *mtpLink) -{ - ftdm_conf_parameter_t *parm = mtp_link->parameters; - int num_parms = mtp_link->n_parameters; - int i; - - /* confirm that we are looking at an mtp_link */ - if (strcasecmp(mtp_link->name, "mtp_link")) { - SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"mtp_link\"!\n",mtp_link->name); - return FTDM_FAIL; - } else { - SS7_DEBUG("Parsing \"mtp_link\"...\n"); - } - - for (i = 0; i < num_parms; i++) { - /* try to match the parameter to what we expect */ - /**********************************************************************/ - if (!strcasecmp(parm->var, "name")) { - strncpy((char *)mtpLink->name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"mtp_link\" named = %s\n", mtpLink->name); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "span")) { - mtpLink->mtp1.span = atoi(parm->val); - SS7_DEBUG("\tFound mtpLink->span = %d\n", mtpLink->mtp1.span); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "chan")) { - mtpLink->mtp1.chan = atoi(parm->val); - SS7_DEBUG("\tFound mtpLink->chan = %d\n", mtpLink->mtp1.chan); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "errorType")) { - if (!strcasecmp(parm->val, "basic")) { - mtpLink->mtp2.errorType = SD_ERR_NRM; - } else if (!strcasecmp(parm->val, "pcr")) { - mtpLink->mtp2.errorType = SD_ERR_CYC; - } else { - SS7_ERROR("\tFound an invalid \"errorType\" = %s\n", parm->var); - return FTDM_FAIL; - } - SS7_DEBUG("\tFound mtpLink->errorType=%s\n", parm->val); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "lssuLength")) { - mtpLink->mtp2.lssuLength = atoi(parm->val); - if ((mtpLink->mtp2.lssuLength != 1) && (mtpLink->mtp2.lssuLength != 2)) { - SS7_ERROR("\tFound an invalid \"lssuLength\" = %d\n", mtpLink->mtp2.lssuLength); - return FTDM_FAIL; - } else { - SS7_DEBUG("\tFound mtpLink->lssuLength=%d\n", mtpLink->mtp2.lssuLength); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "priority")) { - mtpLink->mtp3.priority = atoi(parm->val); - if ((mtpLink->mtp3.priority == 0) || (mtpLink->mtp3.priority == 1) || - (mtpLink->mtp3.priority == 2) || (mtpLink->mtp3.priority == 3)) { - SS7_DEBUG("\tFound mtpLink->priority = %d\n",mtpLink->mtp3.priority); - } else { - SS7_ERROR("\tFound an invalid \"priority\"=%d\n",mtpLink->mtp3.priority); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "linkType")) { - if (!strcasecmp(parm->val, "itu92")) { - mtpLink->mtp2.linkType = LSD_SW_ITU92; - mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFound mtpLink->linkType = \"ITU92\"\n"); - } else if (!strcasecmp(parm->val, "itu88")) { - mtpLink->mtp2.linkType = LSD_SW_ITU88; - mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFound mtpLink->linkType = \"ITU88\"\n"); - } else if (!strcasecmp(parm->val, "ansi96")) { - mtpLink->mtp2.linkType = LSD_SW_ANSI92; - mtpLink->mtp3.linkType = LSN_SW_ANS96; - SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI96\"\n"); - } else if (!strcasecmp(parm->val, "ansi92")) { - mtpLink->mtp2.linkType = LSD_SW_ANSI92; - mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI92\"\n"); - } else if (!strcasecmp(parm->val, "ansi88")) { - mtpLink->mtp2.linkType = LSD_SW_ANSI88; - mtpLink->mtp3.linkType = LSN_SW_ANS; - SS7_DEBUG("\tFound mtpLink->linkType = \"ANSI88\"\n"); - } else if (!strcasecmp(parm->val, "etsi")) { - mtpLink->mtp2.linkType = LSD_SW_ITU92; - mtpLink->mtp3.linkType = LSN_SW_ITU; - SS7_DEBUG("\tFound mtpLink->linkType = \"ETSI\"\n"); - } else { - SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "switchType")) { - if (!strcasecmp(parm->val, "itu97")) { - mtpLink->mtp3.switchType = LSI_SW_ITU97; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU97\"\n"); - } else if (!strcasecmp(parm->val, "itu88")) { - mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU88\"\n"); - } else if (!strcasecmp(parm->val, "itu92")) { - mtpLink->mtp3.switchType = LSI_SW_ITU; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU92\"\n"); - } else if (!strcasecmp(parm->val, "itu00")) { - mtpLink->mtp3.switchType = LSI_SW_ITU2000; - SS7_DEBUG("\tFound mtpLink->switchType = \"ITU00\"\n"); - } else if (!strcasecmp(parm->val, "ETSIV2")) { - mtpLink->mtp3.switchType = LSI_SW_ETSI; - SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV2\"\n"); - } else if (!strcasecmp(parm->val, "ETSIV3")) { - mtpLink->mtp3.switchType = LSI_SW_ETSIV3; - SS7_DEBUG("\tFound mtpLink->switchType = \"ETSIV3\"\n"); - } else if (!strcasecmp(parm->val, "UK")) { - mtpLink->mtp3.switchType = LSI_SW_UK; - SS7_DEBUG("\tFound mtpLink->switchType = \"UK\"\n"); - } else if (!strcasecmp(parm->val, "RUSSIA")) { - mtpLink->mtp3.switchType = LSI_SW_RUSSIA; - SS7_DEBUG("\tFound mtpLink->switchType = \"RUSSIA\"\n"); - } else if (!strcasecmp(parm->val, "INDIA")) { - mtpLink->mtp3.switchType = LSI_SW_INDIA; - SS7_DEBUG("\tFound mtpLink->switchType = \"INDIA\"\n"); - } else if (!strcasecmp(parm->val, "ansi88")) { - mtpLink->mtp3.switchType = LSI_SW_ANS88; - SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI88\"\n"); - } else if (!strcasecmp(parm->val, "ansi92")) { - mtpLink->mtp3.switchType = LSI_SW_ANS92; - SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI92\"\n"); - } else if (!strcasecmp(parm->val, "ansi95")) { - mtpLink->mtp3.switchType = LSI_SW_ANS95; - SS7_DEBUG("\tFound mtpLink->switchType = \"ANSI95\"\n"); - } else { - SS7_ERROR("\tFound an invalid linktype of \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "ssf")) { - if (!strcasecmp(parm->val, "nat")) { - mtpLink->mtp3.ssf = SSF_NAT; - } else if (!strcasecmp(parm->val, "int")) { - mtpLink->mtp3.ssf = SSF_INTL; - } else if (!strcasecmp(parm->val, "spare")) { - mtpLink->mtp3.ssf = SSF_SPARE; - } else if (!strcasecmp(parm->val, "res")) { - mtpLink->mtp3.ssf = SSF_RES; - } else { - SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val); - return FTDM_FAIL; - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "slc")) { - mtpLink->mtp3.slc = atoi(parm->val); - SS7_DEBUG("\tFound mtpLink->slc = \"%d\"\n",mtpLink->mtp3.slc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t1")) { - mtpLink->mtp2.t1 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t1 = \"%d\"\n",mtpLink->mtp2.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t2")) { - mtpLink->mtp2.t2 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t2 = \"%d\"\n",mtpLink->mtp2.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t3")) { - mtpLink->mtp2.t3 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t3 = \"%d\"\n",mtpLink->mtp2.t3); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t4n")) { - mtpLink->mtp2.t4n = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t4n = \"%d\"\n",mtpLink->mtp2.t4n); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t4e")) { - mtpLink->mtp2.t4e = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t4e = \"%d\"\n",mtpLink->mtp2.t4e); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t5")) { - mtpLink->mtp2.t5 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t5 = \"%d\"\n",mtpLink->mtp2.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t6")) { - mtpLink->mtp2.t6 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t6 = \"%d\"\n",mtpLink->mtp2.t6); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp2.t7")) { - mtpLink->mtp2.t7 = atoi(parm->val); - SS7_DEBUG("\tFound mtp2 t7 = \"%d\"\n",mtpLink->mtp2.t7); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t1")) { - mtpLink->mtp3.t1 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t1 = \"%d\"\n",mtpLink->mtp3.t1); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t2")) { - mtpLink->mtp3.t2 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t2 = \"%d\"\n",mtpLink->mtp3.t2); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t3")) { - mtpLink->mtp3.t3 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t3 = \"%d\"\n",mtpLink->mtp3.t3); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t4")) { - mtpLink->mtp3.t4 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t4 = \"%d\"\n",mtpLink->mtp3.t4); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t5")) { - mtpLink->mtp3.t5 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t5 = \"%d\"\n",mtpLink->mtp3.t5); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t7")) { - mtpLink->mtp3.t7 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t7 = \"%d\"\n",mtpLink->mtp3.t7); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t12")) { - mtpLink->mtp3.t12 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t12 = \"%d\"\n",mtpLink->mtp3.t12); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t13")) { - mtpLink->mtp3.t13 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t13 = \"%d\"\n",mtpLink->mtp3.t13); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t14")) { - mtpLink->mtp3.t14 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t14 = \"%d\"\n",mtpLink->mtp3.t14); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t17")) { - mtpLink->mtp3.t17 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t17 = \"%d\"\n",mtpLink->mtp3.t17); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t22")) { - mtpLink->mtp3.t22 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t22 = \"%d\"\n",mtpLink->mtp3.t22); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t23")) { - mtpLink->mtp3.t23 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t23 = \"%d\"\n",mtpLink->mtp3.t23); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t24")) { - mtpLink->mtp3.t24 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t24 = \"%d\"\n",mtpLink->mtp3.t24); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t31")) { - mtpLink->mtp3.t31 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t31 = \"%d\"\n",mtpLink->mtp3.t31); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t32")) { - mtpLink->mtp3.t32 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t32 = \"%d\"\n",mtpLink->mtp3.t32); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t33")) { - mtpLink->mtp3.t33 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t33 = \"%d\"\n",mtpLink->mtp3.t33); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t34")) { - mtpLink->mtp3.t34 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t34 = \"%d\"\n",mtpLink->mtp3.t34); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t35")) { - mtpLink->mtp3.t35 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t35 = \"%d\"\n",mtpLink->mtp3.t35); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t36")) { - mtpLink->mtp3.t36 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t36 = \"%d\"\n",mtpLink->mtp3.t36); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.t37")) { - mtpLink->mtp3.t37 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t37 = \"%d\"\n",mtpLink->mtp3.t37); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.tcraft")) { - mtpLink->mtp3.tcraft = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 tcraft = \"%d\"\n",mtpLink->mtp3.tcraft); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.tflc")) { - mtpLink->mtp3.tflc = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 tflc = \"%d\"\n",mtpLink->mtp3.tflc); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp3.tbnd")) { - mtpLink->mtp3.tbnd = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 tbnd = \"%d\"\n",mtpLink->mtp3.tbnd); - /**********************************************************************/ - } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); - return FTDM_FAIL; + /* go through all the mtp3 links and fill in the apc */ + i = 1; + while (g_ftdm_sngss7_data.cfg.mtp3Link[i].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == mtpLinkSet.id) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtpLinkSet.apc; } - - /* move to the next parameter */ - parm = parm + 1; + + i++; } - + return FTDM_SUCCESS; } @@ -813,6 +1269,11 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) int num_parms = mtp_route->n_parameters; int i; + ftdm_conf_node_t *linkset; + int ls_id; + int numLinks; + + /* initalize the mtpRoute structure */ memset(&mtpRoute, 0x0, sizeof(mtpRoute)); /* confirm that we are looking at an mtp_link */ @@ -824,119 +1285,147 @@ static int ftmod_ss7_parse_mtp_route(ftdm_conf_node_t *mtp_route) } for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + /* try to match the parameter to what we expect */ - /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strncpy((char *)mtpRoute.name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"mtp_route\" named = %s\n", mtpRoute.name); + /**********************************************************************/ + strcpy((char *)mtpRoute.name, parm->val); + SS7_DEBUG("Found an mtpRoute named = %s\n", mtpRoute.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + mtpRoute.id = atoi(parm->val); + SS7_DEBUG("Found an mtpRoute id = %d\n", mtpRoute.id); /**********************************************************************/ } else if (!strcasecmp(parm->var, "dpc")) { - mtpRoute.dpc = atoi(parm->val); - SS7_DEBUG("\tFound mtpRoute->dpc = %d\n", mtpRoute.dpc); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp_linkset")) { - - /* find the linkset by it's name */ - int x = 1; - while (g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id != 0) { - /* check if the name matches */ - if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpLinkSet[x].name, parm->val)) { - - /* now, harvest the required infomormation from the global structure */ - mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].linkType; - mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].switchType; - mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].ssf; - mtpRoute.linkSetId = g_ftdm_sngss7_data.cfg.mtpLinkSet[x].id; - cmbLinkSetId++; - mtpRoute.cmbLinkSetId = cmbLinkSetId; - - /* update the linkset with the new cmbLinkSet value */ - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks++; - g_ftdm_sngss7_data.cfg.mtpLinkSet[x].links[g_ftdm_sngss7_data.cfg.mtpLinkSet[x].numLinks-1] = mtpRoute.cmbLinkSetId; - break; - } - x++; - } - - /* check why we exited the wile loop ... and react accordingly */ - if (mtpRoute.cmbLinkSetId == 0) { - SS7_ERROR("\tFailed to find the linkset = \"%s\"!\n", parm->val); - return FTDM_FAIL; - } else { - SS7_DEBUG("\tFound mtp3_route->linkset = %s\n", parm->val); - } + mtpRoute.dpc = atoi(parm->val); + SS7_DEBUG("Found an mtpRoute dpc = %d\n", mtpRoute.dpc); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isSTP")) { + /**********************************************************************/ if (!strcasecmp(parm->val, "no")) { mtpRoute.isSTP = 0; - SS7_DEBUG("\tFound mtpRoute->isSTP = no\n"); + SS7_DEBUG("Found an mtpRoute isSTP = no\n"); } else if (!strcasecmp(parm->val, "yes")) { mtpRoute.isSTP = 1; - SS7_DEBUG("\tFound mtpRoute->isSTP = yes\n"); + SS7_DEBUG("Found an mtpRoute isSTP = yes\n"); } else { - SS7_ERROR("\tFound an invalid parameter for isSTP \"%s\"!\n", parm->val); + SS7_ERROR("Found an invalid parameter for isSTP %s!\n", parm->val); return FTDM_FAIL; } /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t6")) { + /**********************************************************************/ mtpRoute.t6 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t6 = \"%d\"\n",mtpRoute.t6); + SS7_DEBUG("Found an mtp3 t6 = %d\n",mtpRoute.t6); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t8")) { + /**********************************************************************/ mtpRoute.t8 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t8 = \"%d\"\n",mtpRoute.t8); + SS7_DEBUG("Found an mtp3 t8 = %d\n",mtpRoute.t8); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t10")) { + /**********************************************************************/ mtpRoute.t10 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t10 = \"%d\"\n",mtpRoute.t10); + SS7_DEBUG("Found an mtp3 t10 = %d\n",mtpRoute.t10); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t11")) { + /**********************************************************************/ mtpRoute.t11 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t11 = \"%d\"\n",mtpRoute.t11); + SS7_DEBUG("Found an mtp3 t11 = %d\n",mtpRoute.t11); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t15")) { + /**********************************************************************/ mtpRoute.t15 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t15 = \"%d\"\n",mtpRoute.t15); + SS7_DEBUG("Found an mtp3 t15 = %d\n",mtpRoute.t15); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t16")) { + /**********************************************************************/ mtpRoute.t16 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t16 = \"%d\"\n",mtpRoute.t16); + SS7_DEBUG("Found an mtp3 t16 = %d\n",mtpRoute.t16); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t18")) { + /**********************************************************************/ mtpRoute.t18 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t18 = \"%d\"\n",mtpRoute.t18); + SS7_DEBUG("Found an mtp3 t18 = %d\n",mtpRoute.t18); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t19")) { + /**********************************************************************/ mtpRoute.t19 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t19 = \"%d\"\n",mtpRoute.t19); + SS7_DEBUG("Found an mtp3 t19 = %d\n",mtpRoute.t19); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t21")) { + /**********************************************************************/ mtpRoute.t21 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t21 = \"%d\"\n",mtpRoute.t21); + SS7_DEBUG("Found an mtp3 t21 = %d\n",mtpRoute.t21); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t25")) { + /**********************************************************************/ mtpRoute.t25 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t25 = \"%d\"\n",mtpRoute.t25); + SS7_DEBUG("Found an mtp3 t25 = %d\n",mtpRoute.t25); /**********************************************************************/ } else if (!strcasecmp(parm->var, "mtp3.t26")) { + /**********************************************************************/ mtpRoute.t26 = atoi(parm->val); - SS7_DEBUG("\tFound mtp3 t26 = \"%d\"\n",mtpRoute.t26); + SS7_DEBUG("Found an mtp3 t26 = %d\n",mtpRoute.t26); /**********************************************************************/ } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val); return FTDM_FAIL; - + /**********************************************************************/ } /* move to the next parameter */ parm = parm + 1; } - ftmod_ss7_fill_in_nsap(&mtpRoute); + /* fill in the rest of the values in the mtpRoute struct */ + mtpRoute.nwId = mtpRoute.id; + mtpRoute.cmbLinkSetId = mtpRoute.id; + + /* parse in the list of linksets this route is reachable by */ + linkset = mtp_route->child->child; + + while (linkset != NULL) { + /**************************************************************************/ + /* extract the linkset Id */ + ls_id = atoi(linkset->parameters->val); + + if (g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].id != 0) { + SS7_DEBUG("Found mtpRoute linkset id = %d that is valid\n",ls_id); + } else { + SS7_ERROR("Found mtpRoute linkset id = %d that is invalid\n",ls_id); + goto move_along; + } + + /* pull up the linktype, switchtype, and SSF from the linkset */ + mtpRoute.linkType = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].linkType; + mtpRoute.switchType = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].switchType; + mtpRoute.ssf = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].ssf; + + /* extract the number of cmbLinkSetId aleady on this linkset */ + numLinks = g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].numLinks; + + /* add this routes cmbLinkSetId to the list */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].links[numLinks] = mtpRoute.cmbLinkSetId; + + /* increment the number of cmbLinkSets on this linkset */ + g_ftdm_sngss7_data.cfg.mtpLinkSet[ls_id].numLinks++; + +move_along: + /* move to the next linkset element */ + linkset = linkset->next; + + /**************************************************************************/ + } /* while (linkset != null) */ + ftmod_ss7_fill_in_mtp3_route(&mtpRoute); - + ftmod_ss7_fill_in_nsap(&mtpRoute); return FTDM_SUCCESS; } @@ -979,10 +1468,9 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) ftdm_conf_parameter_t *parm = isup_interface->parameters; int num_parms = isup_interface->n_parameters; int i; - int linkSetId; - int flag_cld_nadi = 0; - int flag_clg_nadi = 0; + int ret; + /* initalize the isup intf and isap structure */ memset(&sng_isup, 0x0, sizeof(sng_isup)); memset(&sng_isap, 0x0, sizeof(sng_isap)); @@ -996,357 +1484,570 @@ static int ftmod_ss7_parse_isup_interface(ftdm_conf_node_t *isup_interface) for (i = 0; i < num_parms; i++) { + /**************************************************************************/ + /* try to match the parameter to what we expect */ - /**********************************************************************/ if (!strcasecmp(parm->var, "name")) { - strncpy((char *)sng_isup.name, parm->val, MAX_NAME_LEN-1); - SS7_DEBUG("\tFound an \"isup_interface\" named = %s\n", sng_isup.name); + /**********************************************************************/ + strcpy((char *)sng_isup.name, parm->val); + SS7_DEBUG("Found an isup_interface named = %s\n", sng_isup.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + sng_isup.id = atoi(parm->val); + SS7_DEBUG("Found an isup id = %d\n", sng_isup.id); /**********************************************************************/ } else if (!strcasecmp(parm->var, "spc")) { + /**********************************************************************/ sng_isup.spc = atoi(parm->val); g_ftdm_sngss7_data.cfg.spc = sng_isup.spc; - SS7_DEBUG("\tFound SPC = %d\n", sng_isup.spc); + SS7_DEBUG("Found an isup SPC = %d\n", sng_isup.spc); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "mtp_route")) { - /* find the route by it's name */ - int x = 1; - - while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) { - - /* check if the name matches */ - if (!strcasecmp((char *)g_ftdm_sngss7_data.cfg.mtpRoute[x].name, parm->val)) { - /* now, harvest the required information from the global structure */ - sng_isup.mtpRouteId = g_ftdm_sngss7_data.cfg.mtpRoute[x].id; - sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[x].dpc; - sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; - sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType; - - /* find the NSAP corresponding to this switchType and SSF */ - int z = 1; - while (g_ftdm_sngss7_data.cfg.nsap[z].id != 0) { - if ((g_ftdm_sngss7_data.cfg.nsap[z].linkType == g_ftdm_sngss7_data.cfg.mtpRoute[x].linkType) && - (g_ftdm_sngss7_data.cfg.nsap[z].switchType == g_ftdm_sngss7_data.cfg.mtpRoute[x].switchType) && - (g_ftdm_sngss7_data.cfg.nsap[z].ssf == g_ftdm_sngss7_data.cfg.mtpRoute[x].ssf)) { - sng_isup.nwId = g_ftdm_sngss7_data.cfg.nsap[z].nwId; - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - z++; - } - break; - } - x++; - } /* while (g_ftdm_sngss7_data.cfg.mtpRoute[x].id != 0) */ - - /* check why we exited the while loop ... and react accordingly */ - if (sng_isup.mtpRouteId == 0) { - SS7_ERROR("\tFailed to find the MTP3 Route = \"%s\"!\n", parm->val); - return FTDM_FAIL; - } else { - SS7_DEBUG("\tFound MTP3 Route = %s\n", parm->val); - } + } else if (!strcasecmp(parm->var, "mtprouteId")) { /**********************************************************************/ - } else if (!strcasecmp(parm->var, "min_digits")) { - sng_isup.min_digits = atoi(parm->val); + sng_isup.mtpRouteId=atoi(parm->val); - SS7_DEBUG("\tFound min_digits = %d\n", sng_isup.min_digits); + SS7_DEBUG("Found an isup mptRouteId = %d\n", sng_isup.mtpRouteId); /**********************************************************************/ } else if (!strcasecmp(parm->var, "ssf")) { - if (!strcasecmp(parm->val, "nat")) { - sng_isup.ssf = SSF_NAT; - sng_isap.ssf = SSF_NAT; - } else if (!strcasecmp(parm->val, "int")) { - sng_isup.ssf = SSF_INTL; - sng_isap.ssf = SSF_INTL; - } else if (!strcasecmp(parm->val, "spare")) { - sng_isup.ssf = SSF_SPARE; - sng_isap.ssf = SSF_SPARE; - } else if (!strcasecmp(parm->val, "res")) { - sng_isup.ssf = SSF_RES; - sng_isap.ssf = SSF_RES; - } else { - SS7_ERROR("\tFound an invalid ssf of \"%s\"!\n", parm->val); + /**********************************************************************/ + ret = find_ssf_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid isup ssf = %s\n", parm->var); return FTDM_FAIL; + } else { + sng_isup.ssf = sng_ssf_type_map[ret].tril_type; + sng_isap.ssf = sng_ssf_type_map[ret].tril_type; + SS7_DEBUG("Found an isup ssf = %s\n", sng_ssf_type_map[ret].sng_type); } /**********************************************************************/ - } else if (!strcasecmp(parm->var, "license")) { - /**********************************************************************/ - strncpy(g_ftdm_sngss7_data.cfg.license, parm->val, MAX_PATH-1); - strncpy(g_ftdm_sngss7_data.cfg.signature, parm->val, MAX_PATH-1); - strcat(g_ftdm_sngss7_data.cfg.signature, ".sig"); - SS7_DEBUG("\tFound license file = %s\n", g_ftdm_sngss7_data.cfg.license); - SS7_DEBUG("\tFound signature file = %s\n", g_ftdm_sngss7_data.cfg.signature); - /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t1")) { + /**********************************************************************/ sng_isap.t1 = atoi(parm->val); - SS7_DEBUG("\tFound isup t1 = \"%d\"\n",sng_isap.t1); + SS7_DEBUG("Found isup t1 = %d\n",sng_isap.t1); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t2")) { + /**********************************************************************/ sng_isap.t2 = atoi(parm->val); - SS7_DEBUG("\tFound isup t2 = \"%d\"\n",sng_isap.t2); + SS7_DEBUG("Found isup t2 = %d\n",sng_isap.t2); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t4")) { + /**********************************************************************/ sng_isup.t4 = atoi(parm->val); - SS7_DEBUG("\tFound isup t4 = \"%d\"\n",sng_isup.t4); + SS7_DEBUG("Found isup t4 = %d\n",sng_isup.t4); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t5")) { + /**********************************************************************/ sng_isap.t5 = atoi(parm->val); - SS7_DEBUG("\tFound isup t5 = \"%d\"\n",sng_isap.t5); + SS7_DEBUG("Found isup t5 = %d\n",sng_isap.t5); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t6")) { + /**********************************************************************/ sng_isap.t6 = atoi(parm->val); - SS7_DEBUG("\tFound isup t6 = \"%d\"\n",sng_isap.t6); + SS7_DEBUG("Found isup t6 = %d\n",sng_isap.t6); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t7")) { + /**********************************************************************/ sng_isap.t7 = atoi(parm->val); - SS7_DEBUG("\tFound isup t7 = \"%d\"\n",sng_isap.t7); + SS7_DEBUG("Found isup t7 = %d\n",sng_isap.t7); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t8")) { + /**********************************************************************/ sng_isap.t8 = atoi(parm->val); - SS7_DEBUG("\tFound isup t8 = \"%d\"\n",sng_isap.t8); + SS7_DEBUG("Found isup t8 = %d\n",sng_isap.t8); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t9")) { + /**********************************************************************/ sng_isap.t9 = atoi(parm->val); - SS7_DEBUG("\tFound isup t9 = \"%d\"\n",sng_isap.t9); + SS7_DEBUG("Found isup t9 = %d\n",sng_isap.t9); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t10")) { + /**********************************************************************/ sng_isup.t10 = atoi(parm->val); - SS7_DEBUG("\tFound isup t10 = \"%d\"\n",sng_isup.t10); + SS7_DEBUG("Found isup t10 = %d\n",sng_isup.t10); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t11")) { + /**********************************************************************/ sng_isup.t11 = atoi(parm->val); - SS7_DEBUG("\tFound isup t11 = \"%d\"\n",sng_isup.t11); + SS7_DEBUG("Found isup t11 = %d\n",sng_isup.t11); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t18")) { + /**********************************************************************/ sng_isup.t18 = atoi(parm->val); - SS7_DEBUG("\tFound isup t18 = \"%d\"\n",sng_isup.t18); + SS7_DEBUG("Found isup t18 = %d\n",sng_isup.t18); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t19")) { + /**********************************************************************/ sng_isup.t19 = atoi(parm->val); - SS7_DEBUG("\tFound isup t19 = \"%d\"\n",sng_isup.t19); + SS7_DEBUG("Found isup t19 = %d\n",sng_isup.t19); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t20")) { + /**********************************************************************/ sng_isup.t20 = atoi(parm->val); - SS7_DEBUG("\tFound isup t20 = \"%d\"\n",sng_isup.t20); + SS7_DEBUG("Found isup t20 = %d\n",sng_isup.t20); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t21")) { + /**********************************************************************/ sng_isup.t21 = atoi(parm->val); - SS7_DEBUG("\tFound isup t21 = \"%d\"\n",sng_isup.t21); + SS7_DEBUG("Found isup t21 = %d\n",sng_isup.t21); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t22")) { + /**********************************************************************/ sng_isup.t22 = atoi(parm->val); - SS7_DEBUG("\tFound isup t22 = \"%d\"\n",sng_isup.t22); + SS7_DEBUG("Found isup t22 = %d\n",sng_isup.t22); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t23")) { + /**********************************************************************/ sng_isup.t23 = atoi(parm->val); - SS7_DEBUG("\tFound isup t23 = \"%d\"\n",sng_isup.t23); + SS7_DEBUG("Found isup t23 = %d\n",sng_isup.t23); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t24")) { + /**********************************************************************/ sng_isup.t24 = atoi(parm->val); - SS7_DEBUG("\tFound isup t24 = \"%d\"\n",sng_isup.t24); + SS7_DEBUG("Found isup t24 = %d\n",sng_isup.t24); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t25")) { + /**********************************************************************/ sng_isup.t25 = atoi(parm->val); - SS7_DEBUG("\tFound isup t25 = \"%d\"\n",sng_isup.t25); + SS7_DEBUG("Found isup t25 = %d\n",sng_isup.t25); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t26")) { + /**********************************************************************/ sng_isup.t26 = atoi(parm->val); - SS7_DEBUG("\tFound isup t26 = \"%d\"\n",sng_isup.t26); + SS7_DEBUG("Found isup t26 = %d\n",sng_isup.t26); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t28")) { + /**********************************************************************/ sng_isup.t28 = atoi(parm->val); - SS7_DEBUG("\tFound isup t28 = \"%d\"\n",sng_isup.t28); + SS7_DEBUG("Found isup t28 = %d\n",sng_isup.t28); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t29")) { + /**********************************************************************/ sng_isup.t29 = atoi(parm->val); - SS7_DEBUG("\tFound isup t29 = \"%d\"\n",sng_isup.t29); + SS7_DEBUG("Found isup t29 = %d\n",sng_isup.t29); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t30")) { + /**********************************************************************/ sng_isup.t30 = atoi(parm->val); - SS7_DEBUG("\tFound isup t30 = \"%d\"\n",sng_isup.t30); + SS7_DEBUG("Found isup t30 = %d\n",sng_isup.t30); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t31")) { + /**********************************************************************/ sng_isap.t31 = atoi(parm->val); - SS7_DEBUG("\tFound isup t31 = \"%d\"\n",sng_isap.t31); + SS7_DEBUG("Found isup t31 = %d\n",sng_isap.t31); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t32")) { + /**********************************************************************/ sng_isup.t32 = atoi(parm->val); - SS7_DEBUG("\tFound isup t32 = \"%d\"\n",sng_isup.t32); + SS7_DEBUG("Found isup t32 = %d\n",sng_isup.t32); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t33")) { + /**********************************************************************/ sng_isap.t33 = atoi(parm->val); - SS7_DEBUG("\tFound isup t33 = \"%d\"\n",sng_isap.t33); + SS7_DEBUG("Found isup t33 = %d\n",sng_isap.t33); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t34")) { - sng_isap.t34 = atoi(parm->val); - SS7_DEBUG("\tFound isup t34 = \"%d\"\n",sng_isap.t34); /**********************************************************************/ - } else if (!strcasecmp(parm->var, "isup.t35")) { - sng_isup.t35 = atoi(parm->val); - SS7_DEBUG("\tFound isup t35 = \"%d\"\n",sng_isup.t35); + sng_isap.t34 = atoi(parm->val); + SS7_DEBUG("Found isup t34 = %d\n",sng_isap.t34); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t36")) { + /**********************************************************************/ sng_isap.t36 = atoi(parm->val); - SS7_DEBUG("\tFound isup t36 = \"%d\"\n",sng_isap.t36); + SS7_DEBUG("Found isup t36 = %d\n",sng_isap.t36); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t37")) { + /**********************************************************************/ sng_isup.t37 = atoi(parm->val); - SS7_DEBUG("\tFound isup t37 = \"%d\"\n",sng_isup.t37); + SS7_DEBUG("Found isup t37 = %d\n",sng_isup.t37); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t38")) { + /**********************************************************************/ sng_isup.t38 = atoi(parm->val); - SS7_DEBUG("\tFound isup t38 = \"%d\"\n",sng_isup.t38); + SS7_DEBUG("Found isup t38 = %d\n",sng_isup.t38); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.t39")) { + /**********************************************************************/ sng_isup.t39 = atoi(parm->val); - SS7_DEBUG("\tFound isup t39 = \"%d\"\n",sng_isup.t39); + SS7_DEBUG("Found isup t39 = %d\n",sng_isup.t39); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tccr")) { + /**********************************************************************/ sng_isap.tccr = atoi(parm->val); - SS7_DEBUG("\tFound isup tccr = \"%d\"\n",sng_isap.tccr); + SS7_DEBUG("Found isup tccr = %d\n",sng_isap.tccr); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tccrt")) { + /**********************************************************************/ sng_isap.tccrt = atoi(parm->val); - SS7_DEBUG("\tFound isup tccrt = \"%d\"\n",sng_isap.tccrt); + SS7_DEBUG("Found isup tccrt = %d\n",sng_isap.tccrt); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tex")) { + /**********************************************************************/ sng_isap.tex = atoi(parm->val); - SS7_DEBUG("\tFound isup tex = \"%d\"\n",sng_isap.tex); + SS7_DEBUG("Found isup tex = %d\n",sng_isap.tex); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tect")) { + /**********************************************************************/ sng_isap.tect = atoi(parm->val); - SS7_DEBUG("\tFound isup tect = \"%d\"\n",sng_isap.tect); + SS7_DEBUG("Found isup tect = %d\n",sng_isap.tect); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tcrm")) { + /**********************************************************************/ sng_isap.tcrm = atoi(parm->val); - SS7_DEBUG("\tFound isup tcrm = \"%d\"\n",sng_isap.tcrm); + SS7_DEBUG("Found isup tcrm = %d\n",sng_isap.tcrm); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tcra")) { + /**********************************************************************/ sng_isap.tcra = atoi(parm->val); - SS7_DEBUG("\tFound isup tcra = \"%d\"\n",sng_isap.tcra); + SS7_DEBUG("Found isup tcra = %d\n",sng_isap.tcra); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tfgr")) { + /**********************************************************************/ sng_isup.tfgr = atoi(parm->val); - SS7_DEBUG("\tFound isup tfgr = \"%d\"\n",sng_isup.tfgr); + SS7_DEBUG("Found isup tfgr = %d\n",sng_isup.tfgr); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.trelrsp")) { + /**********************************************************************/ sng_isap.trelrsp = atoi(parm->val); - SS7_DEBUG("\tFound isup trelrsp = \"%d\"\n",sng_isap.trelrsp); + SS7_DEBUG("Found isup trelrsp = %d\n",sng_isap.trelrsp); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) { + /**********************************************************************/ sng_isap.tfnlrelrsp = atoi(parm->val); - SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp); + SS7_DEBUG("Found isup tfnlrelrsp = %d\n",sng_isap.tfnlrelrsp); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tfnlrelrsp")) { + /**********************************************************************/ sng_isap.tfnlrelrsp = atoi(parm->val); - SS7_DEBUG("\tFound isup tfnlrelrsp = \"%d\"\n",sng_isap.tfnlrelrsp); + SS7_DEBUG("Found isup tfnlrelrsp = %d\n",sng_isap.tfnlrelrsp); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tpause")) { + /**********************************************************************/ sng_isup.tpause = atoi(parm->val); - SS7_DEBUG("\tFound isup tpause = \"%d\"\n",sng_isup.tpause); + SS7_DEBUG("Found isup tpause = %d\n",sng_isup.tpause); /**********************************************************************/ } else if (!strcasecmp(parm->var, "isup.tstaenq")) { + /**********************************************************************/ sng_isup.tstaenq = atoi(parm->val); - SS7_DEBUG("\tFound isup tstaenq = \"%d\"\n",sng_isup.tstaenq); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "clg_nadi")) { - /**********************************************************************/ - /* throw the flag so that we know we got this optional parameter */ - flag_clg_nadi = 1; - sng_isup.clg_nadi = atoi(parm->val); - SS7_DEBUG("\tFound default CLG_NADI value = %d\n", sng_isup.clg_nadi); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "cld_nadi")) { - /**********************************************************************/ - /* throw the flag so that we know we got this optional parameter */ - flag_cld_nadi = 1; - sng_isup.cld_nadi = atoi(parm->val); - SS7_DEBUG("\tFound default CLD_NADI value = %d\n", sng_isup.cld_nadi); - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "obci_bita")) { - /**********************************************************************/ - if (*parm->val == '1') { - sngss7_set_options(&sng_isup, SNGSS7_ACM_OBCI_BITA); - SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) enable option\n"); - } else if (*parm->val == '0') { - sngss7_clear_options(&sng_isup, SNGSS7_ACM_OBCI_BITA); - SS7_DEBUG("\tFound Optional Backwards Indicator: Bit A (early media) disable option\n"); - } else { - SS7_DEBUG("\tInvalid value for \"obci_bita\" option\n"); - } - /**********************************************************************/ - } else if (!strcasecmp(parm->var, "lpa_on_cot")) { - /**********************************************************************/ - if (*parm->val == '1') { - sngss7_set_options(&sng_isup, SNGSS7_LPA_FOR_COT); - SS7_DEBUG("\tFound Tx LPA on COT enable option\n"); - } else if (*parm->val == '0') { - sngss7_clear_options(&sng_isup, SNGSS7_LPA_FOR_COT); - SS7_DEBUG("\tFound Tx LPA on COT disable option\n"); - } else { - SS7_DEBUG("\tInvalid value for \"lpa_on_cot\" option\n"); - } + SS7_DEBUG("Found isup tstaenq = %d\n",sng_isup.tstaenq); /**********************************************************************/ } else { - SS7_ERROR("\tFound an invalid parameter \"%s\"!\n", parm->val); + /**********************************************************************/ + SS7_ERROR("Found an invalid parameter %s!\n", parm->val); return FTDM_FAIL; - + /**********************************************************************/ } /* move to the next parameter */ parm = parm + 1; - } + /**************************************************************************/ + } /* for (i = 0; i < num_parms; i++) */ - /* check if the user filled in a nadi value by looking at flag */ - if (!flag_cld_nadi) { - /* default the nadi value to national */ - sng_isup.cld_nadi = 0x03; - } - - if (!flag_clg_nadi) { - /* default the nadi value to national */ - sng_isup.clg_nadi = 0x03; - } - - /* check if the user requested min_digits value */ - if (sng_isup.min_digits == 0) { - /* default to 7 */ - sng_isup.min_digits = 7; - } - + /* default the interface to paused state */ + sngss7_set_flag(&sng_isup, SNGSS7_PAUSED); /* trickle down the SPC to all sub entities */ + int linkSetId; + linkSetId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].linkSetId; i = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) { - if (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId == linkSetId) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; + while (g_ftdm_sngss7_data.cfg.mtp3Link[i].id != 0) { + if (g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId == linkSetId) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].spc = g_ftdm_sngss7_data.cfg.spc; } i++; } + /* pull values from the lower levels */ + sng_isup.dpc = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].dpc; + sng_isup.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].switchType; + sng_isup.nwId = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].nwId; + + sng_isap.switchType = g_ftdm_sngss7_data.cfg.mtpRoute[sng_isup.mtpRouteId].switchType; + ftmod_ss7_fill_in_isap(&sng_isap); sng_isup.isap = sng_isap.id; ftmod_ss7_fill_in_isup_interface(&sng_isup); + /* setup the self mtp3 route */ + i = sng_isup.mtpRouteId; + + if(ftmod_ss7_fill_in_self_route(sng_isup.spc, + g_ftdm_sngss7_data.cfg.mtpRoute[i].linkType, + g_ftdm_sngss7_data.cfg.mtpRoute[i].switchType, + g_ftdm_sngss7_data.cfg.mtpRoute[i].ssf)) { + + SS7_ERROR("Failed to fill in self route structure!\n"); + return FTDM_FAIL; + + } + return FTDM_SUCCESS; } /******************************************************************************/ -static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) +static int ftmod_ss7_parse_cc_spans(ftdm_conf_node_t *cc_spans) +{ + ftdm_conf_node_t *cc_span = NULL; + + /* confirm that we are looking at cc_spans */ + if (strcasecmp(cc_spans->name, "cc_spans")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_spans\"!\n",cc_spans->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"cc_spans\"...\n"); + } + + /* extract the cc_spans */ + cc_span = cc_spans->child; + + while (cc_span != NULL) { + /* parse the found cc_span */ + if (ftmod_ss7_parse_cc_span(cc_span)) { + SS7_ERROR("Failed to parse \"cc_span\"\n"); + return FTDM_FAIL; + } + + /* go to the next cc_span */ + cc_span = cc_span->next; + } + + return FTDM_SUCCESS; + +} + +/******************************************************************************/ +static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span) +{ + sng_ccSpan_t sng_ccSpan; + ftdm_conf_parameter_t *parm = cc_span->parameters; + int num_parms = cc_span->n_parameters; + int flag_clg_nadi = 0; + int flag_cld_nadi = 0; + int i; + int ret; + + /* initalize the ccSpan structure */ + memset(&sng_ccSpan, 0x0, sizeof(sng_ccSpan)); + + /* confirm that we are looking at an mtp_link */ + if (strcasecmp(cc_span->name, "cc_span")) { + SS7_ERROR("We're looking at \"%s\"...but we're supposed to be looking at \"cc_span\"!\n",cc_span->name); + return FTDM_FAIL; + } else { + SS7_DEBUG("Parsing \"cc_span\"...\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_ccSpan.name, parm->val); + SS7_DEBUG("Found an ccSpan named = %s\n", sng_ccSpan.name); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "id")) { + /**********************************************************************/ + sng_ccSpan.id = atoi(parm->val); + SS7_DEBUG("Found an ccSpan id = %d\n", sng_ccSpan.id); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "procid")) { + /**********************************************************************/ + sng_ccSpan.procId = atoi(parm->val); + SS7_DEBUG("Found an ccSpan procId = %d\n", sng_ccSpan.procId); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "ch_map")) { + /**********************************************************************/ + strcpy(sng_ccSpan.ch_map, parm->val); + SS7_DEBUG("Found channel map %s\n", sng_ccSpan.ch_map); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "typeCntrl")) { + /**********************************************************************/ + ret = find_cic_cntrl_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid ccSpan typeCntrl = %s\n", parm->var); + return FTDM_FAIL; + } else { + sng_ccSpan.typeCntrl = sng_cic_cntrl_type_map[ret].tril_type; + SS7_DEBUG("Found an ccSpan typeCntrl = %s\n", sng_cic_cntrl_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "ssf")) { + /**********************************************************************/ + ret = find_ssf_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid ccSpan ssf = %s\n", parm->var); + return FTDM_FAIL; + } else { + sng_ccSpan.ssf = sng_ssf_type_map[ret].tril_type; + SS7_DEBUG("Found an ccSpan ssf = %s\n", sng_ssf_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "switchType")) { + /**********************************************************************/ + ret = find_switch_type_in_map(parm->val); + if (ret == -1) { + SS7_ERROR("Found an invalid ccSpan switchType = %s\n", parm->var); + return FTDM_FAIL; + } else { + sng_ccSpan.switchType = sng_switch_type_map[ret].tril_isup_type; + SS7_DEBUG("Found an ccSpan switchType = %s\n", sng_switch_type_map[ret].sng_type); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "cicbase")) { + /**********************************************************************/ + sng_ccSpan.cicbase = atoi(parm->val); + SS7_DEBUG("Found a cicbase = %d\n", sng_ccSpan.cicbase); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup_interface")) { + /**********************************************************************/ + sng_ccSpan.isupInf = atoi(parm->val); + SS7_DEBUG("Found an isup_interface = %d\n",sng_ccSpan.isupInf); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "min_digits")) { + /**********************************************************************/ + sng_ccSpan.min_digits = atoi(parm->val); + SS7_DEBUG("Found a min_digits = %d\n",sng_ccSpan.min_digits); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "clg_nadi")) { + /**********************************************************************/ + /* throw the flag so that we know we got this optional parameter */ + flag_clg_nadi = 1; + sng_ccSpan.clg_nadi = atoi(parm->val); + SS7_DEBUG("Found default CLG_NADI parm->value = %d\n", sng_ccSpan.clg_nadi); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "cld_nadi")) { + /**********************************************************************/ + /* throw the flag so that we know we got this optional parameter */ + flag_cld_nadi = 1; + sng_ccSpan.cld_nadi = atoi(parm->val); + SS7_DEBUG("Found default CLD_NADI parm->value = %d\n", sng_ccSpan.cld_nadi); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "obci_bita")) { + /**********************************************************************/ + if (*parm->val == '1') { + sngss7_set_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA); + SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) enable option\n"); + } else if (*parm->val == '0') { + sngss7_clear_options(&sng_ccSpan, SNGSS7_ACM_OBCI_BITA); + SS7_DEBUG("Found Optional Backwards Indicator: Bit A (early media) disable option\n"); + } else { + SS7_DEBUG("Invalid parm->value for obci_bita option\n"); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "lpa_on_cot")) { + /**********************************************************************/ + if (*parm->val == '1') { + sngss7_set_options(&sng_ccSpan, SNGSS7_LPA_FOR_COT); + SS7_DEBUG("Found Tx LPA on COT enable option\n"); + } else if (*parm->val == '0') { + sngss7_clear_options(&sng_ccSpan, SNGSS7_LPA_FOR_COT); + SS7_DEBUG("Found Tx LPA on COT disable option\n"); + } else { + SS7_DEBUG("Invalid parm->value for lpa_on_cot option\n"); + } + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t3")) { + /**********************************************************************/ + sng_ccSpan.t3 = atoi(parm->val); + SS7_DEBUG("Found isup t3 = %d\n", sng_ccSpan.t3); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t12")) { + /**********************************************************************/ + sng_ccSpan.t12 = atoi(parm->val); + SS7_DEBUG("Found isup t12 = %d\n", sng_ccSpan.t12); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t13")) { + /**********************************************************************/ + sng_ccSpan.t13 = atoi(parm->val); + SS7_DEBUG("Found isup t13 = %d\n", sng_ccSpan.t13); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t14")) { + /**********************************************************************/ + sng_ccSpan.t14 = atoi(parm->val); + SS7_DEBUG("Found isup t14 = %d\n", sng_ccSpan.t14); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t15")) { + /**********************************************************************/ + sng_ccSpan.t15 = atoi(parm->val); + SS7_DEBUG("Found isup t15 = %d\n", sng_ccSpan.t15); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t16")) { + /**********************************************************************/ + sng_ccSpan.t16 = atoi(parm->val); + SS7_DEBUG("Found isup t16 = %d\n", sng_ccSpan.t16); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t17")) { + /**********************************************************************/ + sng_ccSpan.t17 = atoi(parm->val); + SS7_DEBUG("Found isup t17 = %d\n", sng_ccSpan.t17); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.t35")) { + /**********************************************************************/ + sng_ccSpan.t35 = atoi(parm->val); + SS7_DEBUG("Found isup t35 = %d\n",sng_ccSpan.t35); + /**********************************************************************/ + } else if (!strcasecmp(parm->var, "isup.tval")) { + /**********************************************************************/ + sng_ccSpan.tval = atoi(parm->val); + SS7_DEBUG("Found isup tval = %d\n", sng_ccSpan.tval); + /**********************************************************************/ + } 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++) */ + + /* check if the user filled in a nadi value by looking at flag */ + if (!flag_cld_nadi) { + /* default the nadi value to national */ + sng_ccSpan.cld_nadi = 0x03; + } + + if (!flag_clg_nadi) { + /* default the nadi value to national */ + sng_ccSpan.clg_nadi = 0x03; + } + + /* add this span to our global listing */ + ftmod_ss7_fill_in_ccSpan(&sng_ccSpan); + + /* make sure the isup interface structure has something in it */ + if (g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].id == 0) { + /* fill in the id, so that we know it exists */ + g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf].id = sng_ccSpan.isupInf; + + /* default the status to PAUSED */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg.isupIntf[sng_ccSpan.isupInf], SNGSS7_PAUSED); + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_relay_channel(sng_relay_t *relay_channel) { int i; - /* go through all the existing links and see if we find a match */ + /* go through all the existing channels and see if we find a match */ i = 1; - while (g_ftdm_sngss7_data.cfg.mtpLink[i].id != 0) { - if ((g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.span == mtpLink->mtp1.span) && - (g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.chan == mtpLink->mtp1.chan)) { + while (g_ftdm_sngss7_data.cfg.relay[i].id != 0) { + if ((g_ftdm_sngss7_data.cfg.relay[i].type == relay_channel->type) && + (g_ftdm_sngss7_data.cfg.relay[i].port == relay_channel->port) && + (g_ftdm_sngss7_data.cfg.relay[i].procId == relay_channel->procId) && + (!strcasecmp(g_ftdm_sngss7_data.cfg.relay[i].hostname, relay_channel->hostname))) { /* we have a match so break out of this loop */ break; @@ -1355,178 +2056,272 @@ static int ftmod_ss7_fill_in_mtpLink(sng_mtp_link_t *mtpLink) i++; } - /* if the id value is 0 that means we didn't find the link */ - if (g_ftdm_sngss7_data.cfg.mtpLink[i].id == 0) { - mtpLink->id = i; - SS7_DEBUG("found new mtpLink on span=%d, chan=%d, id = %d\n", - mtpLink->mtp1.span, - mtpLink->mtp1.chan, - mtpLink->id); + /* if the id value is 0 that means we didn't find the relay channel */ + if (g_ftdm_sngss7_data.cfg.relay[i].id == 0) { + relay_channel->id = i; + SS7_DEBUG("found new relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n", + relay_channel->type, + relay_channel->hostname, + relay_channel->port, + relay_channel->procId, + relay_channel->id); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_RY); } else { - mtpLink->id = i; - SS7_DEBUG("found existing mtpLink on span=%d, chan=%d, id = %d\n", - mtpLink->mtp1.span, - mtpLink->mtp1.chan, - mtpLink->id); + relay_channel->id = i; + SS7_DEBUG("found existing relay channel on type:%d, hostname:%s, port:%d, procId:%d, id = %d\n", + relay_channel->type, + relay_channel->hostname, + relay_channel->port, + relay_channel->procId, + relay_channel->id); } - /* fill in the information */ - strncpy((char *)g_ftdm_sngss7_data.cfg.mtpLink[i].name, (char *)mtpLink->name, MAX_NAME_LEN-1); + g_ftdm_sngss7_data.cfg.relay[i].id = relay_channel->id; + g_ftdm_sngss7_data.cfg.relay[i].type = relay_channel->type; + g_ftdm_sngss7_data.cfg.relay[i].port = relay_channel->port; + g_ftdm_sngss7_data.cfg.relay[i].procId = relay_channel->procId; + strcpy(g_ftdm_sngss7_data.cfg.relay[i].hostname, relay_channel->hostname); + strcpy(g_ftdm_sngss7_data.cfg.relay[i].name, relay_channel->name); - g_ftdm_sngss7_data.cfg.mtpLink[i].id = mtpLink->id; - - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.span = mtpLink->mtp1.span; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp1.chan = mtpLink->mtp1.chan; - - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.linkType = mtpLink->mtp2.linkType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.errorType = mtpLink->mtp2.errorType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.lssuLength = mtpLink->mtp2.lssuLength; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.mtp1Id = mtpLink->id; - - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.priority = mtpLink->mtp3.priority; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkType = mtpLink->mtp3.linkType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.switchType = mtpLink->mtp3.switchType; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.apc = mtpLink->mtp3.apc; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.spc = g_ftdm_sngss7_data.cfg.spc; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.ssf = mtpLink->mtp3.ssf; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.slc = mtpLink->mtp3.slc; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.linkSetId = mtpLink->mtp3.linkSetId; - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.mtp2Id = mtpLink->id; - - if ( mtpLink->mtp2.t1 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t1 = mtpLink->mtp2.t1; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t1 = 500; - } - if ( mtpLink->mtp2.t2 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t2 = mtpLink->mtp2.t2; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t2 = 250; - } - if ( mtpLink->mtp2.t3 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t3 = mtpLink->mtp2.t3; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t3 = 20; - } - if ( mtpLink->mtp2.t4n != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4n = mtpLink->mtp2.t4n; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4n = 80; - } - if ( mtpLink->mtp2.t4e != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4e = mtpLink->mtp2.t4e; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t4e = 5; - } - if ( mtpLink->mtp2.t5 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t5 = mtpLink->mtp2.t5; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t5 = 1; - } - if ( mtpLink->mtp2.t6 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t6 = mtpLink->mtp2.t6; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t6 = 60; - } - if ( mtpLink->mtp2.t7 != 0 ) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = mtpLink->mtp2.t7; - }else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp2.t7 = 40; + /* if this is THE listen channel grab the procId and use it */ + if (relay_channel->type == LRY_CT_TCP_LISTEN) { + g_ftdm_sngss7_data.cfg.procId = relay_channel->procId; } - if (mtpLink->mtp3.t1 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t1 = mtpLink->mtp3.t1; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t1 = 8; - } - if (mtpLink->mtp3.t2 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t2 = mtpLink->mtp3.t2; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t2 = 14; - } - if (mtpLink->mtp3.t3 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t3 = mtpLink->mtp3.t3; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t3 = 8; - } - if (mtpLink->mtp3.t4 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t4 = mtpLink->mtp3.t4; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t4 = 8; - } - if (mtpLink->mtp3.t5 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t5 = mtpLink->mtp3.t5; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t5 = 8; - } - if (mtpLink->mtp3.t7 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t7 = mtpLink->mtp3.t7; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t7 = 15; - } - if (mtpLink->mtp3.t12 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t12 = mtpLink->mtp3.t12; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t12 = 15; - } - if (mtpLink->mtp3.t13 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t13 = mtpLink->mtp3.t13; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t13 = 15; - } - if (mtpLink->mtp3.t14 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t14 = mtpLink->mtp3.t14; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t14 = 30; - } - if (mtpLink->mtp3.t17 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t17 = mtpLink->mtp3.t17; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t17 = 15; - } - if (mtpLink->mtp3.t22 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t22 = mtpLink->mtp3.t22; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t22 = 1800; - } - if (mtpLink->mtp3.t23 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t23 = mtpLink->mtp3.t23; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t23 = 1800; - } - if (mtpLink->mtp3.t24 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t24 = mtpLink->mtp3.t24; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t24 = 5; - } - if (mtpLink->mtp3.t31 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t31 = mtpLink->mtp3.t31; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t31 = 50; - } - if (mtpLink->mtp3.t32 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t32 = mtpLink->mtp3.t32; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t32 = 120; - } - if (mtpLink->mtp3.t33 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t33 = mtpLink->mtp3.t33; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t33 = 3000; - } - if (mtpLink->mtp3.t34 != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t34 = mtpLink->mtp3.t34; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.t34 = 600; - } - if (mtpLink->mtp3.tflc != 0) { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.tflc = mtpLink->mtp3.tflc; - } else { - g_ftdm_sngss7_data.cfg.mtpLink[i].mtp3.tflc = 300; - } - return (mtpLink->id); + return FTDM_SUCCESS; } +/******************************************************************************/ +static int ftmod_ss7_fill_in_mtp1_link(sng_mtp1_link_t *mtp1Link) +{ + int i = mtp1Link->id; + + /* check if this id value has been used already */ + if (g_ftdm_sngss7_data.cfg.mtp1Link[i].id == 0) { + SS7_DEBUG("Found new MTP1 Link: id=%d, name=%s\n", mtp1Link->id, mtp1Link->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP1); + } else { + SS7_DEBUG("Found an existing MTP1 Link: id=%d, name=%s (old name=%s)\n", + mtp1Link->id, + mtp1Link->name, + g_ftdm_sngss7_data.cfg.mtp1Link[i].name); + } + + /* copy over the values */ + strcpy((char *)g_ftdm_sngss7_data.cfg.mtp1Link[i].name, (char *)mtp1Link->name); + + g_ftdm_sngss7_data.cfg.mtp1Link[i].id = mtp1Link->id; + g_ftdm_sngss7_data.cfg.mtp1Link[i].span = mtp1Link->span; + g_ftdm_sngss7_data.cfg.mtp1Link[i].chan = mtp1Link->chan; + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_mtp2_link(sng_mtp2_link_t *mtp2Link) +{ + int i = mtp2Link->id; + + /* check if this id value has been used already */ + if (g_ftdm_sngss7_data.cfg.mtp2Link[i].id == 0) { + SS7_DEBUG("Found new MTP2 Link: id=%d, name=%s\n", mtp2Link->id, mtp2Link->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP2); + } else { + SS7_DEBUG("Found an existing MTP2 Link: id=%d, name=%s (old name=%s)\n", + mtp2Link->id, + mtp2Link->name, + g_ftdm_sngss7_data.cfg.mtp2Link[i].name); + } + + /* copy over the values */ + strcpy((char *)g_ftdm_sngss7_data.cfg.mtp2Link[i].name, (char *)mtp2Link->name); + + g_ftdm_sngss7_data.cfg.mtp2Link[i].id = mtp2Link->id; + g_ftdm_sngss7_data.cfg.mtp2Link[i].lssuLength = mtp2Link->lssuLength; + g_ftdm_sngss7_data.cfg.mtp2Link[i].errorType = mtp2Link->errorType; + g_ftdm_sngss7_data.cfg.mtp2Link[i].linkType = mtp2Link->linkType; + g_ftdm_sngss7_data.cfg.mtp2Link[i].mtp1Id = mtp2Link->mtp1Id; + g_ftdm_sngss7_data.cfg.mtp2Link[i].mtp1ProcId = mtp2Link->mtp1ProcId; + + if ( mtp2Link->t1 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t1 = mtp2Link->t1; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t1 = 500; + } + + if ( mtp2Link->t2 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t2 = mtp2Link->t2; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t2 = 250; + } + + if ( mtp2Link->t3 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t3 = mtp2Link->t3; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t3 = 20; + } + + if ( mtp2Link->t4n != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4n = mtp2Link->t4n; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4n = 80; + } + + if ( mtp2Link->t4e != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4e = mtp2Link->t4e; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t4e = 5; + } + + if ( mtp2Link->t5 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t5 = mtp2Link->t5; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t5 = 1; + } + + if ( mtp2Link->t6 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t6 = mtp2Link->t6; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t6 = 60; + } + + if ( mtp2Link->t7 != 0 ) { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t7 = mtp2Link->t7; + }else { + g_ftdm_sngss7_data.cfg.mtp2Link[i].t7 = 40; + } + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_mtp3_link(sng_mtp3_link_t *mtp3Link) +{ + int i = mtp3Link->id; + + /* check if this id value has been used already */ + if (g_ftdm_sngss7_data.cfg.mtp3Link[i].id == 0) { + SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3Link->id, mtp3Link->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_MTP3); + } else { + SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n", + mtp3Link->id, + mtp3Link->name, + g_ftdm_sngss7_data.cfg.mtp3Link[i].name); + } + + /* copy over the values */ + strcpy((char *)g_ftdm_sngss7_data.cfg.mtp3Link[i].name, (char *)mtp3Link->name); + + g_ftdm_sngss7_data.cfg.mtp3Link[i].id = mtp3Link->id; + g_ftdm_sngss7_data.cfg.mtp3Link[i].priority = mtp3Link->priority; + g_ftdm_sngss7_data.cfg.mtp3Link[i].linkType = mtp3Link->linkType; + g_ftdm_sngss7_data.cfg.mtp3Link[i].switchType = mtp3Link->switchType; + g_ftdm_sngss7_data.cfg.mtp3Link[i].apc = mtp3Link->apc; + g_ftdm_sngss7_data.cfg.mtp3Link[i].spc = mtp3Link->spc; /* unknown at this time */ + g_ftdm_sngss7_data.cfg.mtp3Link[i].ssf = mtp3Link->ssf; + g_ftdm_sngss7_data.cfg.mtp3Link[i].slc = mtp3Link->slc; + g_ftdm_sngss7_data.cfg.mtp3Link[i].linkSetId = mtp3Link->linkSetId; + g_ftdm_sngss7_data.cfg.mtp3Link[i].mtp2Id = mtp3Link->mtp2Id; + g_ftdm_sngss7_data.cfg.mtp3Link[i].mtp2ProcId = mtp3Link->mtp2ProcId; + + if (mtp3Link->t1 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t1 = mtp3Link->t1; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t1 = 8; + } + if (mtp3Link->t2 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t2 = mtp3Link->t2; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t2 = 14; + } + if (mtp3Link->t3 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t3 = mtp3Link->t3; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t3 = 8; + } + if (mtp3Link->t4 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t4 = mtp3Link->t4; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t4 = 8; + } + if (mtp3Link->t5 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t5 = mtp3Link->t5; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t5 = 8; + } + if (mtp3Link->t7 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t7 = mtp3Link->t7; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t7 = 15; + } + if (mtp3Link->t12 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t12 = mtp3Link->t12; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t12 = 15; + } + if (mtp3Link->t13 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t13 = mtp3Link->t13; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t13 = 15; + } + if (mtp3Link->t14 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t14 = mtp3Link->t14; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t14 = 30; + } + if (mtp3Link->t17 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t17 = mtp3Link->t17; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t17 = 15; + } + if (mtp3Link->t22 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t22 = mtp3Link->t22; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t22 = 1800; + } + if (mtp3Link->t23 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t23 = mtp3Link->t23; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t23 = 1800; + } + if (mtp3Link->t24 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t24 = mtp3Link->t24; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t24 = 5; + } + if (mtp3Link->t31 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t31 = mtp3Link->t31; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t31 = 50; + } + if (mtp3Link->t32 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t32 = mtp3Link->t32; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t32 = 120; + } + if (mtp3Link->t33 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t33 = mtp3Link->t33; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t33 = 3000; + } + if (mtp3Link->t34 != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t34 = mtp3Link->t34; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].t34 = 600; + } + if (mtp3Link->tbnd != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tbnd = mtp3Link->tbnd; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tbnd = 30000; + } + if (mtp3Link->tflc != 0) { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tflc = mtp3Link->tflc; + } else { + g_ftdm_sngss7_data.cfg.mtp3Link[i].tflc = 300; + } + return FTDM_SUCCESS; +} /******************************************************************************/ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) @@ -1537,9 +2332,6 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) g_ftdm_sngss7_data.cfg.mtpLinkSet[i].id = mtpLinkSet->id; g_ftdm_sngss7_data.cfg.mtpLinkSet[i].apc = mtpLinkSet->apc; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].linkType = mtpLinkSet->linkType; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].switchType = mtpLinkSet->switchType; - g_ftdm_sngss7_data.cfg.mtpLinkSet[i].ssf = mtpLinkSet->ssf; /* these values are filled in as we find routes and start allocating cmbLinkSetIds */ g_ftdm_sngss7_data.cfg.mtpLinkSet[i].minActive = mtpLinkSet->minActive; @@ -1550,28 +2342,25 @@ static int ftmod_ss7_fill_in_mtpLinkSet(sng_link_set_t *mtpLinkSet) /******************************************************************************/ static int ftmod_ss7_fill_in_mtp3_route(sng_route_t *mtp3_route) { - int i; - - /* go through all the existing routes and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.mtpRoute[i].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.mtpRoute[i].name, mtp3_route->name)) { - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } + int i = mtp3_route->id; + /* check if this id value has been used already */ if (g_ftdm_sngss7_data.cfg.mtpRoute[i].id == 0) { - mtp3_route->id = i; - SS7_DEBUG("found new mtp3_route, id is = %d\n", mtp3_route->id); + SS7_DEBUG("Found new MTP3 Link: id=%d, name=%s\n", mtp3_route->id, mtp3_route->name); } else { - mtp3_route->id = i; - SS7_DEBUG("found existing mtp3_route, id is = %d\n", mtp3_route->id); + SS7_DEBUG("Found an existing MTP3 Link: id=%d, name=%s (old name=%s)\n", + mtp3_route->id, + mtp3_route->name, + g_ftdm_sngss7_data.cfg.mtpRoute[i].name); } - strncpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name, MAX_NAME_LEN-1); + /* fill in the cmbLinkSet in the linkset structure */ + int tmp = g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].numLinks; + + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].links[tmp] = mtp3_route->cmbLinkSetId; + g_ftdm_sngss7_data.cfg.mtpLinkSet[mtp3_route->linkSetId].numLinks++; + + strcpy((char *)g_ftdm_sngss7_data.cfg.mtpRoute[i].name, (char *)mtp3_route->name); g_ftdm_sngss7_data.cfg.mtpRoute[i].id = mtp3_route->id; g_ftdm_sngss7_data.cfg.mtpRoute[i].dpc = mtp3_route->dpc; @@ -1662,11 +2451,9 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) if (g_ftdm_sngss7_data.cfg.nsap[i].id == 0) { g_ftdm_sngss7_data.cfg.nsap[i].id = i; - mtp3_route->nwId = i; SS7_DEBUG("found new mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } else { g_ftdm_sngss7_data.cfg.nsap[i].id = i; - mtp3_route->nwId = i; SS7_DEBUG("found existing mtp3_isup interface, id is = %d\n", g_ftdm_sngss7_data.cfg.nsap[i].id); } @@ -1683,26 +2470,17 @@ static int ftmod_ss7_fill_in_nsap(sng_route_t *mtp3_route) /******************************************************************************/ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) { - int i; - - /* go through all the existing interfaces and see if we find a match */ - i = 1; - while (g_ftdm_sngss7_data.cfg.isupIntf[i].id != 0) { - if (!strcasecmp(g_ftdm_sngss7_data.cfg.isupIntf[i].name, sng_isup->name)) { - - /* we have a match so break out of this loop */ - break; - } - /* move on to the next one */ - i++; - } + int i = sng_isup->id; + /* check if this id value has been used already */ if (g_ftdm_sngss7_data.cfg.isupIntf[i].id == 0) { - sng_isup->id = i; - SS7_DEBUG("found new isup interface, id is = %d\n", sng_isup->id); + SS7_DEBUG("Found new ISUP Interface: id=%d, name=%s\n", sng_isup->id, sng_isup->name); + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_ISUP); } else { - sng_isup->id = i; - SS7_DEBUG("found existing isup interface, id is = %d\n", sng_isup->id); + SS7_DEBUG("Found an existing ISUP Interface: id=%d, name=%s (old name=%s)\n", + sng_isup->id, + sng_isup->name, + g_ftdm_sngss7_data.cfg.isupIntf[i].name); } strncpy((char *)g_ftdm_sngss7_data.cfg.isupIntf[i].name, (char *)sng_isup->name, MAX_NAME_LEN-1); @@ -1715,9 +2493,6 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) g_ftdm_sngss7_data.cfg.isupIntf[i].switchType = sng_isup->switchType; g_ftdm_sngss7_data.cfg.isupIntf[i].ssf = sng_isup->ssf; g_ftdm_sngss7_data.cfg.isupIntf[i].isap = sng_isup->isap; - g_ftdm_sngss7_data.cfg.isupIntf[i].cld_nadi = sng_isup->cld_nadi; - g_ftdm_sngss7_data.cfg.isupIntf[i].clg_nadi = sng_isup->clg_nadi; - g_ftdm_sngss7_data.cfg.isupIntf[i].min_digits = sng_isup->min_digits; g_ftdm_sngss7_data.cfg.isupIntf[i].options = sng_isup->options; if (sng_isup->t4 != 0) { g_ftdm_sngss7_data.cfg.isupIntf[i].t4 = sng_isup->t4; @@ -1799,11 +2574,6 @@ static int ftmod_ss7_fill_in_isup_interface(sng_isup_inf_t *sng_isup) } else { g_ftdm_sngss7_data.cfg.isupIntf[i].t32 = 30; } - if (sng_isup->t35 != 0) { - g_ftdm_sngss7_data.cfg.isupIntf[i].t35 = sng_isup->t35; - } else { - g_ftdm_sngss7_data.cfg.isupIntf[i].t35 = 170; - } if (sng_isup->t37 != 0) { g_ftdm_sngss7_data.cfg.isupIntf[i].t37 = sng_isup->t37; } else { @@ -1857,10 +2627,10 @@ static int ftmod_ss7_fill_in_isap(sng_isap_t *sng_isap) if (g_ftdm_sngss7_data.cfg.isap[i].id == 0) { sng_isap->id = i; - SS7_DEBUG("found new isup to cc interface, id is = %d\n", g_ftdm_sngss7_data.cfg.isap[i].id); + SS7_DEBUG("found new isup to cc interface, id is = %d\n", sng_isap->id); } else { sng_isap->id = i; - SS7_DEBUG("found existing isup to cc interface, id is = %d\n", g_ftdm_sngss7_data.cfg.isap[i].id); + SS7_DEBUG("found existing isup to cc interface, id is = %d\n", sng_isap->id); } g_ftdm_sngss7_data.cfg.isap[i].id = sng_isap->id; @@ -2013,226 +2783,213 @@ static int ftmod_ss7_fill_in_self_route(int spc, int linkType, int switchType, i } /******************************************************************************/ -static int ftmod_ss7_fill_in_circuits(sng_isupCkt_t *isupCkt) +static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan) { - sngss7_chan_data_t *ss7_info = NULL; - ftdm_channel_t *ftdmchan = NULL; sng_timeslot_t timeslot; - int count; - int i; + sngss7_chan_data_t *ss7_info = NULL; int x; + int count = 1; - count = 1; + while (ccSpan->ch_map[0] != '\0') { + /**************************************************************************/ - while (isupCkt->ch_map[0] != '\0') { - - /* pull out the next timeslot */ - if (ftmod_ss7_next_timeslot(isupCkt->ch_map, ×lot)) { + /* pull out the next timeslot */ + if (ftmod_ss7_next_timeslot(ccSpan->ch_map, ×lot)) { SS7_ERROR("Failed to parse the channel map!\n"); return FTDM_FAIL; } - if ((timeslot.siglink) || (timeslot.gap)) { - /* try to find the channel in the circuits structure*/ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == count) && - (g_ftdm_sngss7_data.cfg.isupCkt[x].span == isupCkt->span->channels[1]->physical_span_id)) { + /* find the spot in master array for this circuit */ + x = (ccSpan->procId * 1000) + count; - SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is already exists...id=%d\n", - isupCkt->span->channels[1]->physical_span_id, - count, - x); + /* check if this circuit has already been filled in */ + if (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + SS7_DEVEL_DEBUG("Filling in circuit that already exists...%d\n", x); + } - /* we have a match so this circuit already exists in the structure */ - break; - } - /* move to the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + /* prepare the global info sturcture */ + ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); + ss7_info->ftdmchan = NULL; + ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - /* check why we exited the while loop */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) { - SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n", - isupCkt->span->channels[1]->physical_span_id, - count, - x); + g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; - /* prepare the global info sturcture */ - ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); - ss7_info->ftdmchan = NULL; - ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; + /* fill in the rest of the global structure */ + g_ftdm_sngss7_data.cfg.isupCkt[x].procId = ccSpan->procId; + g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; + g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId = ccSpan->id; + g_ftdm_sngss7_data.cfg.isupCkt[x].span = 0; + g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; - /* circuit is new so fill in the needed information */ - g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; - g_ftdm_sngss7_data.cfg.isupCkt[x].span = isupCkt->span->channels[1]->physical_span_id; - g_ftdm_sngss7_data.cfg.isupCkt[x].chan = count; - if (timeslot.siglink) { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; - } + if (timeslot.siglink) { + g_ftdm_sngss7_data.cfg.isupCkt[x].type = SIG; + } else if (timeslot.gap) { + g_ftdm_sngss7_data.cfg.isupCkt[x].type = HOLE; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE; + + /* throw the flag to indicate that we need to start call control */ + sngss7_set_flag(&g_ftdm_sngss7_data.cfg, SNGSS7_CC); + } - if (timeslot.channel) { - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase; - isupCkt->cicbase++; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0; - } - g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf; - g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl; - g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf; - g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; + if (timeslot.channel) { + g_ftdm_sngss7_data.cfg.isupCkt[x].cic = ccSpan->cicbase; + ccSpan->cicbase++; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 0; + } - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ + g_ftdm_sngss7_data.cfg.isupCkt[x].infId = ccSpan->isupInf; + g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = ccSpan->typeCntrl; + g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = ccSpan->ssf; + g_ftdm_sngss7_data.cfg.isupCkt[x].cld_nadi = ccSpan->cld_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].clg_nadi = ccSpan->clg_nadi; + g_ftdm_sngss7_data.cfg.isupCkt[x].options = ccSpan->options; + g_ftdm_sngss7_data.cfg.isupCkt[x].switchType = ccSpan->switchType; + g_ftdm_sngss7_data.cfg.isupCkt[x].min_digits = ccSpan->min_digits; - /* increment the span channel count */ - count++; + if (ccSpan->t3 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = ccSpan->t3; + } + if (ccSpan->t12 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = ccSpan->t12; + } + if (ccSpan->t13 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = ccSpan->t13; + } + if (ccSpan->t14 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = ccSpan->t14; + } + if (ccSpan->t15 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = ccSpan->t15; + } + if (ccSpan->t16 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = ccSpan->t16; + } + if (ccSpan->t17 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t17; + } + if (ccSpan->t35 == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 170; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = ccSpan->t35; + } + if (ccSpan->tval == 0) { + g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10; + } else { + g_ftdm_sngss7_data.cfg.isupCkt[x].tval = ccSpan->tval; + } - } else { /* if ((timeslot.siglink) || (timeslot.gap)) */ - /* find the ftdm the channel structure for this channel*/ - i = 1; - while (isupCkt->span->channels[i] != NULL) { - if (isupCkt->span->channels[i]->physical_chan_id == timeslot.channel) { - break; - } - i++; - } /* while (span->channels[i] != NULL) */ + SS7_INFO("Added procId=%d, spanId = %d, chan = %d, cic = %d, ISUP cirId = %d\n", + g_ftdm_sngss7_data.cfg.isupCkt[x].procId, + g_ftdm_sngss7_data.cfg.isupCkt[x].ccSpanId, + g_ftdm_sngss7_data.cfg.isupCkt[x].chan, + g_ftdm_sngss7_data.cfg.isupCkt[x].cic, + g_ftdm_sngss7_data.cfg.isupCkt[x].id); - if (isupCkt->span->channels[i] == NULL) { - /* we weren't able to find the channel in the ftdm channels */ - SS7_ERROR("Unable to find the requested channel %d in the FreeTDM channels!\n", timeslot.channel); - return FTDM_FAIL; - } else { - ftdmchan = isupCkt->span->channels[i]; + /* increment the span channel count */ + count++; + + /**************************************************************************/ + } /* while (ccSpan->ch_map[0] != '\0') */ + + + return FTDM_SUCCESS; +} + +/******************************************************************************/ +static int ftmod_ss7_fill_in_circuits(sng_span_t *sngSpan) +{ + ftdm_channel_t *ftdmchan = NULL; + ftdm_span_t *ftdmspan = sngSpan->span; + sng_isup_ckt_t *isupCkt = NULL; + sngss7_chan_data_t *ss7_info = NULL; + int flag; + int i; + int x; + + /* go through all the channels on ftdm span */ + for (i = 1; i < (ftdmspan->chan_count+1); i++) { + /**************************************************************************/ + + /* extract the ftdmchan pointer */ + ftdmchan = ftdmspan->channels[i]; + + /* find the equivalent channel in the global structure */ + x = (g_ftdm_sngss7_data.cfg.procId * 1000) + 1; + flag = 0; + while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { + /**********************************************************************/ + /* pull out the circuit to make it easier to work with */ + isupCkt = &g_ftdm_sngss7_data.cfg.isupCkt[x]; + + /* if the ccSpanId's match fill in the span value...this is for sigs + * because they will never have a channel that matches since they + * have a ftdmchan at this time */ + if (sngSpan->ccSpanId == isupCkt->ccSpanId) { + isupCkt->span = ftdmchan->physical_span_id; } - /* try to find a match for the physical span and chan */ - x = 1; - while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) { - if ((g_ftdm_sngss7_data.cfg.isupCkt[x].chan == ftdmchan->physical_chan_id) && - (g_ftdm_sngss7_data.cfg.isupCkt[x].span == ftdmchan->physical_span_id)) { + /* check if the ccSpanId matches and the physical channel # match */ + if ((sngSpan->ccSpanId == isupCkt->ccSpanId) && + (ftdmchan->physical_chan_id == isupCkt->chan)) { - /* we have a match so this circuit already exists in the structure */ - break; - } - /* move to the next circuit */ - x++; - } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ + /* we've found the channel in the ckt structure...raise the flag */ + flag = 1; - /* check why we exited the while loop */ - if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) { - SS7_DEVEL_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - x); + /* now get out of the loop */ + break; + } - /* prepare the global info sturcture */ - ss7_info = ftdm_calloc(1, sizeof(sngss7_chan_data_t)); - ss7_info->ftdmchan = ftdmchan; - ss7_info->circuit = &g_ftdm_sngss7_data.cfg.isupCkt[x]; - ftdmchan->call_data = ss7_info; + /* move to the next ckt */ + x++; - /* prepare the timer structures */ - ss7_info->t35.sched = ((sngss7_span_data_t *)isupCkt->span->signal_data)->sched; - ss7_info->t35.counter = 1; - ss7_info->t35.beat = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].t35*100; /* beat is in ms, t35 is in 100ms */ - ss7_info->t35.callback = handle_isup_t35; - ss7_info->t35.sngss7_info = ss7_info; + /* check if we are outside of the range of possible indexes */ + if (x == ((g_ftdm_sngss7_data.cfg.procId + 1) * 1000)) { + break; + } + /**********************************************************************/ + } /* while (g_ftdm_sngss7_data.cfg.isupCkt[x].id != 0) */ - /* circuit is new so fill in the needed information */ - g_ftdm_sngss7_data.cfg.isupCkt[x].id = x; - g_ftdm_sngss7_data.cfg.isupCkt[x].span = ftdmchan->physical_span_id; - g_ftdm_sngss7_data.cfg.isupCkt[x].chan = ftdmchan->physical_chan_id; - g_ftdm_sngss7_data.cfg.isupCkt[x].type = VOICE; - g_ftdm_sngss7_data.cfg.isupCkt[x].cic = isupCkt->cicbase; - g_ftdm_sngss7_data.cfg.isupCkt[x].infId = isupCkt->isupInf; - g_ftdm_sngss7_data.cfg.isupCkt[x].typeCntrl = isupCkt->typeCntrl; - if (isupCkt->t3 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = isupCkt->t3; - } - if (isupCkt->t12 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t12 = isupCkt->t12; - } - if (isupCkt->t13 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t13 = isupCkt->t13; - } - if (isupCkt->t14 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t14 = isupCkt->t14; - } - if (isupCkt->t15 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t15 = isupCkt->t15; - } - if (isupCkt->t16 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = 300; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t16 = isupCkt->t16; - } - if (isupCkt->t17 == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = 3000; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].t17 = isupCkt->t17; - } - if (isupCkt->tval == 0) { - g_ftdm_sngss7_data.cfg.isupCkt[x].tval = 10; - } else { - g_ftdm_sngss7_data.cfg.isupCkt[x].tval = isupCkt->tval; - } - g_ftdm_sngss7_data.cfg.isupCkt[x].obj = ss7_info; - g_ftdm_sngss7_data.cfg.isupCkt[x].ssf = g_ftdm_sngss7_data.cfg.isupIntf[isupCkt->isupInf].ssf; - - /* increment the cicbase */ - isupCkt->cicbase++; - } else { /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ - SS7_DEBUG("Circuit for span=%d, chan=%d is new...id=%d\n", - ftdmchan->physical_span_id, - ftdmchan->physical_chan_id, - x); - - /* for now make sure ss7_info is set to null */ - ss7_info = NULL; - - /* KONRAD FIX ME -> confirm that it is the same circuit */ - } /* if (g_ftdm_sngss7_data.cfg.isupCkt[x].id == 0) */ - - /* increment the span channel count */ - count++; - } /* if ((timeslot.siglink) || (timeslot.gap)) */ - - if (ss7_info == NULL) { - SS7_ERROR("KONRAD -> circuit was not configured !\n"); + /* check we found the ckt or not */ + if (!flag) { + SS7_ERROR_CHAN(ftdmchan, "Failed to find this channel in the global ckts!%s\n",""); return FTDM_FAIL; } - if (ss7_info->ftdmchan == NULL) { - SS7_INFO("Added span = %d, chan = %d, cic = %d, FTDM chan = %d, ISUP cirId = %d\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].span, - g_ftdm_sngss7_data.cfg.isupCkt[x].chan, - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - 0, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } else { - SS7_INFO("Added span = %d, chan = %d, cic = %d, FTDM chan = %d, ISUP cirId = %d\n", - g_ftdm_sngss7_data.cfg.isupCkt[x].span, - g_ftdm_sngss7_data.cfg.isupCkt[x].chan, - g_ftdm_sngss7_data.cfg.isupCkt[x].cic, - ss7_info->ftdmchan->chan_id, - g_ftdm_sngss7_data.cfg.isupCkt[x].id); - } + /* fill in the rest of the global sngss7_chan_data_t structure */ + ss7_info = (sngss7_chan_data_t *)isupCkt->obj; + ss7_info->ftdmchan = ftdmchan; - } /* while (ch_map[0] != '\0') */ + /* attach the sngss7_chan_data_t to the freetdm channel structure */ + ftdmchan->call_data = ss7_info; - return 0; + /* prepare the timer structures */ + ss7_info->t35.sched = ((sngss7_span_data_t *)(ftdmspan->signal_data))->sched; + ss7_info->t35.counter = 1; + ss7_info->t35.beat = (isupCkt->t35) * 100; /* beat is in ms, t35 is in 100ms */ + ss7_info->t35.callback = handle_isup_t35; + ss7_info->t35.sngss7_info = ss7_info; + + + /**************************************************************************/ + } /* for (i == 1; i < ftdmspan->chan_count; i++) */ + + return FTDM_SUCCESS; } /******************************************************************************/ diff --git a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c index b3d1fe6355..b648daadaf 100644 --- a/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c +++ b/libs/freetdm/src/ftmod/ftmod_wanpipe/ftmod_wanpipe.c @@ -664,6 +664,8 @@ static FIO_COMMAND_FUNCTION(wanpipe_command) } } break; + case FTDM_COMMAND_DISABLE_ECHOTRAIN: { err = 0; } + break; case FTDM_COMMAND_ENABLE_DTMF_DETECT: { #ifdef WP_API_FEATURE_DTMF_EVENTS diff --git a/libs/iksemel/configure.ac b/libs/iksemel/configure.ac index 1b8af13683..49d8621777 100644 --- a/libs/iksemel/configure.ac +++ b/libs/iksemel/configure.ac @@ -83,11 +83,18 @@ AC_ARG_ENABLE(64, if test "x${ax_cv_c_compiler_vendor}" = "xsun" ; then if test "${enable_64}" = "yes"; then - CFLAGS="$CFLAGS -m64" - CXXFLAGS="$CXXFLAGS -m64 -lgpg-error" + CFLAGS="$CFLAGS -xc99=all -mt -m64 -lgpg-error" + CXXFLAGS="$CXXFLAGS -xc99=all -mt -m64 -lgpg-error" + SUNFLAGS="-xc99=all -mt -m64 -lgpg-error" + else + CFLAGS="$CFLAGS -xc99=all -mt -lgpg-error" + CXXFLAGS="$CXXFLAGS -xc99=all -mt -lgpg-error" + SUNFLAGS="-xc99=all -mt -lgpg-error" fi fi +AC_SUBST(SUNCFLAGS) + dnl Generating makefiles AC_CONFIG_FILES([ Makefile diff --git a/libs/iksemel/src/Makefile.am b/libs/iksemel/src/Makefile.am index 20ca2630aa..9d3da69df2 100644 --- a/libs/iksemel/src/Makefile.am +++ b/libs/iksemel/src/Makefile.am @@ -25,5 +25,5 @@ libiksemel_la_SOURCES = \ base64.c libiksemel_la_LDFLAGS = -version-info 4:0:1 -no-undefined -libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) -libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) +libiksemel_la_CFLAGS = $(CFLAGS) $(LIBGNUTLS_CFLAGS) +libiksemel_la_LIBADD = $(LIBGNUTLS_LIBS) diff --git a/libs/iksemel/tools/Makefile.am b/libs/iksemel/tools/Makefile.am index ab81e66888..b7d80e9b05 100644 --- a/libs/iksemel/tools/Makefile.am +++ b/libs/iksemel/tools/Makefile.am @@ -8,11 +8,11 @@ bin_PROGRAMS = ikslint iksroster iksperf noinst_HEADERS = perf.h -ikslint_LDADD = $(top_builddir)/src/libiksemel.la +ikslint_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ ikslint_SOURCES = ikslint.c hash.c -iksroster_LDADD = $(top_builddir)/src/libiksemel.la +iksroster_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ iksroster_SOURCES = iksroster.c -iksperf_LDADD = $(top_builddir)/src/libiksemel.la +iksperf_LDADD = $(top_builddir)/src/libiksemel.la @SUNCFLAGS@ iksperf_SOURCES = iksperf.c perf.c diff --git a/libs/spandsp/spandsp.pc.in b/libs/spandsp/spandsp.pc.in index 86a50ff62a..1a91ba04e1 100644 --- a/libs/spandsp/spandsp.pc.in +++ b/libs/spandsp/spandsp.pc.in @@ -1,5 +1,5 @@ prefix=@prefix@ -exec_prefix=@exec_prefix@ +exec_prefix=@prefix@ libdir=@libdir@ includedir=@includedir@ diff --git a/scripts/perl/dhcp-inform.pl b/scripts/perl/dhcp-inform.pl index 3f977ca58b..2ca4bb8732 100644 --- a/scripts/perl/dhcp-inform.pl +++ b/scripts/perl/dhcp-inform.pl @@ -61,12 +61,7 @@ while ($sock->recv($newmsg, 1024)) { } print "Sending option 66 as $opt_u\n"; - $handle = IO::Socket::INET->new(Proto => 'udp', - PeerPort => '68', - LocalPort => '67', - ReuseAddr => 1, - PeerAddr => $dhcpreq->ciaddr(), - ) or die "socket: $@"; - $handle->send($dhcpresp->serialize()) + + $sock->send($dhcpresp->serialize()) } } diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 2c4de14334..a1a93c6ac8 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -192,7 +192,7 @@ static inline char switch_itodtmf(char i) r = i + 55; } - return r; + return r + 48; } static inline int switch_dtmftoi(char *s) diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 62c919d470..691dede6a0 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -2372,7 +2372,7 @@ SWITCH_STANDARD_API(uuid_media_function) return SWITCH_STATUS_SUCCESS; } -#define BROADCAST_SYNTAX " [aleg|bleg|both]" +#define BROADCAST_SYNTAX " [aleg|bleg|holdb|both]" SWITCH_STANDARD_API(uuid_broadcast_function) { char *mycmd = NULL, *argv[4] = { 0 }; @@ -2389,15 +2389,26 @@ SWITCH_STANDARD_API(uuid_broadcast_function) switch_media_flag_t flags = SMF_NONE; if (argv[2]) { - if (!strcasecmp(argv[2], "both")) { + if (switch_stristr("both", (argv[2]))) { flags |= (SMF_ECHO_ALEG | SMF_ECHO_BLEG); - } else if (!strcasecmp(argv[2], "aleg")) { + } + + if (switch_stristr("aleg", argv[2])) { flags |= SMF_ECHO_ALEG; - } else if (!strcasecmp(argv[2], "bleg")) { + } + + if (switch_stristr("bleg", argv[2])) { + flags &= ~SMF_HOLD_BLEG; flags |= SMF_ECHO_BLEG; } + + if (switch_stristr("holdb", argv[2])) { + flags &= ~SMF_ECHO_BLEG; + flags |= SMF_HOLD_BLEG; + } + } else { - flags |= SMF_ECHO_ALEG; + flags = SMF_ECHO_ALEG | SMF_HOLD_BLEG; } status = switch_ivr_broadcast(argv[0], argv[1], flags); diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c index 2d9341a598..12b3193363 100644 --- a/src/mod/applications/mod_conference/mod_conference.c +++ b/src/mod/applications/mod_conference/mod_conference.c @@ -152,7 +152,8 @@ typedef enum { CFLAG_BRIDGE_TO = (1 << 6), CFLAG_WAIT_MOD = (1 << 7), CFLAG_VID_FLOOR = (1 << 8), - CFLAG_WASTE_BANDWIDTH = (1 << 9) + CFLAG_WASTE_BANDWIDTH = (1 << 9), + CFLAG_OUTCALL = (1 << 10) } conf_flag_t; typedef enum { @@ -288,6 +289,8 @@ typedef struct conference_obj { uint32_t avg_tally; switch_time_t run_time; char *uuid_str; + uint32_t originating; + switch_call_cause_t cancel_cause; } conference_obj_t; /* Relationship with another member */ @@ -395,11 +398,16 @@ SWITCH_STANDARD_API(conf_api_main); static switch_status_t conference_outcall(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, - char *bridgeto, uint32_t timeout, char *flags, char *cid_name, char *cid_num, switch_call_cause_t *cause); + char *bridgeto, uint32_t timeout, + char *flags, + char *cid_name, + char *cid_num, + switch_call_cause_t *cause, + switch_call_cause_t *cancel_cause); static switch_status_t conference_outcall_bg(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, - const char *cid_num, const char *call_uuid); + const char *cid_num, const char *call_uuid, switch_call_cause_t *cancel_cause); SWITCH_STANDARD_APP(conference_function); static void launch_conference_thread(conference_obj_t *conference); static void launch_conference_video_thread(conference_obj_t *conference); @@ -477,6 +485,7 @@ static switch_status_t conference_add_event_member_data(conference_member_t *mem switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Mute-Detect", "%s", switch_test_flag(member, MFLAG_MUTE_DETECT) ? "true" : "false" ); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-ID", "%u", member->id); switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Member-Type", "%s", switch_test_flag(member, MFLAG_MOD) ? "moderator" : "member"); + switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Energy-Level", "%d", member->energy_level); return status; } @@ -1380,6 +1389,14 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v /* Rinse ... Repeat */ end: + if (switch_test_flag(conference, CFLAG_OUTCALL)) { + conference->cancel_cause = SWITCH_CAUSE_ORIGINATOR_CANCEL; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Ending pending outcall channels for Conference: '%s'\n", conference->name); + while(conference->originating) { + switch_yield(200000); + } + } + if (switch_event_create(&event, SWITCH_EVENT_PRESENCE_IN) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "proto", CONF_CHAT_PROTO); switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "login", conference->name); @@ -2403,6 +2420,8 @@ static void conference_loop_output(conference_member_t *member) switch_channel_set_private(channel, "_conference_autocall_list_", NULL); + switch_set_flag(member->conference, CFLAG_OUTCALL); + if (toval) { to = atoi(toval); if (to < 10 || to > 500) { @@ -2421,7 +2440,8 @@ static void conference_loop_output(conference_member_t *member) for (x = 0; x < argc; x++) { char *dial_str = switch_mprintf("%s%s", switch_str_nil(prefix), argv[x]); switch_assert(dial_str); - conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL); + conference_outcall_bg(member->conference, NULL, NULL, dial_str, to, switch_str_nil(flags), cid_name, cid_num, NULL, + &member->conference->cancel_cause); switch_safe_free(dial_str); } switch_safe_free(cpstr); @@ -4243,9 +4263,9 @@ static switch_status_t conf_api_sub_dial(conference_obj_t *conference, switch_st } if (conference) { - conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], &cause); + conference_outcall(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], &cause, NULL); } else { - conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], &cause); + conference_outcall(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], &cause, NULL); } stream->write_function(stream, "Call Requested: result: [%s]\n", switch_channel_cause2str(cause)); @@ -4268,9 +4288,9 @@ static switch_status_t conf_api_sub_bgdial(conference_obj_t *conference, switch_ switch_uuid_format(uuid_str, &uuid); if (conference) { - conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str); + conference_outcall_bg(conference, NULL, NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL); } else { - conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str); + conference_outcall_bg(NULL, argv[0], NULL, argv[2], 60, NULL, argv[4], argv[3], uuid_str, NULL); } stream->write_function(stream, "OK Job-UUID: %s\n", uuid_str); @@ -4784,7 +4804,11 @@ SWITCH_STANDARD_API(conf_api_main) static switch_status_t conference_outcall(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, - char *bridgeto, uint32_t timeout, char *flags, char *cid_name, char *cid_num, switch_call_cause_t *cause) + char *bridgeto, uint32_t timeout, + char *flags, char *cid_name, + char *cid_num, + switch_call_cause_t *cause, + switch_call_cause_t *cancel_cause) { switch_core_session_t *peer_session = NULL; switch_channel_t *peer_channel; @@ -4830,8 +4854,15 @@ static switch_status_t conference_outcall(conference_obj_t *conference, /* establish an outbound call leg */ - if (switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NO_LIMITS, NULL) != - SWITCH_STATUS_SUCCESS) { + switch_mutex_lock(conference->mutex); + conference->originating++; + switch_mutex_unlock(conference->mutex); + status = switch_ivr_originate(session, &peer_session, cause, bridgeto, timeout, NULL, cid_name, cid_num, NULL, NULL, SOF_NO_LIMITS, cancel_cause); + switch_mutex_lock(conference->mutex); + conference->originating--; + switch_mutex_unlock(conference->mutex); + + if (status != SWITCH_STATUS_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot create outgoing channel, cause: %s\n", switch_channel_cause2str(*cause)); if (caller_channel) { @@ -4908,6 +4939,7 @@ struct bg_call { char *cid_num; char *conference_name; char *uuid; + switch_call_cause_t *cancel_cause; switch_memory_pool_t *pool; }; @@ -4920,7 +4952,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread, switch_event_t *event; conference_outcall(call->conference, call->conference_name, - call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause); + call->session, call->bridgeto, call->timeout, call->flags, call->cid_name, call->cid_num, &cause, call->cancel_cause); if (call->conference && test_eflag(call->conference, EFLAG_BGDIAL_RESULT) && switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) { @@ -4948,7 +4980,7 @@ static void *SWITCH_THREAD_FUNC conference_outcall_run(switch_thread_t *thread, static switch_status_t conference_outcall_bg(conference_obj_t *conference, char *conference_name, switch_core_session_t *session, char *bridgeto, uint32_t timeout, const char *flags, const char *cid_name, - const char *cid_num, const char *call_uuid) + const char *cid_num, const char *call_uuid, switch_call_cause_t *cancel_cause) { struct bg_call *call = NULL; switch_thread_t *thread; @@ -4962,6 +4994,7 @@ static switch_status_t conference_outcall_bg(conference_obj_t *conference, call->conference = conference; call->session = session; call->timeout = timeout; + call->cancel_cause = cancel_cause; if (conference) { pool = conference->pool; @@ -5664,8 +5697,9 @@ SWITCH_STANDARD_APP(conference_function) /* more friendliness */ if (conference->bad_pin_sound) { - conference_local_play_file(conference, session, conference->bad_pin_sound, 20, pin_buf, sizeof(pin_buf)); + conference_local_play_file(conference, session, conference->bad_pin_sound, 20, NULL, 0); } + switch_channel_flush_dtmf(channel); } pin_retries--; } @@ -5715,7 +5749,7 @@ SWITCH_STANDARD_APP(conference_function) /* if we're using "bridge:" make an outbound call and bridge it in */ if (!zstr(bridgeto) && strcasecmp(bridgeto, "none")) { switch_call_cause_t cause; - if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, &cause) != SWITCH_STATUS_SUCCESS) { + if (conference_outcall(conference, NULL, session, bridgeto, 60, NULL, NULL, NULL, &cause, NULL) != SWITCH_STATUS_SUCCESS) { goto done; } } else { diff --git a/src/mod/applications/mod_dptools/mod_dptools.c b/src/mod/applications/mod_dptools/mod_dptools.c index 41417255bb..5a3be0328d 100755 --- a/src/mod/applications/mod_dptools/mod_dptools.c +++ b/src/mod/applications/mod_dptools/mod_dptools.c @@ -2982,6 +2982,8 @@ static switch_call_cause_t user_outgoing_channel(switch_core_session_t *session, } } } + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_user", user); + switch_event_add_header_string(var_event, SWITCH_STACK_BOTTOM, "dialed_domain", domain); if (!dest) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "No dial-string available, please check your user directory.\n"); diff --git a/src/mod/applications/mod_easyroute/mod_easyroute.c b/src/mod/applications/mod_easyroute/mod_easyroute.c index 481df958cf..75b4712f2d 100644 --- a/src/mod/applications/mod_easyroute/mod_easyroute.c +++ b/src/mod/applications/mod_easyroute/mod_easyroute.c @@ -65,6 +65,7 @@ static struct { switch_mutex_t *mutex; char *custom_query; switch_odbc_handle_t *master_odbc; + int odbc_num_retries; } globals; SWITCH_MODULE_LOAD_FUNCTION(mod_easyroute_load); @@ -120,6 +121,8 @@ static switch_status_t load_config(void) set_global_default_gateway(val); } else if (!strcasecmp(var, "custom-query")) { set_global_custom_query(val); + } else if (!strcasecmp(var, "odbc-retries")) { + globals.odbc_num_retries = atoi(val); } } } @@ -143,6 +146,9 @@ static switch_status_t load_config(void) } else { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Opened ODBC Database!\n"); } + if (globals.odbc_num_retries) { + switch_odbc_set_num_retries(globals.master_odbc, globals.odbc_num_retries); + } if (switch_odbc_handle_connect(globals.master_odbc) != SWITCH_ODBC_SUCCESS) { switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Cannot Open ODBC Database!\n"); status = SWITCH_STATUS_FALSE; @@ -205,7 +211,7 @@ static switch_status_t route_lookup(char *dn, easyroute_results_t *results, int switch_mutex_lock(globals.mutex); } /* Do the Query */ - if (switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) { + if (globals.master_odbc && switch_odbc_handle_callback_exec(globals.master_odbc, sql, route_callback, &pdata, NULL) == SWITCH_ODBC_SUCCESS) { char tmp_profile[129]; char tmp_gateway[129]; @@ -418,7 +424,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_easyroute_load) SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_easyroute_shutdown) { - switch_odbc_handle_disconnect(globals.master_odbc); + if (globals.master_odbc) { + switch_odbc_handle_disconnect(globals.master_odbc); + switch_odbc_handle_destroy(&globals.master_odbc); + } switch_safe_free(globals.db_username); switch_safe_free(globals.db_password); switch_safe_free(globals.db_dsn); diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c index 21c6a68a0e..4dd936b8c6 100644 --- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c +++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c @@ -40,6 +40,9 @@ #define MAX_FEC_ENTRIES 4 #define MAX_FEC_SPAN 4 +#define SPANDSP_EVENT_TXFAXRESULT "spandsp::txfaxresult" +#define SPANDSP_EVENT_RXFAXRESULT "spandsp::rxfaxresult" + /***************************************************************************** OUR DEFINES AND STRUCTS *****************************************************************************/ @@ -305,7 +308,14 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) switch_core_session_t *session; switch_channel_t *channel; pvt_t *pvt; - char *tmp; + char *fax_document_transferred_pages = NULL; + char *fax_document_total_pages = NULL; + char *fax_image_resolution = NULL; + char *fax_image_size = NULL; + char *fax_bad_rows = NULL; + char *fax_transfer_rate = NULL; + char *fax_result_code = NULL; + switch_event_t *event; pvt = (pvt_t *) user_data; switch_assert(pvt); @@ -353,13 +363,12 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "==============================================================================\n"); /* - Set our channel variables + Set our channel variables, variables are also used in event */ - tmp = switch_mprintf("%i", result); - if (tmp) { - switch_channel_set_variable(channel, "fax_result_code", tmp); - switch_safe_free(tmp); + fax_result_code = switch_core_session_sprintf(session, "%i", result); + if (fax_result_code) { + switch_channel_set_variable(channel, "fax_result_code", fax_result_code); } switch_channel_set_variable(channel, "fax_result_text", t30_completion_code_to_str(result)); @@ -368,49 +377,56 @@ static void phase_e_handler(t30_state_t *s, void *user_data, int result) switch_channel_set_variable(channel, "fax_local_station_id", local_ident); switch_channel_set_variable(channel, "fax_remote_station_id", far_ident); - tmp = switch_mprintf("%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx); - if (tmp) { - switch_channel_set_variable(channel, "fax_document_transferred_pages", tmp); - switch_safe_free(tmp); + fax_document_transferred_pages = switch_core_session_sprintf(session, "%i", pvt->app_mode == FUNCTION_TX ? t.pages_tx : t.pages_rx); + if (fax_document_transferred_pages) { + switch_channel_set_variable(channel, "fax_document_transferred_pages", fax_document_transferred_pages); } - tmp = switch_mprintf("%i", t.pages_in_file); - if (tmp) { - switch_channel_set_variable(channel, "fax_document_total_pages", tmp); - switch_safe_free(tmp); + fax_document_total_pages = switch_core_session_sprintf(session, "%i", t.pages_in_file); + if (fax_document_total_pages) { + switch_channel_set_variable(channel, "fax_document_total_pages", fax_document_total_pages); } - tmp = switch_mprintf("%ix%i", t.x_resolution, t.y_resolution); - if (tmp) { - switch_channel_set_variable(channel, "fax_image_resolution", tmp); - switch_safe_free(tmp); + fax_image_resolution = switch_core_session_sprintf(session, "%ix%i", t.x_resolution, t.y_resolution); + if (fax_image_resolution) { + switch_channel_set_variable(channel, "fax_image_resolution", fax_image_resolution); } - tmp = switch_mprintf("%d", t.image_size); - if (tmp) { - switch_channel_set_variable(channel, "fax_image_size", tmp); - switch_safe_free(tmp); + fax_image_size = switch_core_session_sprintf(session, "%d", t.image_size); + if (fax_image_size) { + switch_channel_set_variable(channel, "fax_image_size", fax_image_size); } - tmp = switch_mprintf("%d", t.bad_rows); - if (tmp) { - switch_channel_set_variable(channel, "fax_bad_rows", tmp); - switch_safe_free(tmp); + fax_bad_rows = switch_core_session_sprintf(session, "%d", t.bad_rows); + if (fax_bad_rows) { + switch_channel_set_variable(channel, "fax_bad_rows", fax_bad_rows); } - tmp = switch_mprintf("%i", t.bit_rate); - if (tmp) { - switch_channel_set_variable(channel, "fax_transfer_rate", tmp); - switch_safe_free(tmp); + fax_transfer_rate = switch_core_session_sprintf(session, "%i", t.bit_rate); + if (fax_transfer_rate) { + switch_channel_set_variable(channel, "fax_transfer_rate", fax_transfer_rate); } /* switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING); */ pvt->done = 1; - /* - TODO Fire events - */ + /* Fire event */ + + if (switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, pvt->app_mode == FUNCTION_TX ? SPANDSP_EVENT_TXFAXRESULT : SPANDSP_EVENT_RXFAXRESULT) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-transferred-pages", fax_document_transferred_pages); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-document-total-pages", fax_document_total_pages); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-resolution", fax_image_resolution); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-image-size", fax_image_size); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-bad-rows", fax_bad_rows); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-transfer-rate", fax_transfer_rate); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-code", fax_result_code); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-result-text", t30_completion_code_to_str(result)); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-ecm-used", (t.error_correcting_mode) ? "on" : "off"); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-local-station-id", local_ident); + switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "fax-remote-station-id", far_ident); + switch_core_session_queue_private_event(session, &event, SWITCH_FALSE); + } } static int t38_tx_packet_handler(t38_core_state_t *s, void *user_data, const uint8_t *buf, int len, int count) @@ -1026,7 +1042,6 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Fax TX filename not set.\n"); goto done; } else if (pvt->app_mode == FUNCTION_RX) { - char *fname; const char *prefix; switch_time_t time; @@ -1036,11 +1051,7 @@ void mod_spandsp_fax_process_fax(switch_core_session_t *session, const char *dat prefix = globals.prepend_string; } - fname = switch_mprintf("%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time); - if (fname) { - pvt->filename = switch_core_session_strdup(session, fname); - switch_safe_free(fname); - } else { + if (!(pvt->filename = switch_core_session_sprintf(session, "%s/%s-%ld-%ld.tif", globals.spool, prefix, globals.total_sessions, time))) { switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Cannot automatically set fax RX destination file\n"); goto done; } diff --git a/src/mod/codecs/mod_celt/mod_celt.c b/src/mod/codecs/mod_celt/mod_celt.c index 37983f3683..8d36b6af12 100644 --- a/src/mod/codecs/mod_celt/mod_celt.c +++ b/src/mod/codecs/mod_celt/mod_celt.c @@ -53,8 +53,8 @@ static switch_status_t switch_celt_init(switch_codec_t *codec, switch_codec_flag return SWITCH_STATUS_FALSE; } - context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, codec->implementation->samples_per_packet, NULL); - + context->frame_size = codec->implementation->samples_per_packet; + context->mode_object = celt_mode_create(codec->implementation->actual_samples_per_second, context->frame_size, NULL); context->bytes_per_packet = (codec->implementation->bits_per_second * context->frame_size / codec->implementation->actual_samples_per_second + 4) / 8; /* @@ -106,15 +106,22 @@ static switch_status_t switch_celt_encode(switch_codec_t *codec, unsigned int *flag) { struct celt_context *context = codec->private_info; + int bytes = 0; if (!context) { return SWITCH_STATUS_FALSE; } - *encoded_data_len = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, - (unsigned char *) encoded_data, context->bytes_per_packet); + bytes = (uint32_t) celt_encode(context->encoder_object, (void *) decoded_data, codec->implementation->samples_per_packet, + (unsigned char *) encoded_data, context->bytes_per_packet); - return SWITCH_STATUS_SUCCESS; + if (bytes > 0) { + *encoded_data_len = (uint32_t) bytes; + return SWITCH_STATUS_SUCCESS; + } + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Encoder Error!\n"); + return SWITCH_STATUS_GENERR; } static switch_status_t switch_celt_decode(switch_codec_t *codec, @@ -152,23 +159,6 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_celt_load) SWITCH_ADD_CODEC(codec_interface, "CELT ultra-low delay"); - switch_core_codec_add_implementation(pool, codec_interface, SWITCH_CODEC_TYPE_AUDIO, /* enumeration defining the type of the codec */ - 114, /* the IANA code number */ - "CELT", /* the IANA code name */ - NULL, /* default fmtp to send (can be overridden by the init function) */ - 32000, /* samples transferred per second */ - 32000, /* actual samples transferred per second */ - 32000, /* bits transferred per second */ - 10000, /* number of microseconds per frame */ - 320, /* number of samples per frame */ - 640, /* number of bytes per frame decompressed */ - 0, /* number of bytes per frame compressed */ - 1, /* number of channels represented */ - 1, /* number of frames per network packet */ - switch_celt_init, /* function to initialize a codec handle using this implementation */ - switch_celt_encode, /* function to encode raw data into encoded data */ - switch_celt_decode, /* function to decode encoded data into raw data */ - switch_celt_destroy); /* deinitalize a codec handle using this implementation */ ms_per_frame = 2000; samples_per_frame = 96; bytes_per_frame = 192; diff --git a/src/mod/endpoints/mod_gsmopen/.gitignore b/src/mod/endpoints/mod_gsmopen/.gitignore index 9fdeeb1412..fe8dc68bd5 100644 --- a/src/mod/endpoints/mod_gsmopen/.gitignore +++ b/src/mod/endpoints/mod_gsmopen/.gitignore @@ -1,2 +1,4 @@ !/gsmlib/gsmlib-*/aclocal.m4 !/gsmlib/gsmlib-*/configure +!/gsmlib/gsmlib-1.10.tar.gz +!/gsmlib/gsmlib_1.10-12ubuntu1.diff.gz diff --git a/src/mod/endpoints/mod_loopback/mod_loopback.c b/src/mod/endpoints/mod_loopback/mod_loopback.c index f875f6b804..aa57668718 100644 --- a/src/mod/endpoints/mod_loopback/mod_loopback.c +++ b/src/mod/endpoints/mod_loopback/mod_loopback.c @@ -77,11 +77,11 @@ struct private_object { switch_frame_t cng_frame; unsigned char cng_databuf[SWITCH_RECOMMENDED_BUFFER_SIZE]; - switch_timer_t timer; switch_caller_profile_t *caller_profile; int32_t bowout_frame_count; char *other_uuid; switch_queue_t *frame_queue; + switch_codec_implementation_t read_impl; }; typedef struct private_object private_t; @@ -111,7 +111,6 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses int interval = 20; switch_status_t status = SWITCH_STATUS_SUCCESS; switch_channel_t *channel = switch_core_session_get_channel(session); - const switch_codec_implementation_t *read_impl; if (codec) { iananame = codec->implementation->iananame; @@ -166,15 +165,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses switch_core_session_set_read_codec(session, &tech_pvt->read_codec); switch_core_session_set_write_codec(session, &tech_pvt->write_codec); - if (tech_pvt->flag_mutex) { - switch_core_timer_destroy(&tech_pvt->timer); - } - - read_impl = tech_pvt->read_codec.implementation; - - switch_core_timer_init(&tech_pvt->timer, "soft", - read_impl->microseconds_per_packet / 1000, read_impl->samples_per_packet * 4, switch_core_session_get_pool(session)); - + tech_pvt->read_impl = *tech_pvt->read_codec.implementation; if (!tech_pvt->flag_mutex) { switch_mutex_init(&tech_pvt->flag_mutex, SWITCH_MUTEX_NESTED, switch_core_session_get_pool(session)); @@ -376,7 +367,6 @@ static switch_status_t channel_on_destroy(switch_core_session_t *session) tech_pvt = switch_core_session_get_private(session); if (tech_pvt) { - switch_core_timer_destroy(&tech_pvt->timer); if (switch_core_codec_ready(&tech_pvt->read_codec)) { switch_core_codec_destroy(&tech_pvt->read_codec); @@ -568,12 +558,10 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch goto end; } - switch_core_timer_next(&tech_pvt->timer); - mutex = tech_pvt->mutex; - switch_mutex_lock(mutex); - if (switch_queue_trypop(tech_pvt->frame_queue, &pop) == SWITCH_STATUS_SUCCESS && pop) { + + if (switch_queue_pop_timeout(tech_pvt->frame_queue, &pop, tech_pvt->read_impl.microseconds_per_packet) == SWITCH_STATUS_SUCCESS && pop) { if (tech_pvt->write_frame) { switch_frame_free(&tech_pvt->write_frame); } @@ -585,6 +573,8 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch switch_set_flag(tech_pvt, TFLAG_CNG); } + switch_mutex_lock(mutex); + if (switch_test_flag(tech_pvt, TFLAG_CNG)) { unsigned char data[SWITCH_RECOMMENDED_BUFFER_SIZE]; uint32_t flag = 0; @@ -775,8 +765,6 @@ static switch_status_t channel_receive_message(switch_core_session_t *session, s switch_frame_free(&frame); } - switch_core_timer_sync(&tech_pvt->timer); - } break; default: diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c index 33b8a8bbd3..f90c5f75a6 100644 --- a/src/mod/endpoints/mod_sofia/mod_sofia.c +++ b/src/mod/endpoints/mod_sofia/mod_sofia.c @@ -4945,7 +4945,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_sofia_load) sofia_endpoint_interface->state_handler = &sofia_event_handlers; management_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_MANAGEMENT_INTERFACE); - management_interface->relative_oid = "1"; + management_interface->relative_oid = "1001"; management_interface->management_function = sofia_manage; SWITCH_ADD_API(api_interface, "sofia", "Sofia Controls", sofia_function, " "); diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c index 643b3dd814..47f94b151a 100644 --- a/src/mod/endpoints/mod_sofia/sofia.c +++ b/src/mod/endpoints/mod_sofia/sofia.c @@ -808,6 +808,18 @@ void sofia_event_callback(nua_event_t event, } } + if ((event == nua_i_invite) && (!session)) { + uint32_t sess_count = switch_core_session_count(); + uint32_t sess_max = switch_core_session_limit(0); + + if (sess_count >= sess_max || !sofia_test_pflag(profile, PFLAG_RUNNING) || !switch_core_ready()) { + nua_respond(nh, 503, "Maximum Calls In Progress", SIPTAG_RETRY_AFTER_STR("300"), TAG_END()); + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "No more sessions allowed at this time.\n"); + + goto done; + } + } if (sofia_test_pflag(profile, PFLAG_AUTH_ALL) && tech_pvt && tech_pvt->key && sip) { sip_authorization_t const *authorization = NULL; diff --git a/src/mod/endpoints/mod_sofia/sofia_presence.c b/src/mod/endpoints/mod_sofia/sofia_presence.c index 94fef61181..19125c600b 100644 --- a/src/mod/endpoints/mod_sofia/sofia_presence.c +++ b/src/mod/endpoints/mod_sofia/sofia_presence.c @@ -630,6 +630,11 @@ static void actual_sofia_presence_event_handler(switch_event_t *event) char *probe_user = NULL, *probe_euser, *probe_host, *p; struct dialog_helper dh = { { 0 } }; + if (strcasecmp(proto, SOFIA_CHAT_PROTO) != 0) { + goto done; + } + + if (!to || !(probe_user = strdup(to))) { goto done; } @@ -2405,6 +2410,20 @@ void sofia_presence_handle_sip_i_subscribe(int status, switch_event_fire(&sevent); } + } else if (to_user && (strcasecmp(proto, SOFIA_CHAT_PROTO) != 0)) { + if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", proto); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "long", profile->name); + switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "from", "%s@%s", from_user, from_host); + switch_event_add_header(sevent, SWITCH_STACK_BOTTOM, "to", "%s%s%s@%s", proto, "+", to_user, to_host); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto-specific-event-name", event); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "event_type", "presence"); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "alt_event_type", "dialog"); + switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "expires", exp_delta_str); + switch_event_fire(&sevent); + + } } else { if (switch_event_create(&sevent, SWITCH_EVENT_PRESENCE_PROBE) == SWITCH_STATUS_SUCCESS) { switch_event_add_header_string(sevent, SWITCH_STACK_BOTTOM, "proto", SOFIA_CHAT_PROTO); diff --git a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c index a99b52074c..db4f7780e0 100644 --- a/src/mod/event_handlers/mod_erlang_event/ei_helpers.c +++ b/src/mod/event_handlers/mod_erlang_event/ei_helpers.c @@ -111,6 +111,7 @@ void ei_encode_switch_event_headers(ei_x_buff * ebuf, switch_event_t *event) for (hp = event->headers; hp; hp = hp->next) { ei_x_encode_tuple_header(ebuf, 2); _ei_x_encode_string(ebuf, hp->name); + switch_url_decode(hp->value); _ei_x_encode_string(ebuf, hp->value); } diff --git a/src/mod/event_handlers/mod_erlang_event/handle_msg.c b/src/mod/event_handlers/mod_erlang_event/handle_msg.c index 9ae15277fd..87f91fc51b 100644 --- a/src/mod/event_handlers/mod_erlang_event/handle_msg.c +++ b/src/mod/event_handlers/mod_erlang_event/handle_msg.c @@ -778,7 +778,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, e binding->process.pid = msg->from; binding->listener = listener; - switch_thread_rwlock_wrlock(globals.listener_rwlock); + switch_thread_rwlock_wrlock(globals.bindings_rwlock); for (ptr = bindings.head; ptr && ptr->next; ptr = ptr->next); @@ -789,7 +789,7 @@ static switch_status_t handle_msg_bind(listener_t *listener, erlang_msg * msg, e } switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | section); - switch_thread_rwlock_unlock(globals.listener_rwlock); + switch_thread_rwlock_unlock(globals.bindings_rwlock); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sections %d\n", switch_xml_get_binding_sections(bindings.search_binding)); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c index 8d3c594b75..900b9655ff 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.c @@ -90,7 +90,7 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) { struct erlang_binding *ptr, *lst = NULL; - switch_thread_rwlock_wrlock(globals.listener_rwlock); + switch_thread_rwlock_wrlock(globals.bindings_rwlock); switch_xml_set_binding_sections(bindings.search_binding, SWITCH_XML_SECTION_MAX); @@ -100,7 +100,7 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) if (ptr->next) { bindings.head = ptr->next; } else { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed all (only?) listeners\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed all (only?) binding\n"); bindings.head = NULL; break; } @@ -111,13 +111,13 @@ static void remove_binding(listener_t *listener, erlang_pid * pid) lst->next = NULL; } } - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed listener\n"); + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Removed binding\n"); } else { switch_xml_set_binding_sections(bindings.search_binding, switch_xml_get_binding_sections(bindings.search_binding) | ptr->section); } } - switch_thread_rwlock_unlock(globals.listener_rwlock); + switch_thread_rwlock_unlock(globals.bindings_rwlock); } @@ -381,6 +381,8 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c section = switch_xml_parse_section_string((char *) sectionstr); + switch_thread_rwlock_rdlock(globals.bindings_rwlock); + for (ptr = bindings.head; ptr; ptr = ptr->next) { if (ptr->section != section) continue; @@ -417,6 +419,8 @@ static switch_xml_t erlang_fetch(const char *sectionstr, const char *tag_name, c switch_mutex_unlock(ptr->listener->sock_mutex); } + switch_thread_rwlock_unlock(globals.bindings_rwlock); + ei_x_free(&buf); if (!p) { @@ -532,6 +536,7 @@ static switch_status_t notify_new_session(listener_t *listener, session_elem_t * session_element->uuid_str); } + switch_event_destroy(&call_event); ei_x_free(&lbuf); return SWITCH_STATUS_SUCCESS; } @@ -1637,6 +1642,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_erlang_event_load) memset(&prefs, 0, sizeof(prefs)); switch_thread_rwlock_create(&globals.listener_rwlock, pool); + switch_thread_rwlock_create(&globals.bindings_rwlock, pool); switch_mutex_init(&globals.fetch_reply_mutex, SWITCH_MUTEX_DEFAULT, pool); switch_mutex_init(&globals.listener_count_mutex, SWITCH_MUTEX_UNNESTED, pool); switch_core_hash_init(&globals.fetch_reply_hash, pool); diff --git a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h index dacfbd661b..121e7b4f95 100644 --- a/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h +++ b/src/mod/event_handlers/mod_erlang_event/mod_erlang_event.h @@ -161,6 +161,7 @@ struct api_command_struct { struct globals_struct { switch_thread_rwlock_t *listener_rwlock; + switch_thread_rwlock_t *bindings_rwlock; switch_event_node_t *node; switch_mutex_t *ref_mutex; switch_mutex_t *fetch_reply_mutex; diff --git a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c index 344b0ee117..f3a2c92eb3 100644 --- a/src/mod/event_handlers/mod_event_socket/mod_event_socket.c +++ b/src/mod/event_handlers/mod_event_socket/mod_event_socket.c @@ -32,7 +32,7 @@ #include #define CMD_BUFLEN 1024 * 1000 #define MAX_QUEUE_LEN 25000 -#define MAX_MISSED 2000 +#define MAX_MISSED 500 SWITCH_MODULE_LOAD_FUNCTION(mod_event_socket_load); SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_event_socket_shutdown); SWITCH_MODULE_RUNTIME_FUNCTION(mod_event_socket_runtime); @@ -143,7 +143,7 @@ static const char *format2str(event_format_t format) } static void remove_listener(listener_t *listener); -static void kill_listener(listener_t *l); +static void kill_listener(listener_t *l, const char *message); static void kill_all_listeners(void); static uint32_t next_id(void) @@ -170,7 +170,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l if (switch_test_flag(l, LFLAG_LOG) && l->level >= node->level) { switch_log_node_t *dnode = switch_log_node_dup(node); - if (switch_queue_push(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypush(l->log_queue, dnode) == SWITCH_STATUS_SUCCESS) { if (l->lost_logs) { int ll = l->lost_logs; switch_event_t *event; @@ -184,7 +184,7 @@ static switch_status_t socket_logger(const switch_log_node_t *node, switch_log_l } else { switch_log_node_free(&dnode); if (++l->lost_logs > MAX_MISSED) { - kill_listener(l); + kill_listener(l, "Disconnected due to log queue failure.\n"); } } } @@ -366,7 +366,7 @@ static void event_handler(switch_event_t *event) if (send) { if (switch_event_dup(&clone, event) == SWITCH_STATUS_SUCCESS) { - if (switch_queue_push(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypush(l->event_queue, clone) == SWITCH_STATUS_SUCCESS) { if (l->lost_events) { int le = l->lost_events; l->lost_events = 0; @@ -379,7 +379,7 @@ static void event_handler(switch_event_t *event) } } else { if (++l->lost_events > MAX_MISSED) { - kill_listener(l); + kill_listener(l, "Disconnected due to event queue failure.\n"); } switch_event_destroy(&clone); } @@ -579,8 +579,41 @@ static void remove_listener(listener_t *listener) switch_mutex_unlock(globals.listener_mutex); } -static void kill_listener(listener_t *l) +static void send_disconnect(listener_t *listener, const char *message) { + + char disco_buf[512] = ""; + switch_size_t len, mlen; + + if (zstr(message)) { + message = "Disconnected.\n"; + } + + mlen = strlen(message); + + if (listener->session) { + switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n" + "Controlled-Session-UUID: %s\n" + "Content-Disposition: disconnect\n" "Content-Length: %d\n\n", switch_core_session_get_uuid(listener->session), mlen); + } else { + switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length: %d\n\n", mlen); + } + + len = strlen(disco_buf); + switch_socket_send(listener->sock, disco_buf, &len); + if (len > 0) { + len = mlen; + switch_socket_send(listener->sock, message, &len); + } +} + +static void kill_listener(listener_t *l, const char *message) +{ + + if (message) { + send_disconnect(l, message); + } + switch_clear_flag(l, LFLAG_RUNNING); if (l->sock) { switch_socket_shutdown(l->sock, SWITCH_SHUTDOWN_READWRITE); @@ -595,7 +628,7 @@ static void kill_all_listeners(void) switch_mutex_lock(globals.listener_mutex); for (l = listen_list.listeners; l; l = l->next) { - kill_listener(l); + kill_listener(l, "The system is being shut down.\n"); } switch_mutex_unlock(globals.listener_mutex); } @@ -1233,7 +1266,7 @@ static switch_status_t read_packet(listener_t *listener, switch_event_t **event, if (switch_channel_get_state(chan) < CS_HANGUP && switch_channel_test_flag(chan, CF_DIVERT_EVENTS)) { switch_event_t *e = NULL; while (switch_core_session_dequeue_event(listener->session, &e, SWITCH_TRUE) == SWITCH_STATUS_SUCCESS) { - if (switch_queue_push(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) { + if (switch_queue_trypush(listener->event_queue, e) != SWITCH_STATUS_SUCCESS) { switch_core_session_queue_event(listener->session, &e); break; } @@ -2540,22 +2573,7 @@ static void *SWITCH_THREAD_FUNC listener_run(switch_thread_t *thread, void *obj) } if (listener->sock) { - char disco_buf[512] = ""; - const char message[] = "Disconnected, goodbye.\nSee you at ClueCon! http://www.cluecon.com/\n"; - int mlen = strlen(message); - - if (listener->session) { - switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\n" - "Controlled-Session-UUID: %s\n" - "Content-Disposition: disconnect\n" "Content-Length: %d\n\n", switch_core_session_get_uuid(listener->session), mlen); - } else { - switch_snprintf(disco_buf, sizeof(disco_buf), "Content-Type: text/disconnect-notice\nContent-Length: %d\n\n", mlen); - } - - len = strlen(disco_buf); - switch_socket_send(listener->sock, disco_buf, &len); - len = mlen; - switch_socket_send(listener->sock, message, &len); + send_disconnect(listener, "Disconnected, goodbye.\nSee you at ClueCon! http://www.cluecon.com/\n"); close_socket(&listener->sock); } diff --git a/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB new file mode 100644 index 0000000000..9584c8bac3 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/FREESWITCH-MIB @@ -0,0 +1,110 @@ +FREESWITCH-MIB DEFINITIONS ::= BEGIN + +IMPORTS + OBJECT-TYPE, MODULE-IDENTITY, + Integer32, Gauge32, Counter32, Counter64, TimeTicks, + enterprises, + FROM SNMPv2-SMI + + DisplayString + FROM SNMPv2-TC +; + + +freeswitch MODULE-IDENTITY + LAST-UPDATED "201101170000Z" + ORGANIZATION "www.freeswitch.org" + CONTACT-INFO + "Primary contact: Anthony Minessale II + Email: anthm@freeswitch.org" + DESCRIPTION + "This file defines the private FreeSWITCH SNMP MIB extensions." + REVISION "201101170000Z" + DESCRIPTION + "First draft by daniel.swarbrick@seventhsignal.de" + ::= { enterprises 27880 } + + +core OBJECT IDENTIFIER ::= { freeswitch 1 } +mod-sofia OBJECT IDENTIFIER ::= { freeswitch 1001 } +mod-skinny OBJECT IDENTIFIER ::= { freeswitch 1002 } + + +identity OBJECT IDENTIFIER ::= { core 1 } + +versionString OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "FreeSWITCH version as a string" + ::= { identity 1 } + +uuid OBJECT-TYPE + SYNTAX DisplayString + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "FreeSWITCH core UUID" + ::= { identity 2 } + + +systemStats OBJECT IDENTIFIER ::= { core 2 } + +uptime OBJECT-TYPE + SYNTAX TimeTicks + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "FreeSWITCH process uptime in hundredths of seconds" + ::= { systemStats 1 } + +sessionsSinceStartup OBJECT-TYPE + SYNTAX Counter32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Number of sessions since FreeSWITCH process was started" + ::= { systemStats 2 } + +currentSessions OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Currently active sessions" + ::= { systemStats 3 } + +maxSessions OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum permissible active sessions" + ::= { systemStats 4 } + +currentCalls OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Currently active calls" + ::= { systemStats 5 } + +sessionsPerSecond OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Current sessions per second" + ::= { systemStats 6 } + +maxSessionsPerSecond OBJECT-TYPE + SYNTAX Gauge32 + MAX-ACCESS read-only + STATUS current + DESCRIPTION + "Maximum permissible sessions per second" + ::= { systemStats 7 } + +END diff --git a/src/mod/event_handlers/mod_snmp/Makefile b/src/mod/event_handlers/mod_snmp/Makefile new file mode 100644 index 0000000000..1d8827daf1 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/Makefile @@ -0,0 +1,7 @@ +include ../../../../build/modmake.rules + +LOCAL_CFLAGS=-I `net-snmp-config --cflags` +LOCAL_LDFLAGS=`net-snmp-config --agent-libs` +LOCAL_OBJS=subagent.o + +local_depend: $(LOCAL_OBJS) diff --git a/src/mod/event_handlers/mod_snmp/mod_snmp.c b/src/mod/event_handlers/mod_snmp/mod_snmp.c new file mode 100644 index 0000000000..56c7be1ef6 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/mod_snmp.c @@ -0,0 +1,158 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Swarbrick + * Stefan Knoblich + * + * mod_snmp.c -- SNMP AgentX Subagent Module + * + */ +#include + +#include +#include +#include + +#include "subagent.h" + +static struct { + switch_memory_pool_t *pool; + switch_mutex_t *mutex; + int shutdown; +} globals; + +SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load); +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown); +SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime); +SWITCH_MODULE_DEFINITION(mod_snmp, mod_snmp_load, mod_snmp_shutdown, mod_snmp_runtime); + + +static switch_status_t snmp_manage(char *relative_oid, switch_management_action_t action, char *data, switch_size_t datalen) +{ + if (action == SMA_GET) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mutex lock request from relative OID %s.\n", relative_oid); + switch_mutex_lock(globals.mutex); + } else if (action == SMA_SET) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Mutex unlock request from relative OID %s.\n", relative_oid); + switch_mutex_unlock(globals.mutex); + } + + return SWITCH_STATUS_SUCCESS; +} + + +static int snmp_callback_log(int major, int minor, void *serverarg, void *clientarg) +{ + struct snmp_log_message *slm = (struct snmp_log_message *) serverarg; + switch_log_printf(SWITCH_CHANNEL_LOG, slm->priority, "%s", slm->msg); + return SNMP_ERR_NOERROR; +} + + +static switch_status_t load_config(switch_memory_pool_t *pool) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + + memset(&globals, 0, sizeof(globals)); + globals.pool = pool; + switch_mutex_init(&globals.mutex, SWITCH_MUTEX_NESTED, globals.pool); + + return status; +} + + +SWITCH_MODULE_LOAD_FUNCTION(mod_snmp_load) +{ + switch_status_t status = SWITCH_STATUS_SUCCESS; + switch_management_interface_t *management_interface; + + load_config(pool); + + *module_interface = switch_loadable_module_create_module_interface(pool, modname); + management_interface = switch_loadable_module_create_interface(*module_interface, SWITCH_MANAGEMENT_INTERFACE); + management_interface->relative_oid = "1000"; + management_interface->management_function = snmp_manage; + + /* Register callback function so we get Net-SNMP logging handled by FreeSWITCH */ + snmp_register_callback(SNMP_CALLBACK_LIBRARY, SNMP_CALLBACK_LOGGING, snmp_callback_log, NULL); + snmp_enable_calllog(); + + netsnmp_ds_set_boolean(NETSNMP_DS_LIBRARY_ID, NETSNMP_DS_LIB_DONT_PERSIST_STATE, 1); + netsnmp_ds_set_boolean(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_ROLE, 1); + + init_agent("mod_snmp"); + + /* + * Override master/subagent ping interval to 2s, to ensure that + * agent_check_and_process() never blocks for longer than that. + */ + netsnmp_ds_set_int(NETSNMP_DS_APPLICATION_ID, NETSNMP_DS_AGENT_AGENTX_PING_INTERVAL, 2); + + init_subagent(); + init_snmp("mod_snmp"); + + return status; +} + + +SWITCH_MODULE_RUNTIME_FUNCTION(mod_snmp_runtime) +{ + if (!globals.shutdown) { + switch_mutex_lock(globals.mutex); + /* Block on select() */ + agent_check_and_process(1); + switch_mutex_unlock(globals.mutex); + } + + switch_yield(5000); + + return SWITCH_STATUS_SUCCESS; +} + + +SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_snmp_shutdown) +{ + globals.shutdown = 1; + + switch_mutex_lock(globals.mutex); + snmp_shutdown("mod_snmp"); + switch_mutex_unlock(globals.mutex); + + switch_mutex_destroy(globals.mutex); + + return SWITCH_STATUS_SUCCESS; +} + + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/event_handlers/mod_snmp/subagent.c b/src/mod/event_handlers/mod_snmp/subagent.c new file mode 100644 index 0000000000..2da9ebeda6 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/subagent.c @@ -0,0 +1,158 @@ +/* + * FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * Copyright (C) 2005-2011, Anthony Minessale II + * + * Version: MPL 1.1 + * + * The contents of this file are subject to the Mozilla Public License Version + * 1.1 (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * http://www.mozilla.org/MPL/ + * + * Software distributed under the License is distributed on an "AS IS" basis, + * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License + * for the specific language governing rights and limitations under the + * License. + * + * The Original Code is FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application + * + * The Initial Developer of the Original Code is + * Anthony Minessale II + * Portions created by the Initial Developer are Copyright (C) + * the Initial Developer. All Rights Reserved. + * + * Contributor(s): + * Daniel Swarbrick + * Stefan Knoblich + * + * mod_snmp.c -- SNMP AgentX Subagent Module + * + */ +#include +#include + +#include +#include +#include +#include "subagent.h" + + +void init_subagent(void) +{ + static oid identity_oid[] = { 1,3,6,1,4,1,27880,1,1 }; + static oid systemStats_oid[] = { 1,3,6,1,4,1,27880,1,2 }; + + DEBUGMSGTL(("init_subagent", "Initializing\n")); + + netsnmp_register_scalar_group(netsnmp_create_handler_registration("identity", handle_identity, identity_oid, OID_LENGTH(identity_oid), HANDLER_CAN_RONLY), 1, 2); + netsnmp_register_scalar_group(netsnmp_create_handler_registration("systemStats", handle_systemStats, systemStats_oid, OID_LENGTH(systemStats_oid), HANDLER_CAN_RONLY), 1, 7); +} + + +int handle_identity(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) +{ + netsnmp_request_info *request = NULL; + oid subid; + static char const version[] = SWITCH_VERSION_FULL; + char uuid[40] = ""; + + switch(reqinfo->mode) { + case MODE_GET: + subid = requests->requestvb->name[reginfo->rootoid_len - 2]; + + switch (subid) { + case ID_VERSION_STR: + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &version, strlen(version)); + break; + case ID_UUID: + strncpy(uuid, switch_core_get_uuid(), sizeof(uuid)); + snmp_set_var_typed_value(requests->requestvb, ASN_OCTET_STR, (u_char *) &uuid, strlen(uuid)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); + } + break; + + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_identity\n", reqinfo->mode ); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + + +int handle_systemStats(netsnmp_mib_handler *handler, netsnmp_handler_registration *reginfo, netsnmp_agent_request_info *reqinfo, netsnmp_request_info *requests) +{ + netsnmp_request_info *request = NULL; + oid subid; + switch_time_t uptime; + uint32_t int_val; + + switch(reqinfo->mode) { + case MODE_GET: + subid = requests->requestvb->name[reginfo->rootoid_len - 2]; + + switch (subid) { + case SS_UPTIME: + uptime = switch_core_uptime() / 10000; + snmp_set_var_typed_value(requests->requestvb, ASN_TIMETICKS, (u_char *) &uptime, sizeof(uptime)); + break; + case SS_SESSIONS_SINCE_STARTUP: + int_val = switch_core_session_id() - 1; + snmp_set_var_typed_value(requests->requestvb, ASN_COUNTER, (u_char *) &int_val, sizeof(int_val)); + break; + case SS_CURRENT_SESSIONS: + int_val = switch_core_session_count(); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case SS_MAX_SESSIONS: + switch_core_session_ctl(SCSC_MAX_SESSIONS, &int_val);; + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case SS_CURRENT_CALLS: + /* + * This is zero for now, since there is no convenient way to get total call + * count (not to be confused with session count), without touching the + * database. + */ + int_val = 0; + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case SS_SESSIONS_PER_SECOND: + switch_core_session_ctl(SCSC_LAST_SPS, &int_val); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + case SS_MAX_SESSIONS_PER_SECOND: + switch_core_session_ctl(SCSC_SPS, &int_val); + snmp_set_var_typed_value(requests->requestvb, ASN_GAUGE, (u_char *) &int_val, sizeof(int_val)); + break; + default: + snmp_log(LOG_WARNING, "Unregistered OID-suffix requested (%d)\n", (int) subid); + netsnmp_set_request_error(reqinfo, request, SNMP_NOSUCHOBJECT); + } + break; + + default: + /* we should never get here, so this is a really bad error */ + snmp_log(LOG_ERR, "Unknown mode (%d) in handle_systemStats\n", reqinfo->mode); + return SNMP_ERR_GENERR; + } + + return SNMP_ERR_NOERROR; +} + + + +/* For Emacs: + * Local Variables: + * mode:c + * indent-tabs-mode:t + * tab-width:4 + * c-basic-offset:4 + * End: + * For VIM: + * vim:set softtabstop=4 shiftwidth=4 tabstop=4: + */ diff --git a/src/mod/event_handlers/mod_snmp/subagent.h b/src/mod/event_handlers/mod_snmp/subagent.h new file mode 100644 index 0000000000..33153780b5 --- /dev/null +++ b/src/mod/event_handlers/mod_snmp/subagent.h @@ -0,0 +1,22 @@ +#ifndef subagent_H +#define subagent_H + +/* .1.3.6.1.4.1.27880.1.1 */ +#define ID_VERSION_STR 1 +#define ID_UUID 2 + +/* .1.3.6.1.4.1.27880.1.2 */ +#define SS_UPTIME 1 +#define SS_SESSIONS_SINCE_STARTUP 2 +#define SS_CURRENT_SESSIONS 3 +#define SS_MAX_SESSIONS 4 +#define SS_CURRENT_CALLS 5 +#define SS_SESSIONS_PER_SECOND 6 +#define SS_MAX_SESSIONS_PER_SECOND 7 + + +void init_subagent(void); +Netsnmp_Node_Handler handle_identity; +Netsnmp_Node_Handler handle_systemStats; + +#endif /* subagent_H */ diff --git a/src/mod/formats/mod_shout/mod_shout.c b/src/mod/formats/mod_shout/mod_shout.c index a4965c4d67..377cfe520c 100644 --- a/src/mod/formats/mod_shout/mod_shout.c +++ b/src/mod/formats/mod_shout/mod_shout.c @@ -584,7 +584,11 @@ static void launch_write_stream_thread(shout_context_t *context) } #define TC_BUFFER_SIZE 1024 * 32 -#define MPGERROR() {err = "MPG123 Error at __FILE__:__LINE__."; mpg123err = mpg123_strerror(context->mh); goto error; } + +#define CONCAT_LOCATION(_x,_y) _x ":" #_y +#define MAKE_LOCATION(_x,_y) CONCAT_LOCATION(_x,_y) +#define HERE MAKE_LOCATION(__FILE__, __LINE__) +#define MPGERROR() {err = "MPG123 Error at " HERE "."; mpg123err = mpg123_strerror(context->mh); goto error; } static switch_status_t shout_file_open(switch_file_handle_t *handle, const char *path) { shout_context_t *context; diff --git a/src/mod/languages/mod_lua/freeswitch.i b/src/mod/languages/mod_lua/freeswitch.i index 9ccaf8ea9f..25faa5a5df 100644 --- a/src/mod/languages/mod_lua/freeswitch.i +++ b/src/mod/languages/mod_lua/freeswitch.i @@ -89,6 +89,7 @@ class Dbh { ~Dbh(); bool release(); bool connected(); + bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); int affected_rows(); }; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.cpp b/src/mod/languages/mod_lua/freeswitch_lua.cpp index 1a170dcc98..b388f2e491 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.cpp +++ b/src/mod/languages/mod_lua/freeswitch_lua.cpp @@ -312,15 +312,21 @@ switch_status_t Session::run_dtmf_callback(void *input, switch_input_type_t ityp Dbh::Dbh(char *dsn, char *user, char *pass) { switch_cache_db_connection_options_t options = { {0} }; + const char *prefix = "core:"; + m_connected = false; - options.odbc_options.dsn = dsn; - options.odbc_options.user = user; - options.odbc_options.pass = pass; - - if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) == SWITCH_STATUS_SUCCESS) { - m_connected = true; + if (strstr(dsn, prefix) == dsn) { + options.core_db_options.db_path = &dsn[strlen(prefix)]; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_CORE_DB, &options) == SWITCH_STATUS_SUCCESS) { + m_connected = true; + } } else { - m_connected = false; + options.odbc_options.dsn = dsn; + options.odbc_options.user = user; + options.odbc_options.pass = pass; + if (switch_cache_db_get_db_handle(&dbh, SCDB_TYPE_ODBC, &options) == SWITCH_STATUS_SUCCESS) { + m_connected = true; + } } } @@ -344,6 +350,16 @@ bool Dbh::connected() return m_connected; } +bool Dbh::test_reactive(char *test_sql, char *drop_sql, char *reactive_sql) +{ + if (m_connected) { + if (switch_cache_db_test_reactive(dbh, test_sql, drop_sql, reactive_sql) == SWITCH_TRUE) { + return true; + } + } + return false; +} + int Dbh::query_callback(void *pArg, int argc, char **argv, char **cargv) { SWIGLUA_FN *lua_fun = (SWIGLUA_FN *)pArg; diff --git a/src/mod/languages/mod_lua/freeswitch_lua.h b/src/mod/languages/mod_lua/freeswitch_lua.h index 5f7966266c..6411d69697 100644 --- a/src/mod/languages/mod_lua/freeswitch_lua.h +++ b/src/mod/languages/mod_lua/freeswitch_lua.h @@ -62,6 +62,7 @@ namespace LUA { ~Dbh(); bool release(); bool connected(); + bool test_reactive(char *test_sql, char *drop_sql = NULL, char *reactive_sql = NULL); bool query(char *sql, SWIGLUA_FN lua_fun); int affected_rows(); }; diff --git a/src/mod/languages/mod_lua/mod_lua_wrap.cpp b/src/mod/languages/mod_lua/mod_lua_wrap.cpp index f10ed63fca..1d84a39fd5 100644 --- a/src/mod/languages/mod_lua/mod_lua_wrap.cpp +++ b/src/mod/languages/mod_lua/mod_lua_wrap.cpp @@ -7254,6 +7254,184 @@ fail: } +static int _wrap_Dbh_test_reactive__SWIG_0(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + char *arg4 = (char *) 0 ; + bool result; + + SWIG_check_num_args("test_reactive",4,4) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("test_reactive",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("test_reactive",2,"char *"); + if(!lua_isstring(L,3)) SWIG_fail_arg("test_reactive",3,"char *"); + if(!lua_isstring(L,4)) SWIG_fail_arg("test_reactive",4,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_test_reactive",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + arg3 = (char *)lua_tostring(L, 3); + arg4 = (char *)lua_tostring(L, 4); + result = (bool)(arg1)->test_reactive(arg2,arg3,arg4); + SWIG_arg=0; + lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static int _wrap_Dbh_test_reactive__SWIG_1(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + char *arg3 = (char *) 0 ; + bool result; + + SWIG_check_num_args("test_reactive",3,3) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("test_reactive",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("test_reactive",2,"char *"); + if(!lua_isstring(L,3)) SWIG_fail_arg("test_reactive",3,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_test_reactive",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + arg3 = (char *)lua_tostring(L, 3); + result = (bool)(arg1)->test_reactive(arg2,arg3); + SWIG_arg=0; + lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static int _wrap_Dbh_test_reactive__SWIG_2(lua_State* L) { + int SWIG_arg = -1; + LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; + char *arg2 = (char *) 0 ; + bool result; + + SWIG_check_num_args("test_reactive",2,2) + if(!SWIG_isptrtype(L,1)) SWIG_fail_arg("test_reactive",1,"LUA::Dbh *"); + if(!lua_isstring(L,2)) SWIG_fail_arg("test_reactive",2,"char *"); + + if (!SWIG_IsOK(SWIG_ConvertPtr(L,1,(void**)&arg1,SWIGTYPE_p_LUA__Dbh,0))){ + SWIG_fail_ptr("Dbh_test_reactive",1,SWIGTYPE_p_LUA__Dbh); + } + + arg2 = (char *)lua_tostring(L, 2); + result = (bool)(arg1)->test_reactive(arg2); + SWIG_arg=0; + lua_pushboolean(L,(int)(result==true)); SWIG_arg++; + return SWIG_arg; + + if(0) SWIG_fail; + +fail: + lua_error(L); + return SWIG_arg; +} + + +static int _wrap_Dbh_test_reactive(lua_State* L) { + int argc; + int argv[5]={ + 1,2,3,4,5 + }; + + argc = lua_gettop(L); + if (argc == 2) { + int _v; + { + void *ptr; + if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_LUA__Dbh, 0)) { + _v = 0; + } else { + _v = 1; + } + } + if (_v) { + { + _v = lua_isstring(L,argv[1]); + } + if (_v) { + return _wrap_Dbh_test_reactive__SWIG_2(L); + } + } + } + if (argc == 3) { + int _v; + { + void *ptr; + if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_LUA__Dbh, 0)) { + _v = 0; + } else { + _v = 1; + } + } + if (_v) { + { + _v = lua_isstring(L,argv[1]); + } + if (_v) { + { + _v = lua_isstring(L,argv[2]); + } + if (_v) { + return _wrap_Dbh_test_reactive__SWIG_1(L); + } + } + } + } + if (argc == 4) { + int _v; + { + void *ptr; + if (SWIG_isptrtype(L,argv[0])==0 || SWIG_ConvertPtr(L,argv[0], (void **) &ptr, SWIGTYPE_p_LUA__Dbh, 0)) { + _v = 0; + } else { + _v = 1; + } + } + if (_v) { + { + _v = lua_isstring(L,argv[1]); + } + if (_v) { + { + _v = lua_isstring(L,argv[2]); + } + if (_v) { + { + _v = lua_isstring(L,argv[3]); + } + if (_v) { + return _wrap_Dbh_test_reactive__SWIG_0(L); + } + } + } + } + } + + lua_pushstring(L,"No matching function for overloaded 'Dbh_test_reactive'"); + lua_error(L);return 0; +} + + static int _wrap_Dbh_query(lua_State* L) { int SWIG_arg = -1; LUA::Dbh *arg1 = (LUA::Dbh *) 0 ; @@ -7328,6 +7506,7 @@ delete arg1; static swig_lua_method swig_LUA_Dbh_methods[] = { {"release", _wrap_Dbh_release}, {"connected", _wrap_Dbh_connected}, + {"test_reactive", _wrap_Dbh_test_reactive}, {"query", _wrap_Dbh_query}, {"affected_rows", _wrap_Dbh_affected_rows}, {0,0} diff --git a/src/mod/languages/mod_managed/freeswitch_wrap.cxx b/src/mod/languages/mod_managed/freeswitch_wrap.cxx index aa2a84f3f6..3ee6ff62fd 100644 --- a/src/mod/languages/mod_managed/freeswitch_wrap.cxx +++ b/src/mod/languages/mod_managed/freeswitch_wrap.cxx @@ -7413,6 +7413,20 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_core_session_get_dmachine(void * jar } +SWIGEXPORT int SWIGSTDCALL CSharp_switch_core_session_set_codec_slin(void * jarg1, void * jarg2) { + int jresult ; + switch_core_session_t *arg1 = (switch_core_session_t *) 0 ; + switch_slin_data_t *arg2 = (switch_slin_data_t *) 0 ; + switch_status_t result; + + arg1 = (switch_core_session_t *)jarg1; + arg2 = (switch_slin_data_t *)jarg2; + result = (switch_status_t)switch_core_session_set_codec_slin(arg1,arg2); + jresult = result; + return jresult; +} + + SWIGEXPORT char * SWIGSTDCALL CSharp_switch_core_get_uuid() { char * jresult ; char *result = 0 ; @@ -22794,6 +22808,119 @@ SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_api_interface(void * jarg1) { } +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_session_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_core_session_t *arg2 = (switch_core_session_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_core_session_t *)jarg2; + if (arg1) (arg1)->session = arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_session_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_core_session_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_core_session_t *) ((arg1)->session); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_write_frame_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_frame_t *arg2 = (switch_frame_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_frame_t *)jarg2; + if (arg1) (arg1)->write_frame = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_write_frame_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_frame_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_frame_t *)& ((arg1)->write_frame); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_codec_set(void * jarg1, void * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_codec_t *arg2 = (switch_codec_t *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (switch_codec_t *)jarg2; + if (arg1) (arg1)->codec = *arg2; + +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_switch_slin_data_codec_get(void * jarg1) { + void * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + switch_codec_t *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (switch_codec_t *)& ((arg1)->codec); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_switch_slin_data_frame_data_set(void * jarg1, char * jarg2) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + char *arg2 ; + + arg1 = (switch_slin_data *)jarg1; + arg2 = (char *)jarg2; + { + if (arg2) strncpy((char *)arg1->frame_data, (const char *)arg2, 4096); + else arg1->frame_data[0] = 0; + } +} + + +SWIGEXPORT char * SWIGSTDCALL CSharp_switch_slin_data_frame_data_get(void * jarg1) { + char * jresult ; + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + char *result = 0 ; + + arg1 = (switch_slin_data *)jarg1; + result = (char *)(char *) ((arg1)->frame_data); + jresult = SWIG_csharp_string_callback((const char *)result); + return jresult; +} + + +SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_slin_data() { + void * jresult ; + switch_slin_data *result = 0 ; + + result = (switch_slin_data *)new switch_slin_data(); + jresult = (void *)result; + return jresult; +} + + +SWIGEXPORT void SWIGSTDCALL CSharp_delete_switch_slin_data(void * jarg1) { + switch_slin_data *arg1 = (switch_slin_data *) 0 ; + + arg1 = (switch_slin_data *)jarg1; + delete arg1; + +} + + SWIGEXPORT void SWIGSTDCALL CSharp_switch_channel_timetable_profile_created_set(void * jarg1, void * jarg2) { switch_channel_timetable *arg1 = (switch_channel_timetable *) 0 ; switch_time_t arg2 ; diff --git a/src/mod/languages/mod_managed/managed/swig.cs b/src/mod/languages/mod_managed/managed/swig.cs index 5a2188ac83..48d585e334 100644 --- a/src/mod/languages/mod_managed/managed/swig.cs +++ b/src/mod/languages/mod_managed/managed/swig.cs @@ -1357,6 +1357,11 @@ public class freeswitch { return ret; } + public static switch_status_t switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session session, switch_slin_data data) { + switch_status_t ret = (switch_status_t)freeswitchPINVOKE.switch_core_session_set_codec_slin(SWIGTYPE_p_switch_core_session.getCPtr(session), switch_slin_data.getCPtr(data)); + return ret; + } + public static string switch_core_get_uuid() { string ret = freeswitchPINVOKE.switch_core_get_uuid(); return ret; @@ -7504,6 +7509,9 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_get_dmachine")] public static extern IntPtr switch_core_session_get_dmachine(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_session_set_codec_slin")] + public static extern int switch_core_session_set_codec_slin(HandleRef jarg1, HandleRef jarg2); + [DllImport("mod_managed", EntryPoint="CSharp_switch_core_get_uuid")] public static extern string switch_core_get_uuid(); @@ -11188,6 +11196,36 @@ class freeswitchPINVOKE { [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_api_interface")] public static extern void delete_switch_api_interface(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_set")] + public static extern void switch_slin_data_session_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_session_get")] + public static extern IntPtr switch_slin_data_session_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_set")] + public static extern void switch_slin_data_write_frame_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_write_frame_get")] + public static extern IntPtr switch_slin_data_write_frame_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_set")] + public static extern void switch_slin_data_codec_set(HandleRef jarg1, HandleRef jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_codec_get")] + public static extern IntPtr switch_slin_data_codec_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_set")] + public static extern void switch_slin_data_frame_data_set(HandleRef jarg1, string jarg2); + + [DllImport("mod_managed", EntryPoint="CSharp_switch_slin_data_frame_data_get")] + public static extern string switch_slin_data_frame_data_get(HandleRef jarg1); + + [DllImport("mod_managed", EntryPoint="CSharp_new_switch_slin_data")] + public static extern IntPtr new_switch_slin_data(); + + [DllImport("mod_managed", EntryPoint="CSharp_delete_switch_slin_data")] + public static extern void delete_switch_slin_data(HandleRef jarg1); + [DllImport("mod_managed", EntryPoint="CSharp_switch_channel_timetable_profile_created_set")] public static extern void switch_channel_timetable_profile_created_set(HandleRef jarg1, HandleRef jarg2); @@ -28401,7 +28439,8 @@ public enum switch_rtp_bug_flag_t { RTP_BUG_IGNORE_MARK_BIT = (1 << 2), RTP_BUG_SEND_LINEAR_TIMESTAMPS = (1 << 3), RTP_BUG_START_SEQ_AT_ZERO = (1 << 4), - RTP_BUG_NEVER_SEND_MARKER = (1 << 5) + RTP_BUG_NEVER_SEND_MARKER = (1 << 5), + RTP_BUG_IGNORE_DTMF_DURATION = (1 << 6) } } @@ -29437,6 +29476,96 @@ public enum switch_signal_t { namespace FreeSWITCH.Native { +using System; +using System.Runtime.InteropServices; + +public class switch_slin_data : IDisposable { + private HandleRef swigCPtr; + protected bool swigCMemOwn; + + internal switch_slin_data(IntPtr cPtr, bool cMemoryOwn) { + swigCMemOwn = cMemoryOwn; + swigCPtr = new HandleRef(this, cPtr); + } + + internal static HandleRef getCPtr(switch_slin_data obj) { + return (obj == null) ? new HandleRef(null, IntPtr.Zero) : obj.swigCPtr; + } + + ~switch_slin_data() { + Dispose(); + } + + public virtual void Dispose() { + lock(this) { + if(swigCPtr.Handle != IntPtr.Zero && swigCMemOwn) { + swigCMemOwn = false; + freeswitchPINVOKE.delete_switch_slin_data(swigCPtr); + } + swigCPtr = new HandleRef(null, IntPtr.Zero); + GC.SuppressFinalize(this); + } + } + + public SWIGTYPE_p_switch_core_session session { + set { + freeswitchPINVOKE.switch_slin_data_session_set(swigCPtr, SWIGTYPE_p_switch_core_session.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_session_get(swigCPtr); + SWIGTYPE_p_switch_core_session ret = (cPtr == IntPtr.Zero) ? null : new SWIGTYPE_p_switch_core_session(cPtr, false); + return ret; + } + } + + public switch_frame write_frame { + set { + freeswitchPINVOKE.switch_slin_data_write_frame_set(swigCPtr, switch_frame.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_write_frame_get(swigCPtr); + switch_frame ret = (cPtr == IntPtr.Zero) ? null : new switch_frame(cPtr, false); + return ret; + } + } + + public switch_codec codec { + set { + freeswitchPINVOKE.switch_slin_data_codec_set(swigCPtr, switch_codec.getCPtr(value)); + } + get { + IntPtr cPtr = freeswitchPINVOKE.switch_slin_data_codec_get(swigCPtr); + switch_codec ret = (cPtr == IntPtr.Zero) ? null : new switch_codec(cPtr, false); + return ret; + } + } + + public string frame_data { + set { + freeswitchPINVOKE.switch_slin_data_frame_data_set(swigCPtr, value); + } + get { + string ret = freeswitchPINVOKE.switch_slin_data_frame_data_get(swigCPtr); + return ret; + } + } + + public switch_slin_data() : this(freeswitchPINVOKE.new_switch_slin_data(), true) { + } + +} + +} +/* ---------------------------------------------------------------------------- + * This file was automatically generated by SWIG (http://www.swig.org). + * Version 1.3.35 + * + * Do not make changes to this file unless you know what you are doing--modify + * the SWIG interface file instead. + * ----------------------------------------------------------------------------- */ + +namespace FreeSWITCH.Native { + [System.Flags] public enum switch_speech_flag_enum_t { SWITCH_SPEECH_FLAG_NONE = 0, SWITCH_SPEECH_FLAG_HASTEXT = (1 << 0), @@ -30146,7 +30275,7 @@ public enum switch_status_t { SWITCH_STATUS_FALSE, SWITCH_STATUS_TIMEOUT, SWITCH_STATUS_RESTART, - SWITCH_STATUS_TERM, + SWITCH_STATUS_INTR, SWITCH_STATUS_NOTIMPL, SWITCH_STATUS_MEMERR, SWITCH_STATUS_NOOP, @@ -30163,6 +30292,7 @@ public enum switch_status_t { SWITCH_STATUS_TOO_SMALL, SWITCH_STATUS_FOUND, SWITCH_STATUS_CONTINUE, + SWITCH_STATUS_TERM, SWITCH_STATUS_NOT_INITALIZED } diff --git a/src/switch_apr.c b/src/switch_apr.c index efbed0a490..a540a16a30 100644 --- a/src/switch_apr.c +++ b/src/switch_apr.c @@ -846,7 +846,7 @@ SWITCH_DECLARE(switch_status_t) switch_socket_recvfrom(switch_sockaddr_t *from, */ } - if (r == 35) { + if (r == 35 || r == 730035) { r = SWITCH_STATUS_BREAK; } diff --git a/src/switch_channel.c b/src/switch_channel.c index 918ad82a99..de472a91d5 100644 --- a/src/switch_channel.c +++ b/src/switch_channel.c @@ -2564,8 +2564,8 @@ SWITCH_DECLARE(switch_status_t) switch_channel_perform_mark_ring_ready_value(swi char *app; switch_event_t *event; - if (!switch_channel_test_flag(channel, CF_RING_READY) && !switch_channel_test_flag(channel, CF_EARLY_MEDIA && - !switch_channel_test_flag(channel, CF_ANSWERED))) { + if (!switch_channel_test_flag(channel, CF_RING_READY) && + !switch_channel_test_flag(channel, CF_EARLY_MEDIA) && !switch_channel_test_flag(channel, CF_ANSWERED)) { switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_NOTICE, "Ring-Ready %s!\n", channel->name); switch_channel_set_flag_value(channel, CF_RING_READY, rv); if (channel->caller_profile && channel->caller_profile->times) { diff --git a/src/switch_core.c b/src/switch_core.c index 360d810ead..d25f9b0bb3 100644 --- a/src/switch_core.c +++ b/src/switch_core.c @@ -151,13 +151,21 @@ static void check_ip(void) SWITCH_STANDARD_SCHED_FUNC(heartbeat_callback) { send_heartbeat(); - check_ip(); /* reschedule this task */ task->runtime = switch_epoch_time_now(NULL) + 20; } +SWITCH_STANDARD_SCHED_FUNC(check_ip_callback) +{ + check_ip(); + + /* reschedule this task */ + task->runtime = switch_epoch_time_now(NULL) + 60; +} + + SWITCH_DECLARE(switch_status_t) switch_core_set_console(const char *console) { if ((runtime.console = fopen(console, "a")) == 0) { @@ -1363,6 +1371,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switc switch_scheduler_add_task(switch_epoch_time_now(NULL), heartbeat_callback, "heartbeat", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL); + switch_scheduler_add_task(switch_epoch_time_now(NULL), check_ip_callback, "check_ip", "core", 0, NULL, SSHF_NONE | SSHF_NO_DEL | SSHF_OWN_THREAD); + switch_uuid_get(&uuid); switch_uuid_format(runtime.uuid_str, &uuid); diff --git a/src/switch_core_file.c b/src/switch_core_file.c index c00756ffc6..19f23546f0 100644 --- a/src/switch_core_file.c +++ b/src/switch_core_file.c @@ -391,10 +391,10 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_write(switch_file_handle_t *fh, if ((status = fh->file_interface->file_write(fh, fh->pre_buffer_data, &blen)) != SWITCH_STATUS_SUCCESS) { *len = 0; } - fh->samples_out += blen; } } + fh->samples_out += orig_len; return status; } else { switch_status_t status; diff --git a/src/switch_ivr.c b/src/switch_ivr.c index 496c29b524..a40da1b077 100644 --- a/src/switch_ivr.c +++ b/src/switch_ivr.c @@ -224,7 +224,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_sleep(switch_core_session_t *session, switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { switch_dtmf_t dtmf; /* diff --git a/src/switch_ivr_async.c b/src/switch_ivr_async.c index 4354f0dc0d..0a646b6d6e 100644 --- a/src/switch_ivr_async.c +++ b/src/switch_ivr_async.c @@ -3129,6 +3129,7 @@ static void *SWITCH_THREAD_FUNC speech_thread(switch_thread_t *thread, void *obj switch_event_t *dup; if (switch_event_dup(&dup, event) == SWITCH_STATUS_SUCCESS) { + switch_channel_event_set_data(channel, dup); switch_event_fire(&dup); } diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c index d156c700fd..78743e6420 100644 --- a/src/switch_ivr_originate.c +++ b/src/switch_ivr_originate.c @@ -2755,6 +2755,26 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess } } } + + if (session) { + switch_channel_set_variable(originate_status[i].peer_channel, "originating_leg_uuid", switch_core_session_get_uuid(session)); + } + + if ((vvar = switch_channel_get_variable_dup(originate_status[i].peer_channel, "execute_on_originate", SWITCH_FALSE))) { + char *app = switch_core_session_strdup(originate_status[i].peer_session, vvar); + char *arg = NULL; + + if (strstr(app, "::")) { + switch_core_session_execute_application_async(originate_status[i].peer_session, app, arg); + } else { + if ((arg = strchr(app, ' '))) { + *arg++ = '\0'; + } + + switch_core_session_execute_application(originate_status[i].peer_session, app, arg); + } + + } } if (table) { @@ -2773,7 +2793,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess *cause = SWITCH_CAUSE_SUCCESS; goto outer_for; } - + if (!switch_core_session_running(originate_status[i].peer_session)) { if (originate_status[i].per_channel_delay_start) { switch_channel_set_flag(originate_status[i].peer_channel, CF_BLOCK_STATE); diff --git a/src/switch_ivr_play_say.c b/src/switch_ivr_play_say.c index 523dfdeb02..dc263e9be5 100644 --- a/src/switch_ivr_play_say.c +++ b/src/switch_ivr_play_say.c @@ -372,6 +372,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se switch_event_t *event; int divisor = 0; int file_flags = SWITCH_FILE_FLAG_WRITE | SWITCH_FILE_DATA_SHORT; + int restart_limit_on_dtmf = 0; const char *prefix; prefix = switch_channel_get_variable(channel, "sound_prefix"); @@ -528,6 +529,8 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se if (switch_test_flag(fh, SWITCH_FILE_NATIVE)) { asis = 1; } + + restart_limit_on_dtmf = switch_true(switch_channel_get_variable(channel, "record_restart_limit_on_dtmf")); if ((p = switch_channel_get_variable(channel, "RECORD_TITLE"))) { vval = switch_core_session_strdup(session, p); @@ -631,12 +634,17 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_record_file(switch_core_session_t *se break; } - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ if (switch_channel_has_dtmf(channel)) { + + if (limit && restart_limit_on_dtmf) { + start = switch_epoch_time_now(NULL); + } + if (!args->input_callback && !args->buf && !args->dmachine) { status = SWITCH_STATUS_BREAK; break; @@ -854,7 +862,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_gentones(switch_core_session_t *sessi switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during gentones if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. @@ -1306,7 +1314,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_play_file(switch_core_session_t *sess switch_ivr_parse_all_events(session); - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. @@ -1867,7 +1875,7 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t switch_status_t status; memset(digit_buffer, 0, digit_buffer_length); - switch_channel_flush_dtmf(channel); + status = switch_ivr_read(session, min_digits, max_digits, prompt_audio_file, var_name, digit_buffer, digit_buffer_length, timeout, valid_terminators, digit_timeout); if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) { @@ -2029,7 +2037,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_speak_text_handle(switch_core_session switch_event_destroy(&event); } - if (args && (args->input_callback || args->buf || args->buflen || args->dmachine)) { + if (args) { /* dtmf handler function you can hook up to be executed when a digit is dialed during playback * if you return anything but SWITCH_STATUS_SUCCESS the playback will stop. */ diff --git a/src/switch_loadable_module.c b/src/switch_loadable_module.c index 03858aca29..d6796c8119 100644 --- a/src/switch_loadable_module.c +++ b/src/switch_loadable_module.c @@ -1047,20 +1047,24 @@ SWITCH_DECLARE(switch_status_t) switch_loadable_module_unload_module(char *dir, switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Module is not unloadable.\n"); *err = "Module is not unloadable"; status = SWITCH_STATUS_NOUNLOAD; - goto end; + goto unlock; } else { - if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err) != SWITCH_STATUS_SUCCESS)) { - goto end; + /* Prevent anything from using the module while it's shutting down */ + switch_core_hash_delete(loadable_modules.module_hash, fname); + switch_mutex_unlock(loadable_modules.mutex); + if ((status = do_shutdown(module, SWITCH_TRUE, SWITCH_TRUE, !force, err)) != SWITCH_STATUS_SUCCESS) { + /* Something went wrong in the module's shutdown function, add it again */ + switch_core_hash_insert_locked(loadable_modules.module_hash, fname, module, loadable_modules.mutex); } + goto end; } - switch_core_hash_delete(loadable_modules.module_hash, fname); } else { *err = "No such module!"; status = SWITCH_STATUS_FALSE; } - end: +unlock: switch_mutex_unlock(loadable_modules.mutex); - + end: if (force) { switch_yield(1000000); switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "PHEW!\n"); diff --git a/src/switch_rtp.c b/src/switch_rtp.c index 4e5450d7e8..4acadfe2ff 100644 --- a/src/switch_rtp.c +++ b/src/switch_rtp.c @@ -32,6 +32,7 @@ */ //#define DEBUG_2833 //#define RTP_DEBUG_WRITE_DELTA +//#define DEBUG_MISSED_SEQ #include #include #undef PACKAGE_NAME @@ -245,6 +246,9 @@ struct switch_rtp { switch_time_t send_time; switch_byte_t auto_adj_used; uint8_t pause_jb; + uint16_t last_seq; + switch_time_t last_read_time; + switch_size_t last_flush_packet_count; }; struct switch_rtcp_senderinfo { @@ -256,6 +260,180 @@ struct switch_rtcp_senderinfo { unsigned oc:32; }; +typedef enum { + RESULT_CONTINUE, + RESULT_GOTO_END, + RESULT_GOTO_RECVFROM, + RESULT_GOTO_TIMERCHECK +} handle_rfc2833_result_t; + +static handle_rfc2833_result_t handle_rfc2833(switch_rtp_t *rtp_session, switch_size_t bytes, int *do_cng) +{ +#ifdef DEBUG_2833 + if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); + } +#endif + + if (rtp_session->dtmf_data.in_digit_sanity && !--rtp_session->dtmf_data.in_digit_sanity) { + rtp_session->dtmf_data.last_digit = 0; + rtp_session->dtmf_data.in_digit_ts = 0; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF sanity check.\n"); + } + + /* RFC2833 ... like all RFC RE: VoIP, guaranteed to drive you to insanity! + We know the real rules here, but if we enforce them, it's an interop nightmare so, + we put up with as much as we can so we don't have to deal with being punished for + doing it right. Nice guys finish last! + */ + if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && + !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + switch_size_t len = bytes - rtp_header_len; + unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body; + int end; + uint16_t duration; + char key; + uint16_t in_digit_seq; + uint32_t ts; + + if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) { + packet += 4; + len -= 4; + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF payload offset by 4 bytes.\n"); + } + + if (!(packet[0] || packet[1] || packet[2] || packet[3])) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF payload check.\n"); + rtp_session->dtmf_data.last_digit = 0; + rtp_session->dtmf_data.in_digit_ts = 0; + } + + end = packet[1] & 0x80 ? 1 : 0; + duration = (packet[2] << 8) + packet[3]; + key = switch_rfc2833_to_char(packet[0]); + in_digit_seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); + ts = htonl(rtp_session->recv_msg.header.ts); + + if (in_digit_seq < rtp_session->dtmf_data.in_digit_seq) { + if (rtp_session->dtmf_data.in_digit_seq - in_digit_seq > 100) { + rtp_session->dtmf_data.in_digit_seq = 0; + } + } +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) + packet[1], (unsigned) packet[2], (unsigned) packet[3]); +#endif + + if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) { + + rtp_session->dtmf_data.in_digit_seq = in_digit_seq; +#ifdef DEBUG_2833 + + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", + key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, + ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); +#endif + + if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && + rtp_session->dtmf_data.in_digit_ts) { + switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) }; +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); +#endif + switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + rtp_session->dtmf_data.in_digit_queued = 1; + } + + /* only set sanity if we do NOT ignore the packet */ + if (rtp_session->dtmf_data.in_digit_ts) { + rtp_session->dtmf_data.in_digit_sanity = 2000; + } + + if (rtp_session->dtmf_data.last_duration > duration && + rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) { + rtp_session->dtmf_data.flip++; + } + + if (end) { + if (rtp_session->dtmf_data.in_digit_ts) { + switch_dtmf_t dtmf = { key, duration }; + + if (ts > rtp_session->dtmf_data.in_digit_ts) { + dtmf.duration += (ts - rtp_session->dtmf_data.in_digit_ts); + } + if (rtp_session->dtmf_data.flip) { + dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF; + rtp_session->dtmf_data.flip = 0; +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n"); +#endif + } +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", + dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration); +#endif + + if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) { +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); +#endif + switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); + } + + rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit; + + rtp_session->dtmf_data.in_digit_ts = 0; + rtp_session->dtmf_data.in_digit_sanity = 0; + rtp_session->dtmf_data.in_digit_queued = 0; + *do_cng = 1; + } else { + if (!switch_rtp_ready(rtp_session)) { + return RESULT_GOTO_END; + } + switch_cond_next(); + return RESULT_GOTO_RECVFROM; + } + + } else if (!rtp_session->dtmf_data.in_digit_ts) { + rtp_session->dtmf_data.in_digit_ts = ts; + rtp_session->dtmf_data.first_digit = key; + rtp_session->dtmf_data.in_digit_sanity = 2000; + } + + rtp_session->dtmf_data.last_duration = duration; + } else { +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", + key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end); +#endif + switch_cond_next(); + return RESULT_GOTO_RECVFROM; + } + } + + if (bytes && rtp_session->dtmf_data.in_digit_ts) { + if (!switch_rtp_ready(rtp_session)) { + return RESULT_GOTO_END; + } + + if (!rtp_session->dtmf_data.in_interleaved && rtp_session->recv_msg.header.pt != rtp_session->recv_te) { + /* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */ + rtp_session->dtmf_data.in_interleaved = 1; + } + + if (rtp_session->dtmf_data.in_interleaved || (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) { + if (rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + return RESULT_GOTO_RECVFROM; + } + } else { + *do_cng = 1; + return RESULT_GOTO_TIMERCHECK; + } + } + + return RESULT_CONTINUE; +} + static int global_init = 0; static int rtp_common_write(switch_rtp_t *rtp_session, rtp_msg_t *send_msg, void *data, uint32_t datalen, switch_payload_t payload, uint32_t timestamp, switch_frame_flag_t *flags); @@ -2157,6 +2335,15 @@ static void do_flush(switch_rtp_t *rtp_session) bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, &bytes); if (bytes) { + int do_cng = 0; + + /* Make sure to handle RFC2833 packets, even if we're flushing the packets */ + if (bytes > rtp_header_len && rtp_session->recv_te && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { + handle_rfc2833(rtp_session, bytes, &do_cng); +#ifdef DEBUG_2833 + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "*** RTP packet handled in flush loop ***\n"); +#endif + } flushed++; @@ -2195,7 +2382,52 @@ static switch_status_t read_rtp_packet(switch_rtp_t *rtp_session, switch_size_t *bytes = sizeof(rtp_msg_t); status = switch_socket_recvfrom(rtp_session->from_addr, rtp_session->sock_input, 0, (void *) &rtp_session->recv_msg, bytes); ts = ntohl(rtp_session->recv_msg.header.ts); - + + if (*bytes ) { + uint16_t seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); + + if (rtp_session->last_seq && rtp_session->last_seq+1 != seq) { +#ifdef DEBUG_MISSED_SEQ + switch_size_t flushed_packets_diff = rtp_session->stats.inbound.flush_packet_count - rtp_session->last_flush_packet_count; + switch_size_t num_missed = (switch_size_t)seq - (rtp_session->last_seq+1); + + if (num_missed == 1) { /* We missed one packet */ + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Missed one RTP frame with sequence [%d]%s. Time since last read [%d]\n", + rtp_session->last_seq+1, (flushed_packets_diff == 1) ? " (flushed by FS)" : " (missed)", + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else { /* We missed multiple packets */ + if (flushed_packets_diff == 0) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (missed). Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else if (flushed_packets_diff == num_missed) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (flushed by FS). Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else if (num_missed > flushed_packets_diff) { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (%d packets flushed by FS, %d packets missed)." + " Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + flushed_packets_diff, num_missed-flushed_packets_diff, + rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } else { + switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, + "Missed %d RTP frames from sequence [%d] to [%d] (%d packets flushed by FS). Time since last read [%d]\n", + num_missed, rtp_session->last_seq+1, seq-1, + flushed_packets_diff, rtp_session->last_read_time ? switch_micro_time_now()-rtp_session->last_read_time : 0); + } + } +#endif + } + rtp_session->last_seq = seq; + } + + rtp_session->last_flush_packet_count = rtp_session->stats.inbound.flush_packet_count; + rtp_session->last_read_time = switch_micro_time_now(); + if (*bytes && (!rtp_session->recv_te || rtp_session->recv_msg.header.pt != rtp_session->recv_te) && ts && !rtp_session->jb && !rtp_session->pause_jb && ts == rtp_session->last_cng_ts) { /* we already sent this frame..... */ @@ -2494,13 +2726,6 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ } } - if (rtp_session->recv_msg.header.pt != 13 && - rtp_session->recv_msg.header.pt != rtp_session->recv_te && - (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && - rtp_session->recv_msg.header.pt != rtp_session->payload) { - /* drop frames of incorrect payload number and return CNG frame instead */ - return_cng_frame(); - } if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP) && rtp_session->rtcp_read_pollfd) { rtcp_poll_status = switch_poll(rtp_session->rtcp_read_pollfd, 1, &rtcp_fdr, 0); @@ -2579,6 +2804,15 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ goto end; } + if (bytes && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_UDPTL) && + rtp_session->recv_msg.header.pt != 13 && + rtp_session->recv_msg.header.pt != rtp_session->recv_te && + (!rtp_session->cng_pt || rtp_session->recv_msg.header.pt != rtp_session->cng_pt) && + rtp_session->recv_msg.header.pt != rtp_session->payload) { + /* drop frames of incorrect payload number and return CNG frame instead */ + return_cng_frame(); + } + if (!bytes && (io_flags & SWITCH_IO_FLAG_NOBLOCK)) { rtp_session->missed_count = 0; ret = 0; @@ -2835,173 +3069,20 @@ static int rtp_common_read(switch_rtp_t *rtp_session, switch_payload_t *payload_ bytes = sbytes; } -#ifdef DEBUG_2833 - if (rtp_session->dtmf_data.in_digit_sanity && !(rtp_session->dtmf_data.in_digit_sanity % 100)) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "sanity %d\n", rtp_session->dtmf_data.in_digit_sanity); - } -#endif - if (rtp_session->dtmf_data.in_digit_sanity && !--rtp_session->dtmf_data.in_digit_sanity) { - rtp_session->dtmf_data.last_digit = 0; - rtp_session->dtmf_data.in_digit_ts = 0; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF sanity check.\n"); - } - - /* RFC2833 ... like all RFC RE: VoIP, guaranteed to drive you to insanity! - We know the real rules here, but if we enforce them, it's an interop nightmare so, - we put up with as much as we can so we don't have to deal with being punished for - doing it right. Nice guys finish last! - */ - if (bytes > rtp_header_len && !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA) && - !switch_test_flag(rtp_session, SWITCH_RTP_FLAG_PASS_RFC2833) && rtp_session->recv_msg.header.pt == rtp_session->recv_te) { - switch_size_t len = bytes - rtp_header_len; - unsigned char *packet = (unsigned char *) rtp_session->recv_msg.body; - int end; - uint16_t duration; - char key; - uint16_t in_digit_seq; - uint32_t ts; - - - if (!(packet[0] || packet[1] || packet[2] || packet[3]) && len >= 8) { - packet += 4; - len -= 4; - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "DTMF payload offset by 4 bytes.\n"); - } - - if (!(packet[0] || packet[1] || packet[2] || packet[3])) { - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed DTMF payload check.\n"); - rtp_session->dtmf_data.last_digit = 0; - rtp_session->dtmf_data.in_digit_ts = 0; - } - - end = packet[1] & 0x80 ? 1 : 0; - duration = (packet[2] << 8) + packet[3]; - key = switch_rfc2833_to_char(packet[0]); - in_digit_seq = ntohs((uint16_t) rtp_session->recv_msg.header.seq); - ts = htonl(rtp_session->recv_msg.header.ts); - - if (in_digit_seq < rtp_session->dtmf_data.in_digit_seq) { - if (rtp_session->dtmf_data.in_digit_seq - in_digit_seq > 100) { - rtp_session->dtmf_data.in_digit_seq = 0; - } - } -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "packet[%d]: %02x %02x %02x %02x\n", (int) len, (unsigned) packet[0], (unsigned) - packet[1], (unsigned) packet[2], (unsigned) packet[3]); -#endif - - if (in_digit_seq > rtp_session->dtmf_data.in_digit_seq) { - - rtp_session->dtmf_data.in_digit_seq = in_digit_seq; -#ifdef DEBUG_2833 - - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "read: %c %u %u %u %u %d %d %s\n", - key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, - ts, duration, rtp_session->recv_msg.header.m, end, end && !rtp_session->dtmf_data.in_digit_ts ? "ignored" : ""); -#endif - - if (!rtp_session->dtmf_data.in_digit_queued && (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && - rtp_session->dtmf_data.in_digit_ts) { - switch_dtmf_t dtmf = { key, switch_core_min_dtmf_duration(0) }; -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Early Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); -#endif - switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); - rtp_session->dtmf_data.in_digit_queued = 1; - } - - /* only set sanity if we do NOT ignore the packet */ - if (rtp_session->dtmf_data.in_digit_ts) { - rtp_session->dtmf_data.in_digit_sanity = 2000; - } - - if (rtp_session->dtmf_data.last_duration > duration && - rtp_session->dtmf_data.last_duration > 0xFC17 && ts == rtp_session->dtmf_data.in_digit_ts) { - rtp_session->dtmf_data.flip++; - } - - if (end) { - if (rtp_session->dtmf_data.in_digit_ts) { - switch_dtmf_t dtmf = { key, duration }; - - if (ts > rtp_session->dtmf_data.in_digit_ts) { - dtmf.duration += (ts - rtp_session->dtmf_data.in_digit_ts); - } - if (rtp_session->dtmf_data.flip) { - dtmf.duration += rtp_session->dtmf_data.flip * 0xFFFF; - rtp_session->dtmf_data.flip = 0; -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "you're welcome!\n"); -#endif - } -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "done digit=%c ts=%u start_ts=%u dur=%u ddur=%u\n", - dtmf.digit, ts, rtp_session->dtmf_data.in_digit_ts, duration, dtmf.duration); -#endif - - if (!(rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION) && !rtp_session->dtmf_data.in_digit_queued) { -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Queuing digit %c:%d\n", dtmf.digit, dtmf.duration / 8); -#endif - switch_rtp_queue_rfc2833_in(rtp_session, &dtmf); - } - - rtp_session->dtmf_data.last_digit = rtp_session->dtmf_data.first_digit; - - rtp_session->dtmf_data.in_digit_ts = 0; - rtp_session->dtmf_data.in_digit_sanity = 0; - rtp_session->dtmf_data.in_digit_queued = 0; - do_cng = 1; - } else { - if (!switch_rtp_ready(rtp_session)) { - goto end; - } - switch_cond_next(); - goto recvfrom; - } - - } else if (!rtp_session->dtmf_data.in_digit_ts) { - rtp_session->dtmf_data.in_digit_ts = ts; - rtp_session->dtmf_data.first_digit = key; - rtp_session->dtmf_data.in_digit_sanity = 2000; - } - - rtp_session->dtmf_data.last_duration = duration; - } else { -#ifdef DEBUG_2833 - switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "drop: %c %u %u %u %u %d %d\n", - key, in_digit_seq, rtp_session->dtmf_data.in_digit_seq, ts, duration, rtp_session->recv_msg.header.m, end); -#endif - switch_cond_next(); - goto recvfrom; - } - } - - if (rtp_session->dtmf_data.in_digit_ts) { - - } - - - if (bytes && rtp_session->dtmf_data.in_digit_ts) { - if (!switch_rtp_ready(rtp_session)) { - goto end; - } - - if (!rtp_session->dtmf_data.in_interleaved && rtp_session->recv_msg.header.pt != rtp_session->recv_te) { - /* Drat, they are sending audio still as well as DTMF ok fine..... *sigh* */ - rtp_session->dtmf_data.in_interleaved = 1; - } - - if (rtp_session->dtmf_data.in_interleaved || (rtp_session->rtp_bugs & RTP_BUG_IGNORE_DTMF_DURATION)) { - if (rtp_session->recv_msg.header.pt == rtp_session->recv_te) { - goto recvfrom; - } - } else { - return_cng_frame(); - } + /* Handle incoming RFC2833 packets */ + switch (handle_rfc2833(rtp_session, bytes, &do_cng)) { + case RESULT_GOTO_END: + goto end; + case RESULT_GOTO_RECVFROM: + goto recvfrom; + case RESULT_GOTO_TIMERCHECK: + goto timer_check; + case RESULT_CONTINUE: + goto result_continue; } + result_continue: timer_check: if (do_cng) {