[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