[Freeswitch-svn] [commit] r4816 - in freeswitch/trunk/src: . include mod/endpoints/mod_sofia
Freeswitch SVN
anthm at freeswitch.org
Fri Mar 30 18:13:19 EDT 2007
Author: anthm
Date: Fri Mar 30 18:13:19 2007
New Revision: 4816
Modified:
freeswitch/trunk/src/include/switch_channel.h
freeswitch/trunk/src/include/switch_types.h
freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
freeswitch/trunk/src/switch_channel.c
freeswitch/trunk/src/switch_core_session.c
freeswitch/trunk/src/switch_ivr.c
freeswitch/trunk/src/switch_ivr_async.c
freeswitch/trunk/src/switch_ivr_bridge.c
Log:
hold stuff
Modified: freeswitch/trunk/src/include/switch_channel.h
==============================================================================
--- freeswitch/trunk/src/include/switch_channel.h (original)
+++ freeswitch/trunk/src/include/switch_channel.h Fri Mar 30 18:13:19 2007
@@ -259,6 +259,22 @@
SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags);
/*!
+ \brief Set given flag(s) on a given channel's bridge partner
+ \param channel channel to derive the partner channel to set flag(s) on
+ \param flags or'd list of flags to set
+ \return true if the flag was set
+*/
+SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags);
+
+/*!
+ \brief Clears given flag(s) on a given channel's bridge partner
+ \param channel channel to derive the partner channel to clear flag(s) from
+ \param flags the flags to clear
+ \return true if the flag was cleared
+*/
+SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags);
+
+/*!
\brief Set given flag(s) on a given channel to be applied on the next state change
\param channel channel on which to set flag(s)
\param flags or'd list of flags to set
Modified: freeswitch/trunk/src/include/switch_types.h
==============================================================================
--- freeswitch/trunk/src/include/switch_types.h (original)
+++ freeswitch/trunk/src/include/switch_types.h Fri Mar 30 18:13:19 2007
@@ -96,6 +96,7 @@
#endif
#define SWITCH_URL_SEPARATOR "://"
#define SWITCH_ENDPOINT_DISPOSITION_VARIABLE "endpoint_disposition"
+#define SWITCH_HOLD_MUSIC_VARIABLE "hold_music"
#define SWITCH_EXPORT_VARS_VARIABLE "export_vars"
#define SWITCH_R_SDP_VARIABLE "switch_r_sdp"
#define SWITCH_L_SDP_VARIABLE "switch_l_sdp"
@@ -168,6 +169,7 @@
SMF_ECHO_ALEG = (1 << 1),
SMF_ECHO_BLEG = (1 << 2),
SMF_FORCE = (1 << 3),
+ SMF_LOOP = (1 << 4)
} switch_media_flag_t;
typedef enum {
@@ -529,6 +531,8 @@
CF_REPEAT_STATE = (1 << 16) - Tell the state machine to repeat a state
CF_GEN_RINGBACK = (1 << 17) - Channel is generating it's own ringback
CF_RING_READY = (1 << 18) - Channel is ready to send ringback
+CF_BREAK = (1 << 19) - Channel should stop what it's doing
+CF_BROADCAST = (1 << 20) - Channel is broadcasting
</pre>
*/
@@ -551,7 +555,9 @@
CF_EVENT_PARSE = (1 << 15),
CF_REPEAT_STATE = (1 << 16),
CF_GEN_RINGBACK = (1 << 17),
- CF_RING_READY = (1 << 18)
+ CF_RING_READY = (1 << 18),
+ CF_BREAK = (1 << 19),
+ CF_BROADCAST = (1 << 20)
} switch_channel_flag_t;
Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c (original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c Fri Mar 30 18:13:19 2007
@@ -90,7 +90,10 @@
"CREATE TABLE sip_registrations (\n"
" user VARCHAR(255),\n"
" host VARCHAR(255),\n"
- " contact VARCHAR(1024),\n" " status VARCHAR(255),\n" " rpid VARCHAR(255),\n" " expires INTEGER(8)" ");\n";
+ " contact VARCHAR(1024),\n"
+ " status VARCHAR(255),\n"
+ " rpid VARCHAR(255),\n"
+ " expires INTEGER(8)" ");\n";
static char sub_sql[] =
@@ -102,13 +105,19 @@
" sub_to_host VARCHAR(255),\n"
" event VARCHAR(255),\n"
" contact VARCHAR(1024),\n"
- " call_id VARCHAR(255),\n" " full_from VARCHAR(255),\n" " full_via VARCHAR(255),\n" " expires INTEGER(8)" ");\n";
+ " call_id VARCHAR(255),\n"
+ " full_from VARCHAR(255),\n"
+ " full_via VARCHAR(255),\n"
+ " expires INTEGER(8)" ");\n";
static char auth_sql[] =
"CREATE TABLE sip_authentication (\n"
" user VARCHAR(255),\n"
- " host VARCHAR(255),\n" " passwd VARCHAR(255),\n" " nonce VARCHAR(255),\n" " expires INTEGER(8)"
+ " host VARCHAR(255),\n"
+ " passwd VARCHAR(255),\n"
+ " nonce VARCHAR(255),\n"
+ " expires INTEGER(8)"
");\n";
static const char modname[] = "mod_sofia";
@@ -231,6 +240,7 @@
char *bindurl;
char *sipdomain;
char *timer_name;
+ char *hold_music;
int sip_port;
char *codec_string;
int running;
@@ -1024,7 +1034,7 @@
return SWITCH_STATUS_FALSE;
}
-
+
if ((alertbuf = switch_channel_get_variable(channel, "alert_info"))) {
@@ -2418,10 +2428,29 @@
}
for (a = sdp->sdp_attributes; a; a = a->a_next) {
+ if (switch_strlen_zero(a->a_name)) {
+ continue;
+ }
if (!strcasecmp(a->a_name, "sendonly")) {
- switch_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
+ if (!switch_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
+ char *stream;
+
+ switch_set_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
+ switch_channel_set_flag(channel, CF_HOLD);
+ if (!(stream = switch_channel_get_variable(channel, SWITCH_HOLD_MUSIC_VARIABLE))) {
+ stream = tech_pvt->profile->hold_music;
+ }
+ if (stream) {
+ switch_ivr_broadcast(switch_core_session_get_uuid(tech_pvt->session), stream, SMF_ECHO_BLEG | SMF_LOOP);
+ }
+ }
} else if (!strcasecmp(a->a_name, "sendrecv")) {
- switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
+ if (switch_test_flag(tech_pvt, TFLAG_SIP_HOLD)) {
+ switch_clear_flag_locked(tech_pvt, TFLAG_SIP_HOLD);
+ switch_channel_clear_flag(channel, CF_HOLD);
+ switch_channel_clear_flag_partner(channel, CF_BROADCAST);
+ switch_channel_set_flag_partner(channel, CF_BREAK);
+ }
} else if (!strcasecmp(a->a_name, "ptime")) {
dptime = atoi(a->a_value);
}
@@ -5135,6 +5164,8 @@
profile->sipdomain = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "rtp-timer-name")) {
profile->timer_name = switch_core_strdup(profile->pool, val);
+ } else if (!strcasecmp(var, "hold-music")) {
+ profile->hold_music = switch_core_strdup(profile->pool, val);
} else if (!strcasecmp(var, "manage-presence")) {
if (switch_true(val)) {
profile->pflags |= PFLAG_PRESENCE;
Modified: freeswitch/trunk/src/switch_channel.c
==============================================================================
--- freeswitch/trunk/src/switch_channel.c (original)
+++ freeswitch/trunk/src/switch_channel.c Fri Mar 30 18:13:19 2007
@@ -396,6 +396,42 @@
return switch_test_flag(channel, flags) ? 1 : 0;
}
+SWITCH_DECLARE(switch_bool_t) switch_channel_set_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags)
+{
+ char *uuid;
+
+ assert(channel != NULL);
+
+ if ((uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
+ switch_core_session_t *session;
+ if ((session = switch_core_session_locate(uuid))) {
+ switch_channel_set_flag(switch_core_session_get_channel(session), flags);
+ switch_core_session_rwunlock(session);
+ return SWITCH_TRUE;
+ }
+ }
+
+ return SWITCH_FALSE;
+}
+
+SWITCH_DECLARE(switch_bool_t) switch_channel_clear_flag_partner(switch_channel_t *channel, switch_channel_flag_t flags)
+{
+ char *uuid;
+
+ assert(channel != NULL);
+
+ if ((uuid = switch_channel_get_variable(channel, SWITCH_BRIDGE_VARIABLE))) {
+ switch_core_session_t *session;
+ if ((session = switch_core_session_locate(uuid))) {
+ switch_channel_clear_flag(switch_core_session_get_channel(session), flags);
+ switch_core_session_rwunlock(session);
+ return SWITCH_TRUE;
+ }
+ }
+
+ return SWITCH_FALSE;
+}
+
SWITCH_DECLARE(void) switch_channel_set_flag(switch_channel_t *channel, switch_channel_flag_t flags)
{
assert(channel != NULL);
@@ -431,9 +467,20 @@
SWITCH_DECLARE(uint8_t) switch_channel_ready(switch_channel_t *channel)
{
+ uint8_t ret = 0;
+
assert(channel != NULL);
+
+ if (!channel->hangup_cause && channel->state > CS_RING && channel->state < CS_HANGUP && !switch_test_flag(channel, CF_TRANSFER)) {
+ ret++;
+ }
+
+ if (switch_test_flag(channel, CF_BREAK)) {
+ switch_clear_flag_locked(channel, CF_BREAK);
+ ret = (uint8_t) 0;
+ }
- return (!channel->hangup_cause && channel->state > CS_RING && channel->state < CS_HANGUP && !switch_test_flag(channel, CF_TRANSFER)) ? 1 : 0;
+ return ret;
}
static const char *state_names[] = {
Modified: freeswitch/trunk/src/switch_core_session.c
==============================================================================
--- freeswitch/trunk/src/switch_core_session.c (original)
+++ freeswitch/trunk/src/switch_core_session.c Fri Mar 30 18:13:19 2007
@@ -599,6 +599,7 @@
switch_channel_dequeue_dtmf(channel, buf, sizeof(buf));
}
+ switch_channel_clear_flag(channel, CF_BREAK);
}
Modified: freeswitch/trunk/src/switch_ivr.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr.c (original)
+++ freeswitch/trunk/src/switch_ivr.c Fri Mar 30 18:13:19 2007
@@ -108,11 +108,25 @@
const switch_application_interface_t *application_interface;
char *app_name = switch_event_get_header(event, "execute-app-name");
char *app_arg = switch_event_get_header(event, "execute-app-arg");
+ char *loop_h = switch_event_get_header(event, "loops");
+ int loops = 0;
+
+ if (loop_h) {
+ loops = atoi(loop_h);
+ }
if (app_name && app_arg) {
if ((application_interface = switch_loadable_module_get_application_interface(app_name))) {
if (application_interface->application_function) {
- application_interface->application_function(session, app_arg);
+ int x;
+ switch_channel_set_flag(channel, CF_BROADCAST);
+ for (x = 0; x < loops || loops < 0; x++) {
+ application_interface->application_function(session, app_arg);
+ if (!switch_channel_test_flag(channel, CF_BROADCAST)) {
+ break;
+ }
+ }
+ switch_channel_clear_flag(channel, CF_BROADCAST);
}
}
}
Modified: freeswitch/trunk/src/switch_ivr_async.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_async.c (original)
+++ freeswitch/trunk/src/switch_ivr_async.c Fri Mar 30 18:13:19 2007
@@ -737,8 +737,13 @@
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "execute-app-name", "%s", app);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "execute-app-arg", "%s", path);
+ if ((flags & SMF_LOOP)) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
+ }
+
switch_core_session_queue_private_event(other_session, &event);
}
+
switch_core_session_rwunlock(other_session);
master = other_session;
other_session = NULL;
@@ -749,6 +754,9 @@
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "call-command", "execute");
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "execute-app-name", "%s", app);
switch_event_add_header(event, SWITCH_STACK_BOTTOM, "execute-app-arg", "%s", path);
+ if ((flags & SMF_LOOP)) {
+ switch_event_add_header(event, SWITCH_STACK_BOTTOM, "loops", "%d", -1);
+ }
switch_core_session_queue_private_event(session, &event);
}
master = session;
Modified: freeswitch/trunk/src/switch_ivr_bridge.c
==============================================================================
--- freeswitch/trunk/src/switch_ivr_bridge.c (original)
+++ freeswitch/trunk/src/switch_ivr_bridge.c Fri Mar 30 18:13:19 2007
@@ -81,11 +81,22 @@
switch_channel_set_flag(chan_a, CF_BRIDGED);
- while (switch_channel_ready(chan_a) && data->running > 0 && his_thread->running > 0) {
- switch_channel_state_t b_state = switch_channel_get_state(chan_b);
+ for (;;) {
+ switch_channel_state_t b_state;
switch_status_t status;
switch_event_t *event;
+ if (!(data->running > 0 && his_thread->running > 0)) {
+ break;
+ }
+
+ /* if you really want to make sure it's not ready, test it twice because it might be just a break */
+ if (!switch_channel_ready(chan_a) && !switch_channel_ready(chan_a)) {
+ break;
+ }
+
+ b_state = switch_channel_get_state(chan_b);
+
switch (b_state) {
case CS_HANGUP:
case CS_DONE:
More information about the Freeswitch-svn
mailing list