diff --git a/clients/flex/freeswitch.html b/clients/flex/freeswitch.html
index 481b2fb5f4..31d6a17c96 100644
--- a/clients/flex/freeswitch.html
+++ b/clients/flex/freeswitch.html
@@ -228,7 +228,7 @@
function add_call(uuid, name, number, account) {
var c = [ {uuid: uuid, name: name, number: number, account: account } ];
- var elm = $("#call_template").render(c);
+ var elm = $("#call_template").tmpl(c);
elm.data("uuid", uuid);
elm.data("name", name);
@@ -251,7 +251,7 @@
var u = suser + "@" + domain;
var sid = u.replace("@", "_").replace(/\./g, "_");
var c = [ { id: sid, user: u} ];
- var elm = $("#account_template").render(c);
+ var elm = $("#account_template").tmpl(c);
elm.data("user", u);
elm.appendTo("#account_container");
$("a", "#account_" + sid).button();
diff --git a/conf/dialplan/default/01_Talking_Clock.xml b/conf/dialplan/default/01_Talking_Clock.xml
index 205132a249..bc5077053a 100644
--- a/conf/dialplan/default/01_Talking_Clock.xml
+++ b/conf/dialplan/default/01_Talking_Clock.xml
@@ -1,6 +1,8 @@
+
+
@@ -9,6 +11,8 @@
+
+
@@ -18,6 +22,8 @@
+
+
diff --git a/libs/freetdm/conf/tones.conf b/libs/freetdm/conf/tones.conf
index 155b5fe17e..9bb0b43e92 100644
--- a/libs/freetdm/conf/tones.conf
+++ b/libs/freetdm/conf/tones.conf
@@ -1,5 +1,3 @@
-; This file is used to generate telephony tones by FreeTDM
-
[us]
generate-dial => v=-7;%(1000,0,350,440)
detect-dial => 350,440
@@ -47,19 +45,98 @@ detect-fail1 => 913.8
detect-fail2 => 1370.6
detect-fail3 => 1776.7
+
[ru]
generate-dial => v=-7;%(1000,425)
detect-dial => 0
+
generate-ring => v=-7;%(800,5000,425,0)
detect-ring => 425,0
+
generate-busy => v=-7;%(350,350,425,0)
detect-busy => 425,0
+
generate-attn => v=0;%(100,100,1400,2060,2450,2600)
detect-attn => 1400,2060,2450,2600
+
generate-callwaiting-sas => v=0;%(300,0,440)
detect-callwaiting-sas => 440,480
+
generate-callwaiting-cas => v=0;%(80,0,2750,2130)
detect-callwaiting-cas => 2750,2130
+
detect-fail1 => 913.8
detect-fail2 => 1370.6
detect-fail3 => 1776.7
+
+
+[in]
+generate-dial => v=-7;%(1000,0,375,425)
+detect-dial => 375,425
+
+generate-ring => v=-7;%(2000,4000,440,480)
+detect-ring => 440,480
+
+generate-busy => v=-7;%(500,500,480,620)
+detect-busy => 480,620
+
+generate-attn => v=0;%(100,100,1400,2060,2450,2600)
+detect-attn => 1400,2060,2450,2600
+
+generate-callwaiting-sas => v=0;%(300,0,440)
+detect-callwaiting-sas => 440
+
+generate-callwaiting-cas => v=0;%(80,0,2750,2130)
+detect-callwaiting-cas => 2750,2130
+
+detect-fail1 => 913.8
+detect-fail2 => 1370.6
+detect-fail3 => 776.7
+
+
+[th]
+generate-dial => v=-7;%(1000,0,400,400)
+detect-dial => 400,400
+
+generate-ring => v=-7;%(2000,4000,400,400)
+detect-ring => 400,400
+
+generate-busy => v=-7;%(500,500,480,620)
+detect-busy => 480,620
+
+generate-attn => v=0;%(100,100,1400,2060,2450,2600)
+detect-attn => 1400,2060,2450,2600
+
+generate-callwaiting-sas => v=0;%(300,0,440)
+detect-callwaiting-sas => 440
+
+generate-callwaiting-cas => v=0;%(80,0,2750,2130)
+detect-callwaiting-cas => 2750,2130
+
+detect-fail1 => 913.8
+detect-fail2 => 1370.6
+detect-fail3 => 1776.7
+
+
+[au]
+generate-dial => v=-7;%(1000,0,413,438)
+detect-dial => 413,438
+
+generate-ring => v=-7;%(400,200,413,438);%(400,2000,413,438)
+detect-ring => 413,438
+
+generate-busy => v=-7;%(375,375,425)
+detect-busy => 425
+
+generate-attn => v=0;%(100,100,1400,2060,2450,2600)
+detect-attn => 1400,2060,2450,2600
+
+generate-callwaiting-sas => v=0;%(300,0,440)
+detect-callwaiting-sas => 440
+
+generate-callwaiting-cas => v=0;%(80,0,2750,2130)
+detect-callwaiting-cas => 2750,2130
+
+detect-fail1 => 913.8
+detect-fail2 => 1370.6
+detect-fail3 => 776.7
diff --git a/libs/sofia-sip/.update b/libs/sofia-sip/.update
index c2a60933c6..026754ace3 100644
--- a/libs/sofia-sip/.update
+++ b/libs/sofia-sip/.update
@@ -1 +1 @@
-Tue Aug 2 13:51:40 CDT 2011
+Mon Aug 22 12:22:26 CDT 2011
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c
index 9facd8cd23..1a3614c6a1 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_client.c
@@ -837,6 +837,9 @@ int nua_client_request_sendmsg(nua_client_request_t *cr)
if (!sip->sip_user_agent && NH_PGET(nh, user_agent))
sip_add_make(msg, sip, sip_user_agent_class, NH_PGET(nh, user_agent));
+ if (!sip->sip_via && NH_PGET(nh, via))
+ sip_add_make(msg, sip, sip_via_class, NH_PGET(nh, via));
+
/** Any node implementing one or more event packages SHOULD include an
* appropriate @AllowEvents header indicating all supported events in
* all methods which initiate dialogs and their responses (such as
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
index d774b82d8d..019691b611 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.c
@@ -154,6 +154,7 @@ void nua_dialog_store_peer_info(nua_owner_t *own,
sip = NULL; /* Redirected */
if (sip == NULL) {
+ nr->nr_via = NULL, su_free(own, old->nr_via);
nr->nr_allow = NULL, su_free(own, old->nr_allow);
nr->nr_accept = NULL, su_free(own, old->nr_accept);
nr->nr_require = NULL, su_free(own, old->nr_require);
@@ -182,6 +183,11 @@ void nua_dialog_store_peer_info(nua_owner_t *own,
su_free(own, old->nr_supported);
}
+ if (sip->sip_via) {
+ nr->nr_via = sip_via_dup(own, sip->sip_via);
+ su_free(own, old->nr_via);
+ }
+
if (sip->sip_user_agent) {
nr->nr_user_agent = sip_user_agent_dup(own, sip->sip_user_agent);
su_free(own, old->nr_user_agent);
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h
index f48b75e435..707e6a60ec 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_dialog.h
@@ -83,6 +83,7 @@ struct nua_dialog_state
*/
struct nua_dialog_peer_info {
+ sip_via_t *nr_via;
sip_allow_t *nr_allow;
sip_accept_t *nr_accept;
sip_require_t *nr_require;
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
index 8f511796b0..58b480440a 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.c
@@ -957,6 +957,16 @@ static int nhp_set_tags(su_home_t *home,
value = 0;
NHP_SET_STR(nhp, organization, value);
}
+ /* SIPTAG_VIA(via) */
+ else if (tag == siptag_via) {
+ NHP_SET_STR_BY_HEADER(nhp, via, value);
+ }
+ /* SIPTAG_VIA_STR(via_str) */
+ else if (tag == siptag_via_str) {
+ if (value == -1)
+ value = 0;
+ NHP_SET_STR(nhp, via, value);
+ }
/* NUTAG_REGISTRAR(registrar) */
else if (tag == nutag_registrar) {
NHP_SET_STR_BY_URL(nhp, char, registrar, value);
@@ -1134,6 +1144,7 @@ int nhp_save_params(nua_handle_t *nh,
NHP_ZAP_OVERRIDEN(old, dst, msg_header_free, allow_events);
NHP_ZAP_OVERRIDEN(old, dst, su_free, user_agent);
NHP_ZAP_OVERRIDEN(old, dst, su_free, organization);
+ NHP_ZAP_OVERRIDEN(old, dst, su_free, via);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_display);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_username);
NHP_ZAP_OVERRIDEN(old, dst, su_free, m_params);
@@ -1673,6 +1684,9 @@ int nua_stack_get_params(nua_t *nua, nua_handle_t *nh, nua_event_t e,
TIF_SIP(SIPTAG_ORGANIZATION, organization),
TIF(SIPTAG_ORGANIZATION_STR, organization),
+ TIF_SIP(SIPTAG_VIA, via),
+ TIF(SIPTAG_VIA_STR, via),
+
TIF(NUTAG_INITIAL_ROUTE, initial_route),
TIF_STR(NUTAG_INITIAL_ROUTE_STR, initial_route),
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h
index 7aa726d5f9..1904a080c5 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_params.h
@@ -127,6 +127,7 @@ struct nua_handle_preferences
sip_allow_events_t *nhp_allow_events;
char const *nhp_user_agent;
char const *nhp_organization;
+ char const *nhp_via;
char const *nhp_m_display;
char const *nhp_m_username;
@@ -195,6 +196,7 @@ struct nua_handle_preferences
unsigned nhb_allow_events:1;
unsigned nhb_user_agent:1;
unsigned nhb_organization:1;
+ unsigned nhb_via:1;
unsigned nhb_m_display:1;
unsigned nhb_m_username:1;
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_server.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_server.c
index f9649759da..c8c42f44f9 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_server.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_server.c
@@ -537,6 +537,10 @@ int nua_server_respond(nua_server_request_t *sr, tagi_t const *tags)
sip_add_make(msg, sip, sip_organization_class,
NH_PGET(nh, organization)) < 0)
;
+ else if (!sip->sip_via && NH_PGET(nh, via) &&
+ sip_add_make(msg, sip, sip_via_class,
+ NH_PGET(nh, via)) < 0)
+ ;
else if (!sip->sip_allow && NH_PGET(nh, allow) &&
sip_add_dup(msg, sip, (void *)NH_PGET(nh, allow)) < 0)
;
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c
index caf36e1036..96ca20baee 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/nua_tag.c
@@ -2458,6 +2458,31 @@ tag_typedef_t nutag_user_agent = STRTAG_TYPEDEF(user_agent);
*/
+/**@def NUTAG_VIA()
+ *
+ * Via string.
+ *
+ * Indicate the Via header used by the stack.
+ *
+ * @par Used with
+ * nua_set_params(), nua_set_hparams() \n
+ * nua_get_params(), nua_get_hparams(), #nua_r_get_params \n
+ * any handle-specific nua call
+ *
+ * @par Parameter type
+ * char const *
+ *
+ * @par Values
+ * See @RFC3261 \n
+ *
+ * Corresponding tag taking reference parameter is NUTAG_VIA_REF().
+ */
+tag_typedef_t nutag_via = STRTAG_TYPEDEF(via);
+
+/**@def NUTAG_VIA_REF(x)
+ * Reference tag for NUTAG_VIA().
+ */
+
/**@def NUTAG_ALLOW()
*
* Allow a method (or methods).
diff --git a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
index fe39c32981..9e710d052d 100644
--- a/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
+++ b/libs/sofia-sip/libsofia-sip-ua/nua/sofia-sip/nua_tag.h
@@ -437,6 +437,11 @@ SOFIAPUBVAR tag_typedef_t nutag_user_agent;
#define NUTAG_USER_AGENT_REF(x) nutag_user_agent_ref, tag_str_vr(&(x))
SOFIAPUBVAR tag_typedef_t nutag_user_agent_ref;
+#define NUTAG_VIA(x) nutag_via, tag_str_v(x)
+SOFIAPUBVAR tag_typedef_t nutag_via;
+#define NUTAG_VIA_REF(x) nutag_via_ref, tag_str_vr(&(x))
+SOFIAPUBVAR tag_typedef_t nutag_via_ref;
+
#define NUTAG_ALLOW(x) nutag_allow, tag_str_v(x)
SOFIAPUBVAR tag_typedef_t nutag_allow;
#define NUTAG_ALLOW_REF(x) nutag_allow_ref, tag_str_vr(&(x))
diff --git a/src/mod/applications/mod_conference/mod_conference.c b/src/mod/applications/mod_conference/mod_conference.c
index aec526ca38..8217130ed6 100644
--- a/src/mod/applications/mod_conference/mod_conference.c
+++ b/src/mod/applications/mod_conference/mod_conference.c
@@ -144,7 +144,8 @@ typedef enum {
MFLAG_MOD = (1 << 16),
MFLAG_INDICATE_MUTE = (1 << 17),
MFLAG_INDICATE_UNMUTE = (1 << 18),
- MFLAG_NOMOH = (1 << 19)
+ MFLAG_NOMOH = (1 << 19),
+ MFLAG_VIDEO_BRIDGE = (1 << 20)
} member_flag_t;
typedef enum {
@@ -161,7 +162,8 @@ typedef enum {
CFLAG_OUTCALL = (1 << 10),
CFLAG_INHASH = (1 << 11),
CFLAG_EXIT_SOUND = (1 << 12),
- CFLAG_ENTER_SOUND = (1 << 13)
+ CFLAG_ENTER_SOUND = (1 << 13),
+ CFLAG_VIDEO_BRIDGE = (1 << 14)
} conf_flag_t;
typedef enum {
@@ -437,6 +439,7 @@ static switch_status_t chat_send(const char *proto, const char *from, const char
const char *body, const char *type, const char *hint);
static void launch_conference_record_thread(conference_obj_t *conference, char *path);
+static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b);
typedef switch_status_t (*conf_api_args_cmd_t) (conference_obj_t *, switch_stream_handle_t *, int, char **);
typedef switch_status_t (*conf_api_member_cmd_t) (conference_member_t *, switch_stream_handle_t *, void *);
@@ -951,6 +954,56 @@ static switch_status_t conference_del_member(conference_obj_t *conference, confe
return status;
}
+struct vid_helper {
+ conference_member_t *member_a;
+ conference_member_t *member_b;
+ int up;
+};
+
+/* Thread bridging video between two members, there will be two threads if video briding is used */
+static void *SWITCH_THREAD_FUNC conference_video_bridge_thread_run(switch_thread_t *thread, void *obj)
+{
+ struct vid_helper *vh = obj;
+ switch_channel_t *channel_a = switch_core_session_get_channel(vh->member_a->session);
+ switch_channel_t *channel_b = switch_core_session_get_channel(vh->member_b->session);
+ switch_status_t status;
+ switch_frame_t *read_frame;
+
+ /* Acquire locks for both sessions so the helper object and member structures don't get destroyed before we exit */
+ if (switch_core_session_read_lock(vh->member_a->session) != SWITCH_STATUS_SUCCESS) {
+ return NULL;
+ }
+
+ if (switch_core_session_read_lock(vh->member_b->session) != SWITCH_STATUS_SUCCESS) {
+ switch_core_session_rwunlock(vh->member_a->session);
+ return NULL;
+ }
+
+ vh->up = 1;
+ while (switch_test_flag(vh->member_a, MFLAG_RUNNING) && switch_test_flag(vh->member_b, MFLAG_RUNNING) &&
+ switch_channel_ready(channel_a) && switch_channel_ready(channel_b)) {
+ status = switch_core_session_read_video_frame(vh->member_a->session, &read_frame, SWITCH_IO_FLAG_NONE, 0);
+ if (!SWITCH_READ_ACCEPTABLE(status)) {
+ break;
+ }
+
+ if (!switch_test_flag(read_frame, SFF_CNG)) {
+ if (switch_core_session_write_video_frame(vh->member_b->session, read_frame, SWITCH_IO_FLAG_NONE, 0) != SWITCH_STATUS_SUCCESS) {
+ break;
+ }
+ }
+ }
+
+ switch_core_session_rwunlock(vh->member_a->session);
+ switch_core_session_rwunlock(vh->member_b->session);
+
+ switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "%s video thread ended.\n", switch_channel_get_name(channel_a));
+
+ vh->up = 0;
+ return NULL;
+}
+
+
/* Main video monitor thread (1 per distinct conference room) */
static void *SWITCH_THREAD_FUNC conference_video_thread_run(switch_thread_t *thread, void *obj)
{
@@ -1103,6 +1156,7 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
int has_file_data = 0, members_with_video = 0;
uint32_t conf_energy = 0;
int nomoh = 0;
+ conference_member_t *video_bridge_members[2] = { 0 };
/* Sync the conference to a single timing source */
if (switch_core_timer_next(&timer) != SWITCH_STATUS_SUCCESS) {
@@ -1128,6 +1182,14 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
if (switch_test_flag(imember, MFLAG_NOMOH)) {
nomoh++;
}
+
+ if (switch_test_flag(imember, MFLAG_VIDEO_BRIDGE)) {
+ if (!video_bridge_members[0]) {
+ video_bridge_members[0] = imember;
+ } else {
+ video_bridge_members[1] = imember;
+ }
+ }
}
switch_clear_flag_locked(imember, MFLAG_HAS_AUDIO);
@@ -1187,7 +1249,11 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
if (members_with_video && conference->video_running != 1) {
- launch_conference_video_thread(conference);
+ if (!switch_test_flag(conference, CFLAG_VIDEO_BRIDGE)) {
+ launch_conference_video_thread(conference);
+ } else if (video_bridge_members[0] && video_bridge_members[1]){
+ launch_conference_video_bridge_thread(video_bridge_members[0], video_bridge_members[1]);
+ }
}
/* If a file or speech event is being played */
@@ -1498,13 +1564,15 @@ static void *SWITCH_THREAD_FUNC conference_thread_run(switch_thread_t *thread, v
if (!switch_test_flag(imember, MFLAG_NOCHANNEL)) {
channel = switch_core_session_get_channel(imember->session);
- /* add this little bit to preserve the bridge cause code in case of an early media call that */
- /* never answers */
- if (switch_test_flag(conference, CFLAG_ANSWERED)) {
- switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- } else {
- /* put actual cause code from outbound channel hangup here */
- switch_channel_hangup(channel, conference->bridge_hangup_cause);
+ if (!switch_false(switch_channel_get_variable(channel, "hangup_after_conference"))) {
+ /* add this little bit to preserve the bridge cause code in case of an early media call that */
+ /* never answers */
+ if (switch_test_flag(conference, CFLAG_ANSWERED)) {
+ switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
+ } else {
+ /* put actual cause code from outbound channel hangup here */
+ switch_channel_hangup(channel, conference->bridge_hangup_cause);
+ }
}
}
@@ -5448,6 +5516,8 @@ static void set_mflags(const char *flags, member_flag_t *f)
*f |= MFLAG_ENDCONF;
} else if (!strcasecmp(argv[i], "mintwo")) {
*f |= MFLAG_MINTWO;
+ } else if (!strcasecmp(argv[i], "video-bridge")) {
+ *f |= MFLAG_VIDEO_BRIDGE;
}
}
@@ -5480,6 +5550,8 @@ static void set_cflags(const char *flags, uint32_t *f)
*f |= CFLAG_VID_FLOOR;
} else if (!strcasecmp(argv[i], "waste-bandwidth")) {
*f |= CFLAG_WASTE_BANDWIDTH;
+ } else if (!strcasecmp(argv[i], "video-bridge")) {
+ *f |= CFLAG_VIDEO_BRIDGE;
}
}
@@ -6227,20 +6299,44 @@ static void launch_conference_thread(conference_obj_t *conference)
switch_thread_create(&thread, thd_attr, conference_thread_run, conference, conference->pool);
}
-
-/* Create a video thread for the conference and launch it */
-static void launch_conference_video_thread(conference_obj_t *conference)
+static switch_thread_t *launch_thread_detached(switch_thread_start_t func, switch_memory_pool_t *pool, void *data)
{
switch_thread_t *thread;
switch_threadattr_t *thd_attr = NULL;
- switch_threadattr_create(&thd_attr, conference->pool);
+ switch_threadattr_create(&thd_attr, pool);
switch_threadattr_detach_set(thd_attr, 1);
switch_threadattr_stacksize_set(thd_attr, SWITCH_THREAD_STACKSIZE);
- switch_thread_create(&thread, thd_attr, conference_video_thread_run, conference, conference->pool);
+ switch_thread_create(&thread, thd_attr, func, data, pool);
+
+ return thread;
+}
+
+/* Create a video thread for the conference and launch it */
+static void launch_conference_video_thread(conference_obj_t *conference)
+{
+ launch_thread_detached(conference_video_thread_run, conference->pool, conference);
conference->video_running = 1;
}
+/* Create a video thread for the conference and launch it */
+static void launch_conference_video_bridge_thread(conference_member_t *member_a, conference_member_t *member_b)
+{
+ switch_memory_pool_t *pool = member_a->conference->pool;
+ struct vid_helper *vh = switch_core_alloc(pool, 2 * sizeof *vh);
+
+ vh[0].member_a = member_a;
+ vh[0].member_b = member_b;
+
+ vh[1].member_a = member_b;
+ vh[1].member_b = member_a;
+
+ launch_thread_detached(conference_video_bridge_thread_run, pool, &vh[0]);
+ launch_thread_detached(conference_video_bridge_thread_run, pool, &vh[1]);
+
+ member_a->conference->video_running = 1;
+}
+
static void launch_conference_record_thread(conference_obj_t *conference, char *path)
{
switch_thread_t *thread;
diff --git a/src/mod/applications/mod_lcr/sql/mysql-5.0.sql b/src/mod/applications/mod_lcr/sql/mysql-5.0.sql
index a8756b3c21..ec48912351 100644
--- a/src/mod/applications/mod_lcr/sql/mysql-5.0.sql
+++ b/src/mod/applications/mod_lcr/sql/mysql-5.0.sql
@@ -31,7 +31,7 @@ CREATE TABLE `lcr` (
`trail_strip` int(11) NOT NULL,
`prefix` varchar(16) NOT NULL,
`suffix` varchar(16) NOT NULL,
- `lcr_profile` varchar(32) default NULL,
+ `lcr_profile` int(11) NOT NULL default 0,
`date_start` datetime NOT NULL DEFAULT '1970-01-01',
`date_end` datetime NOT NULL DEFAULT '2030-12-31',
`quality` float(10,6) NOT NULL,
diff --git a/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp b/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp
index 4b9c772ee3..37f88baf99 100644
--- a/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp
+++ b/src/mod/applications/mod_soundtouch/mod_soundtouch.cpp
@@ -252,7 +252,7 @@ SWITCH_STANDARD_APP(soundtouch_start_function)
char *argv[6];
int argc;
char *lbuf = NULL;
- int x;
+ int x, n;
if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_soundtouch_"))) {
if (!zstr(data) && !strcasecmp(data, "stop")) {
@@ -275,26 +275,38 @@ SWITCH_STANDARD_APP(soundtouch_start_function)
sth->tempo = 1;
sth->hook_dtmf = false;
sth->send_not_recv = false;
+ n = 0;
for (x = 0; x < argc; x++) {
if (!strncasecmp(argv[x], "send_leg", 8)) {
sth->send_not_recv = true;
} else if (!strncasecmp(argv[x], "hook_dtmf", 9)) {
sth->hook_dtmf = true;
+ n++;
} else if (strchr(argv[x], 'p')) {
- sth->pitch = normalize_soundtouch_value('p',atof(argv[x]));
+ sth->pitch = normalize_soundtouch_value('p', atof(argv[x]));
+ n++;
} else if (strchr(argv[x], 'r')) {
- sth->rate = normalize_soundtouch_value('r',atof(argv[x]));
+ sth->rate = normalize_soundtouch_value('r', atof(argv[x]));
+ n++;
} else if (strchr(argv[x], 'o')) {
sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x])) );
+ n++;
} else if (strchr(argv[x], 's')) {
/*12.0f taken from soundtouch conversion to octaves*/
sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x]) / 12.0f) );
+ n++;
} else if (strchr(argv[x], 't')) {
- sth->tempo = normalize_soundtouch_value('t',atof(argv[x]));
+ sth->tempo = normalize_soundtouch_value('t', atof(argv[x]));
+ n++;
}
}
}
+ if (n < 1) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_WARNING, "Cannot run, no pitch set\n");
+ return;
+ }
+
sth->session = session;
@@ -308,9 +320,134 @@ SWITCH_STANDARD_APP(soundtouch_start_function)
}
+/* API Interface Function */
+#define SOUNDTOUCH_API_SYNTAX " [start|stop] [send_leg] [hook_dtmf] [-]s [-]o p r t"
+SWITCH_STANDARD_API(soundtouch_api_function)
+{
+ switch_core_session_t *rsession = NULL;
+ switch_channel_t *channel = NULL;
+ switch_media_bug_t *bug;
+ switch_status_t status;
+ struct soundtouch_helper *sth;
+ char *mycmd = NULL;
+ int argc = 0;
+ char *argv[10] = { 0 };
+ char *uuid = NULL;
+ char *action = NULL;
+ char *lbuf = NULL;
+ int x, n;
+
+ if (zstr(cmd)) {
+ goto usage;
+ }
+
+ if (!(mycmd = strdup(cmd))) {
+ goto usage;
+ }
+
+ if ((argc = switch_separate_string(mycmd, ' ', argv, (sizeof(argv) / sizeof(argv[0])))) < 2) {
+ goto usage;
+ }
+
+ uuid = argv[0];
+ action = argv[1];
+
+ if (!(rsession = switch_core_session_locate(uuid))) {
+ stream->write_function(stream, "-ERR Cannot locate session!\n");
+ goto done;
+ }
+
+ channel = switch_core_session_get_channel(rsession);
+
+ if ((bug = (switch_media_bug_t *) switch_channel_get_private(channel, "_soundtouch_"))) {
+ if (!zstr(action) && !strcasecmp(action, "stop")) {
+ switch_channel_set_private(channel, "_soundtouch_", NULL);
+ switch_core_media_bug_remove(rsession, &bug);
+ stream->write_function(stream, "+OK Success\n");
+ } else {
+ stream->write_function(stream, "-ERR Cannot run 2 at once on the same channel!\n");
+ }
+ goto done;
+ }
+
+ if (!zstr(action) && strcasecmp(action, "start")) {
+ goto usage;
+ }
+
+ if (argc < 3) {
+ goto usage;
+ }
+
+ sth = (struct soundtouch_helper *) switch_core_session_alloc(rsession, sizeof(*sth));
+ assert(sth != NULL);
+
+
+ sth->pitch = 1;
+ sth->rate = 1;
+ sth->tempo = 1;
+ sth->hook_dtmf = false;
+ sth->send_not_recv = false;
+ n = 0;
+ for (x = 2; x < argc; x++) {
+ if (!strncasecmp(argv[x], "send_leg", 8)) {
+ sth->send_not_recv = true;
+ } else if (!strncasecmp(argv[x], "hook_dtmf", 9)) {
+ sth->hook_dtmf = true;
+ n++;
+ } else if (strchr(argv[x], 'p')) {
+ sth->pitch = normalize_soundtouch_value('p', atof(argv[x]));
+ n++;
+ } else if (strchr(argv[x], 'r')) {
+ sth->rate = normalize_soundtouch_value('r', atof(argv[x]));
+ n++;
+ } else if (strchr(argv[x], 'o')) {
+ sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x])) );
+ n++;
+ } else if (strchr(argv[x], 's')) {
+ /*12.0f taken from soundtouch conversion to octaves*/
+ sth->pitch = normalize_soundtouch_value('p', compute_pitch_from_octaves(atof(argv[x]) / 12.0f) );
+ n++;
+ } else if (strchr(argv[x], 't')) {
+ sth->tempo = normalize_soundtouch_value('t', atof(argv[x]));
+ n++;
+ }
+ }
+
+ if (n < 1) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(rsession), SWITCH_LOG_WARNING, "Cannot run, no pitch set\n");
+ goto usage;
+ }
+
+ sth->session = rsession;
+
+ if ((status = switch_core_media_bug_add(rsession, "soundtouch", NULL, soundtouch_callback, sth, 0,
+ sth->send_not_recv ? SMBF_WRITE_REPLACE : SMBF_READ_REPLACE, &bug)) != SWITCH_STATUS_SUCCESS) {
+ stream->write_function(stream, "-ERR Failure!\n");
+ goto done;
+ } else {
+ switch_channel_set_private(channel, "_soundtouch_", bug);
+ stream->write_function(stream, "+OK Success\n");
+ goto done;
+ }
+
+
+ usage:
+ stream->write_function(stream, "-USAGE: %s\n", SOUNDTOUCH_API_SYNTAX);
+
+ done:
+ if (rsession) {
+ switch_core_session_rwunlock(rsession);
+ }
+
+ switch_safe_free(mycmd);
+ return SWITCH_STATUS_SUCCESS;
+}
+
+
SWITCH_MODULE_LOAD_FUNCTION(mod_soundtouch_load)
{
switch_application_interface_t *app_interface;
+ switch_api_interface_t *api_interface;
/* connect my internal structure to the blank pointer passed to me */
*module_interface = switch_loadable_module_create_module_interface(pool, modname);
@@ -318,6 +455,10 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_soundtouch_load)
SWITCH_ADD_APP(app_interface, "soundtouch", "Alter the audio stream", "Alter the audio stream pitch/rate/tempo",
soundtouch_start_function, "[send_leg] [hook_dtmf] [-]s [-]o p r t", SAF_NONE);
+ SWITCH_ADD_API(api_interface, "soundtouch", "soundtouch", soundtouch_api_function, SOUNDTOUCH_API_SYNTAX);
+
+ switch_console_set_complete("add soundtouch ::console::list_uuid ::[start:stop");
+
/* indicate that the module should continue to be loaded */
return SWITCH_STATUS_SUCCESS;
}
diff --git a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
index 34562faadd..0504b0b082 100644
--- a/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
+++ b/src/mod/applications/mod_spandsp/mod_spandsp_fax.c
@@ -997,13 +997,25 @@ static pvt_t *pvt_init(switch_core_session_t *session, mod_spandsp_fax_applicati
}
if ((tmp = switch_channel_get_variable(channel, "fax_ident"))) {
- pvt->ident = switch_core_session_strdup(session, tmp);
+ char *data = NULL;
+
+ data = strdup(tmp);
+ switch_url_decode(data);
+ pvt->ident = switch_core_session_strdup(session, data);
+
+ switch_safe_free(data);
} else {
pvt->ident = switch_core_session_strdup(session, globals.ident);
}
if ((tmp = switch_channel_get_variable(channel, "fax_header"))) {
- pvt->header = switch_core_session_strdup(session, tmp);
+ char *data = NULL;
+
+ data = strdup(tmp);
+ switch_url_decode(data);
+ pvt->header = switch_core_session_strdup(session, data);
+
+ switch_safe_free(data);
} else {
pvt->header = switch_core_session_strdup(session, globals.header);
}
diff --git a/src/mod/applications/mod_valet_parking/mod_valet_parking.c b/src/mod/applications/mod_valet_parking/mod_valet_parking.c
index 291d6c86a5..0b25a47e94 100644
--- a/src/mod/applications/mod_valet_parking/mod_valet_parking.c
+++ b/src/mod/applications/mod_valet_parking/mod_valet_parking.c
@@ -116,7 +116,7 @@ static void check_timeouts(void)
switch_hash_this(i_hi, &i_var, NULL, &i_val);
i_ext = (char *) i_var;
token = (valet_token_t *) i_val;
- if (token->timeout > 0 && token->timeout < now) {
+ if (token->timeout > 0 && (token->timeout < now || token->timeout == 1)) {
switch_core_hash_delete(lot->hash, i_ext);
switch_safe_free(token);
goto top;
@@ -164,7 +164,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
char dtmf_buf[128] = "";
int is_auto = 0, play_announce = 1;
const char *var;
- valet_token_t *token;
+ valet_token_t *token = NULL;
if ((var = switch_channel_get_variable(channel, "valet_announce_slot"))) {
play_announce = switch_true(var);
@@ -279,6 +279,7 @@ SWITCH_STANDARD_APP(valet_parking_function)
if (!zstr(var)) {
if (!strcmp(var, token->uuid)) {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Valet ticket %s accepted.\n", var);
+ token->timeout = 0;
switch_channel_set_variable(channel, "valet_ticket", NULL);
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Invalid token %s\n", token->uuid);
@@ -319,7 +320,6 @@ SWITCH_STANDARD_APP(valet_parking_function)
}
switch_zmalloc(token, sizeof(*token));
- token->timeout = switch_epoch_time_now(NULL) + 10;
switch_set_string(token->uuid, switch_core_session_get_uuid(session));
switch_core_hash_insert(lot->hash, ext, token);
@@ -335,15 +335,15 @@ SWITCH_STANDARD_APP(valet_parking_function)
switch_core_session_t *b_session;
if ((b_session = switch_core_session_locate(uuid))) {
+ token->timeout = switch_epoch_time_now(NULL) + 10;
if (play_announce) {
switch_ivr_phrase_macro(session, "valet_announce_ext", tmp, NULL, NULL);
}
-
switch_ivr_session_transfer(b_session, dest, "inline", NULL);
switch_mutex_unlock(lot->mutex);
switch_core_session_rwunlock(b_session);
switch_channel_hangup(channel, SWITCH_CAUSE_NORMAL_CLEARING);
- return;
+ goto end;
}
}
@@ -388,6 +388,13 @@ SWITCH_STANDARD_APP(valet_parking_function)
} else {
switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Usage: %s\n", VALET_APP_SYNTAX);
}
+
+ end:
+
+ if (token) {
+ token->timeout = 1;
+ }
+
}
SWITCH_STANDARD_API(valet_info_function)
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.c b/src/mod/endpoints/mod_sofia/mod_sofia.c
index 2774e7135a..930a4a6f3f 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.c
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.c
@@ -741,13 +741,6 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
}
}
- if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
- int v_session_timeout = atoi(val);
- if (v_session_timeout >= 0) {
- session_timeout = v_session_timeout;
- }
- }
-
if (sofia_test_flag(tech_pvt, TFLAG_NAT) ||
(val = switch_channel_get_variable(channel, "sip-force-contact")) ||
((val = switch_channel_get_variable(channel, "sip_sticky_contact")) && switch_true(val))) {
@@ -756,6 +749,13 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
switch_channel_set_variable(channel, "sip_nat_detected", "true");
}
+ if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
+ int v_session_timeout = atoi(val);
+ if (v_session_timeout >= 0) {
+ session_timeout = v_session_timeout;
+ }
+ }
+
if (!sofia_test_flag(tech_pvt, TFLAG_BYE)) {
char *extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_RESPONSE_HEADER_PREFIX);
char *cid = NULL;
@@ -780,19 +780,27 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
}
}
+ if ((tech_pvt->session_timeout = session_timeout)) {
+ tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher;
+ } else {
+ tech_pvt->session_refresher = nua_no_refresher;
+ }
+
+
+
if (sofia_use_soa(tech_pvt)) {
nua_respond(tech_pvt->nh, SIP_200_OK,
NUTAG_AUTOANSWER(0),
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
- NUTAG_SESSION_TIMER(session_timeout),
- NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SOATAG_USER_SDP_STR(tech_pvt->local_sdp_str),
SOATAG_REUSE_REJECTED(1), SOATAG_ORDERED_USER(1), SOATAG_AUDIO_AUX("cn telephone-event"), NUTAG_INCLUDE_EXTRA_SDP(1),
- TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)),
+ TAG_IF(is_proxy, SOATAG_RTP_SELECT(1)),
TAG_IF(!zstr(extra_headers), SIPTAG_HEADER_STR(extra_headers)),
TAG_IF(switch_stristr("update_display", tech_pvt->x_freeswitch_support_remote),
SIPTAG_HEADER_STR("X-FS-Support: " FREESWITCH_SUPPORT)), TAG_END());
@@ -803,8 +811,8 @@ static switch_status_t sofia_answer_channel(switch_core_session_t *session)
TAG_IF(call_info, SIPTAG_CALL_INFO_STR(call_info)),
TAG_IF(sticky, NUTAG_PROXY(tech_pvt->record_route)),
TAG_IF(cid, SIPTAG_HEADER_STR(cid)),
- NUTAG_SESSION_TIMER(session_timeout),
- NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
SIPTAG_CONTACT_STR(tech_pvt->reply_contact),
SIPTAG_CALL_INFO_STR(switch_channel_get_variable(tech_pvt->channel, SOFIA_SIP_HEADER_PREFIX "call_info")),
SIPTAG_CONTENT_TYPE_STR("application/sdp"),
@@ -2001,6 +2009,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", name, number);
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
nua_update(tech_pvt->nh,
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
@@ -2009,17 +2019,21 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
nua_update(tech_pvt->nh,
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
} else if ((ua && (switch_stristr("cisco/spa50", ua) || switch_stristr("cisco/spa525", ua)))) {
- snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" ", name, number, tech_pvt->profile->sipip);
+ snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" ", name, number, tech_pvt->profile->sipip);
- sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
- nua_update(tech_pvt->nh,
- TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
- TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
- }
+ sofia_set_flag_locked(tech_pvt, TFLAG_UPDATING_DISPLAY);
+ nua_update(tech_pvt->nh,
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
+ TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
+ TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
+ }
tech_pvt->last_sent_callee_id_name = switch_core_session_strdup(tech_pvt->session, name);
tech_pvt->last_sent_callee_id_number = switch_core_session_strdup(tech_pvt->session, number);
@@ -2071,6 +2085,8 @@ static switch_status_t sofia_receive_message(switch_core_session_t *session, swi
} else if (ua && switch_stristr("polycom", ua)) {
snprintf(message, sizeof(message), "P-Asserted-Identity: \"%s\" <%s>", msg->string_arg, tech_pvt->caller_profile->destination_number);
nua_update(tech_pvt->nh,
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(!zstr(tech_pvt->route_uri), NUTAG_PROXY(tech_pvt->route_uri)),
TAG_IF(!zstr_buf(message), SIPTAG_HEADER_STR(message)),
TAG_IF(!zstr(tech_pvt->user_via), SIPTAG_VIA_STR(tech_pvt->user_via)), TAG_END());
diff --git a/src/mod/endpoints/mod_sofia/mod_sofia.h b/src/mod/endpoints/mod_sofia/mod_sofia.h
index 8c50a9059d..b6df8170f3 100644
--- a/src/mod/endpoints/mod_sofia/mod_sofia.h
+++ b/src/mod/endpoints/mod_sofia/mod_sofia.h
@@ -45,7 +45,7 @@
#define HAVE_APR
#include
#include
-#define SOFIA_NAT_SESSION_TIMEOUT 1800
+#define SOFIA_NAT_SESSION_TIMEOUT 90
#define SOFIA_MAX_ACL 100
#ifdef _MSC_VER
#define HAVE_FUNCTION 1
@@ -767,6 +767,8 @@ struct private_object {
sofia_cid_type_t cid_type;
switch_payload_t payload_space;
switch_payload_t ianacodes[SWITCH_MAX_CODECS];
+ uint32_t session_timeout;
+ enum nua_session_refresher session_refresher;
};
struct callback_t {
diff --git a/src/mod/endpoints/mod_sofia/sofia.c b/src/mod/endpoints/mod_sofia/sofia.c
index 96df565ee3..5733193743 100644
--- a/src/mod/endpoints/mod_sofia/sofia.c
+++ b/src/mod/endpoints/mod_sofia/sofia.c
@@ -7454,6 +7454,7 @@ void sofia_handle_sip_i_invite(nua_t *nua, sofia_profile_t *profile, nua_handle_
if (sofia_glue_check_nat(profile, tech_pvt->remote_ip)) {
tech_pvt->user_via = sofia_glue_create_external_via(session, profile, tech_pvt->transport);
+ nua_set_hparams(tech_pvt->nh, SIPTAG_VIA_STR(tech_pvt->user_via), TAG_END());
}
if (sip->sip_contact && sip->sip_contact->m_url) {
diff --git a/src/mod/endpoints/mod_sofia/sofia_glue.c b/src/mod/endpoints/mod_sofia/sofia_glue.c
index 9876e9b64b..5ab6bdcc66 100644
--- a/src/mod/endpoints/mod_sofia/sofia_glue.c
+++ b/src/mod/endpoints/mod_sofia/sofia_glue.c
@@ -2366,6 +2366,7 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
extra_headers = sofia_glue_get_extra_headers(channel, SOFIA_SIP_HEADER_PREFIX);
session_timeout = tech_pvt->profile->session_timeout;
+
if ((val = switch_channel_get_variable(channel, SOFIA_SESSION_TIMEOUT))) {
int v_session_timeout = atoi(val);
if (v_session_timeout >= 0) {
@@ -2420,10 +2421,12 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
sofia_clear_flag(tech_pvt, TFLAG_ENABLE_SOA);
}
- if (sofia_test_flag(tech_pvt, TFLAG_RECOVERED)) {
- session_timeout = 0;
+ if ((tech_pvt->session_timeout = session_timeout)) {
+ tech_pvt->session_refresher = switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND ? nua_local_refresher : nua_remote_refresher;
+ } else {
+ tech_pvt->session_refresher = nua_no_refresher;
}
-
+
if (sofia_use_soa(tech_pvt)) {
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
@@ -2431,8 +2434,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
//TAG_IF(!zstr(tech_pvt->local_sdp_str), NUTAG_AUTOACK(1)),
// The code above is breaking things...... grrr WE need this because we handle our own acks and there are 3pcc cases in there too
NUTAG_AUTOACK(0),
- NUTAG_SESSION_TIMER(session_timeout),
- NUTAG_SESSION_REFRESHER(session_timeout ? nua_local_refresher : nua_no_refresher),
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@@ -2465,8 +2468,8 @@ switch_status_t sofia_glue_do_invite(switch_core_session_t *session)
nua_invite(tech_pvt->nh,
NUTAG_AUTOANSWER(0),
NUTAG_AUTOACK(0),
- NUTAG_SESSION_TIMER(session_timeout),
- TAG_IF(session_timeout, NUTAG_SESSION_REFRESHER(nua_remote_refresher)),
+ NUTAG_SESSION_TIMER(tech_pvt->session_timeout),
+ NUTAG_SESSION_REFRESHER(tech_pvt->session_refresher),
TAG_IF(sofia_test_flag(tech_pvt, TFLAG_RECOVERED), NUTAG_INVITE_TIMER(UINT_MAX)),
TAG_IF(invite_full_from, SIPTAG_FROM_STR(invite_full_from)),
TAG_IF(invite_full_to, SIPTAG_TO_STR(invite_full_to)),
@@ -4820,6 +4823,12 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
}
}
+ if (!best_te && (sofia_test_pflag(tech_pvt->profile, PFLAG_LIBERAL_DTMF) || sofia_test_flag(tech_pvt, TFLAG_LIBERAL_DTMF))) {
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG,
+ "No 2833 in SDP. Liberal DTMF mode adding %d as telephone-event.", tech_pvt->profile->te);
+ best_te = tech_pvt->profile->te;
+ }
+
if (best_te) {
if (switch_channel_direction(channel) == SWITCH_CALL_DIRECTION_OUTBOUND) {
te = tech_pvt->te = (switch_payload_t) best_te;
@@ -4836,9 +4845,9 @@ uint8_t sofia_glue_negotiate_sdp(switch_core_session_t *session, const char *r_s
}
}
} else {
- switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "Disable 2833 dtmf\n");
- switch_channel_set_variable(tech_pvt->channel, "dtmf_type", "none");
- tech_pvt->dtmf_type = DTMF_NONE;
+ switch_log_printf(SWITCH_CHANNEL_SESSION_LOG(session), SWITCH_LOG_DEBUG, "No 2833 in SDP. Disable 2833 dtmf and switch to INFO\n");
+ switch_channel_set_variable(tech_pvt->channel, "dtmf_type", "info");
+ tech_pvt->dtmf_type = DTMF_INFO;
te = tech_pvt->recv_te = 0;
}
diff --git a/src/switch_ivr_originate.c b/src/switch_ivr_originate.c
index 91bd1420f0..c097a1935d 100644
--- a/src/switch_ivr_originate.c
+++ b/src/switch_ivr_originate.c
@@ -2299,11 +2299,6 @@ SWITCH_DECLARE(switch_status_t) switch_ivr_originate(switch_core_session_t *sess
chan_type++;
}
- while (chan_type && *chan_type && *chan_type == ' ') {
- chan_type++;
- }
-
-
if ((chan_data = strchr(chan_type, '/')) != 0) {
*chan_data = '\0';
chan_data++;