Merge branch 'master' of ssh://git.freeswitch.org:222/freeswitch

This commit is contained in:
Giovanni Maruzzelli 2011-05-21 02:37:38 -05:00
commit b65a3ebd18
76 changed files with 2102 additions and 519 deletions

View File

@ -9,12 +9,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Co
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Library\FreeSwitchCore.2008.vcproj", "{202D7A4E-760D-4D0E-AFA1-D7459CED30FF}"
ProjectSection(ProjectDependencies) = postProject
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {D331904D-A00A-4694-A5A3-FCFF64AB5DBE}
{8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
{89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}
{F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
{03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
{EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750}
{6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} = {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3}
EndProjectSection

View File

@ -379,12 +379,14 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchConsole", "w32\Co
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "FreeSwitchCoreLib", "w32\Library\FreeSwitchCore.2008.vcproj", "{202D7A4E-760D-4D0E-AFA1-D7459CED30FF}"
ProjectSection(ProjectDependencies) = postProject
{D331904D-A00A-4694-A5A3-FCFF64AB5DBE} = {D331904D-A00A-4694-A5A3-FCFF64AB5DBE}
{8D04B550-D240-4A44-8A18-35DA3F7038D9} = {8D04B550-D240-4A44-8A18-35DA3F7038D9}
{89385C74-5860-4174-9CAF-A39E7C48909C} = {89385C74-5860-4174-9CAF-A39E7C48909C}
{1CBB0077-18C5-455F-801C-0A0CE7B0BBF5} = {1CBB0077-18C5-455F-801C-0A0CE7B0BBF5}
{F057DA7F-79E5-4B00-845C-EF446EF055E3} = {F057DA7F-79E5-4B00-845C-EF446EF055E3}
{03207781-0D1C-4DB3-A71D-45C608F28DBD} = {03207781-0D1C-4DB3-A71D-45C608F28DBD}
{F6C55D93-B927-4483-BB69-15AEF3DD2DFF} = {F6C55D93-B927-4483-BB69-15AEF3DD2DFF}
{87EE9DA4-DE1E-4448-8324-183C98DCA588} = {87EE9DA4-DE1E-4448-8324-183C98DCA588}
{EEF031CB-FED8-451E-A471-91EC8D4F6750} = {EEF031CB-FED8-451E-A471-91EC8D4F6750}
{6EDFEFD5-3596-4FA9-8EBA-B331547B35A3} = {6EDFEFD5-3596-4FA9-8EBA-B331547B35A3}
EndProjectSection

View File

@ -37,6 +37,7 @@ applications/mod_valet_parking
#applications/mod_callcenter
#applications/mod_fsk
#applications/mod_ladspa
#applications/mod_mongo
codecs/mod_g723_1
codecs/mod_amr
#codecs/mod_amrwb

View File

@ -1,3 +1,3 @@
en-us-callie 1.0.15
en-us-callie 1.0.16
ru-RU-elena 1.0.12

View File

@ -0,0 +1,7 @@
<configuration name="mongo.conf">
<settings>
<param name="host" value="127.0.0.1:27017"/>
<param name="min-connections" value="10"/>
<param name="max-connections" value="100"/>
</settings>
</configuration>

View File

@ -808,6 +808,7 @@ SAC_OPENSSL
if test x$HAVE_OPENSSL = x1; then
openssl_CFLAGS="$openssl_CFLAGS -DHAVE_OPENSSL";
APR_ADDTO(SWITCH_AM_CFLAGS, -DHAVE_OPENSSL)
fi
AX_CHECK_JAVA

View File

@ -22,6 +22,7 @@
/opt/freeswitch/conf/autoload_configs/logfile.conf.xml
/opt/freeswitch/conf/autoload_configs/memcache.conf.xml
/opt/freeswitch/conf/autoload_configs/modules.conf.xml
/opt/freeswitch/conf/autoload_configs/mongo.conf.xml
/opt/freeswitch/conf/autoload_configs/nibblebill.conf.xml
/opt/freeswitch/conf/autoload_configs/opal.conf.xml
/opt/freeswitch/conf/autoload_configs/pocketsphinx.conf.xml

View File

@ -29,6 +29,7 @@ opt/freeswitch/conf/autoload_configs/local_stream.conf.xml
opt/freeswitch/conf/autoload_configs/logfile.conf.xml
opt/freeswitch/conf/autoload_configs/memcache.conf.xml
opt/freeswitch/conf/autoload_configs/modules.conf.xml
opt/freeswitch/conf/autoload_configs/mongo.conf.xml
opt/freeswitch/conf/autoload_configs/nibblebill.conf.xml
opt/freeswitch/conf/autoload_configs/opal.conf.xml
opt/freeswitch/conf/autoload_configs/pocketsphinx.conf.xml

View File

@ -5,6 +5,23 @@
<prompt phrase="Pound" filename="35.wav"/>
<prompt phrase="Star" filename="42.wav"/>
<prompt phrase="Dot" filename="46.wav"/>
<prompt phrase="Hyphen" filename="45.wav"/>
<prompt phrase="Exclamation point" filename="33.wav"/>
<prompt phrase="At" filename="64.wav"/>
<prompt phrase="Dollar sign" filename="36.wav"/>
<prompt phrase="Percent" filename="37.wav"/>
<prompt phrase="Ampersand" filename="38.wav"/>
<prompt phrase="Double quote" filename="34.wav"/>
<prompt phrase="Single quote" filename="39.wav"/>
<prompt phrase="Forward slash" filename="47.wav"/>
<prompt phrase="Underscore" filename="95.wav"/>
<prompt phrase="Backslash" filename="92.wav"/>
<prompt phrase="Tilde" filename="126.wav"/>
<prompt phrase="Equal sign" filename="61.wav"/>
<prompt phrase="Colon" filename="58.wav"/>
<prompt phrase="Semicolon" filename="59.wav"/>
<prompt phrase="Caret" filename="94.wav"/>
<prompt phrase="Pipe" filename="124.wav"/>
<prompt phrase="A" filename="97.wav"/>
<prompt phrase="B" filename="98.wav"/>
<prompt phrase="C" filename="99.wav"/>
@ -222,6 +239,8 @@
<prompt phrase="I need to record your first and last name. This recording is used throughout the system, including in the company directory." filename="vm-tutorial_record_name.wav"/>
<prompt phrase="Your personal identification number, or 'pin', is used to prevent others from accessing your voicemail messages. Would you like to change it now?" filename="vm-tutorial_change_pin.wav"/>
<prompt phrase="The person you are trying to reach is not available and does not have voicemail." filename="vm-not_available_no_voicemail.wav"/>
<prompt phrase="The PIN you entered is below the minimum length." filename="voicemail/vm-pin_below_minimum_length.wav"/>
<prompt phrase="The minimum PIN length is..." filename="voicemail/vm-minimum_pin_length_is.wav"/>
</voicemail>
<directory>
<prompt phrase="Please enter the first few letters of the persons" filename="dir-enter_person.wav"/>
@ -270,7 +289,13 @@
<prompt phrase="You are now bi-directionally muted." filename="conf-you_are_now_bidirectionally_muted.wav"/>
<prompt phrase="Enter the number of listeners at this location, then press pound." filename="conf-number_of_listeners.wav"/>
<prompt phrase="...listeners in this conference." filename="conf-listeners_in_conference.wav"/>
<prompt phrase="...members in this conference." filename="conf-members_in_conference.wav"/> </conference>
<prompt phrase="...listener in this conference." filename="conf-listener_in_conference.wav"/>
<prompt phrase="...members in this conference." filename="conf-members_in_conference.wav"/>
<prompt phrase="This conference is in Q and A mode." filename="conference/conf-conference_is_in_qna_mode.wav"/>
<prompt phrase="Q and A mode..." filename="conference/conf-qna_mode.wav"/>
<prompt phrase="Entry sound..." filename="conference/conf-entry_sound.wav"/>
<prompt phrase="Exit sound..." filename="conference/conf-exit_sound.wav"/>
</conference>
<ivr>
<prompt phrase="Account number" filename="ivr-account_number.wav"/>
<prompt phrase="Connect to caller" filename="ivr-connect_to_caller.wav"/>
@ -432,8 +457,6 @@
<prompt phrase="There are..." filename="ivr-there_are.wav"/>
<prompt phrase="Please enter the source telephone number, then press pound." filename="ivr-enter_source_telephone_number.wav"/>
<prompt phrase="Please enter the destination telephone number, then press pound." filename="ivr-enter_destination_telephone_number.wav"/>
<!-- The following phrases still need to be recorded -->
<prompt phrase="Recording started." filename="ivr-recording_started.wav"/>
<prompt phrase="Recording stopped." filename="ivr-recording_stopped.wav"/>
<prompt phrase="Recording paused." filename="ivr-recording_paused.wav"/>
@ -445,37 +468,14 @@
<prompt phrase="...has been answered." filename="ivr-has_been_answered.wav"/>
<prompt phrase="...has been removed." filename="ivr-has_been_removed.wav"/>
<prompt phrase="No questions in queue." filename="ivr-no_questions_in_queue.wav"/>
<prompt phrase="This conference is in Q and A mode." filename="conference/conf-conference_is_in_qna_mode.wav"/>
<prompt phrase="Q and A mode..." filename="conference/conf-qna_mode.wav"/>
<prompt phrase="...is now on." filename="ivr/ivr_is_now_on.wav"/>
<prompt phrase="...is now off." filename="ivr/ivr_is_now_off.wav"/>
<prompt phrase="Entry sound..." filename="conference/conf-entry_sound.wav"/>
<prompt phrase="Exit sound..." filename="conference/conf-exit_sound.wav"/>
<prompt phrase="The PIN you entered is below the minimum length." filename="voicemail/vm-pin_below_minimum_length.wav"/>
<prompt phrase="The minimum PIN length is..." filename="voicemail/vm-minimum_pin_length_is.wav"/>
<prompt phrase="This phone is not allowed to make external calls." filename="ivr-phone_not_make_external_calls.wav"/>
<prompt phrase="I.D. number..." filename="ivr-id_number.wav"/>
<prompt phrase="To skip these instructions..." filename="ivr-skip_instructions.wav"/>
<prompt phrase="Hang up the call without pressing a key to discard the recording." filename="ivr-hangup_to_discard.wav"/>
<prompt phrase="...or press..." filename="ivr-or_press.wav"/>
<prompt phrase="For English, press..." filename="ivr-for_english_press.wav"/>
<prompt phrase="Hyphen" filename="ascii/45.wav"/>
<prompt phrase="Exclamation point" filename="ascii/33.wav"/>
<prompt phrase="At" filename="ascii/64.wav"/>
<prompt phrase="Dollar sign" filename="ascii/36.wav"/>
<prompt phrase="Percent" filename="ascii/37.wav"/>
<prompt phrase="Ampersand" filename="ascii/38.wav"/>
<prompt phrase="Double quote" filename="ascii/34.wav"/>
<prompt phrase="Single quote" filename="ascii/39.wav"/>
<prompt phrase="Forward slash" filename="ascii/47.wav"/>
<prompt phrase="Underscore" filename="ascii/95.wav"/>
<prompt phrase="Backslash" filename="ascii/92.wav"/>
<prompt phrase="Tilde" filename="ascii/126.wav"/>
<prompt phrase="Equal sign" filename="ascii/61.wav"/>
<prompt phrase="Colon" filename="ascii/58.wav"/>
<prompt phrase="Semicolon" filename="ascii/59.wav"/>
<prompt phrase="Caret" filename="ascii/94.wav"/>
<prompt phrase="Pipe" filename="ascii/124.wav"/>
<prompt phrase="Your call cannot be completed as dialed." filename="ivr-call_cannot_be_completed_as_dialed.wav"/>
<prompt phrase="Please check the number and try again." filename="ivr-please_check_number_try_again.wav"/>
<prompt phrase="Failure reason is..." filename="ivr-failure_reason_is.wav"/>
@ -489,6 +489,8 @@
<prompt phrase="Normal unspecified" filename="ivr-normal_unspecified.wav"/>
<prompt phrase="Incompatible destination" filename="ivr-incompatible_destination.wav"/>
<prompt phrase="Normal clearing" filename="ivr-normal_clearing.wav"/>
<!-- The following phrases still need to be recorded -->
</ivr>
<misc>

View File

@ -63,12 +63,12 @@ Vendor: http://www.freeswitch.org/
# Source files and where to get them
#
######################################################################################################################
Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2
Source0: http://files.freeswitch.org/%{name}-%{version}.tar.bz2
Source1: http://files.freeswitch.org/downloads/libs/celt-0.10.0.tar.gz
Source2: http://files.freeswitch.org/downloads/libs/flite-1.3.99-latest.tar.gz
Source3: http://files.freeswitch.org/downloads/libs/lame-3.97.tar.gz
Source4: http://files.freeswitch.org/downloads/libs/libshout-2.2.2.tar.gz
Source5: http://files.freeswitch.org/downloads/libs/mpg123.tar.gz
Source5: http://files.freeswitch.org/downloads/libs/mpg123-1.13.2.tar.gz
Source6: http://files.freeswitch.org/downloads/libs/openldap-2.4.11.tar.gz
Source7: http://files.freeswitch.org/downloads/libs/pocketsphinx-0.5.99-20091212.tar.gz
Source8: http://files.freeswitch.org/downloads/libs/soundtouch-1.3.1.tar.gz
@ -776,6 +776,7 @@ fi
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/logfile.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/memcache.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/modules.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/mongo.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/nibblebill.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/opal.conf.xml
%config(noreplace) %attr(0640, freeswitch, daemon) %{prefix}/conf/autoload_configs/osp.conf.xml

View File

@ -294,6 +294,19 @@ if test "${HAVE_SNG_SS7}" = "yes"; then
fi
fi
##
# zlib (required for Sangoma SS7 Transparent IAM)
#
HAVE_ZLIB="no"
AC_MSG_RESULT([${as_nl}<<>> zlib])
AC_CHECK_LIB([z], [compress], [HAVE_ZLIB="yes"])
AC_MSG_RESULT([checking whether zlib is installed... ${HAVE_ZLIB}])
AM_CONDITIONAL([HAVE_ZLIB], [test "{HAVE_ZLIB]" = "yes"])
if test "${HAVE_ZLIB}" = "yes"; then
CFLAGS="$CFLAGS -DHAVE_ZLIB"
fi
##
# libisdn
#

View File

@ -130,6 +130,10 @@ struct span_config {
int limit_calls;
int limit_seconds;
limit_reset_event_t limit_reset_event;
/* digital codec and digital sampling rate are used to configure the codec
* when bearer capability is set to unrestricted digital */
const char *digital_codec;
int digital_sampling_rate;
chan_pvt_t pvts[FTDM_MAX_CHANNELS_SPAN];
};
@ -294,13 +298,11 @@ static void cycle_foreground(ftdm_channel_t *ftdmchan, int flash, const char *bc
}
}
static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan)
static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *session, ftdm_channel_t *ftdmchan, ftdm_caller_data_t *caller_data)
{
const char *dname = NULL;
uint32_t interval = 0, srate = 8000;
uint32_t span_id;
ftdm_codec_t codec;
tech_pvt->ftdmchan = ftdmchan;
@ -321,6 +323,16 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
return SWITCH_STATUS_GENERR;
}
span_id = ftdm_channel_get_span_id(ftdmchan);
if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED
&& SPAN_CONFIG[span_id].digital_codec) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Initializing digital call with codec %s at %dhz.\n",
SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate);
dname = SPAN_CONFIG[span_id].digital_codec;
srate = SPAN_CONFIG[span_id].digital_sampling_rate;
goto init_codecs;
}
if (FTDM_SUCCESS != ftdm_channel_command(ftdmchan, FTDM_COMMAND_GET_CODEC, &codec)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to retrieve channel codec.\n");
return SWITCH_STATUS_GENERR;
@ -349,6 +361,7 @@ static switch_status_t tech_init(private_t *tech_pvt, switch_core_session_t *ses
}
}
init_codecs:
if (switch_core_codec_init(&tech_pvt->read_codec,
dname,
@ -1093,7 +1106,7 @@ static ftdm_status_t on_channel_found(ftdm_channel_t *fchan, ftdm_caller_data_t
span_id = ftdm_channel_get_span_id(fchan);
chan_id = ftdm_channel_get_id(fchan);
tech_init(hdata->tech_pvt, hdata->new_session, fchan);
tech_init(hdata->tech_pvt, hdata->new_session, fchan, caller_data);
snprintf(name, sizeof(name), "FreeTDM/%u:%u/%s", span_id, chan_id, caller_data->dnis.digits);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Connect outbound channel %s\n", name);
@ -1366,7 +1379,15 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
ftdm_usrmsg_add_var(&usrmsg, "ss7_pres_ind", sipvar);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-CPC");
if (sipvar) {
ftdm_set_calling_party_category(sipvar, (uint8_t *)&caller_data.cpc);
}
sipvar = switch_channel_get_variable(channel, "sip_h_X-FreeTDM-IAM");
if (sipvar) {
ftdm_usrmsg_add_var(&usrmsg, "ss7_iam", sipvar);
}
}
if (switch_test_flag(outbound_profile, SWITCH_CPF_SCREEN)) {
@ -1439,7 +1460,13 @@ static switch_call_cause_t channel_outgoing_channel(switch_core_session_t *sessi
if (!strncasecmp(h->name, FREETDM_VAR_PREFIX, FREETDM_VAR_PREFIX_LEN)) {
char *v = h->name + FREETDM_VAR_PREFIX_LEN;
if (!zstr(v)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
if (!strcasecmp(v, "ss7_iam")) {
/* Do not print the value of ss7_iam as it is very long */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s to channel %d:%d\n", v, span_id, chan_id);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Adding outbound freetdm variable %s=%s to channel %d:%d\n", v, h->value, span_id, chan_id);
}
ftdm_usrmsg_add_var(&usrmsg, v, h->value);
}
}
@ -1542,7 +1569,7 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
tech_pvt = (private_t *) switch_core_session_alloc(session, sizeof(private_t));
assert(tech_pvt != NULL);
channel = switch_core_session_get_channel(session);
if (tech_init(tech_pvt, session, sigmsg->channel) != SWITCH_STATUS_SUCCESS) {
if (tech_init(tech_pvt, session, sigmsg->channel, channel_caller_data) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Initilization Error!\n");
switch_core_session_destroy(&session);
return FTDM_FAIL;
@ -1604,9 +1631,11 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "freetdm_chan_number", "%d", chanid);
switch_channel_set_variable_printf(channel, "freetdm_bearer_capability", "%d", channel_caller_data->bearer_capability);
switch_channel_set_variable_printf(channel, "freetdm_bearer_layer1", "%d", channel_caller_data->bearer_layer1);
switch_channel_set_variable_printf(channel, "freetdm_calling_party_category", ftdm_calling_party_category2str(channel_caller_data->cpc));
switch_channel_set_variable_printf(channel, "screening_ind", ftdm_screening2str(channel_caller_data->screen));
switch_channel_set_variable_printf(channel, "presentation_ind", ftdm_presentation2str(channel_caller_data->pres));
if (globals.sip_headers) {
switch_channel_set_variable(channel, "sip_h_X-FreeTDM-SpanName", ftdm_channel_get_span_name(sigmsg->channel));
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-SpanNumber", "%d", spanid);
@ -1627,6 +1656,8 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS", "%s", channel_caller_data->rdnis.digits);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-NADI", "%d", channel_caller_data->rdnis.type);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-RDNIS-Plan", "%d", channel_caller_data->rdnis.plan);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-CPC", "%s", ftdm_calling_party_category2str(channel_caller_data->cpc));
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_rdnis_screen_ind");
if (!ftdm_strlen_zero(var_value)) {
@ -1672,7 +1703,12 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-GN-NumInComp", "%d", var_value);
}
} /* End - var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_gn_digits"); */
var_value = ftdm_sigmsg_get_var(sigmsg, "ss7_iam");
if (!ftdm_strlen_zero(var_value)) {
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-IAM", "%s", var_value);
}
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Screen", "%d", channel_caller_data->screen);
switch_channel_set_variable_printf(channel, "sip_h_X-FreeTDM-Presentation", "%d", channel_caller_data->pres);
}
@ -1683,7 +1719,12 @@ ftdm_status_t ftdm_channel_from_event(ftdm_sigmsg_t *sigmsg, switch_core_session
ftdm_get_current_var(curr, &var_name, &var_value);
snprintf(name, sizeof(name), FREETDM_VAR_PREFIX "%s", var_name);
switch_channel_set_variable_printf(channel, name, "%s", var_value);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value);
if (!strcasecmp(var_name, "ss7_iam")) {
/* Do not print freetdm_ss7_iam as it is a very long variable */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s is present\n", name);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Call Variable: %s = %s\n", name, var_value);
}
}
ftdm_iterator_free(iter);
@ -2668,6 +2709,7 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
/* some defaults first */
SPAN_CONFIG[span_id].limit_backend = "hash";
SPAN_CONFIG[span_id].limit_reset_event = FTDM_LIMIT_RESET_ON_TIMEOUT;
SPAN_CONFIG[span_id].digital_sampling_rate = 8000;
for (param = switch_xml_child(myspan, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
@ -2682,6 +2724,21 @@ static void parse_bri_pri_spans(switch_xml_t cfg, switch_xml_t spans)
context = val;
} else if (!strcasecmp(var, "dialplan")) {
dialplan = val;
} else if (!strcasecmp(var, "unrestricted-digital-codec")) {
//switch_core_strdup(pool, val);
const switch_codec_implementation_t *codec = NULL;
int num_codecs;
num_codecs = switch_loadable_module_get_codecs_sorted(&codec, 1, &val, 1);
if (num_codecs != 1 || !codec) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"Failed finding codec %s for unrestricted digital calls\n", val);
} else {
SPAN_CONFIG[span_id].digital_codec = switch_core_strdup(module_pool, codec->iananame);
SPAN_CONFIG[span_id].digital_sampling_rate = codec->samples_per_second;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
"Unrestricted digital codec is %s at %dhz for span %d\n",
SPAN_CONFIG[span_id].digital_codec, SPAN_CONFIG[span_id].digital_sampling_rate, span_id);
}
} else if (!strcasecmp(var, "call_limit_backend")) {
SPAN_CONFIG[span_id].limit_backend = val;
ftdm_log(FTDM_LOG_DEBUG, "Using limit backend %s for span %d\n", SPAN_CONFIG[span_id].limit_backend, span_id);

View File

@ -42,6 +42,74 @@
#include <ctype.h>
FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len)
{
/* This implementation of url_encode is slightly different compared to the
* Freeswitch one. This is because this implementation accepts the full
* range of values (0x00 - 0xFF) compared to the Freeswitch implementation
* that does not accept 0x00 */
const char *p;
size_t x = 0,y = 0;
const char urlunsafe[] = "\r\n \"#%&+:;<=>?@[\\]^`{|}";
const char hex[] = "0123456789ABCDEF";
if (!buf) {
return 0;
}
if (!url) {
return 0;
}
len--;
for (p = url; y <= len; p++) {
if (*p < ' ' || *p > '~' || strchr(urlunsafe, *p)) {
buf[x++] = '%';
buf[x++] = hex[(*p >> 4) & 0x0f];
buf[x++] = hex[*p & 0x0f];
} else {
buf[x++] = *p;
}
y++;
}
buf[x] = '\0';
return buf;
}
FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len)
{
/* This implementation of url_decode is slightly different compared to the
* Freeswitch one. This is because this implementation accepts the full
* range of values (0x00 - 0xFF) compared to the Freeswitch implementation
* that does not accept 0x00 */
char *o;
unsigned int tmp;
ftdm_size_t mylen = 0;
if (ftdm_strlen_zero(s)) {
return s;
}
for (o = s; *s; s++, o++) {
if (*s == '%' && strlen(s) > 2 && sscanf(s + 1, "%2x", &tmp) == 1) {
*o = (char) tmp;
s += 2;
} else {
*o = *s;
}
mylen++;
}
*o = '\0';
*len = mylen;
return s;
}
FT_DECLARE(ftdm_status_t) ftdm_set_npi(const char *string, uint8_t *target)
{
uint8_t val;

View File

@ -310,21 +310,6 @@ FTDM_STR2ENUM(ftdm_str2channel_indication, ftdm_channel_indication2str, ftdm_cha
static ftdm_status_t ftdm_group_add_channels(ftdm_span_t* span, int currindex, const char* name);
static const char *cut_path(const char *in)
{
const char *p, *ret = in;
char delims[] = "/\\";
char *i;
for (i = delims; *i; i++) {
p = in;
while ((p = strchr(p, *i)) != 0) {
ret = ++p;
}
}
return ret;
}
static void null_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
{
if (file && func && line && level && fmt) {
@ -350,7 +335,6 @@ static int ftdm_log_level = FTDM_LOG_LEVEL_DEBUG;
static void default_logger(const char *file, const char *func, int line, int level, const char *fmt, ...)
{
const char *fp;
char data[1024];
va_list ap;
@ -360,14 +344,11 @@ static void default_logger(const char *file, const char *func, int line, int lev
if (level > ftdm_log_level) {
return;
}
fp = cut_path(file);
va_start(ap, fmt);
vsnprintf(data, sizeof(data), fmt, ap);
fprintf(stderr, "[%s] %s:%d %s() %s", FTDM_LEVEL_NAMES[level], file, line, func, data);
va_end(ap);
@ -411,13 +392,13 @@ FT_DECLARE(void) ftdm_set_echocancel_call_begin(ftdm_channel_t *chan)
if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC)) {
if (ftdm_channel_test_feature(chan, FTDM_CHANNEL_FEATURE_HWEC_DISABLED_ON_IDLE)) {
/* If the ec is disabled on idle, we need to enable it unless is a digital call */
if (caller_data->bearer_capability != FTDM_BEARER_CAP_64K_UNRESTRICTED) {
if (caller_data->bearer_capability != FTDM_BEARER_CAP_UNRESTRICTED) {
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Enabling ec for call in channel state %s\n", ftdm_channel_state2str(chan->state));
ftdm_channel_command(chan, FTDM_COMMAND_ENABLE_ECHOCANCEL, NULL);
}
} else {
/* If the ec is enabled on idle, we do nothing unless is a digital call that needs it disabled */
if (caller_data->bearer_capability == FTDM_BEARER_CAP_64K_UNRESTRICTED) {
if (caller_data->bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) {
ftdm_log_chan(chan, FTDM_LOG_DEBUG, "Disabling ec for digital call in channel state %s\n", ftdm_channel_state2str(chan->state));
ftdm_channel_command(chan, FTDM_COMMAND_DISABLE_ECHOCANCEL, NULL);
}
@ -508,13 +489,16 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_set_caller_data(ftdm_channel_t *ftdmchan,
{
ftdm_status_t err = FTDM_SUCCESS;
if (!ftdmchan) {
ftdm_log(FTDM_LOG_CRIT, "Error: trying to set caller data, but no ftdmchan!\n");
ftdm_log(FTDM_LOG_CRIT, "trying to set caller data, but no ftdmchan!\n");
return FTDM_FAIL;
}
if ((err = ftdm_set_caller_data(ftdmchan->span, caller_data)) != FTDM_SUCCESS) {
return err;
}
ftdmchan->caller_data = *caller_data;
if (ftdmchan->caller_data.bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) {
ftdm_set_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA);
}
return FTDM_SUCCESS;
}
@ -2628,6 +2612,7 @@ static ftdm_status_t ftdm_channel_done(ftdm_channel_t *ftdmchan)
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_MEDIA);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_ANSWERED);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_USER_HANGUP);
ftdm_clear_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA);
ftdm_mutex_lock(ftdmchan->pre_buffer_mutex);
ftdm_buffer_destroy(&ftdmchan->pre_buffer);
ftdmchan->pre_buffer_size = 0;
@ -3780,6 +3765,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
handle_tone_generation(ftdmchan);
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) {
goto done;
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
codec_func = fio_ulaw2slin;
@ -3934,7 +3923,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
memset(data, 255, *datalen);
memset(data, FTDM_SILENCE_VALUE(ftdmchan), *datalen);
if (ftdmchan->skip_read_frames > 0) {
ftdmchan->skip_read_frames--;
@ -3946,7 +3935,7 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_read(ftdm_channel_t *ftdmchan, void *data
if (ftdm_buffer_inuse(ftdmchan->pre_buffer) >= ftdmchan->pre_buffer_size) {
ftdm_buffer_read(ftdmchan->pre_buffer, data, *datalen);
} else {
memset(data, 255, *datalen);
memset(data, FTDM_SILENCE_VALUE(ftdmchan), *datalen);
}
}
ftdm_mutex_unlock(ftdmchan->pre_buffer_mutex);
@ -3994,6 +3983,10 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
status = FTDM_FAIL;
goto done;
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_DIGITAL_MEDIA)) {
goto do_write;
}
if (ftdm_test_flag(ftdmchan, FTDM_CHANNEL_TRANSCODE) && ftdmchan->effective_codec != ftdmchan->native_codec) {
if (ftdmchan->native_codec == FTDM_CODEC_ULAW && ftdmchan->effective_codec == FTDM_CODEC_SLIN) {
@ -4025,6 +4018,8 @@ FT_DECLARE(ftdm_status_t) ftdm_channel_write(ftdm_channel_t *ftdmchan, void *dat
}
}
do_write:
if (ftdmchan->span->sig_write) {
status = ftdmchan->span->sig_write(ftdmchan, data, *datalen);
if (status == FTDM_BREAK) {
@ -5374,10 +5369,12 @@ FT_DECLARE(ftdm_status_t) ftdm_span_send_signal(ftdm_span_t *span, ftdm_sigmsg_t
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_CALL_STARTED);
ftdm_call_set_call_id(sigmsg->channel, &sigmsg->channel->caller_data);
/* when cleaning up the public API I added this because mod_freetdm.c on_fxs_signal was
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
* is needed at all?
* */
* doing it during SIGEVENT_START, but now that flags are private they can't, wonder if
* is needed at all? */
ftdm_clear_flag(sigmsg->channel, FTDM_CHANNEL_HOLD);
if (sigmsg->channel->caller_data.bearer_capability == FTDM_BEARER_CAP_UNRESTRICTED) {
ftdm_set_flag(sigmsg->channel, FTDM_CHANNEL_DIGITAL_MEDIA);
}
}
break;

View File

@ -426,7 +426,6 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = analog_data->wait_dialtone_timeout;
uint32_t answer_on_polarity_counter = 0;
ftdm_sigmsg_t sig;
ftdm_status_t status;
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "ANALOG CHANNEL thread starting.\n");
@ -916,7 +915,7 @@ static void *ftdm_analog_channel_run(ftdm_thread_t *me, void *obj)
}
if (codec_func) {
status = codec_func(frame, sizeof(frame), &rlen);
codec_func(frame, sizeof(frame), &rlen);
} else {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
goto done;

View File

@ -221,7 +221,6 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
ftdm_channel_t *closed_chan;
uint32_t state_counter = 0, elapsed = 0, collecting = 0, interval = 0, last_digit = 0, indicate = 0, dial_timeout = 30000;
ftdm_sigmsg_t sig;
ftdm_status_t status;
ftdm_log(FTDM_LOG_DEBUG, "ANALOG EM CHANNEL thread starting.\n");
@ -545,7 +544,7 @@ static void *ftdm_analog_em_channel_run(ftdm_thread_t *me, void *obj)
}
if (codec_func) {
status = codec_func(frame, sizeof(frame), &rlen);
codec_func(frame, sizeof(frame), &rlen);
} else {
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "codec error!");
goto done;

View File

@ -1965,6 +1965,10 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
assert(isdn_data != NULL);
memset(isdn_data, 0, sizeof(*isdn_data));
/* set some default values */
isdn_data->mode = PRI_CPE;
isdn_data->ton = PRI_UNKNOWN;
switch (ftdm_span_get_trunk_type(span)) {
case FTDM_TRUNK_BRI:
case FTDM_TRUNK_BRI_PTMP:
@ -1975,12 +1979,14 @@ static FIO_CONFIGURE_SPAN_SIGNALING_FUNCTION(ftdm_libpri_configure_span)
#endif
case FTDM_TRUNK_E1:
ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ALAW since this is an E1/BRI/BRI PTMP trunk\n");
isdn_data->layer1 = PRI_LAYER_1_ALAW;
isdn_data->layer1 = PRI_LAYER_1_ALAW;
isdn_data->dialect = PRI_SWITCH_EUROISDN_E1;
break;
case FTDM_TRUNK_T1:
case FTDM_TRUNK_J1:
ftdm_log(FTDM_LOG_NOTICE, "Setting default Layer 1 to ULAW since this is a T1/J1 trunk\n");
isdn_data->layer1 = PRI_LAYER_1_ULAW;
isdn_data->layer1 = PRI_LAYER_1_ULAW;
isdn_data->dialect = PRI_SWITCH_LUCENT5E;
break;
default:
ftdm_log(FTDM_LOG_ERROR, "Invalid trunk type: '%s'\n", ftdm_span_get_trunk_type_str(span));

View File

@ -292,6 +292,12 @@ typedef struct ftdm_sngisdn_data {
sngisdn_span_data_t *spans[MAX_L1_LINKS+1]; /* spans are indexed by link_id */
}ftdm_sngisdn_data_t;
typedef struct ftdm2trillium
{
uint8_t ftdm_val;
uint8_t trillium_val;
}ftdm2trillium_t;
/* TODO implement these 2 functions */
#define ISDN_FUNC_TRACE_ENTER(a)

View File

@ -745,8 +745,16 @@ ftdm_status_t sngisdn_stack_cfg_q931_dlsap(ftdm_span_t *span)
/* TODO: Fill in these timers with proper values - eventually pass them */
cfg.t.cfg.s.inDLSAP.tmr.t301.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t301.val = 180;
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15;
/* It looks like ETSI is the only variant that supports Overlap */
if (signal_data->switchtype == SNGISDN_SWITCH_EUROISDN) {
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 15;
} else {
cfg.t.cfg.s.inDLSAP.tmr.t302.enb = FALSE;
cfg.t.cfg.s.inDLSAP.tmr.t302.val = 0;
}
cfg.t.cfg.s.inDLSAP.tmr.t303.enb = TRUE;
cfg.t.cfg.s.inDLSAP.tmr.t303.val = 4;
cfg.t.cfg.s.inDLSAP.tmr.t304.enb = TRUE;

View File

@ -831,7 +831,7 @@ void sngisdn_process_fac_ind (sngisdn_event_data_t *sngisdn_event)
if (sng_isdn_retrieve_facility_caller_name(&facEvnt->facElmt.facStr.val[2], facEvnt->facElmt.facStr.len, retrieved_str) == 0) {
strcpy(ftdmchan->caller_data.cid_name, retrieved_str);
} else {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_WARNING, "Failed to retrieve Caller Name from Facility IE\n");
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "Failed to retrieve Caller Name from Facility IE\n");
}
if (signal_data->facility_timeout) {
/* Cancel facility timeout */

View File

@ -779,7 +779,6 @@ void sngisdn_rcv_cc_ind(CcMngmt *status)
void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
{
MsgLen mlen;
MsgLen i;
int16_t j;
Buffer *tmp;
Data *cptr;
@ -802,7 +801,6 @@ void sngisdn_rcv_q931_trace(InMngmt *trc, Buffer *mBuf)
tmp = mBuf->b_cont;
cptr = tmp->b_rptr;
data = *cptr++;
i = 0;
for(j=0;j<mlen;j++) {
tdata[j]= data;

View File

@ -43,9 +43,55 @@ SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_descr, ftdm_sngisdn_progind_descr
SNGISDN_ENUM_NAMES(SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_STRINGS)
SNGISDN_STR2ENUM(ftdm_str2ftdm_sngisdn_progind_loc, ftdm_sngisdn_progind_loc2str, ftdm_sngisdn_progind_loc_t, SNGISDN_PROGIND_LOC_NAMES, SNGISDN_PROGIND_LOC_INVALID)
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val);
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val);
extern ftdm_sngisdn_data_t g_sngisdn_data;
void get_memory_info(void);
ftdm2trillium_t npi_codes[] = {
{FTDM_NPI_UNKNOWN, IN_NP_UNK},
{FTDM_NPI_ISDN, IN_NP_ISDN},
{FTDM_NPI_DATA, IN_NP_DATA},
{FTDM_NPI_TELEX, IN_NP_TELEX},
{FTDM_NPI_NATIONAL, IN_NP_NATIONAL},
{FTDM_NPI_PRIVATE, IN_NP_PRIVATE},
{FTDM_NPI_RESERVED, IN_NP_EXT},
};
ftdm2trillium_t ton_codes[] = {
{FTDM_TON_UNKNOWN, IN_TON_UNK},
{FTDM_TON_INTERNATIONAL, IN_TON_INT},
{FTDM_TON_NATIONAL, IN_TON_NAT},
{FTDM_TON_NETWORK_SPECIFIC, IN_TON_NETSPEC},
{FTDM_TON_SUBSCRIBER_NUMBER, IN_TON_SUB},
{FTDM_TON_ABBREVIATED_NUMBER, IN_TON_ABB},
{FTDM_TON_RESERVED, IN_TON_EXT},
};
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val)
{
ftdm2trillium_t *val = vals;
while(val++) {
if (val->ftdm_val == ftdm_val) {
return val->trillium_val;
}
}
return default_val;
}
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val)
{
ftdm2trillium_t *val = vals;
while(val++) {
if (val->trillium_val == trillium_val) {
return val->ftdm_val;
}
}
return default_val;
}
void clear_call_data(sngisdn_chan_data_t *sngisdn_info)
{
uint32_t cc_id = ((sngisdn_span_data_t*)sngisdn_info->ftdmchan->span->signal_data)->cc_id;
@ -257,11 +303,11 @@ ftdm_status_t get_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
}
if (cdPtyNmb->nmbPlanId.pres == PRSNT_NODEF) {
caller_data->dnis.plan = cdPtyNmb->nmbPlanId.val;
caller_data->dnis.plan = get_ftdm_val(npi_codes, cdPtyNmb->nmbPlanId.val, IN_NP_UNK);
}
if (cdPtyNmb->typeNmb0.pres == PRSNT_NODEF) {
caller_data->dnis.type = cdPtyNmb->typeNmb0.val;
caller_data->dnis.type = get_ftdm_val(ton_codes, cdPtyNmb->typeNmb0.val, IN_TON_UNK);
}
if (cdPtyNmb->nmbDigits.pres == PRSNT_NODEF) {
@ -281,11 +327,11 @@ ftdm_status_t get_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
}
if (redirNmb->nmbPlanId.pres == PRSNT_NODEF) {
caller_data->rdnis.plan = redirNmb->nmbPlanId.val;
caller_data->rdnis.plan = get_ftdm_val(npi_codes, redirNmb->nmbPlanId.val, IN_NP_UNK);
}
if (redirNmb->typeNmb.pres == PRSNT_NODEF) {
caller_data->rdnis.type = redirNmb->typeNmb.val;
caller_data->rdnis.type = get_ftdm_val(ton_codes, redirNmb->typeNmb.val, IN_TON_UNK);
}
if (redirNmb->nmbDigits.pres == PRSNT_NODEF) {
@ -380,11 +426,13 @@ ftdm_status_t get_facility_ie_str(ftdm_channel_t *ftdmchan, uint8_t *data, uint8
ftdm_status_t get_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd)
{
uint8_t val;
if (!progInd->eh.pres) {
return FTDM_FAIL;
}
if (progInd->progDesc.pres) {
/* TODO: use get_ftdm_val function and table here */
switch (progInd->progDesc.val) {
case IN_PD_NOTETEISDN:
val = SNGISDN_PROGIND_DESCR_NETE_ISDN;
@ -462,19 +510,11 @@ ftdm_status_t set_calling_num(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
cgPtyNmb->presInd0.val = caller_data->pres;
cgPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
if (caller_data->cid_num.plan >= FTDM_NPI_INVALID) {
cgPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
}
cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->cid_num.plan, IN_NP_UNK);
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
if (caller_data->cid_num.type >= FTDM_TON_INVALID) {
cgPtyNmb->typeNmb1.val = FTDM_TON_UNKNOWN;
} else {
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
}
cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, caller_data->cid_num.type, IN_TON_UNK);
cgPtyNmb->nmbDigits.pres = PRSNT_NODEF;
cgPtyNmb->nmbDigits.len = len;
@ -508,7 +548,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
val = FTDM_SCREENING_INVALID;
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.screening_ind");
if ((string != NULL) && (*string)) {
if (!ftdm_strlen_zero(string)) {
val = ftdm_str2ftdm_screening(string);
}
@ -525,7 +565,7 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
val = FTDM_PRES_INVALID;
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.presentation_ind");
if ((string != NULL) && (*string)) {
if (!ftdm_strlen_zero(string)) {
val = ftdm_str2ftdm_presentation(string);
}
@ -540,14 +580,14 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
val = FTDM_NPI_INVALID;
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.npi");
if ((string != NULL) && (*string)) {
if (!ftdm_strlen_zero(string)) {
val = ftdm_str2ftdm_npi(string);
}
if (val == FTDM_NPI_INVALID) {
cgPtyNmb->nmbPlanId.val = caller_data->cid_num.plan;
} else {
cgPtyNmb->nmbPlanId.val = val;
cgPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, val, IN_NP_UNK);
}
cgPtyNmb->typeNmb1.pres = PRSNT_NODEF;
@ -555,14 +595,14 @@ ftdm_status_t set_calling_num2(ftdm_channel_t *ftdmchan, CgPtyNmb *cgPtyNmb)
/* Type of Number */
val = FTDM_TON_INVALID;
string = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.cg_pty2.ton");
if ((string != NULL) && (*string)) {
if (!ftdm_strlen_zero(string)) {
val = ftdm_str2ftdm_ton(string);
}
if (val == FTDM_TON_INVALID) {
cgPtyNmb->typeNmb1.val = caller_data->cid_num.type;
} else {
cgPtyNmb->typeNmb1.val = val;
cgPtyNmb->typeNmb1.val = get_trillium_val(ton_codes, val, IN_TON_UNK);
}
return FTDM_SUCCESS;
}
@ -575,21 +615,14 @@ ftdm_status_t set_called_num(ftdm_channel_t *ftdmchan, CdPtyNmb *cdPtyNmb)
if (!len) {
return FTDM_SUCCESS;
}
cdPtyNmb->eh.pres = PRSNT_NODEF;
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
if (caller_data->dnis.plan >= FTDM_NPI_INVALID) {
cdPtyNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
cdPtyNmb->nmbPlanId.val = caller_data->dnis.plan;
}
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
if (caller_data->dnis.type >= FTDM_TON_INVALID) {
cdPtyNmb->typeNmb0.val = FTDM_TON_UNKNOWN;
} else {
cdPtyNmb->typeNmb0.val = caller_data->dnis.type;
}
cdPtyNmb->eh.pres = PRSNT_NODEF;
cdPtyNmb->nmbPlanId.pres = PRSNT_NODEF;
cdPtyNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->dnis.plan, IN_NP_UNK);
cdPtyNmb->typeNmb0.pres = PRSNT_NODEF;
cdPtyNmb->typeNmb0.val = get_trillium_val(ton_codes, caller_data->dnis.type, IN_TON_UNK);
cdPtyNmb->nmbDigits.pres = PRSNT_NODEF;
cdPtyNmb->nmbDigits.len = len;
@ -610,18 +643,10 @@ ftdm_status_t set_redir_num(ftdm_channel_t *ftdmchan, RedirNmb *redirNmb)
redirNmb->eh.pres = PRSNT_NODEF;
redirNmb->nmbPlanId.pres = PRSNT_NODEF;
if (caller_data->rdnis.plan >= FTDM_NPI_INVALID) {
redirNmb->nmbPlanId.val = FTDM_NPI_UNKNOWN;
} else {
redirNmb->nmbPlanId.val = caller_data->rdnis.plan;
}
redirNmb->nmbPlanId.val = get_trillium_val(npi_codes, caller_data->rdnis.plan, IN_NP_UNK);
redirNmb->typeNmb.pres = PRSNT_NODEF;
if (caller_data->rdnis.type >= FTDM_TON_INVALID) {
redirNmb->typeNmb.val = FTDM_TON_UNKNOWN;
} else {
redirNmb->typeNmb.val = caller_data->rdnis.type;
}
redirNmb->typeNmb.val = get_trillium_val(ton_codes, caller_data->rdnis.type, IN_TON_UNK);
redirNmb->nmbDigits.pres = PRSNT_NODEF;
redirNmb->nmbDigits.len = len;
@ -741,7 +766,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
int loc = prog_ind.loc;
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.descr");
if (str && *str) {
if (!ftdm_strlen_zero(str)) {
/* User wants to override progress indicator */
descr = ftdm_str2ftdm_sngisdn_progind_descr(str);
}
@ -752,7 +777,7 @@ ftdm_status_t set_prog_ind_ie(ftdm_channel_t *ftdmchan, ProgInd *progInd, ftdm_s
}
str = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "isdn.prog_ind.loc");
if (str && *str) {
if (!ftdm_strlen_zero(str)) {
loc = ftdm_str2ftdm_sngisdn_progind_loc(str);
}
if (loc == SNGISDN_PROGIND_LOC_INVALID) {
@ -1067,18 +1092,20 @@ void get_memory_info(void)
return;
}
uint8_t sngisdn_get_infoTranCap_from_user(ftdm_bearer_cap_t bearer_capability)
{
switch(bearer_capability) {
case FTDM_BEARER_CAP_SPEECH:
return IN_ITC_SPEECH;
case FTDM_BEARER_CAP_64K_UNRESTRICTED:
case FTDM_BEARER_CAP_UNRESTRICTED:
return IN_ITC_UNRDIG;
case FTDM_BEARER_CAP_3_1KHZ_AUDIO:
return IN_ITC_A31KHZ;
case FTDM_BEARER_CAP_INVALID:
return IN_ITC_SPEECH;
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
default:
return IN_ITC_SPEECH;
}
return FTDM_BEARER_CAP_SPEECH;
}
@ -1094,7 +1121,8 @@ uint8_t sngisdn_get_usrInfoLyr1Prot_from_user(ftdm_user_layer1_prot_t layer1_pro
return IN_UIL1_G711ALAW;
case FTDM_USER_LAYER1_PROT_INVALID:
return IN_UIL1_G711ULAW;
/* Do not put a default case here, so we can see compile warnings if we have unhandled cases */
default:
return IN_UIL1_G711ULAW;
}
return IN_UIL1_G711ULAW;
}
@ -1103,9 +1131,9 @@ ftdm_bearer_cap_t sngisdn_get_infoTranCap_from_stack(uint8_t bearer_capability)
{
switch(bearer_capability) {
case IN_ITC_SPEECH:
return FTDM_BEARER_CAP_SPEECH;
return FTDM_BEARER_CAP_SPEECH;
case IN_ITC_UNRDIG:
return FTDM_BEARER_CAP_64K_UNRESTRICTED;
return FTDM_BEARER_CAP_UNRESTRICTED;
case IN_ITC_A31KHZ:
return FTDM_BEARER_CAP_3_1KHZ_AUDIO;
default:

View File

@ -334,11 +334,12 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
switch(ieId) {
case PROT_Q931_IE_BEARER_CAP:
{
uint8_t codingStandard, infTransferCap, transferMode, infTransferRate, usrL1Prot;
uint8_t codingStandard, infTransferCap, infTransferRate, usrL1Prot;
/*uint8_t transferMode;*/
codingStandard = get_bits(OCTET(3),6,7);
infTransferCap = get_bits(OCTET(3),1,5);
transferMode = get_bits(OCTET(4),6,7);
/*transferMode = get_bits(OCTET(4),6,7);*/
infTransferRate = get_bits(OCTET(4),1,5);
usrL1Prot = get_bits(OCTET(5),1,5);
@ -404,8 +405,9 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
uint8_t infoChannelSelection=0;
uint8_t prefExclusive=0;
uint8_t ifaceIdPresent=0;
uint8_t ifaceIdentifier = 0; /* octet_3_1 */
uint8_t chanType=0, numberMap=0, codingStandard=0;
/* uint8_t ifaceIdentifier = 0; */ /* octet_3_1 */
uint8_t chanType=0, numberMap=0;
/* uint8_t codingStandard=0; */
uint8_t channelNo = 0;
infoChannelSelection = get_bits(OCTET(3),1,2);
@ -413,15 +415,15 @@ uint32_t sngisdn_decode_ie(char *str, uint32_t *str_len, uint8_t current_codeset
ifaceIdPresent = get_bits(OCTET(3),7,7);
if (ifaceIdPresent) {
ifaceIdentifier= get_bits(OCTET(4),1,7);
/*ifaceIdentifier= get_bits(OCTET(4),1,7);*/
chanType = get_bits(OCTET(5),1,4);
numberMap = get_bits(OCTET(5),5,5);
codingStandard = get_bits(OCTET(5),6,7);
/*codingStandard = get_bits(OCTET(5),6,7);*/
channelNo = get_bits(OCTET(6),1,7);
} else {
chanType = get_bits(OCTET(4),1,4);
numberMap = get_bits(OCTET(4),5,5);
codingStandard = get_bits(OCTET(4),6,7);
/*codingStandard = get_bits(OCTET(4),6,7);*/
channelNo = get_bits(OCTET(5),1,7);
}

View File

@ -33,12 +33,14 @@
/* INCLUDE ********************************************************************/
#include "ftmod_sangoma_ss7_main.h"
/******************************************************************************/
/* DEFINES ********************************************************************/
/******************************************************************************/
/* GLOBALS ********************************************************************/
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
@ -79,14 +81,14 @@ ftdm_status_t handle_olm_msg(uint32_t suInstId, uint32_t spInstId, uint32_t circ
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt)
{
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
sngss7_chan_data_t *sngss7_info = NULL;
ftdm_channel_t *ftdmchan = NULL;
char nadi[2];
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
memset(nadi, '\0', sizeof(nadi));
/* get the ftdmchan and ss7_chan_data from the circuit */
@ -189,6 +191,8 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
copy_genNmb_from_sngss7(ftdmchan, &siConEvnt->genNmb);
copy_cgPtyCat_from_sngss7(ftdmchan, &siConEvnt->cgPtyCat);
/* fill in the TMR/bearer capability */
if (siConEvnt->txMedReq.eh.pres) {
if (siConEvnt->txMedReq.trMedReq.pres) {
@ -206,6 +210,10 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
sprintf(nadi, "%d", siConEvnt->cdPtyNum.natAddrInd.val);
sngss7_add_var(sngss7_info, "ss7_cld_nadi", nadi);
if (sngss7_info->circuit->transparent_iam) {
sngss7_save_iam(ftdmchan, siConEvnt);
}
/* check if a COT test is requested */
if ((siConEvnt->natConInd.eh.pres) &&
(siConEvnt->natConInd.contChkInd.pres) &&
@ -229,7 +237,6 @@ ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circ
siConEvnt->cgPtyNum.natAddrInd.val,
ftdmchan->caller_data.dnis.digits,
siConEvnt->cdPtyNum.natAddrInd.val);
} /* if (channel is usable */
break;

View File

@ -42,6 +42,7 @@
static sng_isup_event_interface_t sng_event;
static ftdm_io_interface_t g_ftdm_sngss7_interface;
ftdm_sngss7_data_t g_ftdm_sngss7_data;
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
@ -509,11 +510,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
SS7_DEBUG_CHAN(ftdmchan, "ftmod_sangoma_ss7 processing state %s\n", ftdm_channel_state2str (ftdmchan->state));
#if 0
/* clear the state change flag...since we might be setting a new state */
ftdm_channel_complete_state(ftdmchan);
#endif
/*check what state we are supposed to be in */
switch (ftdmchan->state) {
/**************************************************************************/
@ -674,9 +670,6 @@ ftdm_status_t ftdm_sangoma_ss7_process_state_change (ftdm_channel_t * ftdmchan)
} else {
/*INBOUND...so FS told us it was going to answer...tell the stack */
ft_to_sngss7_anm(ftdmchan);
#if 1 /* DAVIDY */
ft_to_sngss7_itx(ftdmchan);
#endif
}
break;

View File

@ -60,6 +60,13 @@
#define MAX_SIZEOF_SUBADDR_IE 24 /* as per Q931 4.5.9 */
typedef struct ftdm2trillium
{
uint8_t ftdm_val;
uint8_t trillium_val;
}ftdm2trillium_t;
typedef enum {
SNGSS7_CON_IND_EVENT = 0,
SNGSS7_CON_CFM_EVENT,
@ -332,6 +339,7 @@ typedef struct sng_isup_ckt {
uint32_t min_digits;
uint8_t itx_auto_reply;
uint8_t transparent_iam;
void *obj;
uint16_t t3;
uint16_t t12;
@ -399,6 +407,7 @@ typedef struct sng_ss7_cfg {
uint32_t procId;
char license[MAX_PATH];
char signature[MAX_PATH];
uint32_t transparent_iam_max_size;
uint32_t flags;
sng_relay_t relay[MAX_RELAY_CHANNELS+1];
sng_mtp1_link_t mtp1Link[MAX_MTP_LINKS+1];
@ -758,6 +767,10 @@ void sngss7_resm_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiR
void sngss7_susp_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiSuspEvnt *siSuspEvnt);
void sngss7_ssp_sta_cfm(uint32_t infId);
ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt);
ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt);
ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt);
/* in ftmod_sangoma_ss7_handle.c */
ftdm_status_t handle_con_ind(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiConEvnt *siConEvnt);
ftdm_status_t handle_con_sta(uint32_t suInstId, uint32_t spInstId, uint32_t circuit, SiCnStEvnt *siCnStEvnt, uint8_t evntType);
@ -806,6 +819,13 @@ ftdm_status_t copy_redirgNum_to_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *red
ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *redirgNum);
ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb);
ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat);
ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt);
ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd);
ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd);
ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq);
ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA);
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);
ftdm_status_t append_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven);

View File

@ -36,10 +36,8 @@
/******************************************************************************/
/* DEFINES ********************************************************************/
/******************************************************************************/
/* GLOBALS ********************************************************************/
/******************************************************************************/
/* PROTOTYPES *****************************************************************/
void ft_to_sngss7_iam(ftdm_channel_t * ftdmchan);
@ -66,221 +64,70 @@ void ft_to_sngss7_cgu(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgba(ftdm_channel_t * ftdmchan);
void ft_to_sngss7_cgua(ftdm_channel_t * ftdmchan);
/******************************************************************************/
/* FUNCTIONS ******************************************************************/
void ft_to_sngss7_iam (ftdm_channel_t * ftdmchan)
{
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
const char *clg_subAddr = NULL;
const char *cld_subAddr = NULL;
char subAddrIE[MAX_SIZEOF_SUBADDR_IE];
{
SiConEvnt iam;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;;
SS7_FUNC_TRACE_ENTER (__FUNCTION__);
sngss7_info->suInstId = get_unique_id ();
sngss7_info->spInstId = 0;
sngss7_info->spId = 1;
memset (&iam, 0x0, sizeof (iam));
/* copy down the nature of connection indicators */
iam.natConInd.eh.pres = PRSNT_NODEF;
iam.natConInd.satInd.pres = PRSNT_NODEF;
iam.natConInd.satInd.val = 0; /* no satellite circuit */
iam.natConInd.contChkInd.pres = PRSNT_NODEF;
iam.natConInd.contChkInd.val = CONTCHK_NOTREQ;
iam.natConInd.echoCntrlDevInd.pres = PRSNT_NODEF;
iam.natConInd.echoCntrlDevInd.val = ECHOCDEV_INCL;
/* copy down the forward call indicators */
iam.fwdCallInd.eh.pres = PRSNT_NODEF;
iam.fwdCallInd.natIntCallInd.pres = PRSNT_NODEF;
iam.fwdCallInd.natIntCallInd.val = 0x00;
iam.fwdCallInd.end2EndMethInd.pres = PRSNT_NODEF;
iam.fwdCallInd.end2EndMethInd.val = E2EMTH_NOMETH;
iam.fwdCallInd.intInd.pres = PRSNT_NODEF;
iam.fwdCallInd.intInd.val = INTIND_NOINTW;
iam.fwdCallInd.end2EndInfoInd.pres = PRSNT_NODEF;
iam.fwdCallInd.end2EndInfoInd.val = E2EINF_NOINFO;
iam.fwdCallInd.isdnUsrPrtInd.pres = PRSNT_NODEF;
iam.fwdCallInd.isdnUsrPrtInd.val = ISUP_USED;
iam.fwdCallInd.isdnUsrPrtPrfInd.pres = PRSNT_NODEF;
iam.fwdCallInd.isdnUsrPrtPrfInd.val = PREF_PREFAW;
iam.fwdCallInd.isdnAccInd.pres = PRSNT_NODEF;
iam.fwdCallInd.isdnAccInd.val = ISDNACC_ISDN;
iam.fwdCallInd.sccpMethInd.pres = PRSNT_NODEF;
iam.fwdCallInd.sccpMethInd.val = SCCPMTH_NOIND;
/* copy down the calling number information */
iam.cgPtyCat.eh.pres = PRSNT_NODEF;
iam.cgPtyCat.cgPtyCat.pres = PRSNT_NODEF;
iam.cgPtyCat.cgPtyCat.val = CAT_ORD; /* ordinary suscriber */
/* copy down the transmission medium requirements */
iam.txMedReq.eh.pres = PRSNT_NODEF;
iam.txMedReq.trMedReq.pres = PRSNT_NODEF;
iam.txMedReq.trMedReq.val = ftdmchan->caller_data.bearer_capability;
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)) {
if (sngss7_info->circuit->transparent_iam &&
sngss7_retrieve_iam(ftdmchan, &iam) == FTDM_SUCCESS) {
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM (Transparent)\n", sngss7_info->circuit->cic);
} else {
/* Nature of Connection Indicators */
copy_natConInd_to_sngss7(ftdmchan, &iam.natConInd);
/* include only if we're running ANSI */
iam.fwdCallInd.transCallNInd.pres = PRSNT_NODEF;
iam.fwdCallInd.transCallNInd.val = 0x0;
/* Forward Call Indicators */
copy_fwdCallInd_to_sngss7(ftdmchan, &iam.fwdCallInd);
iam.usrServInfoA.eh.pres = PRSNT_NODEF;
/* Transmission medium requirements */
copy_txMedReq_to_sngss7(ftdmchan, &iam.txMedReq);
iam.usrServInfoA.infoTranCap.pres = PRSNT_NODEF;
switch (ftdmchan->caller_data.bearer_capability) {
/**********************************************************************/
case (FTDM_BEARER_CAP_SPEECH):
iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
iam.usrServInfoA.infoTranCap.val = 0x8; /* unrestricted digital as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
case (FTDM_BEARER_CAP_3_1KHZ_AUDIO):
iam.usrServInfoA.infoTranCap.val = 0x10; /* 3.1kHz audio as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
default:
SS7_ERROR_CHAN(ftdmchan, "Unknown Bearer capability falling back to speech%s\n", " ");
iam.usrServInfoA.infoTranCap.val = 0x0; /* speech as per ATIS-1000113.3.2005 */
break;
/**********************************************************************/
} /* switch (ftdmchan->caller_data.bearer_capability) */
iam.usrServInfoA.cdeStand.pres = PRSNT_NODEF;
iam.usrServInfoA.cdeStand.val = 0x0; /* ITU-T standardized coding */
iam.usrServInfoA.tranMode.pres = PRSNT_NODEF;
iam.usrServInfoA.tranMode.val = 0x0; /* circuit mode */
iam.usrServInfoA.infoTranRate0.pres = PRSNT_NODEF;
iam.usrServInfoA.infoTranRate0.val = 0x10; /* 64kbps origination to destination */
iam.usrServInfoA.infoTranRate1.pres = PRSNT_NODEF;
iam.usrServInfoA.infoTranRate1.val = 0x10; /* 64kbps destination to origination */
iam.usrServInfoA.chanStruct.pres = PRSNT_NODEF;
iam.usrServInfoA.chanStruct.val = 0x1; /* 8kHz integrity */
iam.usrServInfoA.config.pres = PRSNT_NODEF;
iam.usrServInfoA.config.val = 0x0; /* point to point configuration */
iam.usrServInfoA.establish.pres = PRSNT_NODEF;
iam.usrServInfoA.establish.val = 0x0; /* on demand */
iam.usrServInfoA.symmetry.pres = PRSNT_NODEF;
iam.usrServInfoA.symmetry.val = 0x0; /* bi-directional symmetric */
iam.usrServInfoA.usrInfLyr1Prot.pres = PRSNT_NODEF;
iam.usrServInfoA.usrInfLyr1Prot.val = 0x2; /* G.711 ulaw */
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, &iam.cdPtyNum);
/* copy down the calling number information */
copy_cgPtyNum_to_sngss7 (ftdmchan, &iam.cgPtyNum);
/* copy down the generic number information */
copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
/* TODO - move this to copy_clg_subAddr_to_sngss7 function */
/* check if the user would like us to send a clg_sub-address */
clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr");
if (!ftdm_strlen_zero(clg_subAddr)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
/* User Service Info A */
copy_usrServInfoA_to_sngss7(ftdmchan, &iam.usrServInfoA);
/* clean out the subAddrIE */
memset(subAddrIE, 0x0, sizeof(subAddrIE));
/* Called Number information */
copy_cdPtyNum_to_sngss7(ftdmchan, &iam.cdPtyNum);
/* Calling Number information */
copy_cgPtyNum_to_sngss7(ftdmchan, &iam.cgPtyNum);
/* check the first character in the sub-address to see what type of encoding to use */
switch (clg_subAddr[0]) {
case '0': /* NSAP */
encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
break;
case '1': /* national variant */
encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
break;
default:
SS7_ERROR_CHAN(ftdmchan,"Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
break;
} /* switch (cld_subAddr[0]) */
/* Generic Number information */
copy_genNmb_to_sngss7(ftdmchan, &iam.genNmb);
/* Calling Party's Category */
copy_cgPtyCat_to_sngss7(ftdmchan, &iam.cgPtyCat);
/* if subaddIE is still empty don't copy it in */
if (subAddrIE[0] != '0') {
/* check if the clg_subAddr has already been added */
if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
/* append the subAddrIE */
memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
} else {
/* fill in from the beginning */
iam.accTrnspt.eh.pres = PRSNT_NODEF;
iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
} /* if (iam.accTrnspt.eh.pres */
} /* if (subAddrIE[0] != '0') */
/* Redirecting Number */
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* Access Transport */
copy_accTrnspt_to_sngss7(ftdmchan, &iam.accTrnspt);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
sngss7_info->circuit->cic,
ftdmchan->caller_data.cid_num.digits,
iam.cgPtyNum.natAddrInd.val,
ftdmchan->caller_data.dnis.digits,
iam.cdPtyNum.natAddrInd.val);
}
copy_redirgNum_to_sngss7(ftdmchan, &iam.redirgNum);
/* check if the user would like us to send a cld_sub-address */
cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr");
if ((cld_subAddr != NULL) && (*cld_subAddr)) {
SS7_DEBUG_CHAN(ftdmchan,"Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
/* clean out the subAddrIE */
memset(subAddrIE, 0x0, sizeof(subAddrIE));
/* check the first character in the sub-address to see what type of encoding to use */
switch (cld_subAddr[0]) {
case '0': /* NSAP */
encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
break;
case '1': /* national variant */
encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
break;
default:
SS7_ERROR_CHAN(ftdmchan,"Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
break;
} /* switch (cld_subAddr[0]) */
/* if subaddIE is still empty don't copy it in */
if (subAddrIE[0] != '0') {
/* check if the cld_subAddr has already been added */
if (iam.accTrnspt.eh.pres == PRSNT_NODEF) {
/* append the subAddrIE */
memcpy(&iam.accTrnspt.infoElmts.val[iam.accTrnspt.infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = iam.accTrnspt.infoElmts.len +subAddrIE[1] + 2;
} else {
/* fill in from the beginning */
iam.accTrnspt.eh.pres = PRSNT_NODEF;
iam.accTrnspt.infoElmts.pres = PRSNT_NODEF;
memcpy(iam.accTrnspt.infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
iam.accTrnspt.infoElmts.len = subAddrIE[1] + 2;
} /* if (iam.accTrnspt.eh.pres */
} /* if (subAddrIE[0] != '0') */
} /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
sng_cc_con_request (sngss7_info->spId,
sngss7_info->suInstId,
sngss7_info->spInstId,
sngss7_info->circuit->id,
&iam,
sngss7_info->circuit->id,
&iam,
0);
SS7_INFO_CHAN(ftdmchan,"[CIC:%d]Tx IAM clg = \"%s\" (NADI=%d), cld = \"%s\" (NADI=%d)\n",
sngss7_info->circuit->cic,
ftdmchan->caller_data.cid_num.digits,
iam.cgPtyNum.natAddrInd.val,
ftdmchan->caller_data.dnis.digits,
iam.cdPtyNum.natAddrInd.val);
SS7_FUNC_TRACE_EXIT (__FUNCTION__);
return;
}
@ -321,7 +168,7 @@ void ft_to_sngss7_acm (ftdm_channel_t * ftdmchan)
acm.bckCallInd.echoCtrlDevInd.val = 0x1;
break;
/**********************************************************************/
case (FTDM_BEARER_CAP_64K_UNRESTRICTED):
case (FTDM_BEARER_CAP_UNRESTRICTED):
acm.bckCallInd.echoCtrlDevInd.val = 0x0;
break;
/**********************************************************************/

View File

@ -33,6 +33,9 @@
/* INCLUDE ********************************************************************/
#include "ftmod_sangoma_ss7_main.h"
#ifdef HAVE_ZLIB
#include <zlib.h>
#endif
/******************************************************************************/
/* DEFINES ********************************************************************/
@ -91,9 +94,60 @@ FTDM_ENUM_NAMES(BLK_FLAGS_NAMES, BLK_FLAGS_STRING)
FTDM_STR2ENUM(ftmod_ss7_blk_state2flag, ftmod_ss7_blk_flag2str, sng_ckt_block_flag_t, BLK_FLAGS_NAMES, 31)
/* FUNCTIONS ******************************************************************/
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val);
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val);
/* Maps generic FreeTDM CPC codes to SS7 CPC codes */
ftdm2trillium_t cpc_codes[] = {
{FTDM_CPC_UNKNOWN, CAT_UNKNOWN},
{FTDM_CPC_OPERATOR_FRENCH, CAT_OPLANGFR},
{FTDM_CPC_OPERATOR_ENGLISH, CAT_OPLANGENG},
{FTDM_CPC_OPERATOR_GERMAN, CAT_OPLANGGER},
{FTDM_CPC_OPERATOR_RUSSIAN, CAT_OPLANGRUS},
{FTDM_CPC_OPERATOR_SPANISH, CAT_OPLANGSP},
{FTDM_CPC_ORDINARY, CAT_ORD},
{FTDM_CPC_PRIORITY, CAT_PRIOR},
{FTDM_CPC_DATA, CAT_DATA},
{FTDM_CPC_TEST, CAT_TEST},
{FTDM_CPC_PAYPHONE, CAT_PAYPHONE},
};
ftdm2trillium_t bc_cap_codes[] = {
{FTDM_BEARER_CAP_SPEECH, ITC_SPEECH}, /* speech as per ATIS-1000113.3.2005 */
{FTDM_BEARER_CAP_UNRESTRICTED, ITC_UNRDIG}, /* unrestricted digital as per ATIS-1000113.3.2005 */
{FTDM_BEARER_CAP_RESTRICTED, ITC_UNRDIG}, /* Restricted Digital */
{FTDM_BEARER_CAP_3_1KHZ_AUDIO, ITC_A31KHZ}, /* 3.1kHz audio as per ATIS-1000113.3.2005 */
{FTDM_BEARER_CAP_7KHZ_AUDIO, ITC_A7KHZ}, /* 7Khz audio */
{FTDM_BEARER_CAP_15KHZ_AUDIO, ITC_A15KHZ}, /* 15Khz audio */
{FTDM_BEARER_CAP_VIDEO, ITC_VIDEO}, /* Video */
};
static uint8_t get_trillium_val(ftdm2trillium_t *vals, uint8_t ftdm_val, uint8_t default_val)
{
ftdm2trillium_t *val = vals;
while(val++) {
if (val->ftdm_val == ftdm_val) {
return val->trillium_val;
}
}
return default_val;
}
static uint8_t get_ftdm_val(ftdm2trillium_t *vals, uint8_t trillium_val, uint8_t default_val)
{
ftdm2trillium_t *val = vals;
while(val++) {
if (val->trillium_val == trillium_val) {
return val->ftdm_val;
}
}
return default_val;
}
ftdm_status_t copy_cgPtyNum_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyNum *cgPtyNum)
{
return FTDM_SUCCESS;
}
@ -174,7 +228,6 @@ ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb)
{
const char *val = NULL;
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
val = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_gn_digits");
if (!ftdm_strlen_zero(val)) {
@ -183,9 +236,9 @@ ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb)
return FTDM_FAIL;
}
} else {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number qualifier \"%s\"\n", val);
return FTDM_SUCCESS;
}
genNmb->eh.pres = PRSNT_NODEF;
genNmb->addrSig.pres = PRSNT_NODEF;
@ -243,7 +296,6 @@ ftdm_status_t copy_genNmb_to_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb)
genNmb->niInd.val = g_ftdm_sngss7_data.cfg.isupCkt[sngss7_info->circuit->id].gn_num_inc_ind;
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "No user supplied Generic Number \"number incomplete indicator\" \"%d\"\n", genNmb->niInd.val);
}
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
@ -251,7 +303,6 @@ ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb
{
char val[64];
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
SS7_FUNC_TRACE_ENTER(__FUNCTION__);
memset(val, 0, sizeof(val));
@ -301,7 +352,6 @@ ftdm_status_t copy_genNmb_from_sngss7(ftdm_channel_t *ftdmchan, SiGenNum *genNmb
sngss7_add_var(sngss7_info, "ss7_gn_num_inc_ind", val);
}
SS7_FUNC_TRACE_EXIT(__FUNCTION__);
return FTDM_SUCCESS;
}
@ -423,6 +473,212 @@ ftdm_status_t copy_redirgNum_from_sngss7(ftdm_channel_t *ftdmchan, SiRedirNum *r
return FTDM_SUCCESS;
}
ftdm_status_t copy_cgPtyCat_to_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat)
{
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
cgPtyCat->eh.pres = PRSNT_NODEF;
cgPtyCat->cgPtyCat.pres = PRSNT_NODEF;
cgPtyCat->cgPtyCat.val = get_trillium_val(cpc_codes, caller_data->cpc, CAT_ORD);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Category:0x%x\n",cgPtyCat->cgPtyCat.val);
return FTDM_SUCCESS;
}
ftdm_status_t copy_cgPtyCat_from_sngss7(ftdm_channel_t *ftdmchan, SiCgPtyCat *cgPtyCat)
{
ftdm_caller_data_t *caller_data = &ftdmchan->caller_data;
if (cgPtyCat->eh.pres == PRSNT_NODEF &&
cgPtyCat->cgPtyCat.pres == PRSNT_NODEF) {
caller_data->cpc = get_ftdm_val(cpc_codes, cgPtyCat->cgPtyCat.val, FTDM_CPC_UNKNOWN);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Calling Party Category:0x%x\n", cgPtyCat->cgPtyCat.val);
}
return FTDM_SUCCESS;
}
ftdm_status_t copy_accTrnspt_to_sngss7(ftdm_channel_t *ftdmchan, SiAccTrnspt *accTrnspt)
{
const char *clg_subAddr = NULL;
const char *cld_subAddr = NULL;
char subAddrIE[MAX_SIZEOF_SUBADDR_IE];
/* check if the user would like us to send a clg_sub-address */
clg_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_clg_subaddr");
if (!ftdm_strlen_zero(clg_subAddr)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Calling Sub-Address value \"%s\"\n", clg_subAddr);
/* clean out the subAddrIE */
memset(subAddrIE, 0x0, sizeof(subAddrIE));
/* check the first character in the sub-address to see what type of encoding to use */
switch (clg_subAddr[0]) {
case '0': /* NSAP */
encode_subAddrIE_nsap(&clg_subAddr[1], subAddrIE, SNG_CALLING);
break;
case '1': /* national variant */
encode_subAddrIE_nat(&clg_subAddr[1], subAddrIE, SNG_CALLING);
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid Calling Sub-Address encoding requested: %c\n", clg_subAddr[0]);
break;
} /* switch (cld_subAddr[0]) */
/* if subaddIE is still empty don't copy it in */
if (subAddrIE[0] != '0') {
/* check if the clg_subAddr has already been added */
if (accTrnspt->eh.pres == PRSNT_NODEF) {
/* append the subAddrIE */
memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
accTrnspt->infoElmts.len = accTrnspt->infoElmts.len +subAddrIE[1] + 2;
} else {
/* fill in from the beginning */
accTrnspt->eh.pres = PRSNT_NODEF;
accTrnspt->infoElmts.pres = PRSNT_NODEF;
memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
accTrnspt->infoElmts.len = subAddrIE[1] + 2;
}
}
}
/* check if the user would like us to send a cld_sub-address */
cld_subAddr = ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_cld_subaddr");
if ((cld_subAddr != NULL) && (*cld_subAddr)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Found user supplied Called Sub-Address value \"%s\"\n", cld_subAddr);
/* clean out the subAddrIE */
memset(subAddrIE, 0x0, sizeof(subAddrIE));
/* check the first character in the sub-address to see what type of encoding to use */
switch (cld_subAddr[0]) {
case '0': /* NSAP */
encode_subAddrIE_nsap(&cld_subAddr[1], subAddrIE, SNG_CALLED);
break;
case '1': /* national variant */
encode_subAddrIE_nat(&cld_subAddr[1], subAddrIE, SNG_CALLED);
break;
default:
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Invalid Called Sub-Address encoding requested: %c\n", cld_subAddr[0]);
break;
} /* switch (cld_subAddr[0]) */
/* if subaddIE is still empty don't copy it in */
if (subAddrIE[0] != '0') {
/* check if the cld_subAddr has already been added */
if (accTrnspt->eh.pres == PRSNT_NODEF) {
/* append the subAddrIE */
memcpy(&accTrnspt->infoElmts.val[accTrnspt->infoElmts.len], subAddrIE, (subAddrIE[1] + 2));
accTrnspt->infoElmts.len = accTrnspt->infoElmts.len +subAddrIE[1] + 2;
} else {
/* fill in from the beginning */
accTrnspt->eh.pres = PRSNT_NODEF;
accTrnspt->infoElmts.pres = PRSNT_NODEF;
memcpy(accTrnspt->infoElmts.val, subAddrIE, (subAddrIE[1] + 2));
accTrnspt->infoElmts.len = subAddrIE[1] + 2;
}
}
} /* if ((cld_subAddr != NULL) && (*cld_subAddr)) */
return FTDM_SUCCESS;
}
ftdm_status_t copy_natConInd_to_sngss7(ftdm_channel_t *ftdmchan, SiNatConInd *natConInd)
{
/* copy down the nature of connection indicators */
natConInd->eh.pres = PRSNT_NODEF;
natConInd->satInd.pres = PRSNT_NODEF;
natConInd->satInd.val = 0; /* no satellite circuit */
natConInd->contChkInd.pres = PRSNT_NODEF;
natConInd->contChkInd.val = CONTCHK_NOTREQ;
natConInd->echoCntrlDevInd.pres = PRSNT_NODEF;
natConInd->echoCntrlDevInd.val = ECHOCDEV_INCL;
return FTDM_SUCCESS;
}
ftdm_status_t copy_fwdCallInd_to_sngss7(ftdm_channel_t *ftdmchan, SiFwdCallInd *fwdCallInd)
{
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
fwdCallInd->eh.pres = PRSNT_NODEF;
fwdCallInd->natIntCallInd.pres = PRSNT_NODEF;
fwdCallInd->natIntCallInd.val = 0x00;
fwdCallInd->end2EndMethInd.pres = PRSNT_NODEF;
fwdCallInd->end2EndMethInd.val = E2EMTH_NOMETH;
fwdCallInd->intInd.pres = PRSNT_NODEF;
fwdCallInd->intInd.val = INTIND_NOINTW;
fwdCallInd->end2EndInfoInd.pres = PRSNT_NODEF;
fwdCallInd->end2EndInfoInd.val = E2EINF_NOINFO;
fwdCallInd->isdnUsrPrtInd.pres = PRSNT_NODEF;
fwdCallInd->isdnUsrPrtInd.val = ISUP_USED;
fwdCallInd->isdnUsrPrtPrfInd.pres = PRSNT_NODEF;
fwdCallInd->isdnUsrPrtPrfInd.val = PREF_PREFAW;
fwdCallInd->isdnAccInd.pres = PRSNT_NODEF;
fwdCallInd->isdnAccInd.val = ISDNACC_ISDN;
fwdCallInd->sccpMethInd.pres = PRSNT_NODEF;
fwdCallInd->sccpMethInd.val = SCCPMTH_NOIND;
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 */
fwdCallInd->transCallNInd.pres = PRSNT_NODEF;
fwdCallInd->transCallNInd.val = 0x0;
}
return FTDM_SUCCESS;
}
ftdm_status_t copy_txMedReq_to_sngss7(ftdm_channel_t *ftdmchan, SiTxMedReq *txMedReq)
{
txMedReq->eh.pres = PRSNT_NODEF;
txMedReq->trMedReq.pres = PRSNT_NODEF;
txMedReq->trMedReq.val = ftdmchan->caller_data.bearer_capability;
return FTDM_SUCCESS;
}
ftdm_status_t copy_usrServInfoA_to_sngss7(ftdm_channel_t *ftdmchan, SiUsrServInfo *usrServInfoA)
{
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
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)) {
usrServInfoA->eh.pres = PRSNT_NODEF;
usrServInfoA->infoTranCap.pres = PRSNT_NODEF;
usrServInfoA->infoTranCap.val = get_trillium_val(bc_cap_codes, ftdmchan->caller_data.bearer_capability, ITC_SPEECH);
usrServInfoA->cdeStand.pres = PRSNT_NODEF;
usrServInfoA->cdeStand.val = 0x0; /* ITU-T standardized coding */
usrServInfoA->tranMode.pres = PRSNT_NODEF;
usrServInfoA->tranMode.val = 0x0; /* circuit mode */
usrServInfoA->infoTranRate0.pres = PRSNT_NODEF;
usrServInfoA->infoTranRate0.val = 0x10; /* 64kbps origination to destination */
usrServInfoA->infoTranRate1.pres = PRSNT_NODEF;
usrServInfoA->infoTranRate1.val = 0x10; /* 64kbps destination to origination */
usrServInfoA->chanStruct.pres = PRSNT_NODEF;
usrServInfoA->chanStruct.val = 0x1; /* 8kHz integrity */
usrServInfoA->config.pres = PRSNT_NODEF;
usrServInfoA->config.val = 0x0; /* point to point configuration */
usrServInfoA->establish.pres = PRSNT_NODEF;
usrServInfoA->establish.val = 0x0; /* on demand */
usrServInfoA->symmetry.pres = PRSNT_NODEF;
usrServInfoA->symmetry.val = 0x0; /* bi-directional symmetric */
usrServInfoA->usrInfLyr1Prot.pres = PRSNT_NODEF;
usrServInfoA->usrInfLyr1Prot.val = 0x2; /* G.711 ulaw */
usrServInfoA->rateMultiplier.pres = PRSNT_NODEF;
usrServInfoA->rateMultiplier.val = 0x1; /* 1x rate multipler */
} /* if ANSI */
return FTDM_SUCCESS;
}
ftdm_status_t copy_tknStr_from_sngss7(TknStr str, char *ftdm, TknU8 oddEven)
{
uint8_t i;
@ -524,10 +780,17 @@ ftdm_status_t copy_tknStr_to_sngss7(char* val, TknStr *tknStr, TknU8 *oddEven)
/* check if the digit is a number and that is not null */
while (!(isxdigit(tmp[0])) && (tmp[0] != '\0')) {
SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
/* move on to the next value */
k++;
tmp[0] = val[k];
if (tmp[0] == '*') {
/* Could not find a spec that specifies this , but on customer system, * was transmitted as 0x0b */
SS7_DEBUG("Replacing * with 0x0b");
k++;
tmp[0] = 0x0b;
} else {
SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
/* move on to the next value */
k++;
tmp[0] = val[k];
}
} /* while(!(isdigit(tmp))) */
/* check if tmp is null or a digit */
@ -648,8 +911,6 @@ int check_cics_in_range(sngss7_chan_data_t *sngss7_info)
/******************************************************************************/
ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_info, ftdm_channel_t **ftdmchan)
{
/*SS7_FUNC_TRACE_ENTER(__FUNCTION__);*/
if (g_ftdm_sngss7_data.cfg.isupCkt[circuit].obj == NULL) {
SS7_ERROR("sngss7_info is Null for circuit #%d\n", circuit);
return FTDM_FAIL;
@ -662,7 +923,6 @@ ftdm_status_t extract_chan_data(uint32_t circuit, sngss7_chan_data_t **sngss7_in
ftdm_assert_return((*sngss7_info)->ftdmchan, FTDM_FAIL, "received message on signalling link or non-configured cic\n");
*ftdmchan = (*sngss7_info)->ftdmchan;
/*SS7_FUNC_TRACE_EXIT(__FUNCTION__);*/
return FTDM_SUCCESS;
}
@ -1291,10 +1551,17 @@ ftdm_status_t encode_subAddrIE_nat(const char *subAddr, char *subAddrIE, int typ
/* confirm it is a hex digit */
while ((!isxdigit(tmp[0])) && (tmp[0] != '\0')) {
SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
/* move to the next character in subAddr */
x++;
tmp[0] = subAddr[x];
if (tmp[0] == '*') {
/* Could not find a spec that specifies this, but on customer system, * was transmitted as 0x0b */
SS7_DEBUG("Replacing * with 0x0b");
x++;
tmp[0] = 0x0b;
} else {
SS7_INFO("Dropping invalid digit: %c\n", tmp[0]);
/* move to the next character in subAddr */
x++;
tmp[0] = subAddr[x];
}
}
/* check if tmp is null or a digit */
@ -1651,7 +1918,7 @@ void sngss7_set_sig_status(sngss7_chan_data_t *sngss7_info, ftdm_signaling_statu
sig.ev_data.sigstatus.status = status;
if (ftdm_span_send_signal(ftdmchan->span, &sig) != FTDM_SUCCESS) {
SS7_ERROR_CHAN(ftdmchan, "Failed to change channel status to %s\n",
ftdm_log_chan(ftdmchan, FTDM_LOG_ERROR, "Failed to change channel status to %s\n",
ftdm_signaling_status2str(status));
}
return;
@ -1826,6 +2093,336 @@ ftdm_status_t check_for_reconfig_flag(ftdm_span_t *ftdmspan)
return FTDM_SUCCESS;
}
ftdm_status_t sngss7_bufferzero_iam(SiConEvnt *siConEvnt)
{
if (siConEvnt->natConInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natConInd, 0, sizeof(siConEvnt->natConInd));
if (siConEvnt->fwdCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdCallInd, 0, sizeof(siConEvnt->fwdCallInd));
if (siConEvnt->cgPtyCat.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyCat, 0, sizeof(siConEvnt->cgPtyCat));
if (siConEvnt->txMedReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedReq, 0, sizeof(siConEvnt->txMedReq));
#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL)
if (siConEvnt->usrServInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfoA, 0, sizeof(siConEvnt->usrServInfoA));
#endif
if (siConEvnt->cdPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdPtyNum, 0, sizeof(siConEvnt->cdPtyNum));
#if TNS_ANSI
#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL)
if (siConEvnt->tranNetSel1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel1, 0, sizeof(siConEvnt->tranNetSel1));
#endif
#endif
if (siConEvnt->tranNetSel.eh.pres != PRSNT_NODEF) memset(&siConEvnt->tranNetSel, 0, sizeof(siConEvnt->tranNetSel));
#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA)
if (siConEvnt->callRefA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRefA, 0, sizeof(siConEvnt->callRefA));
#endif
if (siConEvnt->callRef.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callRef, 0, sizeof(siConEvnt->callRef));
if (siConEvnt->cgPtyNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum, 0, sizeof(siConEvnt->cgPtyNum));
#if SS7_BELL
if (siConEvnt->cgPtyNumB.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumB, 0, sizeof(siConEvnt->cgPtyNumB));
#endif
if (siConEvnt->opFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalInd, 0, sizeof(siConEvnt->opFwdCalInd));
#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT)
if (siConEvnt->opFwdCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndQ, 0, sizeof(siConEvnt->opFwdCalIndQ));
#endif
#if SS7_Q767IT
if (siConEvnt->fwdVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->fwdVad, 0, sizeof(siConEvnt->fwdVad));
#endif
#if SS7_ANS88
if (siConEvnt->opFwdCalIndA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->opFwdCalIndA, 0, sizeof(siConEvnt->opFwdCalIndA));
#endif
if (siConEvnt->redirgNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirgNum, 0, sizeof(siConEvnt->redirgNum));
if (siConEvnt->redirInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfo, 0, sizeof(siConEvnt->redirInfo));
if (siConEvnt->cugIntCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCode, 0, sizeof(siConEvnt->cugIntCode));
#if SS7_ANS88
if (siConEvnt->cugIntCodeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cugIntCodeA, 0, sizeof(siConEvnt->cugIntCodeA));
#endif
#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL || SS7_CHINA)
if (siConEvnt->connReqA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReqA, 0, sizeof(siConEvnt->connReqA));
#endif
#if SS7_ANS88
if (siConEvnt->usr2UsrInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfoA, 0, sizeof(siConEvnt->usr2UsrInfoA));
#endif
if (siConEvnt->connReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connReq, 0, sizeof(siConEvnt->connReq));
if (siConEvnt->origCdNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCdNum, 0, sizeof(siConEvnt->origCdNum));
if (siConEvnt->usr2UsrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInfo, 0, sizeof(siConEvnt->usr2UsrInfo));
if (siConEvnt->accTrnspt.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accTrnspt, 0, sizeof(siConEvnt->accTrnspt));
if (siConEvnt->echoControl.eh.pres != PRSNT_NODEF) memset(&siConEvnt->echoControl, 0, sizeof(siConEvnt->echoControl));
#if SS7_ANS88
if (siConEvnt->redirInfoA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirInfoA, 0, sizeof(siConEvnt->redirInfoA));
#endif
#if (SS7_ANS88 || SS7_ANS92 || SS7_ANS95 || SS7_BELL)
if (siConEvnt->chargeNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->chargeNum, 0, sizeof(siConEvnt->chargeNum));
if (siConEvnt->origLineInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origLineInf, 0, sizeof(siConEvnt->origLineInf));
#endif
if (siConEvnt->usrServInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo, 0, sizeof(siConEvnt->usrServInfo));
if (siConEvnt->usr2UsrInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usr2UsrInd, 0, sizeof(siConEvnt->usr2UsrInd));
if (siConEvnt->propDly.eh.pres != PRSNT_NODEF) memset(&siConEvnt->propDly, 0, sizeof(siConEvnt->propDly));
if (siConEvnt->usrServInfo1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrServInfo1, 0, sizeof(siConEvnt->usrServInfo1));
if (siConEvnt->netFac.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netFac, 0, sizeof(siConEvnt->netFac));
#ifdef SS7_CHINA
if (siConEvnt->orgPteCdeA.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCdeA, 0, sizeof(siConEvnt->orgPteCdeA));
#endif
if (siConEvnt->orgPteCde.eh.pres != PRSNT_NODEF) memset(&siConEvnt->orgPteCde, 0, sizeof(siConEvnt->orgPteCde));
if (siConEvnt->genDigits.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigits, 0, sizeof(siConEvnt->genDigits));
if (siConEvnt->genDigitsR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genDigitsR, 0, sizeof(siConEvnt->genDigitsR));
if (siConEvnt->usrTSrvInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->usrTSrvInfo, 0, sizeof(siConEvnt->usrTSrvInfo));
if (siConEvnt->remotOper.eh.pres != PRSNT_NODEF) memset(&siConEvnt->remotOper, 0, sizeof(siConEvnt->remotOper));
if (siConEvnt->parmCom.eh.pres != PRSNT_NODEF) memset(&siConEvnt->parmCom, 0, sizeof(siConEvnt->parmCom));
#if (SS7_ANS92 || SS7_ANS95)
if (siConEvnt->servCode.eh.pres != PRSNT_NODEF) memset(&siConEvnt->servCode, 0, sizeof(siConEvnt->servCode));
#endif
#if SS7_ANS92
if (siConEvnt->serviceAct1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct1, 0, sizeof(siConEvnt->serviceAct1));
#endif
#if SS7_CHINA
if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2));
#endif
if (siConEvnt->serviceAct2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct2, 0, sizeof(siConEvnt->serviceAct2));
if (siConEvnt->serviceAct.eh.pres != PRSNT_NODEF) memset(&siConEvnt->serviceAct, 0, sizeof(siConEvnt->serviceAct));
if (siConEvnt->mlppPrec.eh.pres != PRSNT_NODEF) memset(&siConEvnt->mlppPrec, 0, sizeof(siConEvnt->mlppPrec));
#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT))
if (siConEvnt->txMedUsPr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->txMedUsPr, 0, sizeof(siConEvnt->txMedUsPr));
#endif
if (siConEvnt->bckCallInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->bckCallInd, 0, sizeof(siConEvnt->bckCallInd));
if (siConEvnt->cgPtyNum1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNum1, 0, sizeof(siConEvnt->cgPtyNum1));
if (siConEvnt->optBckCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalInd, 0, sizeof(siConEvnt->optBckCalInd));
#if (SS7_Q767 || SS7_RUSSIA || SS7_NTT)
if (siConEvnt->optBckCalIndQ.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optBckCalIndQ, 0, sizeof(siConEvnt->optBckCalIndQ));
#endif
if (siConEvnt->connNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum, 0, sizeof(siConEvnt->connNum));
#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT))
if (siConEvnt->connNum2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->connNum2, 0, sizeof(siConEvnt->connNum2));
#endif
if (siConEvnt->accDelInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->accDelInfo, 0, sizeof(siConEvnt->accDelInfo));
if (siConEvnt->notifInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd, 0, sizeof(siConEvnt->notifInd));
if (siConEvnt->notifIndR2.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR2, 0, sizeof(siConEvnt->notifIndR2));
if (siConEvnt->cllHstry.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cllHstry, 0, sizeof(siConEvnt->cllHstry));
if (siConEvnt->genNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmb, 0, sizeof(siConEvnt->genNmb));
if (siConEvnt->genNmbR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genNmbR, 0, sizeof(siConEvnt->genNmbR));
if (siConEvnt->redirNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirNum, 0, sizeof(siConEvnt->redirNum));
if (siConEvnt->redirRstr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirRstr, 0, sizeof(siConEvnt->redirRstr));
#if SS7_Q767IT
if (siConEvnt->backVad.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backVad, 0, sizeof(siConEvnt->backVad));
#endif
#if SS7_SINGTEL
if (siConEvnt->cgPtyNumS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cgPtyNumS, 0, sizeof(siConEvnt->cgPtyNumS));
#endif
#if (SS7_ANS92 || SS7_ANS95 || SS7_BELL)
if (siConEvnt->businessGrp.eh.pres != PRSNT_NODEF) memset(&siConEvnt->businessGrp, 0, sizeof(siConEvnt->businessGrp));
if (siConEvnt->infoInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoInd, 0, sizeof(siConEvnt->infoInd));
if (siConEvnt->carrierId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierId, 0, sizeof(siConEvnt->carrierId));
if (siConEvnt->carSelInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carSelInf, 0, sizeof(siConEvnt->carSelInf));
if (siConEvnt->egress.eh.pres != PRSNT_NODEF) memset(&siConEvnt->egress, 0, sizeof(siConEvnt->egress));
if (siConEvnt->genAddr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddr, 0, sizeof(siConEvnt->genAddr));
if (siConEvnt->genAddrR.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genAddrR, 0, sizeof(siConEvnt->genAddrR));
if (siConEvnt->infoReqInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->infoReqInd, 0, sizeof(siConEvnt->infoReqInd));
if (siConEvnt->jurisInf.eh.pres != PRSNT_NODEF) memset(&siConEvnt->jurisInf, 0, sizeof(siConEvnt->jurisInf));
if (siConEvnt->netTransport.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netTransport, 0, sizeof(siConEvnt->netTransport));
if (siConEvnt->specProcReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->specProcReq, 0, sizeof(siConEvnt->specProcReq));
if (siConEvnt->transReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->transReq, 0, sizeof(siConEvnt->transReq));
#endif
#if (defined(SIT_PARAMETER) || defined(TDS_ROLL_UPGRADE_SUPPORT))
#if (SS7_ANS92 || SS7_ANS95)
if (siConEvnt->notifInd1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifInd1, 0, sizeof(siConEvnt->notifInd1));
if (siConEvnt->notifIndR1.eh.pres != PRSNT_NODEF) memset(&siConEvnt->notifIndR1, 0, sizeof(siConEvnt->notifIndR1));
#endif /* SS7_ANS92 */
#endif /* SIT_PARAMETER || TDS_ROLL_UPGRADE_SUPPORT */
#if (SS7_BELL || SS7_ANS95)
if (siConEvnt->genName.eh.pres != PRSNT_NODEF) memset(&siConEvnt->genName, 0, sizeof(siConEvnt->genName));
#endif
#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \
SS7_BELL || SS7_ANS95 || SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ)
if (siConEvnt->hopCounter.eh.pres != PRSNT_NODEF) memset(&siConEvnt->hopCounter, 0, sizeof(siConEvnt->hopCounter));
#endif
#if (SS7_BELL || SS7_ITU2000 || SS7_KZ)
if (siConEvnt->redirCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCap, 0, sizeof(siConEvnt->redirCap));
if (siConEvnt->redirCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->redirCntr, 0, sizeof(siConEvnt->redirCntr));
#endif
#if (SS7_ETSI || SS7_FTZ)
if (siConEvnt->ccbsParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccbsParam, 0, sizeof(siConEvnt->ccbsParam));
if (siConEvnt->freePhParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->freePhParam, 0, sizeof(siConEvnt->freePhParam));
#endif
#ifdef SS7_FTZ
if (siConEvnt->naPaFF.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFF, 0, sizeof(siConEvnt->naPaFF));
if (siConEvnt->naPaFE.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaFE, 0, sizeof(siConEvnt->naPaFE));
if (siConEvnt->naPaSSP.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSSP, 0, sizeof(siConEvnt->naPaSSP));
if (siConEvnt->naPaCdPNO.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaCdPNO, 0, sizeof(siConEvnt->naPaCdPNO));
if (siConEvnt->naPaSPV.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaSPV, 0, sizeof(siConEvnt->naPaSPV));
if (siConEvnt->naPaUKK.eh.pres != PRSNT_NODEF) memset(&siConEvnt->naPaUKK, 0, sizeof(siConEvnt->naPaUKK));
#endif
#if SS7_NTT
if (siConEvnt->msgAreaInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->msgAreaInfo, 0, sizeof(siConEvnt->msgAreaInfo));
if (siConEvnt->subsNumber.eh.pres != PRSNT_NODEF) memset(&siConEvnt->subsNumber, 0, sizeof(siConEvnt->subsNumber));
if (siConEvnt->rpCllngNo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->rpCllngNo, 0, sizeof(siConEvnt->rpCllngNo));
if (siConEvnt->supplUserType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->supplUserType, 0, sizeof(siConEvnt->supplUserType));
if (siConEvnt->carrierInfoTrans.eh.pres != PRSNT_NODEF) memset(&siConEvnt->carrierInfoTrans, 0, sizeof(siConEvnt->carrierInfoTrans));
if (siConEvnt->nwFuncType.eh.pres != PRSNT_NODEF) memset(&siConEvnt->nwFuncType, 0, sizeof(siConEvnt->nwFuncType));
#endif
#if SS7_ANS95
if (siConEvnt->optrServicesInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->optrServicesInfo, 0, sizeof(siConEvnt->optrServicesInfo));
#endif
#if (SS7_ANS95 || SS7_ITU97 || SS7_RUSS2000|| SS7_ITU2000 || SS7_NZL || SS7_KZ)
if (siConEvnt->cirAsgnMap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cirAsgnMap, 0, sizeof(siConEvnt->cirAsgnMap));
#endif
#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_ETSIV3 || \
SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ)
if (siConEvnt->displayInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->displayInfo, 0, sizeof(siConEvnt->displayInfo));
if (siConEvnt->confTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->confTrtInd, 0, sizeof(siConEvnt->confTrtInd));
if (siConEvnt->netMgmtControls.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netMgmtControls, 0, sizeof(siConEvnt->netMgmtControls));
if (siConEvnt->correlationId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->correlationId, 0, sizeof(siConEvnt->correlationId));
if (siConEvnt->callDivTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callDivTrtInd, 0, sizeof(siConEvnt->callDivTrtInd));
if (siConEvnt->callInNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callInNmb, 0, sizeof(siConEvnt->callInNmb));
if (siConEvnt->callOfferTrtInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->callOfferTrtInd, 0, sizeof(siConEvnt->callOfferTrtInd));
if (siConEvnt->scfId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->scfId, 0, sizeof(siConEvnt->scfId));
if (siConEvnt->uidCapInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->uidCapInd, 0, sizeof(siConEvnt->uidCapInd));
if (siConEvnt->collCallReq.eh.pres != PRSNT_NODEF) memset(&siConEvnt->collCallReq, 0, sizeof(siConEvnt->collCallReq));
if (siConEvnt->ccss.eh.pres != PRSNT_NODEF) memset(&siConEvnt->ccss, 0, sizeof(siConEvnt->ccss));
#endif
#if (SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ)
if (siConEvnt->backGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->backGVNS, 0, sizeof(siConEvnt->backGVNS));
if (siConEvnt->forwardGVNS.eh.pres != PRSNT_NODEF) memset(&siConEvnt->forwardGVNS, 0, sizeof(siConEvnt->forwardGVNS));
#endif
#if (SS7_ETSIV3 || SS7_ITU97 || SS7_RUSS2000 || SS7_ITU2000 || \
SS7_INDIA || SS7_UK || SS7_NZL || SS7_KZ)
if (siConEvnt->appTransParam.eh.pres != PRSNT_NODEF) memset(&siConEvnt->appTransParam, 0, sizeof(siConEvnt->appTransParam));
#endif
#if (SS7_ITU2000 || SS7_UK || SS7_NZL || SS7_KZ)
if (siConEvnt->htrInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->htrInfo, 0, sizeof(siConEvnt->htrInfo));
if (siConEvnt->pivotCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCap, 0, sizeof(siConEvnt->pivotCap));
if (siConEvnt->cadDirNmb.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cadDirNmb, 0, sizeof(siConEvnt->cadDirNmb));
if (siConEvnt->origCallInNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->origCallInNum, 0, sizeof(siConEvnt->origCallInNum));
if (siConEvnt->calgGeoLoc.eh.pres != PRSNT_NODEF) memset(&siConEvnt->calgGeoLoc, 0, sizeof(siConEvnt->calgGeoLoc));
if (siConEvnt->netRoutNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->netRoutNum, 0, sizeof(siConEvnt->netRoutNum));
if (siConEvnt->qonRelCap.eh.pres != PRSNT_NODEF) memset(&siConEvnt->qonRelCap, 0, sizeof(siConEvnt->qonRelCap));
if (siConEvnt->pivotCntr.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotCntr, 0, sizeof(siConEvnt->pivotCntr));
if (siConEvnt->pivotRtgFwInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgFwInfo, 0, sizeof(siConEvnt->pivotRtgFwInfo));
if (siConEvnt->pivotRtgBkInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pivotRtgBkInfo, 0, sizeof(siConEvnt->pivotRtgBkInfo));
if (siConEvnt->numPortFwdInfo.eh.pres != PRSNT_NODEF) memset(&siConEvnt->numPortFwdInfo, 0, sizeof(siConEvnt->numPortFwdInfo));
#endif
#ifdef SS7_UK
if (siConEvnt->natFwdCalInd.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalInd, 0, sizeof(siConEvnt->natFwdCalInd));
if (siConEvnt->presntNum.eh.pres != PRSNT_NODEF) memset(&siConEvnt->presntNum, 0, sizeof(siConEvnt->presntNum));
if (siConEvnt->lstDvrtLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->lstDvrtLineId, 0, sizeof(siConEvnt->lstDvrtLineId));
if (siConEvnt->pcgLineId.eh.pres != PRSNT_NODEF) memset(&siConEvnt->pcgLineId, 0, sizeof(siConEvnt->pcgLineId));
if (siConEvnt->natFwdCalIndLnk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->natFwdCalIndLnk, 0, sizeof(siConEvnt->natFwdCalIndLnk));
if (siConEvnt->cdBascSrvcMrk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->cdBascSrvcMrk, 0, sizeof(siConEvnt->cdBascSrvcMrk));
#endif /* SS7_UK */
#if (defined(CGPN_CHK))
if (siConEvnt->causeDgnCgPnChk.eh.pres != PRSNT_NODEF) memset(&siConEvnt->causeDgnCgPnChk, 0, sizeof(siConEvnt->causeDgnCgPnChk));
#endif
return FTDM_SUCCESS;
}
ftdm_status_t sngss7_save_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
{
#ifndef HAVE_ZLIB
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n");
return FTDM_FAIL;
#else
unsigned ret_val = FTDM_FAIL;
char *compressed_iam = NULL;
char *url_encoded_iam = NULL;
uLongf len = sizeof(*siConEvnt);
sngss7_chan_data_t *sngss7_info = ftdmchan->call_data;
/* By default, Trillium does not memset their whole structure to zero for
* performance. But we want to memset all the IE's that are not present to
* optimize compressed size */
sngss7_bufferzero_iam(siConEvnt);
compressed_iam = ftdm_malloc(sizeof(*siConEvnt));
if (!compressed_iam) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocate buffer for compressed_iam\n");
goto done;
}
/* Compress IAM structure to minimize buffer size */
ret_val = compress((Bytef *)compressed_iam, &len, (const Bytef *)siConEvnt, (uLong)sizeof(*siConEvnt));
if (ret_val != Z_OK) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to compress IAM (error:%d)\n", ret_val);
ret_val = FTDM_FAIL;
goto done;
}
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", len);
/* Worst case: size will triple after url encode */
url_encoded_iam = ftdm_malloc(3*sizeof(*siConEvnt));
if (!url_encoded_iam) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Failed to allocated buffer for url_encoded_iam\n");
ret_val = FTDM_FAIL;
goto done;
}
memset(url_encoded_iam, 0, 2*sizeof(*siConEvnt));
/* URL encode buffer to that its safe to store it in a string */
ftdm_url_encode((const char*)compressed_iam, url_encoded_iam, len);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(url_encoded_iam));
if (strlen(url_encoded_iam) > g_ftdm_sngss7_data.cfg.transparent_iam_max_size) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "IAM variable length exceeds max size (len:%d max:%d) \n", strlen(url_encoded_iam), g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
ret_val = FTDM_FAIL;
goto done;
}
sngss7_add_var(sngss7_info, "ss7_iam", url_encoded_iam);
done:
ftdm_safe_free(compressed_iam);
ftdm_safe_free(url_encoded_iam);
return ret_val;
#endif
}
ftdm_status_t sngss7_retrieve_iam(ftdm_channel_t *ftdmchan, SiConEvnt *siConEvnt)
{
#ifndef HAVE_ZLIB
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_CRIT, "Cannot perform transparent IAM because zlib is missing\n");
return FTDM_FAIL;
#else
uLongf len = 3*sizeof(*siConEvnt); /* worst case: URL encoded buffer is 3x length of buffer */
char *val = NULL;
unsigned ret_val = FTDM_FAIL;
void *uncompressed_buffer = NULL;
char *url_encoded_iam = NULL;
ftdm_size_t url_encoded_iam_len;
val = (char*)ftdm_usrmsg_get_var(ftdmchan->usrmsg, "ss7_iam");
if (ftdm_strlen_zero(val)) {
ftdm_log_chan_msg(ftdmchan, FTDM_LOG_DEBUG, "No Transparent IAM info available\n");
return FTDM_FAIL;
}
url_encoded_iam = ftdm_strdup(val);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "IAM variable length:%d\n", strlen(val));
ftdm_url_decode(url_encoded_iam, &url_encoded_iam_len);
ftdm_log_chan(ftdmchan, FTDM_LOG_DEBUG, "Compressed IAM size:%d\n", url_encoded_iam_len);
uncompressed_buffer = ftdm_malloc(sizeof(*siConEvnt));
ftdm_assert_return(uncompressed_buffer, FTDM_FAIL, "Failed to allocate buffer for uncompressed buffer\n");
ret_val = uncompress(uncompressed_buffer, &len, (const Bytef *)url_encoded_iam, (uLong)url_encoded_iam_len);
if (ret_val != Z_OK) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Failed to uncompress IAM (error:%d)\n", ret_val);
goto done;
}
if (len != sizeof(*siConEvnt)) {
ftdm_log_chan(ftdmchan, FTDM_LOG_CRIT, "Incompatible IAM structure size (expected:%d size:%d)\n", sizeof(*siConEvnt), strlen(uncompressed_buffer));
goto done;
}
memcpy(siConEvnt, uncompressed_buffer, sizeof(*siConEvnt));
ret_val = FTDM_SUCCESS;
done:
ftdm_safe_free(uncompressed_buffer);
ftdm_safe_free(url_encoded_iam);
return ret_val;
#endif
}
/******************************************************************************/
/* For Emacs:
* Local Variables:

View File

@ -124,7 +124,8 @@ typedef struct sng_ccSpan
uint32_t cld_nadi;
uint32_t rdnis_nadi;
uint32_t min_digits;
uint32_t itx_auto_reply;
uint8_t itx_auto_reply;
uint8_t transparent_iam;
uint32_t t3;
uint32_t t12;
uint32_t t13;
@ -466,6 +467,9 @@ static int ftmod_ss7_parse_sng_gen(ftdm_conf_node_t *sng_gen)
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, "transparent_iam_max_size")) {
g_ftdm_sngss7_data.cfg.transparent_iam_max_size = atoi(parm->val);
SS7_DEBUG("Found a transparent_iam max size = %d\n", g_ftdm_sngss7_data.cfg.transparent_iam_max_size);
} else {
/**********************************************************************/
SS7_ERROR("Found an invalid parameter \"%s\"!\n", parm->val);
@ -1896,6 +1900,13 @@ static int ftmod_ss7_parse_cc_span(ftdm_conf_node_t *cc_span)
} else if (!strcasecmp(parm->var, "itx_auto_reply")) {
sng_ccSpan.itx_auto_reply = ftdm_true(parm->val);
SS7_DEBUG("Found itx_auto_reply %d\n", sng_ccSpan.itx_auto_reply);
} else if (!strcasecmp(parm->var, "transparent_iam")) {
#ifndef HAVE_ZLIB
SS7_CRIT("Cannot enable transparent IAM becauze zlib not installed\n");
#else
sng_ccSpan.transparent_iam = ftdm_true(parm->val);
SS7_DEBUG("Found transparent_iam %d\n", sng_ccSpan.transparent_iam);
#endif
} else if (!strcasecmp(parm->var, "cicbase")) {
/**********************************************************************/
sng_ccSpan.cicbase = atoi(parm->val);
@ -2907,16 +2918,17 @@ static int ftmod_ss7_fill_in_ccSpan(sng_ccSpan_t *ccSpan)
g_ftdm_sngss7_data.cfg.isupCkt[x].cic = 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].rdnis_nadi = ccSpan->rdnis_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;
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
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].rdnis_nadi = ccSpan->rdnis_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;
g_ftdm_sngss7_data.cfg.isupCkt[x].itx_auto_reply = ccSpan->itx_auto_reply;
g_ftdm_sngss7_data.cfg.isupCkt[x].transparent_iam = ccSpan->transparent_iam;
if (ccSpan->t3 == 0) {
g_ftdm_sngss7_data.cfg.isupCkt[x].t3 = 1200;

View File

@ -950,7 +950,6 @@ static void wanpipe_read_stats(ftdm_channel_t *ftdmchan, wp_tdm_api_rx_hdr_t *rx
static FIO_READ_FUNCTION(wanpipe_read)
{
int rx_len = 0;
int myerrno = 0;
wp_tdm_api_rx_hdr_t hdrframe;
memset(&hdrframe, 0, sizeof(hdrframe));
@ -964,7 +963,6 @@ static FIO_READ_FUNCTION(wanpipe_read)
}
if (rx_len < 0) {
myerrno = errno;
snprintf(ftdmchan->last_error, sizeof(ftdmchan->last_error), "%s", strerror(errno));
ftdm_log_chan(ftdmchan, FTDM_LOG_WARNING, "Failed to read from sangoma device: %s (%d)\n", strerror(errno), rx_len);
return FTDM_FAIL;

View File

@ -241,12 +241,12 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_ton, ftdm_ton2str, ftdm_ton_t)
/*! Numbering Plan Identification (NPI) */
typedef enum {
FTDM_NPI_UNKNOWN = 0,
FTDM_NPI_ISDN = 1,
FTDM_NPI_DATA = 3,
FTDM_NPI_TELEX = 4,
FTDM_NPI_NATIONAL = 8,
FTDM_NPI_PRIVATE = 9,
FTDM_NPI_RESERVED = 10,
FTDM_NPI_ISDN,
FTDM_NPI_DATA,
FTDM_NPI_TELEX,
FTDM_NPI_NATIONAL,
FTDM_NPI_PRIVATE,
FTDM_NPI_RESERVED,
FTDM_NPI_INVALID
} ftdm_npi_t;
#define NPI_STRINGS "unknown", "ISDN", "data", "telex", "national", "private", "reserved", "invalid"
@ -276,12 +276,16 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_screening, ftdm_screening2str, ftdm_screening_t)
/*! \brief bearer capability */
typedef enum {
FTDM_BEARER_CAP_SPEECH = 0x00,
FTDM_BEARER_CAP_64K_UNRESTRICTED = 0x02,
FTDM_BEARER_CAP_3_1KHZ_AUDIO = 0x03,
FTDM_BEARER_CAP_SPEECH = 0x00, /* Speech */
FTDM_BEARER_CAP_UNRESTRICTED, /* Unrestricted Digital */
FTDM_BEARER_CAP_RESTRICTED, /* Restricted Digital */
FTDM_BEARER_CAP_3_1KHZ_AUDIO, /* 3.1 Khz Audio */
FTDM_BEARER_CAP_7KHZ_AUDIO, /* 7 Khz Audio or Unrestricted digital w tones */
FTDM_BEARER_CAP_15KHZ_AUDIO, /* 15 Khz Audio */
FTDM_BEARER_CAP_VIDEO, /* Video */
FTDM_BEARER_CAP_INVALID
} ftdm_bearer_cap_t;
#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "3.1-Khz-audio", "invalid"
#define BEARER_CAP_STRINGS "speech", "unrestricted-digital-information", "restricted-digital-information", "3.1-Khz-audio", "7-Khz-audio", "15-Khz-audio", "video", "invalid"
FTDM_STR2ENUM_P(ftdm_str2ftdm_bearer_cap, ftdm_bearer_cap2str, ftdm_bearer_cap_t)
/*! \brief user information layer 1 protocol */
@ -298,6 +302,11 @@ FTDM_STR2ENUM_P(ftdm_str2ftdm_usr_layer1_prot, ftdm_user_layer1_prot2str, ftdm_u
typedef enum {
FTDM_CPC_UNKNOWN,
FTDM_CPC_OPERATOR,
FTDM_CPC_OPERATOR_FRENCH,
FTDM_CPC_OPERATOR_ENGLISH,
FTDM_CPC_OPERATOR_GERMAN,
FTDM_CPC_OPERATOR_RUSSIAN,
FTDM_CPC_OPERATOR_SPANISH,
FTDM_CPC_ORDINARY,
FTDM_CPC_PRIORITY,
FTDM_CPC_DATA,
@ -305,12 +314,14 @@ typedef enum {
FTDM_CPC_PAYPHONE,
FTDM_CPC_INVALID
} ftdm_calling_party_category_t;
#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid"
#define CALLING_PARTY_CATEGORY_STRINGS "unknown", "operator", "operator-french", "operator-english", "operator-german", "operator-russian", "operator-spanish", "ordinary", "priority", "data-call", "test-call", "payphone", "invalid"
FTDM_STR2ENUM_P(ftdm_str2ftdm_calling_party_category, ftdm_calling_party_category2str, ftdm_calling_party_category_t)
/*! \brief Digit limit used in DNIS/ANI */
#define FTDM_DIGITS_LIMIT 25
#define FTDM_SILENCE_VALUE(fchan) (fchan)->native_codec == FTDM_CODEC_ULAW ? 255 : (fchan)->native_codec == FTDM_CODEC_ALAW ? 0xD5 : 0x00
/*! \brief Number abstraction */
typedef struct {
char digits[FTDM_DIGITS_LIMIT];

View File

@ -131,5 +131,24 @@ FT_DECLARE(ftdm_status_t) ftdm_is_number(const char *number);
*/
FT_DECLARE(ftdm_status_t) ftdm_set_calling_party_category(const char *string, uint8_t *target);
/*!
* \brief URL encode a buffer
*
* \param url buffer to convert
* \param buf target to save converted string to
* \param len size of buffer
*
* \retval pointer to converted string
*/
FT_DECLARE(char *) ftdm_url_encode(const char *url, char *buf, ftdm_size_t len);
/*!
* \param s buffer to convert
* \param len size of buffer
*
* \retval pointer to converted string
*/
FT_DECLARE(char *) ftdm_url_decode(char *s, ftdm_size_t *len);
#endif /* __FTDM_CALL_UTILS_H__ */

View File

@ -249,6 +249,8 @@ typedef enum {
#define FTDM_CHANNEL_IND_ACK_PENDING (1ULL << 34)
/*!< There is someone blocking in the channel waiting for state completion */
#define FTDM_CHANNEL_BLOCKING (1ULL << 35)
/*!< Media is digital */
#define FTDM_CHANNEL_DIGITAL_MEDIA (1ULL << 36)
#include "ftdm_state.h"

View File

@ -273,7 +273,7 @@ TELETONE_API(int) teletone_mux_tones(teletone_generation_session_t *ts, teletone
TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cmd)
{
char *data = NULL, *cur = NULL, *end = NULL;
int var = 0, LOOPING = 0;
int LOOPING = 0;
if (!cmd) {
return -1;
@ -287,7 +287,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
cur = data;
while (*cur) {
var = 0;
if (*cur == ' ' || *cur == '\r' || *cur == '\n') {
cur++;
continue;
@ -298,7 +297,6 @@ TELETONE_API(int) teletone_run(teletone_generation_session_t *ts, const char *cm
}
if (*(cur + 1) == '=') {
var = 1;
switch(*cur) {
case 'c':
ts->channels = atoi(cur + 2);

View File

@ -242,7 +242,7 @@ static void default_logger(char *file, const char *func, int line, int level, ch
vsnprintf(data, sizeof(data), fmt, ap);
fprintf(globals.log_stream, "%s:%d %s() %s", file, line, func, data);
fprintf(globals.log_stream, "%s:%d %s() %s", fp, line, func, data);
va_end(ap);
@ -997,9 +997,9 @@ static int on_commands(void *user_data, ikspak *pak)
uint8_t is_result = strcasecmp(type, "result") ? 0 : 1;
uint8_t is_error = strcasecmp(type, "error") ? 0 : 1;
iks *xml, *xsession, *xerror = NULL, *xredir = NULL;
struct iks_tag* tmp;
xml = iks_child (pak->x);
tmp = (struct iks_tag*) xml;
if (is_error) {
if ((xerror = working_find(xml, "error"))) {
char *code = iks_find_attrib(xerror, "code");

View File

@ -0,0 +1,74 @@
--
-- sound_test.lua
--
-- accepts two args and then rolls through the sound files
-- arg 1: type
-- arg 2: rate
--
--[[ Use a dialplan entry like this:
<extension name="sound file tester">
<condition field="destination_number" expression="^((8|16|32|48)000)(.*)$">
<action application="lua" data="sound_test.lua $3 $1"/>
<action application="hangup"/>
</condition>
</extension>
Note the syntax of the destination number: <rate><type>
Rate can be 8000, 16000, 32000, or 48000
Type can be ivr, conference, voicemail, misc, digits, etc.
Using the extension listed above you could call it with mod_portaudio from fs_cli:
pa call 16000ivr
pa call 8000conference
pa call 32000conference
etc.
]]
-- Create tables that hold our rates and types
tbl_types = {
['ascii'] = 1,
['base256'] = 1,
['conference'] = 1,
['currency'] = 1,
['digits'] = 1,
['directory'] = 1,
['ivr'] = 1,
['misc'] = 1,
['phonetic-ascii'] = 1,
['time'] = 1,
['voicemail'] = 1,
['zrtp'] = 1
};
tbl_rates = {['8000'] = 1 ,['16000'] = 1, ['32000'] = 1, ['48000'] = 1};
stype = argv[1];
srate = argv[2];
freeswitch.consoleLog("INFO","Args: Type = " .. argv[1] .. ', Rate = ' .. argv[2] .. "\n");
if ( tbl_types[stype] == nil ) then
freeswitch.consoleLog("ERR","Type '" .. stype .. "' is not valid.\n");
elseif ( tbl_rates[srate] == nil ) then
freeswitch.consoleLog("ERR","Rate '" .. srate .. "' is not valid.\n");
else
-- Looks good, let's play some sound files
sound_base = session:getVariable('sounds_dir') .. '/en/us/callie/' .. stype .. '/' .. srate;
input_file = '/tmp/filez.txt';
res = os.execute('ls -1 ' .. sound_base .. ' > ' .. input_file);
freeswitch.consoleLog("INFO","Result of system call: " .. res .. "\n");
if ( res == 0 ) then
for fname in io.lines(input_file) do
freeswitch.consoleLog("NOTICE","Playing file: " .. fname .. "\n");
session:streamFile(sound_base .. '/' .. fname);
session:sleep(100);
end
else
freeswitch.consoleLog("ERR","Result of system call: " .. res .. "\n");
end
end

View File

@ -253,6 +253,8 @@ struct switch_runtime {
int multiple_registrations;
uint32_t max_db_handles;
uint32_t db_handle_timeout;
int curl_count;
int ssl_count;
};
extern struct switch_runtime runtime;

View File

@ -56,6 +56,15 @@
#include <switch.h>
SWITCH_BEGIN_EXTERN_C
typedef struct profile_node_s {
char *var;
char *val;
struct profile_node_s *next;
} profile_node_t;
/*! \brief Call Specific Data
*/
struct switch_caller_profile {
@ -110,6 +119,7 @@ SWITCH_BEGIN_EXTERN_C
switch_memory_pool_t *pool;
struct switch_caller_profile *next;
switch_call_direction_t direction;
profile_node_t *soft;
};
/*! \brief An Abstract Representation of a dialplan Application */

View File

@ -57,6 +57,7 @@ SWITCH_BEGIN_EXTERN_C
struct switch_app_log {
char *app;
char *arg;
switch_time_t stamp;
struct switch_app_log *next;
};
@ -434,6 +435,9 @@ SWITCH_DECLARE(void) switch_core_session_rwunlock(_In_ switch_core_session_t *se
*/
SWITCH_DECLARE(int) switch_core_add_state_handler(_In_ const switch_state_handler_table_t *state_handler);
SWITCH_DECLARE(int) switch_core_curl_count(int *val);
SWITCH_DECLARE(int) switch_core_ssl_count(int *val);
/*!
\brief Remove a global state handler
\param state_handler the state handler to remove

81
src/include/switch_curl.h Normal file
View File

@ -0,0 +1,81 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* switch_curl.h
*
*/
#ifndef __SWITCH_CURL_H
#define __SWITCH_CURL_H
#include <curl/curl.h>
#include <switch_ssl.h>
static inline void switch_curl_init(void)
{
int curl_count = switch_core_curl_count(NULL);
if (curl_count == 0) {
curl_global_init(CURL_GLOBAL_ALL);
#if defined(HAVE_OPENSSL)
switch_ssl_init_ssl_locks();
#endif
}
curl_count++;
switch_core_curl_count(&curl_count);
}
static inline void switch_curl_destroy()
{
int curl_count = switch_core_curl_count(NULL);
curl_count--;
if (curl_count == 0) {
#if defined(HAVE_OPENSSL)
switch_ssl_destroy_ssl_locks();
#endif
curl_global_cleanup();
}
switch_core_curl_count(&curl_count);
}
#endif
/* 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:
*/

107
src/include/switch_ssl.h Normal file
View File

@ -0,0 +1,107 @@
/*
* FreeSWITCH Modular Media Switching Software Library / Soft-Switch Application
* Copyright (C) 2005-2010, Anthony Minessale II <anthm@freeswitch.org>
*
* 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 <anthm@freeswitch.org>
* Portions created by the Initial Developer are Copyright (C)
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* switch_ssl.h
*
*/
#ifndef __SWITCH_SSL_H
#define __SWITCH_SSL_H
#if defined(HAVE_OPENSSL)
#include <openssl/crypto.h>
static switch_mutex_t **ssl_mutexes;
static switch_memory_pool_t *ssl_pool = NULL;
static inline void switch_ssl_ssl_lock_callback(int mode, int type, char *file, int line)
{
if (mode & CRYPTO_LOCK) {
switch_mutex_lock(ssl_mutexes[type]);
}
else {
switch_mutex_unlock(ssl_mutexes[type]);
}
}
static inline unsigned long switch_ssl_ssl_thread_id(void)
{
return (unsigned long) switch_thread_self();
}
static inline void switch_ssl_init_ssl_locks(void)
{
int ssl_count = switch_core_ssl_count(NULL);
int i, num;
if (ssl_count == 0) {
num = CRYPTO_num_locks();
ssl_mutexes = OPENSSL_malloc(CRYPTO_num_locks() * sizeof(switch_mutex_t*));
switch_assert(ssl_mutexes != NULL);
switch_core_new_memory_pool(&ssl_pool);
for (i = 0; i < num; i++) {
switch_mutex_init(&(ssl_mutexes[i]), SWITCH_MUTEX_NESTED, ssl_pool);
switch_assert(ssl_mutexes[i] != NULL);
}
CRYPTO_set_id_callback(switch_ssl_ssl_thread_id);
CRYPTO_set_locking_callback((void (*)(int, int, const char*, int))switch_ssl_ssl_lock_callback);
}
ssl_count++;
switch_core_ssl_count(&ssl_count);
}
static inline void switch_ssl_destroy_ssl_locks()
{
int i;
int ssl_count = switch_core_ssl_count(NULL);
ssl_count--;
if (ssl_count == 0) {
CRYPTO_set_locking_callback(NULL);
for (i = 0; i < CRYPTO_num_locks(); i++) {
switch_mutex_destroy(ssl_mutexes[i]);
}
OPENSSL_free(ssl_mutexes);
}
switch_core_ssl_count(&ssl_count);
}
#else
static inline void switch_ssl_init_ssl_locks(void) { return; }
static inline void switch_ssl_destroy_ssl_locks(void) { return; }
#endif
#endif

2
src/mod/.gitignore vendored
View File

@ -9,8 +9,6 @@
/applications/mod_conference/Makefile
/applications/mod_db/Makefile
/applications/mod_dptools/Makefile
/applications/mod_enum/Makefile
/applications/mod_enum/Makefile.in
/applications/mod_enum/mod_enum.log
/applications/mod_expr/Makefile
/applications/mod_expr/Makefile.in

View File

@ -1985,12 +1985,12 @@ static int members_callback(void *pArg, int argc, char **argv, char **columnName
/* Checking for cleanup Abandonded calls from the db */
if (!strcasecmp(member_state, cc_member_state2str(CC_MEMBER_STATE_ABANDONED))) {
long abandoned_epoch = atol(member_abandoned_epoch);
switch_time_t abandoned_epoch = atoll(member_abandoned_epoch);
if (abandoned_epoch == 0) {
abandoned_epoch = atol(cbt.member_joined_epoch);
abandoned_epoch = atoll(cbt.member_joined_epoch);
}
/* Once we pass a certain point, we want to get rid of the abandoned call */
if (abandoned_epoch + discard_abandoned_after < (long) local_epoch_time_now(NULL)) {
if (abandoned_epoch + discard_abandoned_after < local_epoch_time_now(NULL)) {
sql = switch_mprintf("DELETE FROM members WHERE system = 'single_box' AND uuid = '%q' AND (abandoned_epoch = '%" SWITCH_TIME_T_FMT "' OR joined_epoch = '%q')", cbt.member_uuid, abandoned_epoch, cbt.member_joined_epoch);
cc_execute_sql(NULL, sql, NULL);
switch_safe_free(sql);

View File

@ -200,7 +200,6 @@ typedef enum {
EFLAG_FLOOR_CHANGE = (1 << 25),
EFLAG_MUTE_DETECT = (1 << 26),
EFLAG_RECORD = (1 << 27),
EFLAG_AUTO_GAIN_LEVEL = (1 << 28)
} event_type_t;
typedef struct conference_file_node {
@ -815,12 +814,19 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
switch_event_t *event;
conference_file_node_t *member_fnode;
switch_speech_handle_t *member_sh;
const char *exit_sound = NULL;
switch_assert(conference != NULL);
switch_assert(member != NULL);
switch_thread_rwlock_wrlock(member->rwlock);
if (member->session && (exit_sound = switch_channel_get_variable(switch_core_session_get_channel(member->session), "conference_exit_sound"))) {
conference_play_file(conference, (char *)exit_sound, CONF_DEFAULT_LEADIN,
switch_core_session_get_channel(member->session), !switch_test_flag(conference, CFLAG_WAIT_MOD) ? 0 : 1);
}
lock_member(member);
member_fnode = member->fnode;
member_sh = member->sh;
@ -910,7 +916,7 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
|| (switch_test_flag(conference, CFLAG_DYNAMIC) && conference->count == 0)) {
switch_set_flag(conference, CFLAG_DESTRUCT);
} else {
if (conference->exit_sound && switch_test_flag(conference, CFLAG_EXIT_SOUND)) {
if (!exit_sound && conference->exit_sound && switch_test_flag(conference, CFLAG_EXIT_SOUND)) {
conference_play_file(conference, conference->exit_sound, 0, switch_core_session_get_channel(member->session), 0);
}
if (conference->count == 1 && conference->alone_sound && !switch_test_flag(conference, CFLAG_WAIT_MOD)) {
@ -2056,7 +2062,7 @@ static void clear_avg(conference_member_t *member)
static void check_agc_levels(conference_member_t *member)
{
int x = 0, y = member->agc_volume_in_level;
int x = 0;
if (!member->avg_score) return;
@ -2071,8 +2077,6 @@ static void check_agc_levels(conference_member_t *member)
}
if (x) {
switch_event_t *event;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG7,
"AGC %s:%d diff:%d level:%d cur:%d avg:%d vol:%d %s\n",
member->conference->name,
@ -2080,17 +2084,6 @@ static void check_agc_levels(conference_member_t *member)
member->score, member->avg_score, member->agc_volume_in_level, x > 0 ? "+++" : "---");
clear_avg(member);
if (test_eflag(member->conference, EFLAG_AUTO_GAIN_LEVEL) &&
switch_event_create_subclass(&event, SWITCH_EVENT_CUSTOM, CONF_EVENT_MAINT) == SWITCH_STATUS_SUCCESS) {
conference_add_event_member_data(member, event);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, "Action", "auto-gain-level");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "Old-Level", "%d", y);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "New-Level", "%d", member->agc_volume_in_level);
switch_event_fire(&event);
}
}
}

View File

@ -1664,7 +1664,7 @@ static void write_data(switch_stream_handle_t *stream, switch_bool_t as_xml, con
SWITCH_STANDARD_API(dialplan_lcr_function)
{
char *argv[4] = { 0 };
char *argv[9] = { 0 };
int argc;
char *mydata = NULL;
//char *dialstring = NULL;
@ -1825,7 +1825,7 @@ SWITCH_STANDARD_API(dialplan_lcr_function)
if (as_xml) {
event_xml = switch_event_xmlize(current->fields, SWITCH_VA_NONE);
event_str = switch_xml_toxml(event_xml, SWITCH_FALSE);
stream->write_function(stream, event_str);
stream->write_function(stream, "%s", event_str);
switch_xml_free(event_xml);
switch_safe_free(event_str);
}

View File

@ -0,0 +1,29 @@
BASE=../../../..
MONGO_CXX_DRIVER_VERSION=v1.8
MONGO_CXX_DRIVER_URL=http://downloads.mongodb.org/cxx-driver
MONGO_CXX_DRIVER_TARBALL=mongodb-linux-x86_64-$(MONGO_CXX_DRIVER_VERSION)-latest.tgz
MONGO_CXX_DRIVER_SRC=$(BASE)/libs/mongo-cxx-driver-$(MONGO_CXX_DRIVER_VERSION)
LIBMONGOCLIENT_A =$(MONGO_CXX_DRIVER_SRC)/libmongoclient.a
LOCAL_SOURCES=mongo_conn.cpp
LOCAL_OBJS=mongo_conn.o
LOCAL_CFLAGS=-I$(MONGO_CXX_DRIVER_SRC)/mongo
LOCAL_LIBADD=$(LIBMONGOCLIENT_A)
LOCAL_LDFLAGS=-lboost_thread -lboost_filesystem-mt -lboost_system-mt
MODDIR=$(shell pwd)
include $(BASE)/build/modmake.rules
$(MONGO_CXX_DRIVER_SRC):
$(GETLIB) $(MONGO_CXX_DRIVER_URL) $(MONGO_CXX_DRIVER_TARBALL)
cd $(MONGO_CXX_DRIVER_SRC) && patch -p0 -i $(MODDIR)/fpic_hack.diff
$(TOUCH_TARGET)
$(LIBMONGOCLIENT_A): $(MONGO_CXX_DRIVER_SRC)
cd $(MONGO_CXX_DRIVER_SRC) && scons
$(TOUCH_TARGET)

View File

@ -0,0 +1,11 @@
--- SConstruct.orig 2011-04-28 19:00:36.000000000 +0200
+++ SConstruct 2011-04-28 19:01:19.000000000 +0200
@@ -45,7 +45,7 @@
linux = True
if nix:
- env.Append( CPPFLAGS=" -O3" )
+ env.Append( CPPFLAGS=" -I../pcre -fPIC -O3" )
env.Append( LIBS=["pthread"] )
if linux:
env.Append( LINKFLAGS=" -Wl,--as-needed -Wl,-zdefs " )

View File

@ -0,0 +1,151 @@
#include <switch.h>
#include "mod_mongo.h"
static struct {
mongo_connection_pool_t *conn_pool;
} globals;
static const char *SYNTAX = "mongo_find_one ns; query; fields";
SWITCH_STANDARD_API(mongo_find_one_function)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
char *ns = NULL, *json_query = NULL, *json_fields = NULL;
char delim = ';';
ns = strdup(cmd);
switch_assert(ns != NULL);
if ((json_query = strchr(ns, delim))) {
*json_query++ = '\0';
if ((json_fields = strchr(json_query, delim))) {
*json_fields++ = '\0';
}
}
if (!zstr(ns) && !zstr(json_query) && !zstr(json_fields)) {
DBClientConnection *conn = NULL;
try {
BSONObj query = fromjson(json_query);
BSONObj fields = fromjson(json_fields);
conn = mongo_connection_pool_get(globals.conn_pool);
if (conn) {
BSONObj res = conn->findOne(ns, Query(query), &fields);
mongo_connection_pool_put(globals.conn_pool, conn);
stream->write_function(stream, "-OK\n%s\n", res.toString().c_str());
} else {
stream->write_function(stream, "-ERR\nNo connection\n");
}
} catch (DBException &e) {
if (conn) {
mongo_connection_destroy(&conn);
}
stream->write_function(stream, "-ERR\n%s\n", e.toString().c_str());
}
} else {
stream->write_function(stream, "-ERR\n%s\n", SYNTAX);
}
switch_safe_free(ns);
return status;
}
static switch_status_t config(void)
{
const char *cf = "mongo.conf";
switch_xml_t cfg, xml, settings, param;
switch_status_t status = SWITCH_STATUS_SUCCESS;
const char *host = "127.0.0.1";
switch_size_t min_connections = 1, max_connections = 1;
if (!(xml = switch_xml_open_cfg(cf, &cfg, NULL))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Open of %s failed\n", cf);
return SWITCH_STATUS_GENERR;
}
if ((settings = switch_xml_child(cfg, "settings"))) {
for (param = switch_xml_child(settings, "param"); param; param = param->next) {
char *var = (char *) switch_xml_attr_soft(param, "name");
char *val = (char *) switch_xml_attr_soft(param, "value");
int tmp;
if (!strcmp(var, "host")) {
host = val;
} else if (!strcmp(var, "min-connections")) {
if ((tmp = atoi(val)) > 0) {
min_connections = tmp;
}
} else if (!strcmp(var, "max-connections")) {
if ((tmp = atoi(val)) > 0) {
max_connections = tmp;
}
}
}
}
if (mongo_connection_pool_create(&globals.conn_pool, min_connections, max_connections, host) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Can't create connection pool\n");
status = SWITCH_STATUS_GENERR;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Mongo connection pool created [%s %d/%d]\n", host, (int)min_connections, (int)max_connections);
}
switch_xml_free(xml);
return status;
}
SWITCH_BEGIN_EXTERN_C
SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown);
SWITCH_MODULE_DEFINITION(mod_mongo, mod_mongo_load, mod_mongo_shutdown, NULL);
SWITCH_MODULE_LOAD_FUNCTION(mod_mongo_load)
{
switch_api_interface_t *api_interface;
switch_application_interface_t *app_interface;
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
memset(&globals, 0, sizeof(globals));
if (config() != SWITCH_STATUS_SUCCESS) {
return SWITCH_STATUS_TERM;
}
SWITCH_ADD_API(api_interface, "mongo_find_one", "mongo", mongo_find_one_function, SYNTAX);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_mongo_shutdown)
{
mongo_connection_pool_destroy(&globals.conn_pool);
return SWITCH_STATUS_SUCCESS;
}
SWITCH_END_EXTERN_C
/* 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
*/

View File

@ -0,0 +1,38 @@
#ifndef MOD_MONGO_H
#define MOD_MONGO_H
#include <client/dbclient.h>
#include <client/connpool.h>
#include <db/json.h>
#include <bson/bson.h>
using namespace mongo;
typedef struct {
char *host;
switch_size_t min_connections;
switch_size_t max_connections;
switch_size_t size;
switch_queue_t *connections;
switch_mutex_t *mutex;
switch_memory_pool_t *pool;
} mongo_connection_pool_t;
switch_status_t mongo_connection_create(DBClientConnection **connection, const char *host);
void mongo_connection_destroy(DBClientConnection **conn);
switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections,
const char *host);
void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool);
DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool);
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientConnection *conn);
#endif

View File

@ -0,0 +1,161 @@
#include <switch.h>
#include "mod_mongo.h"
/*
we could use the driver's connection pool,
if we could set the max connections (PoolForHost::setMaxPerHost)
ScopedDbConnection scoped_conn("host");
DBClientConnection *conn = dynamic_cast< DBClientConnection* >(&scoped_conn.conn());
scoped_conn.done();
*/
switch_status_t mongo_connection_create(DBClientConnection **connection, const char *host)
{
DBClientConnection *conn = new DBClientConnection();
try {
conn->connect(host);
} catch (DBException &e) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Can't connect to mongo [%s]\n", host);
return SWITCH_STATUS_GENERR;
}
*connection = conn;
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Connected to mongo [%s]\n", host);
return SWITCH_STATUS_SUCCESS;
}
void mongo_connection_destroy(DBClientConnection **conn)
{
switch_assert(*conn != NULL);
delete *conn;
*conn = NULL;
}
switch_status_t mongo_connection_pool_create(mongo_connection_pool_t **conn_pool, switch_size_t min_connections, switch_size_t max_connections,
const char *host)
{
switch_memory_pool_t *pool = NULL;
switch_status_t status = SWITCH_STATUS_SUCCESS;
mongo_connection_pool_t *cpool = NULL;
DBClientConnection *conn = NULL;
if ((status = switch_core_new_memory_pool(&pool)) != SWITCH_STATUS_SUCCESS) {
return status;
}
if (!(cpool = (mongo_connection_pool_t *)switch_core_alloc(pool, sizeof(mongo_connection_pool_t)))) {
switch_goto_status(SWITCH_STATUS_MEMERR, done);
}
if ((status = switch_mutex_init(&cpool->mutex, SWITCH_MUTEX_NESTED, pool)) != SWITCH_STATUS_SUCCESS) {
goto done;
}
if ((status = switch_queue_create(&cpool->connections, max_connections, pool)) != SWITCH_STATUS_SUCCESS) {
goto done;
}
cpool->min_connections = min_connections;
cpool->max_connections = max_connections;
cpool->host = switch_core_strdup(pool, host);
cpool->pool = pool;
for (cpool->size = 0; cpool->size < min_connections; cpool->size++) {
if (mongo_connection_create(&conn, host) == SWITCH_STATUS_SUCCESS) {
mongo_connection_pool_put(cpool, conn);
} else {
break;
}
}
done:
if (status == SWITCH_STATUS_SUCCESS) {
*conn_pool = cpool;
} else {
switch_core_destroy_memory_pool(&pool);
}
return status;
}
void mongo_connection_pool_destroy(mongo_connection_pool_t **conn_pool)
{
mongo_connection_pool_t *cpool = *conn_pool;
void *data = NULL;
switch_assert(cpool != NULL);
while (switch_queue_trypop(cpool->connections, &data) == SWITCH_STATUS_SUCCESS) {
mongo_connection_destroy((DBClientConnection **)&data);
}
switch_mutex_destroy(cpool->mutex);
switch_core_destroy_memory_pool(&cpool->pool);
*conn_pool = NULL;
}
DBClientConnection *mongo_connection_pool_get(mongo_connection_pool_t *conn_pool)
{
DBClientConnection *conn = NULL;
void *data = NULL;
switch_assert(conn_pool != NULL);
switch_mutex_lock(conn_pool->mutex);
if (switch_queue_trypop(conn_pool->connections, &data) == SWITCH_STATUS_SUCCESS) {
conn = (DBClientConnection *) data;
} else if (mongo_connection_create(&conn, conn_pool->host) == SWITCH_STATUS_SUCCESS) {
if (++conn_pool->size > conn_pool->max_connections) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Connection pool is empty. You may want to increase 'max-connections'\n");
}
}
switch_mutex_unlock(conn_pool->mutex);
#ifdef MONGO_POOL_DEBUG
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL get: size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn);
#endif
return conn;
}
switch_status_t mongo_connection_pool_put(mongo_connection_pool_t *conn_pool, DBClientConnection *conn)
{
switch_status_t status = SWITCH_STATUS_SUCCESS;
switch_assert(conn_pool != NULL);
switch_assert(conn != NULL);
switch_mutex_lock(conn_pool->mutex);
if (conn_pool->size > conn_pool->max_connections) {
#ifdef MONGO_POOL_DEBUG
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: Destroy connection %p\n", conn);
#endif
mongo_connection_destroy(&conn);
conn_pool->size--;
} else {
#ifdef MONGO_POOL_DEBUG
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: push connection %p\n", conn);
#endif
status = switch_queue_push(conn_pool->connections, conn);
}
switch_mutex_unlock(conn_pool->mutex);
#ifdef MONGO_POOL_DEBUG
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "POOL: put size %d conn: %p\n", (int) switch_queue_size(conn_pool->connections), conn);
#endif
return status;
}

View File

@ -902,7 +902,7 @@ switch_state_handler_table_t nibble_state_handler = {
/* on_hibernate */ NULL,
/* on_reset */ NULL,
/* on_park */ NULL,
/* on_reporting */ process_hangup, /* force billing event on b-leg if we can */
/* on_reporting */ NULL,
/* on_destroy */ NULL
};

View File

@ -96,7 +96,7 @@ vocallo_codec_t g_codec_map[] =
/* manually initialized */
{ SNGTC_CODEC_GSM_FR, IANA_GSM_A_8000_1, "GSM", "Sangoma GSM", 20, 13200, 20000, 160, 320, 33, 8000, 8000, 0 },
{ SNGTC_CODEC_G723_1_63, IANA_G723_A_8000_1, "G723", "Sangoma G723", 90, 6300, 30000, 240, 480, 24, 8000, 8000, 0 },
{ SNGTC_CODEC_AMR_1220, IANA_AMR_WB_16000_1, "AMR", "Sangoma AMR", 20, 12200, 20000, 160, 320, 0, 8000, 8000, 0 },
{ SNGTC_CODEC_AMR_1220, IANA_AMR_A_8000_1, "AMR", "Sangoma AMR", 20, 12200, 20000, 160, 320, 0, 8000, 8000, 0 },
{ SNGTC_CODEC_SIREN7_24, IANA_SIREN7, "G7221", "Sangoma G722.1", 20, 24000, 20000, 320, 640, 60, 16000, 16000, 0 },
{ SNGTC_CODEC_SIREN7_32, IANA_SIREN7, "G7221", "Sangoma G722.1", 20, 32000, 20000, 320, 640, 80, 16000, 16000, 0 },
{ SNGTC_CODEC_ILBC_133, IANA_ILBC_133_8000_1, "iLBC", "Sangoma iLBC", 30, 13300, 30000, 240, 480, 50, 8000, 8000, 0 },
@ -131,6 +131,7 @@ struct codec_data {
/* packet counters */
unsigned long tx;
unsigned long rx;
unsigned long ticks;
/* Lost packets */
long lastrxseqno;
@ -467,6 +468,8 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec
func_start_time = switch_micro_time_now();
}
sess->encoder.ticks++;
/* start assuming we will not encode anything */
*encoded_data_len = 0;
@ -547,7 +550,7 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec
continue;
}
if (encoded_frame.datalen != codec->implementation->encoded_bytes_per_packet) {
if (codec->implementation->encoded_bytes_per_packet && encoded_frame.datalen != codec->implementation->encoded_bytes_per_packet) {
/* seen when silence suppression is enabled */
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Ignoring encoded frame of %d bytes intead of %d bytes\n", encoded_frame.datalen, codec->implementation->encoded_bytes_per_packet);
continue;
@ -619,7 +622,7 @@ static switch_status_t switch_sangoma_encode(switch_codec_t *codec, switch_codec
sess->encoder.rtp_queue[sess->encoder.queue_rindex].datalen = 0;
SAFE_INDEX_INC(sess->encoder.rtp_queue, sess->encoder.queue_rindex);
sess->encoder.queue_size--;
if (*encoded_data_len != codec->implementation->encoded_bytes_per_packet) {
if (codec->implementation->encoded_bytes_per_packet && *encoded_data_len != codec->implementation->encoded_bytes_per_packet) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Returning odd encoded frame of %d bytes intead of %d bytes\n", *encoded_data_len, codec->implementation->encoded_bytes_per_packet);
}
} else {
@ -667,6 +670,7 @@ static switch_status_t switch_sangoma_decode(switch_codec_t *codec, /* codec ses
}
dbuf_linear = decoded_data;
sess->decoder.ticks++;
/* start assuming we will not decode anything */
*decoded_data_len = 0;
@ -989,6 +993,7 @@ SWITCH_STANDARD_API(sangoma_function)
stream->write_function(stream, "Rx %s at %d.%d.%d.%d:%d from %d.%d.%d.%d:%d\n\n", sess->impl->iananame, SNGTC_NIPV4(sess->encoder.reply.b.host_ip), sess->encoder.reply.b.host_udp_port,
SNGTC_NIPV4(sess->encoder.reply.b.codec_ip), sess->encoder.reply.b.codec_udp_port);
stream->write_function(stream, "Ticks: %lu\n", sess->encoder.ticks);
stream->write_function(stream, "-- Inbound Stats --\n");
stream->write_function(stream, "Rx Discarded: %lu\n", sess->encoder.rxdiscarded);
@ -1008,6 +1013,7 @@ SWITCH_STANDARD_API(sangoma_function)
SNGTC_NIPV4(sess->decoder.reply.a.codec_ip), sess->decoder.reply.a.codec_udp_port);
stream->write_function(stream, "Rx L16 at %d.%d.%d.%d:%d from %d.%d.%d.%d:%d\n\n", SNGTC_NIPV4(sess->decoder.reply.b.host_ip), sess->decoder.reply.b.host_udp_port,
SNGTC_NIPV4(sess->decoder.reply.b.codec_ip), sess->decoder.reply.b.codec_udp_port);
stream->write_function(stream, "Ticks: %lu\n", sess->decoder.ticks);
stream->write_function(stream, "-- Inbound Stats --\n");
stream->write_function(stream, "Rx Discarded: %lu\n", sess->decoder.rxdiscarded);

View File

@ -30,6 +30,7 @@
*
*/
#include <switch.h>
#include <switch_ssl.h>
#include <switch_stun.h>
#include <libdingaling.h>
@ -1399,7 +1400,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
{
struct private_object *tech_pvt = NULL;
switch_channel_t *channel = switch_core_session_get_channel(session);
int payload = 0;
//int payload = 0;
tech_pvt = (struct private_object *) switch_core_session_get_private(session);
switch_assert(tech_pvt != NULL);
@ -1443,7 +1444,7 @@ static switch_status_t channel_read_frame(switch_core_session_t *session, switch
payload = tech_pvt->read_frame.payload;
//payload = tech_pvt->read_frame.payload;
#if 0
elapsed = (unsigned int) ((switch_micro_time_now() - started) / 1000);
@ -1911,6 +1912,9 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_dingaling_load)
SWITCH_ADD_API(api_interface, "dingaling", "DingaLing Menu", dingaling, DINGALING_SYNTAX);
SWITCH_ADD_CHAT(chat_interface, MDL_CHAT_PROTO, chat_send);
switch_ssl_init_ssl_locks();
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
@ -2008,6 +2012,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_dingaling_shutdown)
switch_safe_free(globals.codec_string);
switch_safe_free(globals.codec_rates_string);
switch_ssl_destroy_ssl_locks();
return SWITCH_STATUS_SUCCESS;
}

View File

@ -1,13 +1 @@
faststart and codecs v CallProceeding due to h323plus, grep "Very Frustrating - S.H." in h323plus
source and uncomment commented lines.
exploration form developer of h323plus:
Yes that should be mera.
The problem is that Callproceeding does not always come from the remote it
may be generated by the gatekeeper. MERA where sending fast start elements
in the Call proceeding and connect. The call proceeding where not valid and
causing the media to fail. Normally (although valid) EP's do not set Fast
Start in Call proceeding so the code was disabled to resolve the MERA issue.
seems none for now

View File

@ -1241,6 +1241,7 @@ static void start_udptl(private_object_t *tech_pvt, switch_t38_options_t *t38_op
switch_port_t remote_port = switch_rtp_get_remote_port(tech_pvt->rtp_session);
const char *err, *val;
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
switch_rtp_udptl_mode(tech_pvt->rtp_session);
if (!t38_options || !t38_options->remote_ip) {
@ -1527,8 +1528,11 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
}
if (sofia_test_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE)) {
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
if (!switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_UDPTL) &&
!switch_rtp_test_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA)) {
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
switch_rtp_set_flag(tech_pvt->rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
}
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
}
@ -2153,6 +2157,7 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
if (t38_options) {
sofia_glue_set_image_sdp(tech_pvt, t38_options, 0);
if (switch_rtp_ready(tech_pvt->rtp_session)) {
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
switch_rtp_udptl_mode(tech_pvt->rtp_session);
}
}

View File

@ -4514,6 +4514,7 @@ static void sofia_handle_sip_r_invite(switch_core_session_t *session, int status
if (status == 200 && sofia_test_flag(tech_pvt, TFLAG_T38_PASSTHRU) && has_t38) {
if (switch_rtp_ready(tech_pvt->rtp_session) && switch_rtp_ready(other_tech_pvt->rtp_session)) {
sofia_clear_flag(tech_pvt, TFLAG_NOTIMER_DURING_BRIDGE);
switch_rtp_udptl_mode(tech_pvt->rtp_session);
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_INFO, "Activating T38 Passthru\n");
}
@ -5558,13 +5559,6 @@ nua_handle_t *sofia_global_nua_handle_by_replaces(sip_replaces_t *replaces)
const void *var;
void *val;
sofia_profile_t *profile;
switch_xml_t xml_root;
const char *err;
if ((xml_root = switch_xml_open_root(1, &err))) {
switch_xml_free(xml_root);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Reload XML [%s]\n", err);
}
switch_mutex_lock(mod_sofia_globals.hash_mutex);
if (mod_sofia_globals.profile_hash) {

View File

@ -2171,6 +2171,15 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
if (!strncasecmp(url_str, "sips:", 5)) {
s = url_str + 5;
}
/* tel: patch from jaybinks, added by MC
It compiles but I don't have a way to test it
*/
if (!strncasecmp(url_str, "tel:", 4)) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session),
SWITCH_LOG_ERROR, "URL Error! tel: uri's not supported at this time\n");
return SWITCH_STATUS_FALSE;
}
if (!s) {
s = url_str;
}
@ -3009,6 +3018,21 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
if (remote_host && remote_port && !strcmp(remote_host, tech_pvt->remote_sdp_audio_ip) && remote_port == tech_pvt->remote_sdp_audio_port) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params are unchanged for %s.\n",
switch_channel_get_name(tech_pvt->channel));
if (switch_rtp_ready(tech_pvt->rtp_session)) {
if (tech_pvt->audio_recv_pt != tech_pvt->agreed_pt) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"%s Set audio receive payload in Re-INVITE for non-matching dynamic PT to %u\n",
switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt);
switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->audio_recv_pt);
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG,
"%s Setting audio receive payload in Re-INVITE to %u\n",
switch_channel_get_name(tech_pvt->channel), tech_pvt->audio_recv_pt);
switch_rtp_set_recv_pt(tech_pvt->rtp_session, tech_pvt->agreed_pt);
}
}
goto video;
} else {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(tech_pvt->session), SWITCH_LOG_DEBUG, "Audio params changed for %s from %s:%d to %s:%d\n",
@ -3436,9 +3460,9 @@ switch_status_t sofia_glue_activate_rtp(private_object_t *tech_pvt, switch_rtp_f
if (!sofia_test_pflag(tech_pvt->profile, PFLAG_DISABLE_RTP_AUTOADJ) && !switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MODE) &&
!((val = switch_channel_get_variable(tech_pvt->channel, "disable_rtp_auto_adjust")) && switch_true(val))) {
flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE);
flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_AUTOADJ | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE);
} else {
flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_USE_TIMER | SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE);
flags = (switch_rtp_flag_t) (SWITCH_RTP_FLAG_DATAWAIT | SWITCH_RTP_FLAG_RAW_WRITE);
}
if (switch_channel_test_flag(tech_pvt->channel, CF_PROXY_MEDIA)) {

View File

@ -1417,6 +1417,11 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
}
if (!(nh = nua_handle_by_call_id(profile->nua, call_id))) {
if (mod_sofia_globals.debug_presence > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Failed to find handle for call id %s\n", call_id);
}
goto end;
}
@ -1468,12 +1473,18 @@ static int sofia_presence_sub_callback(void *pArg, int argc, char **argv, char *
const char *astate = switch_str_nil(switch_event_get_header(helper->event, "astate"));
const char *answer_state = switch_str_nil(switch_event_get_header(helper->event, "answer-state"));
const char *dft_state;
const char *from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number"));
const char *from_id;
const char *to_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_to_user"));
const char *from_user = switch_str_nil(switch_event_get_header(helper->event, "variable_sip_from_user"));
char *clean_to_user = NULL;
char *clean_from_user = NULL;
int force_status = 0;
if (!strcasecmp(direction, "inbound")) {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Caller-Destination-Number"));
} else {
from_id = switch_str_nil(switch_event_get_header(helper->event, "Other-Leg-Caller-ID-Number"));
}
#if 0
char *buf;
switch_event_serialize(helper->event, &buf, SWITCH_FALSE);
@ -2175,58 +2186,79 @@ void sofia_presence_handle_sip_i_subscribe(int status,
sip->sip_expires->ex_delta = 31536000;
}
if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' "
"or (proto='%q' and sip_user='%q' and sip_host='%q' "
"and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q' "
"and contact='%q')",
call_id, proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname, contact_str);
} else {
sql = switch_mprintf("delete from sip_subscriptions where "
"proto='%q' and sip_user='%q' and sip_host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q'",
proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname);
}
switch_mutex_lock(profile->ireg_mutex);
switch_assert(sql != NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
switch_safe_free(sql);
if (sub_state == nua_substate_terminated) {
sstr = switch_mprintf("terminated");
} else {
sip_accept_t *ap = sip->sip_accept;
char accept[256] = "";
full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
while (ap) {
switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
ap = ap->ac_next;
}
sql = switch_mprintf("insert into sip_subscriptions "
"(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip) "
"values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q')",
proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host,
event, contact_str, call_id, full_from, full_via,
//sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
if ((sub_state == nua_substate_active) && (switch_stristr("dialog", (const char *) event))) {
sstr = switch_mprintf("active;expires=%ld", exp_delta);
sql = switch_mprintf("update sip_subscriptions "
"set expires=%ld "
"where call_id='%q' and event='dialog' and hostname='%q' ",
(long) switch_epoch_time_now(NULL) + (exp_delta * 2),
full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip);
switch_assert(sql != NULL);
call_id,
mod_sofia_globals.hostname);
if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n",
profile->name, from_user, from_host, to_user, to_host, sql);
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
"re-subscribe with dialog detected, sql: %s\n", sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
} else {
if (sofia_test_pflag(profile, PFLAG_MULTIREG)) {
sql = switch_mprintf("delete from sip_subscriptions where call_id='%q' "
"or (proto='%q' and sip_user='%q' and sip_host='%q' "
"and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q' "
"and contact='%q')",
call_id, proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname, contact_str);
} else {
sql = switch_mprintf("delete from sip_subscriptions where "
"proto='%q' and sip_user='%q' and sip_host='%q' and sub_to_user='%q' and sub_to_host='%q' and event='%q' and hostname='%q'",
proto, from_user, from_host, to_user, to_host, event, mod_sofia_globals.hostname);
}
switch_mutex_lock(profile->ireg_mutex);
switch_assert(sql != NULL);
sofia_glue_actually_execute_sql(profile, sql, NULL);
switch_safe_free(sql);
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sstr = switch_mprintf("active;expires=%ld", exp_delta);
if (sub_state == nua_substate_terminated) {
sstr = switch_mprintf("terminated");
} else {
sip_accept_t *ap = sip->sip_accept;
char accept[256] = "";
full_agent = sip_header_as_string(profile->home, (void *) sip->sip_user_agent);
while (ap) {
switch_snprintf(accept + strlen(accept), sizeof(accept) - strlen(accept), "%s%s ", ap->ac_type, ap->ac_next ? "," : "");
ap = ap->ac_next;
}
sql = switch_mprintf("insert into sip_subscriptions "
"(proto,sip_user,sip_host,sub_to_user,sub_to_host,presence_hosts,event,contact,call_id,full_from,"
"full_via,expires,user_agent,accept,profile_name,hostname,network_port,network_ip) "
"values ('%q','%q','%q','%q','%q','%q','%q','%q','%q','%q','%q',%ld,'%q','%q','%q','%q','%d','%q')",
proto, from_user, from_host, to_user, to_host, profile->presence_hosts ? profile->presence_hosts : to_host,
event, contact_str, call_id, full_from, full_via,
//sofia_test_pflag(profile, PFLAG_MULTIREG) ? switch_epoch_time_now(NULL) + exp_delta : exp_delta * -1,
(long) switch_epoch_time_now(NULL) + (exp_delta * 2),
full_agent, accept, profile->name, mod_sofia_globals.hostname, np.network_port, np.network_ip);
switch_assert(sql != NULL);
if (mod_sofia_globals.debug_presence > 0 || mod_sofia_globals.debug_sla > 0) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "%s SUBSCRIBE %s@%s %s@%s\n%s\n",
profile->name, from_user, from_host, to_user, to_host, sql);
}
sofia_glue_execute_sql_now(profile, &sql, SWITCH_TRUE);
sstr = switch_mprintf("active;expires=%ld", exp_delta);
}
switch_mutex_unlock(profile->ireg_mutex);
}
if (status < 200) {
char *sticky = NULL;

View File

@ -1106,7 +1106,7 @@ static int config(void)
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid encoding strategy '%s' specified\n", val);
}
} else if (!strcasecmp(var, "apply-inbound-acl")) {
} else if (!strcasecmp(var, "apply-inbound-acl") && ! zstr(val)) {
if (prefs.acl_count < MAX_ACL) {
prefs.acl[prefs.acl_count++] = strdup(val);
} else {

View File

@ -36,7 +36,7 @@
#include <switch.h>
#include <shout/shout.h>
#include <lame.h>
#include <curl/curl.h>
#include <switch_curl.h>
#define OUTSCALE 8192 * 2
#define MP3_SCACHE 16384 * 2
@ -1480,7 +1480,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_shout_load)
supported_formats[0] = "shout";
supported_formats[1] = "mp3";
curl_global_init(CURL_GLOBAL_ALL);
switch_curl_init();
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
@ -1507,7 +1507,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_shout_load)
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_shout_shutdown)
{
curl_global_cleanup();
switch_curl_destroy();
mpg123_exit();
return SWITCH_STATUS_SUCCESS;
}

View File

@ -3023,6 +3023,35 @@ SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_numbers_t_flush_packet_count_get
}
SWIGEXPORT void SWIGSTDCALL CSharp_switch_rtp_numbers_t_largest_jb_size_set(void * jarg1, void * jarg2) {
switch_rtp_numbers_t *arg1 = (switch_rtp_numbers_t *) 0 ;
switch_size_t arg2 ;
switch_size_t *argp2 ;
arg1 = (switch_rtp_numbers_t *)jarg1;
argp2 = (switch_size_t *)jarg2;
if (!argp2) {
SWIG_CSharpSetPendingExceptionArgument(SWIG_CSharpArgumentNullException, "Attempt to dereference null switch_size_t", 0);
return ;
}
arg2 = *argp2;
if (arg1) (arg1)->largest_jb_size = arg2;
}
SWIGEXPORT void * SWIGSTDCALL CSharp_switch_rtp_numbers_t_largest_jb_size_get(void * jarg1) {
void * jresult ;
switch_rtp_numbers_t *arg1 = (switch_rtp_numbers_t *) 0 ;
switch_size_t result;
arg1 = (switch_rtp_numbers_t *)jarg1;
result = ((arg1)->largest_jb_size);
jresult = new switch_size_t((switch_size_t &)result);
return jresult;
}
SWIGEXPORT void * SWIGSTDCALL CSharp_new_switch_rtp_numbers_t() {
void * jresult ;
switch_rtp_numbers_t *result = 0 ;

View File

@ -6597,6 +6597,12 @@ class freeswitchPINVOKE {
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_numbers_t_flush_packet_count_get")]
public static extern IntPtr switch_rtp_numbers_t_flush_packet_count_get(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_numbers_t_largest_jb_size_set")]
public static extern void switch_rtp_numbers_t_largest_jb_size_set(HandleRef jarg1, HandleRef jarg2);
[DllImport("mod_managed", EntryPoint="CSharp_switch_rtp_numbers_t_largest_jb_size_get")]
public static extern IntPtr switch_rtp_numbers_t_largest_jb_size_get(HandleRef jarg1);
[DllImport("mod_managed", EntryPoint="CSharp_new_switch_rtp_numbers_t")]
public static extern IntPtr new_switch_rtp_numbers_t();
@ -29222,6 +29228,18 @@ public class switch_rtp_numbers_t : IDisposable {
}
}
public SWIGTYPE_p_switch_size_t largest_jb_size {
set {
freeswitchPINVOKE.switch_rtp_numbers_t_largest_jb_size_set(swigCPtr, SWIGTYPE_p_switch_size_t.getCPtr(value));
if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve();
}
get {
SWIGTYPE_p_switch_size_t ret = new SWIGTYPE_p_switch_size_t(freeswitchPINVOKE.switch_rtp_numbers_t_largest_jb_size_get(swigCPtr), true);
if (freeswitchPINVOKE.SWIGPendingException.Pending) throw freeswitchPINVOKE.SWIGPendingException.Retrieve();
return ret;
}
}
public switch_rtp_numbers_t() : this(freeswitchPINVOKE.new_switch_rtp_numbers_t(), true) {
}

View File

@ -35,7 +35,7 @@
#include "mod_spidermonkey.h"
#ifdef HAVE_CURL
#include <curl/curl.h>
#include <switch_curl.h>
#endif
static int foo = 0;
static jsval check_hangup_hook(struct js_session *jss, jsval * rp);
@ -2551,7 +2551,6 @@ static JSBool js_fetchurl_file(JSContext * cx, JSObject * obj, uintN argc, jsval
url = JS_GetStringBytes(JS_ValueToString(cx, argv[0]));
filename = JS_GetStringBytes(JS_ValueToString(cx, argv[1]));
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
if (!strncasecmp(url, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
@ -2600,7 +2599,6 @@ static JSBool js_fetchurl(JSContext * cx, JSObject * obj, uintN argc, jsval * ar
JS_ValueToInt32(cx, argv[1], &buffer_size);
}
curl_global_init(CURL_GLOBAL_ALL);
curl_handle = curl_easy_init();
if (!strncasecmp(url, "https", 5)) {
curl_easy_setopt(curl_handle, CURLOPT_SSL_VERIFYPEER, 0);
@ -3803,7 +3801,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_spidermonkey_load)
SWITCH_ADD_APP(app_interface, "javascript", "Launch JS ivr", "Run a javascript ivr on a channel", js_dp_function, "<script> [additional_vars [...]]",
SAF_SUPPORT_NOMEDIA);
curl_global_init(CURL_GLOBAL_ALL);
switch_curl_init();
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_NOUNLOAD;
@ -3814,7 +3812,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_spidermonkey_shutdown)
// this causes a crash
//JS_DestroyRuntime(globals.rt);
curl_global_cleanup();
switch_curl_destroy();
switch_core_hash_destroy(&module_manager.mod_hash);
switch_core_hash_destroy(&module_manager.load_hash);

View File

@ -30,7 +30,7 @@
*
*/
#include "mod_spidermonkey.h"
#include <curl/curl.h>
#include <switch_curl.h>
static const char modname[] = "CURL";
@ -242,7 +242,7 @@ const sm_module_interface_t curl_module_interface = {
SWITCH_MOD_DECLARE_NONSTD(switch_status_t) spidermonkey_init(const sm_module_interface_t ** module_interface)
{
curl_global_init(CURL_GLOBAL_ALL);
switch_curl_init();
*module_interface = &curl_module_interface;
return SWITCH_STATUS_SUCCESS;
}

View File

@ -32,7 +32,7 @@
*/
#include <sys/stat.h>
#include <switch.h>
#include <curl/curl.h>
#include <switch_curl.h>
#define MAX_URLS 20
#define ENCODING_NONE 0
@ -610,6 +610,11 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_cdr_load)
set_xml_cdr_log_dirs();
switch_xml_free(xml);
if (status == SWITCH_STATUS_SUCCESS) {
switch_curl_init();
}
return status;
}
@ -626,6 +631,8 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_cdr_shutdown)
switch_thread_rwlock_destroy(globals.log_path_lock);
switch_curl_destroy();
return SWITCH_STATUS_SUCCESS;
}

View File

@ -31,7 +31,8 @@
*
*/
#include <switch.h>
#include <curl/curl.h>
#include <switch_curl.h>
SWITCH_MODULE_LOAD_FUNCTION(mod_xml_curl_load);
SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_curl_shutdown);
@ -548,7 +549,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_xml_curl_load)
globals.hash_tail = NULL;
if (do_config() == SWITCH_STATUS_SUCCESS) {
curl_global_init(CURL_GLOBAL_ALL);
switch_curl_init();
} else {
return SWITCH_STATUS_FALSE;
}
@ -573,7 +574,7 @@ SWITCH_MODULE_SHUTDOWN_FUNCTION(mod_xml_curl_shutdown)
}
switch_xml_unbind_search_function_ptr(xml_url_fetch);
curl_global_cleanup();
switch_curl_destroy();
return SWITCH_STATUS_SUCCESS;
}

View File

@ -324,6 +324,16 @@ SWITCH_DECLARE(void) switch_caller_profile_event_set_data(switch_caller_profile_
switch_snprintf(header_name, sizeof(header_name), "%s-Profile-Index", prefix);
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, header_name, caller_profile->profile_index);
}
if (caller_profile->soft) {
profile_node_t *pn;
for (pn = caller_profile->soft; pn; pn = pn->next) {
switch_event_add_header_string(event, SWITCH_STACK_BOTTOM, pn->var, pn->val);
}
}
if (caller_profile->times) {
switch_snprintf(header_name, sizeof(header_name), "%s-Profile-Created-Time", prefix);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, header_name, "%" SWITCH_TIME_T_FMT, caller_profile->times->profile_created);

View File

@ -877,7 +877,20 @@ SWITCH_DECLARE(switch_status_t) switch_channel_set_profile_var(switch_channel_t
} else if (!strcasecmp(name, "chan_name")) {
channel->caller_profile->chan_name = v;
} else {
status = SWITCH_STATUS_FALSE;
profile_node_t *pn, *n = switch_core_alloc(channel->caller_profile->pool, sizeof(*n));
n->var = switch_core_strdup(channel->caller_profile->pool, name);
n->val = v;
if (!channel->caller_profile->soft) {
channel->caller_profile->soft = n;
} else {
for(pn = channel->caller_profile->soft; pn && pn->next; pn = pn->next);
if (pn) {
pn->next = n;
}
}
}
switch_mutex_unlock(channel->profile_mutex);
@ -1638,11 +1651,8 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
const char *file, const char *func, int line)
{
int x;
switch_mutex_lock(channel->state_mutex);
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) Running State Change %s\n",
channel->name, state_names[state]);
channel->running_state = state;
switch_mutex_lock(channel->flag_mutex);
if (channel->state_flags[0]) {
for (x = 1; x < CF_FLAG_MAX; x++) {
if (channel->state_flags[x]) {
@ -1652,8 +1662,18 @@ SWITCH_DECLARE(switch_channel_state_t) switch_channel_perform_set_running_state(
}
channel->state_flags[0] = 0;
}
switch_mutex_unlock(channel->flag_mutex);
switch_channel_clear_flag(channel, CF_TAGGED);
switch_mutex_lock(channel->state_mutex);
switch_log_printf(SWITCH_CHANNEL_ID_LOG, file, func, line, switch_channel_get_uuid(channel), SWITCH_LOG_DEBUG, "(%s) Running State Change %s\n",
channel->name, state_names[state]);
channel->running_state = state;
if (channel->state == CS_ROUTING || channel->state == CS_HANGUP) {
switch_channel_presence(channel, "unknown", (const char *) state_names[state], NULL);

View File

@ -197,6 +197,34 @@ SWITCH_DECLARE(FILE *) switch_core_data_channel(switch_text_channel_t channel)
return handle;
}
SWITCH_DECLARE(int) switch_core_curl_count(int *val)
{
if (!val) {
switch_mutex_lock(runtime.global_mutex);
return runtime.curl_count;
}
runtime.curl_count = *val;
switch_mutex_unlock(runtime.global_mutex);
return 0;
}
SWITCH_DECLARE(int) switch_core_ssl_count(int *val)
{
if (!val) {
switch_mutex_lock(runtime.global_mutex);
return runtime.ssl_count;
}
runtime.ssl_count = *val;
switch_mutex_unlock(runtime.global_mutex);
return 0;
}
SWITCH_DECLARE(void) switch_core_remove_state_handler(const switch_state_handler_table_t *state_handler)
{
int index, tmp_index = 0;
@ -1300,6 +1328,7 @@ static void switch_core_set_serial(void)
switch_core_set_variable("switch_serial", buf);
}
SWITCH_DECLARE(switch_status_t) switch_core_init(switch_core_flag_t flags, switch_bool_t console, const char **err)
{
switch_uuid_t uuid;

View File

@ -445,15 +445,12 @@ SWITCH_DECLARE(switch_status_t) switch_core_file_seek(switch_file_handle_t *fh,
switch_set_flag(fh, SWITCH_FILE_SEEK);
status = fh->file_interface->file_seek(fh, cur_pos, samples, whence);
if (samples) {
fh->offset_pos = *cur_pos;
fh->offset_pos = *cur_pos;
if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
fh->samples_out = *cur_pos;
}
if (switch_test_flag(fh, SWITCH_FILE_FLAG_WRITE)) {
fh->samples_out = *cur_pos;
}
return status;
}

View File

@ -2010,6 +2010,8 @@ SWITCH_DECLARE(switch_status_t) switch_core_session_exec(switch_core_session_t *
log->arg = switch_core_session_strdup(session, expanded);
}
log->stamp = switch_time_now();
for (lp = session->app_log; lp && lp->next; lp = lp->next);
if (lp) {

View File

@ -1350,6 +1350,16 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_media(const char *uuid, switch_media_
if (switch_channel_test_flag(channel, CF_PROXY_MODE)) {
status = SWITCH_STATUS_SUCCESS;
/* If we had early media in bypass mode before, it is no longer relevant */
if (switch_channel_test_flag(channel, CF_EARLY_MEDIA)) {
switch_core_session_message_t msg2 = { 0 };
msg2.message_id = SWITCH_MESSAGE_INDICATE_CLEAR_PROGRESS;
msg2.from = __FILE__;
switch_core_session_receive_message(session, &msg2);
}
if (switch_core_session_receive_message(session, &msg) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_ERROR, "Can't re-establsh media on %s\n", switch_channel_get_name(channel));
switch_core_session_rwunlock(session);
@ -1954,6 +1964,21 @@ SWITCH_DECLARE(int) switch_ivr_set_xml_profile_data(switch_xml_t xml, switch_cal
}
switch_xml_set_txt_d(param, caller_profile->chan_name);
if (caller_profile->soft) {
profile_node_t *pn;
for (pn = caller_profile->soft; pn; pn = pn->next) {
if (!(param = switch_xml_add_child_d(xml, pn->var, off++))) {
return -1;
}
switch_xml_set_txt_d(param, pn->val);
}
}
return off;
}
@ -2043,6 +2068,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
goto error;
}
for (ap = app_log; ap; ap = ap->next) {
char tmp[128];
if (!(x_application = switch_xml_add_child_d(x_apps, "application", app_off++))) {
goto error;
@ -2050,6 +2076,9 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_generate_xml_cdr(switch_core_session_
switch_xml_set_attr_d(x_application, "app_name", ap->app);
switch_xml_set_attr_d(x_application, "app_data", ap->arg);
switch_snprintf(tmp, sizeof(tmp), "%" SWITCH_TIME_T_FMT, ap->stamp);
switch_xml_set_attr_d_buf(x_application, "app_stamp", tmp);
}
}

View File

@ -2454,6 +2454,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
if (fail_on_single_reject == 1 || switch_stristr(cause_str, fail_on_single_reject_var)) {
force_reason = reason;
status = SWITCH_STATUS_FALSE;
goto outer_for;
}
}

View File

@ -1900,7 +1900,18 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
if (tb[0]) {
char *p;
switch_channel_set_variable(channel, SWITCH_READ_TERMINATOR_USED_VARIABLE, tb);
if ((p = strchr(valid_terminators, tb[0]))) {
if (p >= (valid_terminators + 1) && (*(p - 1) == '+' || *(p - 1) == 'x')) {
switch_snprintf(digit_buffer + strlen(digit_buffer), digit_buffer_length - strlen(digit_buffer), "%s", tb);
if (*(p - 1) == 'x') {
status = SWITCH_STATUS_RESTART;
}
}
}
}
len = strlen(digit_buffer);
@ -1923,7 +1934,7 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_read(switch_core_session_t *session,
end:
if (max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)) {
if (status != SWITCH_STATUS_RESTART && max_digits == 1 && len == 1 && valid_terminators && strchr(valid_terminators, *digit_buffer)) {
*digit_buffer = '\0';
}
@ -1958,6 +1969,11 @@ SWITCH_DECLARE(switch_status_t) switch_play_and_get_digits(switch_core_session_t
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_RESTART) {
return status;
}
if (status == SWITCH_STATUS_TIMEOUT && strlen(digit_buffer) >= min_digits) {
status = SWITCH_STATUS_SUCCESS;
}

View File

@ -1262,9 +1262,10 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session)
READ_INC(rtp_session);
WRITE_INC(rtp_session);
if (rtp_session->timer.timer_interface) {
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER) || rtp_session->timer.timer_interface) {
switch_core_timer_destroy(&rtp_session->timer);
memset(&rtp_session->timer, 0, sizeof(rtp_session->timer));
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
}
switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_ENABLE_RTCP);
@ -1293,9 +1294,7 @@ SWITCH_DECLARE(switch_status_t) switch_rtp_udptl_mode(switch_rtp_t *rtp_session)
switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_UDPTL);
switch_set_flag_locked(rtp_session, SWITCH_RTP_FLAG_PROXY_MEDIA);
switch_socket_opt_set(rtp_session->sock_input, SWITCH_SO_NONBLOCK, FALSE);
switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER);
switch_clear_flag(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
switch_clear_flag_locked(rtp_session, SWITCH_RTP_FLAG_NOBLOCK);
WRITE_DEC(rtp_session);
READ_DEC(rtp_session);
@ -3850,7 +3849,7 @@ static int rtp_common_write(switch_rtp_t *rtp_session,
if (switch_test_flag(rtp_session, SWITCH_RTP_FLAG_USE_TIMER)) {
rtp_session->last_write_samplecount = rtp_session->timer.samplecount;
} else {
rtp_session->last_write_timestamp = (uint32_t) switch_micro_time_now();
rtp_session->last_write_timestamp = switch_micro_time_now();
}
rtp_session->last_write_ts = this_ts;

View File

@ -1329,11 +1329,17 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)
char replace[1024] = "";
switch_time_t ret = 0;
char *pattern = "^(\\d+)-(\\d+)-(\\d+)\\s*(\\d*):{0,1}(\\d*):{0,1}(\\d*)";
char *pattern2 = "^(\\d{4})(\\d{2})(\\d{2})(\\d{2})(\\d{2})(\\d{2})";
switch_time_exp_lt(&tm, switch_micro_time_now());
tm.tm_year = tm.tm_mon = tm.tm_mday = tm.tm_hour = tm.tm_min = tm.tm_sec = 0;
if ((proceed = switch_regex_perform(in, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
if (!(proceed = switch_regex_perform(in, pattern, &re, ovector, sizeof(ovector) / sizeof(ovector[0])))) {
switch_regex_safe_free(re);
proceed = switch_regex_perform(in, pattern2, &re, ovector, sizeof(ovector) / sizeof(ovector[0]));
}
if (proceed) {
if (proceed > 1) {
switch_regex_copy_substring(in, ovector, proceed, 1, replace, sizeof(replace));
@ -1365,10 +1371,14 @@ SWITCH_DECLARE(switch_time_t) switch_str_time(const char *in)
tm.tm_sec = atoi(replace);
}
switch_regex_safe_free(re);
switch_time_exp_gmt_get(&ret, &tm);
return ret;
}
/* possible else with more patterns later */
switch_regex_safe_free(re);
return ret;
}