Freeswitch-trunk
Threads by month
- ----- 2026 -----
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2025 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2024 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2023 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2022 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2021 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2020 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2019 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2018 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2017 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2016 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2015 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2014 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2013 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2012 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2011 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2010 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2009 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2008 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2007 -----
- December
- November
- October
- September
- August
- July
- June
- May
- April
- March
- February
- January
- ----- 2006 -----
- December
- November
- October
- September
- August
- July
- June
- 14172 discussions
Author: anthm
Date: Tue Mar 27 13:15:10 2007
New Revision: 4776
Modified:
freeswitch/trunk/src/switch_ivr.c
Log:
This patch adds 2 important variables to the originate subsystem
originate_retries:
This variable controls how many times the system should retry the
entire dialstring before exiting on failure (default 1)
originate_retry_sleep_ms:
This variable controls how long in milliseconds to pause between
retries (default 1000)
*NOTE* when using the , and & symbols to call sequential or simultaneous channels in conjunction with this feature,
the *entire* dialstring will be repeated as many times as you specify in ${originate_retries}
Here is an example using the bridge application to originate the call. (The feature will also work anywhere else
an origination can be made.)
<extension name="1000">
<condition field="destination_number" expression="^1000$">
<action application="set" data="originate_retries=10"/>
<action application="set" data="originate_retry_sleep_ms=1000"/>
<action application="bridge" data="sofia/$${domain}/1000(a)somehost.com"/>
</condition>
</extension>
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Tue Mar 27 13:15:10 2007
@@ -2498,7 +2498,7 @@
switch_frame_t *read_frame = NULL;
switch_memory_pool_t *pool = NULL;
int r = 0, i, and_argc = 0, or_argc = 0;
- int32_t idx = IDX_NADA;
+ int32_t sleep_ms = 1000, try =0, retries = 1, idx = IDX_NADA;
switch_codec_t write_codec = {0};
switch_frame_t write_frame = {0};
uint8_t fdata[1024], pass = 0;
@@ -2512,6 +2512,8 @@
switch_event_t *var_event = NULL;
uint8_t fail_on_single_reject = 0;
uint8_t ring_ready = 0;
+ char *loop_data = NULL;
+
write_frame.data = fdata;
*bleg = NULL;
@@ -2605,7 +2607,7 @@
}
}
- // When using the AND operator, the fail_on_single_reject flage may be set in order to indicate that a single
+ // When using the AND operator, the fail_on_single_reject flag may be set in order to indicate that a single
// rejections should terminate the attempt rather than a timeout, answer, or rejection by all.
if ((var = switch_event_get_header(var_event, "fail_on_single_reject")) && switch_true(var)) {
fail_on_single_reject = 1;
@@ -2619,6 +2621,28 @@
early_ok = 0;
}
+ if ((var_val = switch_event_get_header(var_event, "originate_retries")) && switch_true(var_val)) {
+ int32_t tmp;
+ tmp = atoi(var_val);
+ if (tmp > 0 && tmp < 101) {
+ retries = tmp;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+ "Invalid originate_retries setting of %d ignored, value must be between 1 and 100\n", tmp);
+ }
+ }
+
+ if ((var_val = switch_event_get_header(var_event, "originate_retry_sleep_ms")) && switch_true(var_val)) {
+ int32_t tmp;
+ tmp = atoi(var_val);
+ if (tmp > 500 && tmp < 60000) {
+ sleep_ms = tmp;
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING,
+ "Invalid originate_retry_sleep_ms setting of %d ignored, value must be between 500 and 60000\n", tmp);
+ }
+ }
+
if (!cid_name_override) {
cid_name_override = switch_event_get_header(var_event, "origination_caller_id_name");
}
@@ -2628,517 +2652,528 @@
}
- or_argc = switch_separate_string(data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
-
- if (caller_channel && or_argc > 1 && !ringback_data) {
- switch_channel_ring_ready(caller_channel);
- sent_ring = 1;
- }
-
- for (r = 0; r < or_argc; r++) {
- uint32_t hups;
- reason = SWITCH_CAUSE_UNALLOCATED;
- memset(peer_names, 0, sizeof(peer_names));
- peer_session = NULL;
- memset(peer_sessions, 0, sizeof(peer_sessions));
- memset(peer_channels, 0, sizeof(peer_channels));
- memset(caller_profiles, 0, sizeof(caller_profiles));
- chan_type = NULL;
- chan_data = NULL;
- peer_channel = NULL;
- start = 0;
- read_frame = NULL;
- pool = NULL;
- pass = 0;
- file = NULL;
- key = NULL;
- var = NULL;
- to = 0;
- and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
-
- if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) {
+ for (try = 0; try < retries; try++) {
+ switch_safe_free(loop_data);
+ assert(loop_data = strdup(data));
+ or_argc = switch_separate_string(loop_data, '|', pipe_names, (sizeof(pipe_names) / sizeof(pipe_names[0])));
+
+ if (caller_channel && or_argc > 1 && !ringback_data) {
switch_channel_ring_ready(caller_channel);
sent_ring = 1;
}
- for (i = 0; i < and_argc; i++) {
-
- chan_type = peer_names[i];
- if ((chan_data = strchr(chan_type, '/')) != 0) {
- *chan_data = '\0';
- chan_data++;
+ for (r = 0; r < or_argc; r++) {
+ uint32_t hups;
+ reason = SWITCH_CAUSE_UNALLOCATED;
+ memset(peer_names, 0, sizeof(peer_names));
+ peer_session = NULL;
+ memset(peer_sessions, 0, sizeof(peer_sessions));
+ memset(peer_channels, 0, sizeof(peer_channels));
+ memset(caller_profiles, 0, sizeof(caller_profiles));
+ chan_type = NULL;
+ chan_data = NULL;
+ peer_channel = NULL;
+ start = 0;
+ read_frame = NULL;
+ pool = NULL;
+ pass = 0;
+ file = NULL;
+ key = NULL;
+ var = NULL;
+ to = 0;
+
+ if (try > 0) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_NOTICE, "Originate attempt %d/%d in %d ms\n", try + 1, retries, sleep_ms);
+ switch_yield(sleep_ms * 1000);
}
-
- if (session) {
- if (!switch_channel_ready(caller_channel)) {
- status = SWITCH_STATUS_FALSE;
- goto done;
- }
- caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
-
- if (!cid_name_override) {
- cid_name_override = caller_caller_profile->caller_id_name;
- }
- if (!cid_num_override) {
- cid_num_override = caller_caller_profile->caller_id_number;
- }
+ and_argc = switch_separate_string(pipe_names[r], ',', peer_names, (sizeof(peer_names) / sizeof(peer_names[0])));
+
+ if (caller_channel && !sent_ring && and_argc > 1 && !ringback_data) {
+ switch_channel_ring_ready(caller_channel);
+ sent_ring = 1;
+ }
- caller_profiles[i] = switch_caller_profile_new(switch_core_session_get_pool(session),
- caller_caller_profile->username,
- caller_caller_profile->dialplan,
- cid_name_override,
- cid_num_override,
- caller_caller_profile->network_addr,
- NULL,
- NULL,
- caller_caller_profile->rdnis,
- caller_caller_profile->source,
- caller_caller_profile->context,
- chan_data);
- caller_profiles[i]->flags = caller_caller_profile->flags;
- pool = NULL;
- } else {
- if (!cid_name_override) {
- cid_name_override = "FreeSWITCH";
- }
- if (!cid_num_override) {
- cid_num_override = "0000000000";
+ for (i = 0; i < and_argc; i++) {
+
+ chan_type = peer_names[i];
+ if ((chan_data = strchr(chan_type, '/')) != 0) {
+ *chan_data = '\0';
+ chan_data++;
}
+
+ if (session) {
+ if (!switch_channel_ready(caller_channel)) {
+ status = SWITCH_STATUS_FALSE;
+ goto done;
+ }
- if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
- status = SWITCH_STATUS_TERM;
- goto done;
- }
+ caller_caller_profile = caller_profile_override ? caller_profile_override : switch_channel_get_caller_profile(caller_channel);
+
+ if (!cid_name_override) {
+ cid_name_override = caller_caller_profile->caller_id_name;
+ }
+ if (!cid_num_override) {
+ cid_num_override = caller_caller_profile->caller_id_number;
+ }
- if (caller_profile_override) {
- caller_profiles[i] = switch_caller_profile_new(pool,
- caller_profile_override->username,
- caller_profile_override->dialplan,
- caller_profile_override->caller_id_name,
- caller_profile_override->caller_id_number,
- caller_profile_override->network_addr,
- caller_profile_override->ani,
- caller_profile_override->aniii,
- caller_profile_override->rdnis,
- caller_profile_override->source,
- caller_profile_override->context,
- chan_data);
- } else {
- caller_profiles[i] = switch_caller_profile_new(pool,
- NULL,
- NULL,
+ caller_profiles[i] = switch_caller_profile_new(switch_core_session_get_pool(session),
+ caller_caller_profile->username,
+ caller_caller_profile->dialplan,
cid_name_override,
cid_num_override,
+ caller_caller_profile->network_addr,
NULL,
- NULL,
- NULL,
- NULL,
- __FILE__,
NULL,
+ caller_caller_profile->rdnis,
+ caller_caller_profile->source,
+ caller_caller_profile->context,
chan_data);
+ caller_profiles[i]->flags = caller_caller_profile->flags;
+ pool = NULL;
+ } else {
+ if (!cid_name_override) {
+ cid_name_override = "FreeSWITCH";
+ }
+ if (!cid_num_override) {
+ cid_num_override = "0000000000";
+ }
+
+ if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
+ status = SWITCH_STATUS_TERM;
+ goto done;
+ }
+
+ if (caller_profile_override) {
+ caller_profiles[i] = switch_caller_profile_new(pool,
+ caller_profile_override->username,
+ caller_profile_override->dialplan,
+ caller_profile_override->caller_id_name,
+ caller_profile_override->caller_id_number,
+ caller_profile_override->network_addr,
+ caller_profile_override->ani,
+ caller_profile_override->aniii,
+ caller_profile_override->rdnis,
+ caller_profile_override->source,
+ caller_profile_override->context,
+ chan_data);
+ } else {
+ caller_profiles[i] = switch_caller_profile_new(pool,
+ NULL,
+ NULL,
+ cid_name_override,
+ cid_num_override,
+ NULL,
+ NULL,
+ NULL,
+ NULL,
+ __FILE__,
+ NULL,
+ chan_data);
+ }
}
- }
- if ((reason = switch_core_session_outgoing_channel(session, chan_type, caller_profiles[i], &peer_sessions[i], &pool)) != SWITCH_CAUSE_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason));
- if (pool) {
- switch_core_destroy_memory_pool(&pool);
- }
- caller_profiles[i] = NULL;
- peer_channels[i] = NULL;
- peer_sessions[i] = NULL;
- continue;
- }
+ if ((reason = switch_core_session_outgoing_channel(session, chan_type, caller_profiles[i], &peer_sessions[i], &pool)) != SWITCH_CAUSE_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Cannot Create Outgoing Channel! cause: %s\n", switch_channel_cause2str(reason));
+ if (pool) {
+ switch_core_destroy_memory_pool(&pool);
+ }
+ caller_profiles[i] = NULL;
+ peer_channels[i] = NULL;
+ peer_sessions[i] = NULL;
+ continue;
+ }
- switch_core_session_read_lock(peer_sessions[i]);
- pool = NULL;
+ switch_core_session_read_lock(peer_sessions[i]);
+ pool = NULL;
- peer_channels[i] = switch_core_session_get_channel(peer_sessions[i]);
- assert(peer_channels[i] != NULL);
+ peer_channels[i] = switch_core_session_get_channel(peer_sessions[i]);
+ assert(peer_channels[i] != NULL);
- if (!table) {
- table = &originate_state_handlers;
- }
+ if (!table) {
+ table = &originate_state_handlers;
+ }
- if (table) {
- switch_channel_add_state_handler(peer_channels[i], table);
- }
+ if (table) {
+ switch_channel_add_state_handler(peer_channels[i], table);
+ }
- if (switch_core_session_running(peer_sessions[i])) {
- switch_channel_set_state(peer_channels[i], CS_RING);
- } else {
- switch_core_session_thread_launch(peer_sessions[i]);
+ if (switch_core_session_running(peer_sessions[i])) {
+ switch_channel_set_state(peer_channels[i], CS_RING);
+ } else {
+ switch_core_session_thread_launch(peer_sessions[i]);
+ }
}
- }
- time(&start);
+ time(&start);
- for (;;) {
- uint32_t valid_channels = 0;
- for (i = 0; i < and_argc; i++) {
- int state;
+ for (;;) {
+ uint32_t valid_channels = 0;
+ for (i = 0; i < and_argc; i++) {
+ int state;
- if (!peer_channels[i]) {
- continue;
- }
- valid_channels++;
- state = switch_channel_get_state(peer_channels[i]);
+ if (!peer_channels[i]) {
+ continue;
+ }
+ valid_channels++;
+ state = switch_channel_get_state(peer_channels[i]);
- if (state >= CS_HANGUP) {
- goto notready;
- } else if (state >= CS_RING) {
- goto endfor1;
- }
+ if (state >= CS_HANGUP) {
+ goto notready;
+ } else if (state >= CS_RING) {
+ goto endfor1;
+ }
- if (caller_channel && !switch_channel_ready(caller_channel)) {
- goto notready;
- }
+ if (caller_channel && !switch_channel_ready(caller_channel)) {
+ goto notready;
+ }
- if ((time(NULL) - start) > (time_t)timelimit_sec) {
- to++;
- idx = IDX_CANCEL;
- goto notready;
+ if ((time(NULL) - start) > (time_t)timelimit_sec) {
+ to++;
+ idx = IDX_CANCEL;
+ goto notready;
+ }
+ switch_yield(1000);
}
- switch_yield(1000);
- }
- if (valid_channels == 0) {
- status = SWITCH_STATUS_GENERR;
- goto done;
- }
+ if (valid_channels == 0) {
+ status = SWITCH_STATUS_GENERR;
+ goto done;
+ }
- }
- endfor1:
+ }
+ endfor1:
- if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
- switch_channel_pre_answer(caller_channel);
- }
+ if (ringback_data && !switch_channel_test_flag(caller_channel, CF_ANSWERED) && !switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA)) {
+ switch_channel_pre_answer(caller_channel);
+ }
- if (session && (read_codec = switch_core_session_get_read_codec(session)) &&
- (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+ if (session && (read_codec = switch_core_session_get_read_codec(session)) &&
+ (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
- if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
- if (switch_core_codec_init(&write_codec,
- "L16",
- NULL,
- read_codec->implementation->samples_per_second,
- read_codec->implementation->microseconds_per_frame / 1000,
- 1,
- SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
- NULL,
- pool) == SWITCH_STATUS_SUCCESS) {
+ if (!(pass = (uint8_t)switch_test_flag(read_codec, SWITCH_CODEC_FLAG_PASSTHROUGH))) {
+ if (switch_core_codec_init(&write_codec,
+ "L16",
+ NULL,
+ read_codec->implementation->samples_per_second,
+ read_codec->implementation->microseconds_per_frame / 1000,
+ 1,
+ SWITCH_CODEC_FLAG_ENCODE | SWITCH_CODEC_FLAG_DECODE,
+ NULL,
+ pool) == SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
- read_codec->implementation->samples_per_second,
- read_codec->implementation->microseconds_per_frame / 1000);
- write_frame.codec = &write_codec;
- write_frame.datalen = read_codec->implementation->bytes_per_frame;
- write_frame.samples = write_frame.datalen / 2;
- memset(write_frame.data, 255, write_frame.datalen);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Raw Codec Activation Success L16@%uhz 1 channel %dms\n",
+ read_codec->implementation->samples_per_second,
+ read_codec->implementation->microseconds_per_frame / 1000);
+ write_frame.codec = &write_codec;
+ write_frame.datalen = read_codec->implementation->bytes_per_frame;
+ write_frame.samples = write_frame.datalen / 2;
+ memset(write_frame.data, 255, write_frame.datalen);
- if (ringback_data) {
- char *tmp_data = NULL;
+ if (ringback_data) {
+ char *tmp_data = NULL;
- switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
- switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
+ switch_buffer_create_dynamic(&ringback.audio_buffer, 512, 1024, 0);
+ switch_buffer_create_dynamic(&ringback.loop_buffer, 512, 1024, 0);
- if (*ringback_data == '/') {
- char *ext;
+ if (*ringback_data == '/') {
+ char *ext;
- if ((ext = strrchr(ringback_data, '.'))) {
- switch_core_session_set_read_codec(session, &write_codec);
- ext++;
- } else {
- ringback.asis++;
- write_frame.codec = read_codec;
- ext = read_codec->implementation->iananame;
- tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
- ringback_data = tmp_data;
- }
+ if ((ext = strrchr(ringback_data, '.'))) {
+ switch_core_session_set_read_codec(session, &write_codec);
+ ext++;
+ } else {
+ ringback.asis++;
+ write_frame.codec = read_codec;
+ ext = read_codec->implementation->iananame;
+ tmp_data = switch_mprintf("%s.%s", ringback_data, ext);
+ ringback_data = tmp_data;
+ }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback File [%s]\n", ringback_data);
- ringback.fhb.channels = read_codec->implementation->number_of_channels;
- ringback.fhb.samplerate = read_codec->implementation->samples_per_second;
- if (switch_core_file_open(&ringback.fhb,
- ringback_data,
- read_codec->implementation->number_of_channels,
- read_codec->implementation->samples_per_second,
- SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
- switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
- switch_safe_free(tmp_data);
- goto notready;
- }
- ringback.fh = &ringback.fhb;
+ ringback.fhb.channels = read_codec->implementation->number_of_channels;
+ ringback.fhb.samplerate = read_codec->implementation->samples_per_second;
+ if (switch_core_file_open(&ringback.fhb,
+ ringback_data,
+ read_codec->implementation->number_of_channels,
+ read_codec->implementation->samples_per_second,
+ SWITCH_FILE_FLAG_READ | SWITCH_FILE_DATA_SHORT,
+ switch_core_session_get_pool(session)) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing File\n");
+ switch_safe_free(tmp_data);
+ goto notready;
+ }
+ ringback.fh = &ringback.fhb;
- } else {
- teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
- //ringback.ts.debug = 1;
- //ringback.ts.debug_stream = switch_core_get_console();
- if (teletone_run(&ringback.ts, ringback_data)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
- teletone_destroy_session(&ringback.ts);
- switch_buffer_destroy(&ringback.audio_buffer);
- switch_buffer_destroy(&ringback.loop_buffer);
- ringback_data = NULL;
+ } else {
+ teletone_init_session(&ringback.ts, 0, teletone_handler, &ringback);
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Play Ringback Tone [%s]\n", ringback_data);
+ //ringback.ts.debug = 1;
+ //ringback.ts.debug_stream = switch_core_get_console();
+ if (teletone_run(&ringback.ts, ringback_data)) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Playing Tone\n");
+ teletone_destroy_session(&ringback.ts);
+ switch_buffer_destroy(&ringback.audio_buffer);
+ switch_buffer_destroy(&ringback.loop_buffer);
+ ringback_data = NULL;
+ }
}
+ switch_safe_free(tmp_data);
}
- switch_safe_free(tmp_data);
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error!");
+ switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
+ read_codec = NULL;
}
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Codec Error!");
- switch_channel_hangup(caller_channel, SWITCH_CAUSE_NORMAL_TEMPORARY_FAILURE);
- read_codec = NULL;
}
}
- }
- if (ringback_data) {
- early_ok = 0;
- }
-
- while ((!caller_channel || switch_channel_ready(caller_channel)) &&
- check_channel_status(peer_channels, peer_sessions, and_argc, &idx, &hups, file, key, early_ok, &ring_ready)) {
-
- // When the AND operator is being used, and fail_on_single_reject is set, a hangup indicates that the call should fail.
- if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec)) || (fail_on_single_reject && hups)) {
- idx = IDX_CANCEL;
- goto notready;
+ if (ringback_data) {
+ early_ok = 0;
}
- if (peer_sessions[0] && switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
- if (session && !ringback_data && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge and no ringback */
- switch_core_session_receive_message(session, message);
+ while ((!caller_channel || switch_channel_ready(caller_channel)) &&
+ check_channel_status(peer_channels, peer_sessions, and_argc, &idx, &hups, file, key, early_ok, &ring_ready)) {
+
+ // When the AND operator is being used, and fail_on_single_reject is set, a hangup indicates that the call should fail.
+ if ((to = (uint8_t)((time(NULL) - start) >= (time_t)timelimit_sec)) || (fail_on_single_reject && hups)) {
+ idx = IDX_CANCEL;
+ goto notready;
}
+
+ if (peer_sessions[0] && switch_core_session_dequeue_message(peer_sessions[0], &message) == SWITCH_STATUS_SUCCESS) {
+ if (session && !ringback_data && or_argc == 1 && and_argc == 1) { /* when there is only 1 channel to call and bridge and no ringback */
+ switch_core_session_receive_message(session, message);
+ }
- if (switch_test_flag(message, SCSMF_DYNAMIC)) {
- switch_safe_free(message);
- } else {
- message = NULL;
+ if (switch_test_flag(message, SCSMF_DYNAMIC)) {
+ switch_safe_free(message);
+ } else {
+ message = NULL;
+ }
}
- }
- /* read from the channel while we wait if the audio is up on it */
- if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) &&
- (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) {
- switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
+ /* read from the channel while we wait if the audio is up on it */
+ if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA)) &&
+ (switch_channel_test_flag(caller_channel, CF_ANSWERED) || switch_channel_test_flag(caller_channel, CF_EARLY_MEDIA))) {
+ switch_status_t status = switch_core_session_read_frame(session, &read_frame, 1000, 0);
- if (!SWITCH_READ_ACCEPTABLE(status)) {
- break;
- }
+ if (!SWITCH_READ_ACCEPTABLE(status)) {
+ break;
+ }
- if (ring_ready && read_frame && !pass && !switch_test_flag(read_frame, SFF_CNG) && read_frame->datalen > 1) {
- if (ringback.fh) {
- uint8_t abuf[1024];
- switch_size_t mlen, olen;
- unsigned int pos = 0;
+ if (ring_ready && read_frame && !pass && !switch_test_flag(read_frame, SFF_CNG) && read_frame->datalen > 1) {
+ if (ringback.fh) {
+ uint8_t abuf[1024];
+ switch_size_t mlen, olen;
+ unsigned int pos = 0;
- if (ringback.asis) {
- mlen = read_frame->datalen;
- } else {
- mlen = read_frame->datalen / 2;
- }
+ if (ringback.asis) {
+ mlen = read_frame->datalen;
+ } else {
+ mlen = read_frame->datalen / 2;
+ }
- olen = mlen;
- switch_core_file_read(ringback.fh, abuf, &olen);
-
- if (olen == 0) {
olen = mlen;
- ringback.fh->speed = 0;
- switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
switch_core_file_read(ringback.fh, abuf, &olen);
+
if (olen == 0) {
+ olen = mlen;
+ ringback.fh->speed = 0;
+ switch_core_file_seek(ringback.fh, &pos, 0, SEEK_SET);
+ switch_core_file_read(ringback.fh, abuf, &olen);
+ if (olen == 0) {
+ break;
+ }
+ }
+ write_frame.data = abuf;
+ write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
+ if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
break;
}
- }
- write_frame.data = abuf;
- write_frame.datalen = (uint32_t) (ringback.asis ? olen : olen * 2);
- if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
- break;
- }
- } else if (ringback.audio_buffer) {
- if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
- write_frame.data,
- write_frame.codec->implementation->bytes_per_frame)) <= 0) {
- switch_buffer_t *tmp;
- tmp = ringback.audio_buffer;
- ringback.audio_buffer = ringback.loop_buffer;
- ringback.loop_buffer = tmp;
+ } else if (ringback.audio_buffer) {
if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
write_frame.data,
write_frame.codec->implementation->bytes_per_frame)) <= 0) {
- break;
+ switch_buffer_t *tmp;
+ tmp = ringback.audio_buffer;
+ ringback.audio_buffer = ringback.loop_buffer;
+ ringback.loop_buffer = tmp;
+ if ((write_frame.datalen = (uint32_t)switch_buffer_read(ringback.audio_buffer,
+ write_frame.data,
+ write_frame.codec->implementation->bytes_per_frame)) <= 0) {
+ break;
+ }
}
}
- }
- if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
- break;
- }
- if (ringback.loop_buffer) {
- switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
+ if (switch_core_session_write_frame(session, &write_frame, 1000, 0) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ if (ringback.loop_buffer) {
+ switch_buffer_write(ringback.loop_buffer, write_frame.data, write_frame.datalen);
+ }
}
- }
- } else {
- switch_yield(1000);
- }
+ } else {
+ switch_yield(1000);
+ }
- }
-
- notready:
+ }
- if (caller_channel && !switch_channel_ready(caller_channel)) {
- idx = IDX_CANCEL;
- }
+ notready:
- if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
- switch_core_session_reset(session);
- }
+ if (caller_channel && !switch_channel_ready(caller_channel)) {
+ idx = IDX_CANCEL;
+ }
- for (i = 0; i < and_argc; i++) {
- if (!peer_channels[i]) {
- continue;
+ if (session && (ringback_data || !switch_channel_test_flag(caller_channel, CF_NOMEDIA))) {
+ switch_core_session_reset(session);
}
- if (i != idx) {
- if (idx == IDX_CANCEL) {
- if (to) {
- reason = SWITCH_CAUSE_NO_ANSWER;
- } else {
- reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
- }
- } else {
- if (to) {
- reason = SWITCH_CAUSE_NO_ANSWER;
- } else if (and_argc > 1) {
- reason = SWITCH_CAUSE_LOSE_RACE;
+
+ for (i = 0; i < and_argc; i++) {
+ if (!peer_channels[i]) {
+ continue;
+ }
+ if (i != idx) {
+ if (idx == IDX_CANCEL) {
+ if (to) {
+ reason = SWITCH_CAUSE_NO_ANSWER;
+ } else {
+ reason = SWITCH_CAUSE_ORIGINATOR_CANCEL;
+ }
} else {
- reason = SWITCH_CAUSE_NO_ANSWER;
+ if (to) {
+ reason = SWITCH_CAUSE_NO_ANSWER;
+ } else if (and_argc > 1) {
+ reason = SWITCH_CAUSE_LOSE_RACE;
+ } else {
+ reason = SWITCH_CAUSE_NO_ANSWER;
+ }
}
- }
- switch_channel_hangup(peer_channels[i], reason);
+ switch_channel_hangup(peer_channels[i], reason);
+ }
}
- }
- if (idx > IDX_NADA) {
- peer_session = peer_sessions[idx];
- peer_channel = peer_channels[idx];
- } else {
- status = SWITCH_STATUS_FALSE;
- goto done;
- }
+ if (idx > IDX_NADA) {
+ peer_session = peer_sessions[idx];
+ peer_channel = peer_channels[idx];
+ } else {
+ status = SWITCH_STATUS_FALSE;
+ goto done;
+ }
- if (caller_channel) {
- if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
- switch_channel_answer(caller_channel);
- } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
- switch_channel_pre_answer(caller_channel);
+ if (caller_channel) {
+ if (switch_channel_test_flag(peer_channel, CF_ANSWERED)) {
+ switch_channel_answer(caller_channel);
+ } else if (switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+ switch_channel_pre_answer(caller_channel);
+ }
}
- }
- if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
- *bleg = peer_session;
- status = SWITCH_STATUS_SUCCESS;
- } else {
- status = SWITCH_STATUS_FALSE;
- }
+ if (switch_channel_test_flag(peer_channel, CF_ANSWERED) || switch_channel_test_flag(peer_channel, CF_EARLY_MEDIA)) {
+ *bleg = peer_session;
+ status = SWITCH_STATUS_SUCCESS;
+ } else {
+ status = SWITCH_STATUS_FALSE;
+ }
- done:
- *cause = SWITCH_CAUSE_UNALLOCATED;
+ done:
+ *cause = SWITCH_CAUSE_UNALLOCATED;
- if (var_event) {
- if (peer_channel && !caller_channel) { /* install the vars from the {} params */
- switch_event_header_t *header;
- for (header = var_event->headers; header; header = header->next) {
- switch_channel_set_variable(peer_channel, header->name, header->value);
- }
- }
- switch_event_destroy(&var_event);
- }
+ if (var_event) {
+ if (peer_channel && !caller_channel) { /* install the vars from the {} params */
+ switch_event_header_t *header;
+ for (header = var_event->headers; header; header = header->next) {
+ switch_channel_set_variable(peer_channel, header->name, header->value);
+ }
+ }
+ switch_event_destroy(&var_event);
+ }
- if (status == SWITCH_STATUS_SUCCESS) {
- if (caller_channel) {
- switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
- }
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", switch_channel_get_name(peer_channel));
- *cause = SWITCH_CAUSE_SUCCESS;
+ if (status == SWITCH_STATUS_SUCCESS) {
+ if (caller_channel) {
+ switch_channel_set_variable(caller_channel, "originate_disposition", "call accepted");
+ }
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Success: [%s]\n", switch_channel_get_name(peer_channel));
+ *cause = SWITCH_CAUSE_SUCCESS;
- } else {
- if (peer_channel) {
- *cause = switch_channel_get_cause(peer_channel);
} else {
- for (i = 0; i < and_argc; i++) {
- if (!peer_channels[i]) {
- continue;
+ if (peer_channel) {
+ *cause = switch_channel_get_cause(peer_channel);
+ } else {
+ for (i = 0; i < and_argc; i++) {
+ if (!peer_channels[i]) {
+ continue;
+ }
+ *cause = switch_channel_get_cause(peer_channels[i]);
+ break;
}
- *cause = switch_channel_get_cause(peer_channels[i]);
- break;
}
- }
- if (!*cause) {
- if (reason) {
- *cause = reason;
- } else if (caller_channel) {
- *cause = switch_channel_get_cause(caller_channel);
- } else {
- *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
- }
- }
+ if (!*cause) {
+ if (reason) {
+ *cause = reason;
+ } else if (caller_channel) {
+ *cause = switch_channel_get_cause(caller_channel);
+ } else {
+ *cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+ }
+ }
- if (idx == IDX_CANCEL) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
- *cause, switch_channel_cause2str(*cause));
+ if (idx == IDX_CANCEL) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Cancelled by originator termination Cause: %d [%s]\n",
+ *cause, switch_channel_cause2str(*cause));
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Error Cause: %d [%s]\n",
- *cause, switch_channel_cause2str(*cause));
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Originate Resulted in Error Cause: %d [%s]\n",
+ *cause, switch_channel_cause2str(*cause));
+ }
}
- }
- if (caller_channel) {
- switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
- }
-
- if (!pass && write_codec.implementation) {
- switch_core_codec_destroy(&write_codec);
- }
+ if (caller_channel) {
+ switch_channel_set_variable(caller_channel, "originate_disposition", switch_channel_cause2str(*cause));
+ }
- if (ringback.fh) {
- switch_core_file_close(ringback.fh);
- ringback.fh = NULL;
- if (read_codec && !ringback.asis) {
- switch_core_session_set_read_codec(session, read_codec);
- switch_core_session_reset(session);
+ if (!pass && write_codec.implementation) {
+ switch_core_codec_destroy(&write_codec);
}
- } else if (ringback.audio_buffer) {
- teletone_destroy_session(&ringback.ts);
- switch_buffer_destroy(&ringback.audio_buffer);
- switch_buffer_destroy(&ringback.loop_buffer);
- }
- for (i = 0; i < and_argc; i++) {
- if (!peer_channels[i]) {
- continue;
+ if (ringback.fh) {
+ switch_core_file_close(ringback.fh);
+ ringback.fh = NULL;
+ if (read_codec && !ringback.asis) {
+ switch_core_session_set_read_codec(session, read_codec);
+ switch_core_session_reset(session);
+ }
+ } else if (ringback.audio_buffer) {
+ teletone_destroy_session(&ringback.ts);
+ switch_buffer_destroy(&ringback.audio_buffer);
+ switch_buffer_destroy(&ringback.loop_buffer);
}
- switch_core_session_rwunlock(peer_sessions[i]);
- }
- if (status == SWITCH_STATUS_SUCCESS) {
- break;
+ for (i = 0; i < and_argc; i++) {
+ if (!peer_channels[i]) {
+ continue;
+ }
+ switch_core_session_rwunlock(peer_sessions[i]);
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ goto outer_for;
+ }
}
}
-
+ outer_for:
+ switch_safe_free(loop_data);
switch_safe_free(odata);
return status;
}
1
0
Author: mikej
Date: Tue Mar 27 01:15:16 2007
New Revision: 4775
Modified:
freeswitch/trunk/libs/libdingaling/src/libdingaling.c
Log:
use logger for iksemel logs too instead of stderr.
Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.c
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.c (original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.c Tue Mar 27 01:15:16 2007
@@ -1218,15 +1218,12 @@
static void on_log(ldl_handle_t *handle, const char *data, size_t size, int is_incoming)
{
- if (iks_is_secure(handle->parser)) {
- fprintf(stderr, "Sec");
+ if (globals.debug) {
+ globals.logger(DL_LOG_DEBUG, "\n%s%s[%s]\n",
+ iks_is_secure(handle->parser) ? "Sec" : "",
+ is_incoming ? "RECV" : "SEND",
+ data);
}
- if (is_incoming) {
- fprintf(stderr, "RECV");
- } else {
- fprintf(stderr, "SEND");
- }
- fprintf(stderr, "[%s]\n", data);
}
static void j_setup_filter(ldl_handle_t *handle)
1
0
Author: mikej
Date: Tue Mar 27 00:14:48 2007
New Revision: 4774
Modified:
freeswitch/trunk/libs/libdingaling/src/libdingaling.c
Log:
reconnect on failure
Modified: freeswitch/trunk/libs/libdingaling/src/libdingaling.c
==============================================================================
--- freeswitch/trunk/libs/libdingaling/src/libdingaling.c (original)
+++ freeswitch/trunk/libs/libdingaling/src/libdingaling.c Tue Mar 27 00:14:48 2007
@@ -1423,16 +1423,18 @@
break;
case IKS_NET_NODNS:
globals.logger(DL_LOG_DEBUG, "hostname lookup failed\n");
+ microsleep(1000);
+ goto fail;
case IKS_NET_NOCONN:
globals.logger(DL_LOG_DEBUG, "connection failed\n");
+ microsleep(1000);
+ goto fail;
default:
- globals.logger(DL_LOG_DEBUG, "io error %d\n", e);
- microsleep(500);
- continue;
+ globals.logger(DL_LOG_DEBUG, "io error 1 %d\n", e);
+ microsleep(1000);
+ goto fail;
}
-
-
handle->counter = opt_timeout;
if (ldl_test_flag(handle, LDL_FLAG_TLS)) {
launch_queue_thread(handle);
@@ -1456,9 +1458,9 @@
}
if (IKS_OK != e) {
- globals.logger(DL_LOG_DEBUG, "io error %d\n", e);
- microsleep(500);
- break;
+ globals.logger(DL_LOG_DEBUG, "io error 2 %d\n", e);
+ microsleep(1000);
+ goto fail;
}
@@ -1481,10 +1483,12 @@
}
}
+ fail:
iks_disconnect(handle->parser);
iks_parser_delete(handle->parser);
ldl_clear_flag_locked(handle, LDL_FLAG_CONNECTED);
ldl_clear_flag_locked(handle, LDL_FLAG_AUTHORIZED);
+ handle->state = CS_NEW;
}
ldl_clear_flag_locked(handle, LDL_FLAG_RUNNING);
1
0
[commit] r4773 - in freeswitch/trunk/src: . include mod/languages/mod_spidermonkey
by Freeswitch SVN 27 Mar '07
by Freeswitch SVN 27 Mar '07
27 Mar '07
Author: anthm
Date: Mon Mar 26 20:40:53 2007
New Revision: 4773
Modified:
freeswitch/trunk/src/include/switch_core.h
freeswitch/trunk/src/include/switch_module_interfaces.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h
freeswitch/trunk/src/switch_core.c
Log:
Add state change i/o hook to the core and change some spidermonkey behaviour.
The most important thing to check is you now must create a new session with a blank constructor:
s = new Session();
then call s.originate() with all the former args that were documented to be for the constructor
this will will return true or false to indicate if the call worked.
See below this sample code demonstrates all of the changes:
////////////////////////////////////////////////////////////////////////////////
function on_hangup(hup_session)
{
console_log("debug", "HANGUP!!!! name: " + hup_session.name + " cause: " + hup_session.cause + "\n");
//exit here would end the script so you could cleanup and just be done
//exit();
}
//set the on_hangup function to be called when this session is hungup
session.setHangupHook(on_hangup);
//allocate a new b_session
var b_session = new Session();
//make a call with b_session. If this fails, all we will be able to access is the b_session.cause attr
if (b_session.originate(session, "sofia/mydomain.com/888@conference.freeswitch.org")) {
//Inform the scripting engine to automaticly hang this session up when the script ends
b_session.setAutoHangup(true);
//set the on_hangup function to be called when this session is hungup
b_session.setHangupHook(on_hangup);
//bridge session with b_session
bridge(session, b_session);
} else {
console_log("debug", "Originate Failed.. cause: " + b_session.cause + "\n");
}
////////////////////////////////////////////////////////////////////////////////
Modified: freeswitch/trunk/src/include/switch_core.h
==============================================================================
--- freeswitch/trunk/src/include/switch_core.h (original)
+++ freeswitch/trunk/src/include/switch_core.h Mon Mar 26 20:40:53 2007
@@ -856,6 +856,15 @@
\return SWITCH_STATUS_SUCCESS on suceess
*/
SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_send_dtmf(switch_core_session_t *session, switch_send_dtmf_hook_t send_dtmf);
+
+/*!
+ \brief Add an event hook to be executed when a session receives a state change signal
+ \param session session to bind hook to
+ \param state_change hook to bind
+ \return SWITCH_STATUS_SUCCESS on suceess
+*/
+SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_state_change(switch_core_session_t *session,
+ switch_answer_channel_hook_t state_change);
///\}
///\defgroup hashf Hash Functions
Modified: freeswitch/trunk/src/include/switch_module_interfaces.h
==============================================================================
--- freeswitch/trunk/src/include/switch_module_interfaces.h (original)
+++ freeswitch/trunk/src/include/switch_module_interfaces.h Mon Mar 26 20:40:53 2007
@@ -145,6 +145,13 @@
struct switch_io_event_hook_send_dtmf *next;
};
+/*! \brief Node in which to store state change callback hooks */
+struct switch_io_event_hook_state_change {
+ /*! the send dtmf channel callback hook*/
+ switch_state_change_hook_t state_change;
+ struct switch_io_event_hook_state_change *next;
+};
+
/*! \brief A table of lists of io_event_hooks to store the event hooks associated with a session */
struct switch_io_event_hooks {
/*! a list of outgoing channel hooks */
@@ -167,6 +174,8 @@
switch_io_event_hook_waitfor_write_t *waitfor_write;
/*! a list of send dtmf hooks */
switch_io_event_hook_send_dtmf_t *send_dtmf;
+ /*! a list of state change hooks */
+ switch_io_event_hook_state_change_t *state_change;
};
/*! \brief A table of i/o routines that an endpoint interface can implement */
@@ -191,6 +200,8 @@
switch_status_t (*receive_message)(switch_core_session_t *, switch_core_session_message_t *);
/*! queue a message for another session*/
switch_status_t (*receive_event)(switch_core_session_t *, switch_event_t *);
+ /*! change a sessions channel state */
+ switch_status_t (*state_change)(switch_core_session_t *);
};
/*! \brief Abstraction of an module endpoint interface
Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Mon Mar 26 20:40:53 2007
@@ -954,6 +954,7 @@
typedef struct switch_io_event_hook_waitfor_read switch_io_event_hook_waitfor_read_t;
typedef struct switch_io_event_hook_waitfor_write switch_io_event_hook_waitfor_write_t;
typedef struct switch_io_event_hook_send_dtmf switch_io_event_hook_send_dtmf_t;
+typedef struct switch_io_event_hook_state_change switch_io_event_hook_state_change_t;
typedef struct switch_io_routines switch_io_routines_t;
typedef struct switch_io_event_hooks switch_io_event_hooks_t;
typedef struct switch_speech_handle switch_speech_handle_t;
@@ -989,6 +990,7 @@
typedef switch_status_t (*switch_waitfor_read_hook_t)(switch_core_session_t *, int, int);
typedef switch_status_t (*switch_waitfor_write_hook_t)(switch_core_session_t *, int, int);
typedef switch_status_t (*switch_send_dtmf_hook_t)(switch_core_session_t *, char *);
+typedef switch_status_t (*switch_state_change_hook_t)(switch_core_session_t *);
typedef struct switch_stream_handle switch_stream_handle_t;
typedef switch_status_t (*switch_stream_handle_write_function_t)(switch_stream_handle_t *handle, const char *fmt, ...);
typedef switch_status_t (*switch_api_function_t)(char *in, switch_core_session_t *session, switch_stream_handle_t *stream);
Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c (original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.c Mon Mar 26 20:40:53 2007
@@ -43,6 +43,7 @@
static void session_destroy(JSContext *cx, JSObject *obj);
static JSBool session_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
+static JSBool session_originate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval);
static switch_api_interface_t js_run_interface;
static struct {
@@ -79,7 +80,8 @@
typedef struct sm_loadable_module sm_loadable_module_t;
typedef enum {
- S_HUP = (1 << 0)
+ S_HUP = (1 << 0),
+ S_FREE = (1 << 1)
} session_flag_t;
struct input_callback_state {
@@ -640,7 +642,8 @@
jsval argv[4];
JSObject *Event = NULL;
- if (!jss) {
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
return SWITCH_STATUS_FALSE;
}
@@ -822,15 +825,15 @@
switch_size_t has;
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
-
while ((has = switch_channel_has_dtmf(channel))) {
switch_channel_dequeue_dtmf(channel, buf, sizeof(buf));
}
@@ -845,14 +848,14 @@
switch_event_t *event;
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
while (switch_core_session_dequeue_event(jss->session, &event) == SWITCH_STATUS_SUCCESS) {
switch_event_destroy(&event);
@@ -877,6 +880,12 @@
int32 limit = 0;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -953,6 +962,13 @@
JSFunction *function;
switch_input_args_t args = {0};
+
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1014,6 +1030,12 @@
JSFunction *function;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1074,6 +1096,55 @@
return JS_TRUE;
}
+static void check_hangup_hook(struct js_session *jss)
+{
+ jsval argv[2] = {0};
+ int argc = 0;
+ jsval ret;
+ if (jss->on_hangup ) {
+ argv[argc++] = OBJECT_TO_JSVAL(jss->obj);
+ JS_CallFunction(jss->cx, jss->obj, jss->on_hangup, argc, argv, &ret);
+ }
+}
+
+static switch_status_t hanguphook(switch_core_session_t *session)
+{
+ switch_channel_t *channel;
+ struct js_session *jss = NULL;
+
+ channel = switch_core_session_get_channel(session);
+ assert(channel != NULL);
+ if (switch_channel_get_state(channel) == CS_HANGUP) {
+ if ((jss = switch_channel_get_private(channel, "jss"))) {
+ check_hangup_hook(jss);
+ }
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+}
+
+static JSBool session_hanguphook(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ JSFunction *function;
+ struct js_session *jss;
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+
+ if ((jss = JS_GetPrivate(cx, obj)) && jss->session) {
+ if (argc > 0) {
+ if ((function = JS_ValueToFunction(cx, argv[0]))) {
+ switch_channel_t *channel = switch_core_session_get_channel(jss->session);
+ assert(channel != NULL);
+ jss->on_hangup = function;
+ switch_channel_set_private(channel, "jss", jss);
+ switch_core_session_add_event_hook_state_change(jss->session, hanguphook);
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ }
+ }
+ }
+
+ return JS_TRUE;
+}
+
static JSBool session_streamfile(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
struct js_session *jss = JS_GetPrivate(cx, obj);
@@ -1088,6 +1159,12 @@
JSFunction *function;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1147,16 +1224,15 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
-
-
if (argc > 1) {
char *var, *val;
@@ -1176,16 +1252,14 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
-
-
if (argc > 0) {
char *var, *val;
@@ -1220,6 +1294,12 @@
JSFunction *function;
switch_input_args_t args = {0};
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1286,6 +1366,12 @@
int32 digits = 0, timeout = 5000;
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1321,11 +1407,42 @@
return JS_FALSE;
}
+static JSBool session_autohangup(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ struct js_session *jss = JS_GetPrivate(cx, obj);
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
+
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
+ if (argv[0]) {
+ JSBool tf;
+ JS_ValueToBoolean(cx, argv[0], &tf);
+ if (tf == JS_TRUE) {
+ switch_set_flag(jss, S_HUP);
+ } else {
+ switch_clear_flag(jss, S_HUP);
+ }
+ *rval = BOOLEAN_TO_JSVAL(tf);
+ }
+
+ return JS_TRUE;
+}
+
static JSBool session_answer(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1349,6 +1466,11 @@
/*Always a pessimist... sheesh!*/
*rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ return JS_TRUE;
+ }
+
if (switch_ivr_generate_xml_cdr(jss->session, &cdr) == SWITCH_STATUS_SUCCESS) {
char *xml_text;
if ((xml_text = switch_xml_toxml(cdr))) {
@@ -1366,6 +1488,12 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_channel_t *channel;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1384,6 +1512,12 @@
unsigned int elapsed;
int32 timeout = 60;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1419,6 +1553,12 @@
unsigned int elapsed;
int32 timeout = 60;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1451,6 +1591,12 @@
switch_channel_t *channel;
struct js_session *jss = JS_GetPrivate(cx, obj);
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1468,6 +1614,12 @@
struct js_session *jss = JS_GetPrivate(cx, obj);
jsrefcount saveDepth;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
if (application_interface->application_function) {
saveDepth = JS_SuspendRequest(cx);
@@ -1486,17 +1638,12 @@
{
struct js_session *jss = JS_GetPrivate(cx, obj);
switch_event_t *event;
- switch_channel_t *channel;
-
- channel = switch_core_session_get_channel(jss->session);
- assert(channel != NULL);
-
- if (!switch_channel_ready(channel)) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Session is not active!\n");
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
- return JS_TRUE;
- }
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
if (switch_core_session_dequeue_event(jss->session, &event) == SWITCH_STATUS_SUCCESS) {
JSObject *Event;
@@ -1528,6 +1675,12 @@
JSObject *Event;
struct event_obj *eo;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
if (argc > 0) {
if (JS_ValueToObject(cx, argv[0], &Event)) {
if ((eo = JS_GetPrivate(cx, Event))) {
@@ -1554,6 +1707,12 @@
char *cause_name = NULL;
switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
+ if (!jss || !jss->session) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "You must call the session.originate method before calling this method!\n");
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+ return JS_TRUE;
+ }
+
channel = switch_core_session_get_channel(jss->session);
assert(channel != NULL);
@@ -1722,10 +1881,13 @@
/*********************************************************************************/
enum session_tinyid {
SESSION_NAME, SESSION_STATE,
- PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI_II, PROFILE_DEST, SESSION_UUID
+ PROFILE_DIALPLAN, PROFILE_CID_NAME, PROFILE_CID_NUM, PROFILE_IP, PROFILE_ANI, PROFILE_ANI_II, PROFILE_DEST, SESSION_UUID, SESSION_CAUSE
};
static JSFunctionSpec session_methods[] = {
+ {"originate", session_originate, 2},
+ {"setHangupHook", session_hanguphook, 1},
+ {"setAutoHangup", session_autohangup, 1},
{"sayPhrase", session_sayphrase, 1},
{"streamFile", session_streamfile, 1},
{"collectInput", session_collect_input, 1},
@@ -1760,6 +1922,7 @@
{"aniii", PROFILE_ANI_II, JSPROP_READONLY|JSPROP_PERMANENT},
{"destination", PROFILE_DEST, JSPROP_READONLY|JSPROP_PERMANENT},
{"uuid", SESSION_UUID, JSPROP_READONLY|JSPROP_PERMANENT},
+ {"cause", SESSION_CAUSE, JSPROP_READONLY|JSPROP_PERMANENT},
{0}
};
@@ -1767,29 +1930,40 @@
{
struct js_session *jss = JS_GetPrivate(cx, obj);
int param = 0;
- JSBool res = JS_TRUE;
- switch_channel_t *channel;
- switch_caller_profile_t *caller_profile;
- char *name;
-
- if (!jss || !jss->session) {
- return JS_FALSE;
+ switch_channel_t *channel = NULL;
+ switch_caller_profile_t *caller_profile = NULL;
+ char *name = NULL;
+
+ if (jss && jss->session) {
+ channel = switch_core_session_get_channel(jss->session);
+ assert(channel != NULL);
+ caller_profile = switch_channel_get_caller_profile(channel);
}
- channel = switch_core_session_get_channel(jss->session);
- assert(channel != NULL);
-
- caller_profile = switch_channel_get_caller_profile(channel);
-
name = JS_GetStringBytes(JS_ValueToString(cx, id));
+
/* numbers are our props anything else is a method */
if (name[0] >= 48 && name[0] <= 57) {
param = atoi(name);
} else {
return JS_TRUE;
}
-
+
+ if (!channel) {
+ switch(param) {
+ case SESSION_CAUSE:
+ *vp = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, switch_channel_cause2str(jss->cause)));
+ break;
+ default:
+ *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
+ }
+ return JS_TRUE;
+ }
+
switch(param) {
+ case SESSION_CAUSE:
+ *vp = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, switch_channel_cause2str(switch_channel_get_cause(channel))));
+ break;
case SESSION_NAME:
*vp = STRING_TO_JSVAL(JS_NewStringCopyZ(cx, switch_channel_get_name(channel)));
break;
@@ -1835,12 +2009,12 @@
}
break;
default:
- res = JS_FALSE;
+ *vp = BOOLEAN_TO_JSVAL(JS_FALSE);
break;
-
+
}
- return res;
+ return JS_TRUE;
}
JSClass session_class = {
@@ -1859,7 +2033,7 @@
jss->session = session;
jss->flags = flags;
jss->cx = cx;
- jss->obj = obj;
+ jss->obj = session_obj;
if ((JS_SetPrivate(cx, session_obj, jss) &&
JS_DefineProperties(cx, session_obj, session_props) &&
JS_DefineFunctions(cx, session_obj, session_methods))) {
@@ -1870,18 +2044,36 @@
return NULL;
}
-
/* Session Object */
/*********************************************************************************/
+
static JSBool session_construct(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
{
+ struct js_session *jss = NULL;
+
+ assert((jss = malloc(sizeof(*jss))));
+ memset(jss, 0, sizeof(*jss));
+ jss->cx = cx;
+ jss->obj = obj;
+ switch_set_flag(jss, S_FREE);
+
+ JS_SetPrivate(cx, obj, jss);
+
+ return JS_TRUE;
+}
+
+static JSBool session_originate(JSContext *cx, JSObject *obj, uintN argc, jsval *argv, jsval *rval)
+{
+ struct js_session *jss = NULL;
switch_memory_pool_t *pool = NULL;
+
+ jss = JS_GetPrivate(cx, obj);
+ jss->cause = SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER;
+
if (argc > 1) {
- switch_call_cause_t cause = SWITCH_CAUSE_NORMAL_CLEARING;
- struct js_session *jss = NULL;
JSObject *session_obj;
switch_core_session_t *session = NULL, *peer_session = NULL;
- switch_caller_profile_t *caller_profile = NULL;
+ switch_caller_profile_t *caller_profile = NULL, *orig_caller_profile = NULL;
char *dest = NULL;
char *dialplan = NULL;
char *cid_name = "";
@@ -1893,12 +2085,22 @@
char *context = "";
char *username = NULL;
char *to = NULL;
- *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
+
+ *rval = BOOLEAN_TO_JSVAL(JS_FALSE);
if (JS_ValueToObject(cx, argv[0], &session_obj)) {
struct js_session *old_jss = NULL;
if ((old_jss = JS_GetPrivate(cx, session_obj))) {
session = old_jss->session;
+ orig_caller_profile = switch_channel_get_caller_profile(switch_core_session_get_channel(session));
+ dialplan = orig_caller_profile->dialplan;
+ cid_name = orig_caller_profile->caller_id_name;
+ cid_num = orig_caller_profile->caller_id_number;
+ ani = orig_caller_profile->ani;
+ aniii = orig_caller_profile->aniii;
+ rdnis = orig_caller_profile->rdnis;
+ context = orig_caller_profile->context;
+ username = orig_caller_profile->username;
}
}
@@ -1906,7 +2108,7 @@
if (!strchr(dest, '/')) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Invalid Channel String\n");
- return JS_TRUE;
+ goto done;
}
if (argc > 2) {
@@ -1940,7 +2142,6 @@
to = JS_GetStringBytes(JS_ValueToString(cx, argv[11]));
}
-
if (switch_core_new_memory_pool(&pool) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "OH OH no pool\n");
return JS_FALSE;
@@ -1959,41 +2160,45 @@
context,
dest);
- if (switch_ivr_originate(session, &peer_session, &cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile) != SWITCH_STATUS_SUCCESS) {
+ if (switch_ivr_originate(session, &peer_session, &jss->cause, dest, to ? atoi(to) : 60, NULL, NULL, NULL, caller_profile) != SWITCH_STATUS_SUCCESS) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Cannot Create Outgoing Channel! [%s]\n", dest);
- return JS_TRUE;
+ goto done;
}
- *rval = STRING_TO_JSVAL (JS_NewStringCopyZ(cx, switch_channel_cause2str(cause)));
-
- jss = switch_core_session_alloc(peer_session, sizeof(*jss));
jss->session = peer_session;
jss->flags = 0;
- jss->cx = cx;
- jss->obj = obj;
- JS_SetPrivate(cx, obj, jss);
- switch_set_flag(jss, S_HUP);
+
+ *rval = BOOLEAN_TO_JSVAL(JS_TRUE);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "Missing Args\n");
}
+ done:
return JS_TRUE;
}
+
+
+
static void session_destroy(JSContext *cx, JSObject *obj)
{
struct js_session *jss;
+ switch_channel_t *channel = NULL;
if (cx && obj) {
if ((jss = JS_GetPrivate(cx, obj))) {
- if (switch_test_flag(jss, S_HUP)) {
- switch_channel_t *channel;
+ if (jss->session) {
+ channel = switch_core_session_get_channel(jss->session);
+ switch_channel_set_private(channel, "jss", NULL);
+ }
- if (jss->session) {
- channel = switch_core_session_get_channel(jss->session);
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- }
+ if (channel && switch_test_flag(jss, S_HUP)) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ }
+
+ if (switch_test_flag(jss, S_FREE)) {
+ free(jss);
}
}
}
@@ -2073,8 +2278,9 @@
switch_size_t read = 0;
*rval = BOOLEAN_TO_JSVAL( JS_FALSE );
-
- if (fio) {
+
+ if (!fio) {
+ *rval = BOOLEAN_TO_JSVAL( JS_FALSE );
return JS_TRUE;
}
Modified: freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h
==============================================================================
--- freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h (original)
+++ freeswitch/trunk/src/mod/languages/mod_spidermonkey/mod_spidermonkey.h Mon Mar 26 20:40:53 2007
@@ -132,6 +132,8 @@
JSContext *cx;
JSObject *obj;
unsigned int flags;
+ switch_call_cause_t cause;
+ JSFunction *on_hangup;
};
Modified: freeswitch/trunk/src/switch_core.c
==============================================================================
--- freeswitch/trunk/src/switch_core.c (original)
+++ freeswitch/trunk/src/switch_core.c Mon Mar 26 20:40:53 2007
@@ -185,7 +185,6 @@
/* The main runtime obj we keep this hidden for ourselves */
static struct switch_core_runtime runtime;
-
static void db_pick_path(char *dbname, char *buf, switch_size_t size)
{
@@ -1835,20 +1834,22 @@
SWITCH_DECLARE(switch_status_t) switch_core_session_answer_channel(switch_core_session_t *session)
{
switch_io_event_hook_answer_channel_t *ptr;
- switch_status_t status = SWITCH_STATUS_FALSE;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
assert(session != NULL);
+
if (session->endpoint_interface->io_routines->answer_channel) {
- if ((status = session->endpoint_interface->io_routines->answer_channel(session)) == SWITCH_STATUS_SUCCESS) {
- for (ptr = session->event_hooks.answer_channel; ptr; ptr = ptr->next) {
- if ((status = ptr->answer_channel(session)) != SWITCH_STATUS_SUCCESS) {
- break;
- }
+ status = session->endpoint_interface->io_routines->answer_channel(session);
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ for (ptr = session->event_hooks.answer_channel; ptr; ptr = ptr->next) {
+ if ((status = ptr->answer_channel(session)) != SWITCH_STATUS_SUCCESS) {
+ break;
}
}
- } else {
- status = SWITCH_STATUS_SUCCESS;
}
+
return status;
}
@@ -1856,19 +1857,23 @@
SWITCH_DECLARE(switch_status_t) switch_core_session_receive_message(switch_core_session_t *session, switch_core_session_message_t *message)
{
switch_io_event_hook_receive_message_t *ptr;
- switch_status_t status = SWITCH_STATUS_FALSE;
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
assert(session != NULL);
+
if (session->endpoint_interface->io_routines->receive_message) {
- if ((status =
- session->endpoint_interface->io_routines->receive_message(session, message)) == SWITCH_STATUS_SUCCESS) {
- for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
- if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
- break;
- }
+ status = session->endpoint_interface->io_routines->receive_message(session, message);
+
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ for (ptr = session->event_hooks.receive_message; ptr; ptr = ptr->next) {
+ if ((status = ptr->receive_message(session, message)) != SWITCH_STATUS_SUCCESS) {
+ break;
}
}
}
+
switch_core_session_kill_channel(session, SWITCH_SIG_BREAK);
return status;
}
@@ -2874,6 +2879,31 @@
}
+SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_state_change(switch_core_session_t *session,
+ switch_answer_channel_hook_t state_change)
+
+
+{
+ switch_io_event_hook_state_change_t *hook, *ptr;
+
+ assert(state_change != NULL);
+ if ((hook = switch_core_session_alloc(session, sizeof(*hook))) != 0) {
+ hook->state_change = state_change;
+ if (!session->event_hooks.state_change) {
+ session->event_hooks.state_change = hook;
+ } else {
+ for (ptr = session->event_hooks.state_change; ptr && ptr->next; ptr = ptr->next);
+ ptr->next = hook;
+
+ }
+
+ return SWITCH_STATUS_SUCCESS;
+ }
+
+ return SWITCH_STATUS_MEMERR;
+
+}
+
SWITCH_DECLARE(switch_status_t) switch_core_session_add_event_hook_read_frame(switch_core_session_t *session,
switch_read_frame_hook_t read_frame)
{
@@ -3216,13 +3246,26 @@
SWITCH_DECLARE(void) switch_core_session_signal_state_change(switch_core_session_t *session)
{
+ switch_status_t status = SWITCH_STATUS_SUCCESS;
+ switch_io_event_hook_state_change_t *ptr;
/* If trylock fails the signal is already awake so we needn't bother */
if (switch_mutex_trylock(session->mutex) == SWITCH_STATUS_SUCCESS) {
switch_thread_cond_signal(session->cond);
switch_mutex_unlock(session->mutex);
}
-
+
+ if (session->endpoint_interface->io_routines->state_change) {
+ status = session->endpoint_interface->io_routines->state_change(session);
+ }
+
+ if (status == SWITCH_STATUS_SUCCESS) {
+ for (ptr = session->event_hooks.state_change; ptr; ptr = ptr->next) {
+ if ((status = ptr->state_change(session)) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
+ }
}
SWITCH_DECLARE(unsigned int) switch_core_session_running(switch_core_session_t *session)
1
0
26 Mar '07
Author: mikej
Date: Mon Mar 26 17:35:19 2007
New Revision: 4771
Modified:
freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
Log:
don't double switch_xml_free
Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c (original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c Mon Mar 26 17:35:19 2007
@@ -368,6 +368,7 @@
switch_xml_free(xml);
+ xml = NULL;
if (extension) {
switch_channel_set_state(channel, CS_EXECUTE);
1
0
[commit] r4770 - in freeswitch/trunk: libs libs/portaudio/test src/mod/event_handlers/mod_cdr
by Freeswitch SVN 26 Mar '07
by Freeswitch SVN 26 Mar '07
26 Mar '07
Author: mikej
Date: Mon Mar 26 17:21:44 2007
New Revision: 4770
Modified:
freeswitch/trunk/libs/ (props changed)
freeswitch/trunk/libs/portaudio/test/ (props changed)
freeswitch/trunk/src/mod/event_handlers/mod_cdr/ (props changed)
Log:
svn:ignore props
1
0
25 Mar '07
Author: mikej
Date: Sun Mar 25 11:21:22 2007
New Revision: 4766
Modified:
freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
Log:
refactor in mod_dialplan_xml. Factor out a function for the hint string generation/xml_locate so that we do not need to generate the xml hint string when using a static file. Dont add blank items from the caller profile to the hint string.
Modified: freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c
==============================================================================
--- freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c (original)
+++ freeswitch/trunk/src/mod/dialplans/mod_dialplan_xml/mod_dialplan_xml.c Sun Mar 25 11:21:22 2007
@@ -34,11 +34,8 @@
#include <sys/stat.h>
#include <fcntl.h>
-
static const char modname[] = "mod_dialplan_xml";
-
-
typedef enum {
BREAK_ON_TRUE,
BREAK_ON_FALSE,
@@ -193,36 +190,26 @@
return proceed;
}
-static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session, void *arg)
+static switch_status_t dialplan_xml_locate(switch_core_session_t *session,
+ switch_caller_profile_t *caller_profile,
+ switch_xml_t *root,
+ switch_xml_t *node)
{
- switch_caller_profile_t *caller_profile;
- switch_caller_extension_t *extension = NULL;
+ switch_status_t status = SWITCH_STATUS_GENERR;
switch_channel_t *channel;
- switch_xml_t alt_root = NULL, cfg, xml, xcontext, xexten;
- char *context = NULL;
switch_stream_handle_t stream = {0};
switch_size_t encode_len = 1024, new_len = 0;
char *encode_buf = NULL;
char *prof[12] = {0}, *prof_names[12] = {0}, *e = NULL;
switch_hash_index_t *hi;
uint32_t x = 0;
- char *alt_path = (char *) arg;
channel = switch_core_session_get_channel(session);
- if ((caller_profile = switch_channel_get_caller_profile(channel))) {
- context = caller_profile->context ? caller_profile->context : "default";
- } else {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
- return NULL;
- }
-
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing %s->%s!\n", caller_profile->caller_id_name,
- caller_profile->destination_number);
SWITCH_STANDARD_STREAM(stream);
if (!(encode_buf = malloc(encode_len))) {
- return NULL;
+ goto done;
}
prof[0] = caller_profile->context;
@@ -250,6 +237,9 @@
prof_names[10] = "uuid";
for (x = 0; prof[x]; x++) {
+ if (switch_strlen_zero(prof[x])) {
+ continue;
+ }
new_len = (strlen(prof[x]) * 3) + 1;
if (encode_len < new_len) {
char *tmp;
@@ -257,8 +247,7 @@
encode_len = new_len;
if (!(tmp = realloc(encode_buf, encode_len))) {
- switch_safe_free(encode_buf);
- return NULL;
+ goto done;
}
encode_buf = tmp;
@@ -280,8 +269,7 @@
encode_len = new_len;
if (!(tmp = realloc(encode_buf, encode_len))) {
- switch_safe_free(encode_buf);
- return NULL;
+ goto done;
}
encode_buf = tmp;
@@ -298,11 +286,43 @@
*e = '\0';
}
- if (!switch_strlen_zero(alt_path)) {
+ status = switch_xml_locate("dialplan", NULL, NULL, NULL, root, node, stream.data);
+
+done:
+ switch_safe_free(stream.data);
+ switch_safe_free(encode_buf);
+ return status;
+}
+
+static switch_caller_extension_t *dialplan_hunt(switch_core_session_t *session, void *arg)
+{
+ switch_caller_profile_t *caller_profile;
+ switch_caller_extension_t *extension = NULL;
+ switch_channel_t *channel;
+ switch_xml_t alt_root = NULL, cfg, xml = NULL, xcontext, xexten;
+ char *alt_path = (char *) arg;
+
+ channel = switch_core_session_get_channel(session);
+
+ if ((caller_profile = switch_channel_get_caller_profile(channel))) {
+ if (!caller_profile->context) {
+ caller_profile->context = "default";
+ }
+ } else {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error Obtaining Profile!\n");
+ goto done;
+ }
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_INFO, "Processing %s->%s!\n", caller_profile->caller_id_name,
+ caller_profile->destination_number);
+
+ /* get our handle to the "dialplan" section of the config */
+
+ if (!switch_strlen_zero(alt_path)) {
switch_xml_t conf = NULL, tag = NULL;
if (!(alt_root = switch_xml_parse_file(alt_path))) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of [%s] failed\n", alt_path);
- return NULL;
+ goto done;
}
if ((conf = switch_xml_find_child(alt_root, "section", "name", "dialplan")) &&
@@ -312,22 +332,20 @@
cfg = tag;
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of dialplan failed\n");
- return NULL;
+ goto done;
}
- } else if (switch_xml_locate("dialplan", NULL, NULL, NULL, &xml, &cfg, stream.data) != SWITCH_STATUS_SUCCESS) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of dialplan failed\n");
- return NULL;
+ } else {
+ if (dialplan_xml_locate(session, caller_profile, &xml, &cfg) != SWITCH_STATUS_SUCCESS) {
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of dialplan failed\n");
+ goto done;
+ }
}
-
- switch_safe_free(stream.data);
- switch_safe_free(encode_buf);
-
- if (!(xcontext = switch_xml_find_child(cfg, "context", "name", context))) {
+ /* get a handle to the context tag */
+ if (!(xcontext = switch_xml_find_child(cfg, "context", "name", caller_profile->context))) {
if (!(xcontext = switch_xml_find_child(cfg, "context", "name", "global"))) {
- switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "context %s not found\n", context);
- switch_xml_free(xml);
- return NULL;
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "context %s not found\n", caller_profile->context);
+ goto done;
}
}
@@ -355,6 +373,8 @@
switch_channel_set_state(channel, CS_EXECUTE);
}
+done:
+ switch_xml_free(xml);
return extension;
}
1
0
25 Mar '07
Author: mikej
Date: Sat Mar 24 21:11:03 2007
New Revision: 4765
Modified:
freeswitch/trunk/libs/portaudio/Makefile.in
freeswitch/trunk/libs/portaudio/src/common/pa_ringbuffer.c
Log:
fix portaudio bsd build and remove gmakeisms from the portaudio lib makefile
Modified: freeswitch/trunk/libs/portaudio/Makefile.in
==============================================================================
--- freeswitch/trunk/libs/portaudio/Makefile.in (original)
+++ freeswitch/trunk/libs/portaudio/Makefile.in Sat Mar 24 21:11:03 2007
@@ -57,61 +57,61 @@
src/common/pa_trace.o
TESTS = \
- bin/paqa_devs \
- bin/paqa_errs \
- bin/patest1 \
- bin/patest_buffer \
- bin/patest_callbackstop \
- bin/patest_clip \
- bin/patest_dither \
- bin/patest_hang \
- bin/patest_in_overflow \
- bin/patest_latency \
- bin/patest_leftright \
- bin/patest_longsine \
- bin/patest_many \
- bin/patest_maxsines \
- bin/patest_multi_sine \
- bin/patest_out_underflow \
- bin/patest_pink \
- bin/patest_prime \
- bin/patest_read_record \
- bin/patest_read_write_wire \
- bin/patest_record \
- bin/patest_ringmix \
- bin/patest_saw \
- bin/patest_sine8 \
- bin/patest_sine \
- bin/patest_sine_formats \
- bin/patest_sine_time \
- bin/patest_start_stop \
- bin/patest_stop \
- bin/patest_stop_playout \
- bin/patest_toomanysines \
- bin/patest_underflow \
- bin/patest_wire \
- bin/patest_write_sine \
- bin/pa_devs \
- bin/pa_fuzz \
- bin/pa_minlat
+ test/paqa_devs \
+ test/paqa_errs \
+ test/patest1 \
+ test/patest_buffer \
+ test/patest_callbackstop \
+ test/patest_clip \
+ test/patest_dither \
+ test/patest_hang \
+ test/patest_in_overflow \
+ test/patest_latency \
+ test/patest_leftright \
+ test/patest_longsine \
+ test/patest_many \
+ test/patest_maxsines \
+ test/patest_multi_sine \
+ test/patest_out_underflow \
+ test/patest_pink \
+ test/patest_prime \
+ test/patest_read_record \
+ test/patest_read_write_wire \
+ test/patest_record \
+ test/patest_ringmix \
+ test/patest_saw \
+ test/patest_sine8 \
+ test/patest_sine \
+ test/patest_sine_formats \
+ test/patest_sine_time \
+ test/patest_start_stop \
+ test/patest_stop \
+ test/patest_stop_playout \
+ test/patest_toomanysines \
+ test/patest_underflow \
+ test/patest_wire \
+ test/patest_write_sine \
+ test/pa_devs \
+ test/pa_fuzz \
+ test/pa_minlat
# Most of these don't compile yet. Put them in TESTS, above, if
# you want to try to compile them...
ALL_TESTS = \
$(TESTS) \
- bin/patest_sync \
- bin/debug_convert \
- bin/debug_dither_calc \
- bin/debug_dual \
- bin/debug_multi_in \
- bin/debug_multi_out \
- bin/debug_record \
- bin/debug_record_reuse \
- bin/debug_sine_amp \
- bin/debug_sine \
- bin/debug_sine_formats \
- bin/debug_srate \
- bin/debug_test1
+ test/patest_sync \
+ test/debug_convert \
+ test/debug_dither_calc \
+ test/debug_dual \
+ test/debug_multi_in \
+ test/debug_multi_out \
+ test/debug_record \
+ test/debug_record_reuse \
+ test/debug_sine_amp \
+ test/debug_sine \
+ test/debug_sine_formats \
+ test/debug_srate \
+ test/debug_test1
OBJS = $(COMMON_OBJS) $(OTHER_OBJS)
@@ -128,9 +128,8 @@
lib/$(PALIB): lib-stamp $(LTOBJS) $(MAKEFILE) $(PAINC)
$(LIBTOOL) --mode=link $(CC) $(PA_LDFLAGS) -o lib/$(PALIB) $(LTOBJS) $(DLL_LIBS)
-$(ALL_TESTS): bin/%: lib/$(PALIB) $(MAKEFILE) $(PAINC) test/%.c
- $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/test/$*.c lib/$(PALIB) $(LIBS)
-
+$(ALL_TESTS): lib/$(PALIB) $(MAKEFILE) $(PAINC)
+ $(LIBTOOL) --mode=link $(CC) -o $@ $(CFLAGS) $(top_srcdir)/$@.c lib/$(PALIB) $(LIBS)
install: lib/$(PALIB) portaudio-2.0.pc
$(INSTALL) -d $(DESTDIR)$(libdir)
Modified: freeswitch/trunk/libs/portaudio/src/common/pa_ringbuffer.c
==============================================================================
--- freeswitch/trunk/libs/portaudio/src/common/pa_ringbuffer.c (original)
+++ freeswitch/trunk/libs/portaudio/src/common/pa_ringbuffer.c Sat Mar 24 21:11:03 2007
@@ -71,7 +71,7 @@
*
****************/
-#if defined(HAVE_LIBKERN_OSATOMIC_H) && defined(__APPLE__) || defined(__FreeBSD__)
+#if defined(HAVE_LIBKERN_OSATOMIC_H) && (defined(__APPLE__) || defined(__FreeBSD__))
# include <libkern/OSAtomic.h>
/* Here are the memory barrier functions. Mac OS X and FreeBSD only provide
full memory barriers, so the three types of barriers are the same. */
1
0
Author: mikej
Date: Sat Mar 24 16:12:41 2007
New Revision: 4764
Modified:
freeswitch/trunk/src/switch_apr.c
Log:
I think this is actually more correct from what I read.
Modified: freeswitch/trunk/src/switch_apr.c
==============================================================================
--- freeswitch/trunk/src/switch_apr.c (original)
+++ freeswitch/trunk/src/switch_apr.c Sat Mar 24 16:12:41 2007
@@ -616,8 +616,15 @@
char *buf;
int len;
size_t buflen;
+ va_list ap2;
- len = vsnprintf(NULL, 0, fmt, ap);
+#ifdef _MSC_VER
+ ap2 = ap;
+#else
+ va_copy(ap2, ap);
+#endif
+
+ len = vsnprintf(NULL, 0, fmt, ap2);
if (len > 0 && (buf = malloc((buflen = (size_t)(len + 1)))) != NULL) {
len = vsnprintf(buf, buflen, fmt, ap);
@@ -627,6 +634,7 @@
len = -1;
}
+ va_end(ap2);
return len;
#endif
1
0
Author: mikej
Date: Sat Mar 24 15:54:38 2007
New Revision: 4763
Modified:
freeswitch/trunk/src/switch_apr.c
Log:
a bit cleaner.
Modified: freeswitch/trunk/src/switch_apr.c
==============================================================================
--- freeswitch/trunk/src/switch_apr.c (original)
+++ freeswitch/trunk/src/switch_apr.c Sat Mar 24 15:54:38 2007
@@ -618,17 +618,15 @@
size_t buflen;
len = vsnprintf(NULL, 0, fmt, ap);
- if (len > 0) {
- buflen = (size_t)(len + 1);
- if ((buf = malloc(buflen)) == NULL) {
- *ret = NULL;
- return -1;
- }
+
+ if (len > 0 && (buf = malloc((buflen = (size_t)(len + 1)))) != NULL) {
len = vsnprintf(buf, buflen, fmt, ap);
*ret = buf;
} else {
*ret = NULL;
+ len = -1;
}
+
return len;
#endif
1
0